指定者的本质是什么?

Bag*_*ers 5 common-lisp

Svante通过在另一个答案中显示字符串指示符来引起我的注意:

(string= :& "&") -> T
Run Code Online (Sandbox Code Playgroud)

看看CLHS,他们说A designator is an object that denotes another object.哪个好,但由于这些是不同的对象,某种强制需要在某个地方发生.我的意思是,如果下面的列表指示符可以通过'非零原子'来满足,则某些逻辑存在于处理此问题的某处.

列表指示符 对象列表的指示符; 也就是说,一个表示列表的对象,它是以下之一:非零原子(表示单元素列表,其元素是非零原子)或正确的列表(表示自身).

我认为指示符可能是一个概念,例如,通用函数......但是来自CLHS的以下行...

除非另有说明,否则在所表示的对象可能被多次使用的情况下,无论对象是仅被强制一次还是每次必须使用对象时都发生强制,它都是依赖于实现的.

...然后看起来非常具体.

所以我的问题

  • 什么是如何在实现中实现指示符的示例?
  • 这种机制是否可由用户以任何方式扩展?
  • 这种机制在指定人员中是否一致?(看起来似乎有18种指示符)

干杯

Jos*_*lor 7

指定符只不过是(或更少)指定另一个指定符的对象.关于他们的语言并没有什么特别之处; 指示符的概念只是使某些编程实践更容易的概念.词汇表说:

标志 ñ.表示另一个对象的对象.在操作符的字典条目中,如果参数被描述为类型的指示符,则操作符的描述以假定已经发生对该类型的适当强制的方式编写; 也就是说,该参数已经是所表示的类型.有关更多详细信息,请参见第1.4.1.5节(指示符).

该部分的链接很有帮助:

1.4.1.5指示符

指示符是表示另一个对象的对象.

在将操作符的参数描述为指示符的情况下,以假定参数的值是表示的对象的方式编写操作符的描述; 也就是说,该参数已经是所表示的类型.(由"«type»指示符"表示的对象的特定性质或"«type"的"指示符"可在"«type»指示符的词汇表条目中找到.")

能够在词汇表中查找内容有助于.例如,字符串指示符 可以代表字符串:

串标志 ñ.字符串的指示符; 也就是说,一个表示字符串的对象,它是以下之一:一个字符(表示以字符作为唯一元素的单个字符串),一个符号(表示其名称的字符串)或一个字符串(表示自身) ).意图是这个术语与字符串的行为一致; 扩展字符串的实现必须以兼容的方式扩展该术语的含义.

该标准也恰好定义了获取字符串指示符指定的字符串的函数字符串:

返回x描述的字符串; 特别:

  • 如果x是一个字符串,则返回它.
  • 如果x是符号,则返回其名称.
  • 如果x是一个字符,则返回包含该一个字符的字符串.string可能会执行其他实现定义的转换.

这简化了必须使用字符串和字符串之类的函数的实现.例如,您可以定义一个make-person函数接受一个字符串指示符:

(defun make-person (name)
  "Return a person with the name designated by NAME."
  (list :name (string name)))

(defun person-name (person)
  "Return the name of a person (a string)."
  (getf person :name))
Run Code Online (Sandbox Code Playgroud)

指定符的概念不仅仅是一种编程约定,它使得定义灵活的API变得更容易.Common Lisp被定义为将一堆现有Lisp联合起来的语言,它可能是统一不同实现行为的更简单方法之一.

列表指示符的概念可以在案例中使用

列表标志 ñ.对象列表的指示符; 也就是说,一个表示列表的对象,它是以下之一:非零原子(表示单元素列表,其元素是非零原子)或正确的列表(表示自身).

case keyform {normal-clause}*[otherwise-clause] => result*

normal-clause :: =(密钥形式*)

keys - 对象列表的指示符.在情况下,符号t和否则可以不用作键指示符.要将这些符号自身称为键,必须分别使用指示符(t)和(否则).

我不知道,它返回一个列表标志指定列表中的功能,但它很容易写(这不处理的特殊行为ŧ否则情况下的需求,但它处理一般名单代号):

(defun to-list (x)
  "Return the list designated by x."
  (if (listp x) x
    (list x)))
Run Code Online (Sandbox Code Playgroud)

像这样的约定有时会在你自己的代码中有用,特别是如果你定义的东西是"注册表"的东西.例如,如果你写了以下任何一个:

(defmacro deftransform (name &rest args)
  `(setf (gethash ',name *transforms*)
         (make-transform ,@args)))
Run Code Online (Sandbox Code Playgroud)

(defmacro deftransform (name &rest args)
  (setf (get ',name 'transform) (make-transform ,@args)))
Run Code Online (Sandbox Code Playgroud)

然后,您可以将变换指示符的概念定义为变换对象或符号(指定*变换*表中符号的值,或符号上变换属性的值).例如:

(defun transform (x)
  (if (transformp x) x
    (gethash name *transforms*)))
Run Code Online (Sandbox Code Playgroud)

(defun transform (x)
  (if (transformp x) x
    (get x 'transform)))
Run Code Online (Sandbox Code Playgroud)

这可能会使您的部分代码更易于使用.功能指示符类似


ace*_*ent 6

对象指示符通常是包含多种对象来表示或命名预期对象的东西。

好的指示符定义不包含nil(即允许您指定对象),具有不相交的指示符类型,并且指示符通常是指向预期对象的名称或对象。

注意:在我看来,指示符是不必要的快捷方式,在使用 REPL 或原型设计时最有用。

以下是主观分类的指示符的非详尽列表。

好的指示符(本质上是非零、命名或容器、指示符):

不太好的指示符:

  • 外部文件格式指示符

    它的定义故意是开放式的并且依赖于实现,因此由实现来尝试定义好的指示符。除此之外,还可以。

  • 封装代号

    它的定义基于字符串指示符。除此之外,还可以。

  • 路径名指示符

    我对此有复杂的感觉,主要是因为流不是可靠的路径名指示符。只有文件流和此类流的同义词流才是。

    对于可以获取流或打开流本身的给定函数,有时传递一个已经打开的流进行读取或写入并可选择将其保持打开状态很有用,有时传递要在(或类似with-open-file的),所以这里的汇合就丢失了。

    但是,这样的函数可能应该分为两部分,一个显式采用流指示符,另一个显式采用路径名指示符。

  • 字符串指示符

    字符串包含一个字符,而不是相反。然而,单例字符串可以用它的单个字符来命名,所以我想这还不错。

    该指示符不好的一种特殊情况是破坏性操作,该操作仅采用实际字符串。这是预期的,但这是您必须注意的细节,例如,如果您从 切换string-upcasenstring-upcase.

错误的指示符:

  • 列表指示符

    您必须知道,没有 的指示符(nil)

  • 可读表指示符

    nil代表标准可读表,不能不指定可读表。否则,一个不显眼的信号nil不会表示错误。

  • 流指示符

    nil用作上下文相关指示符时,在这种情况下不能不指定流。否则,一个不显眼的信号nil不会表示错误。

  • 流变量指示符

    与流指示符的原因相同。