为什么Common Lisp不区分大小写?

wro*_*ame 15 common-lisp case-sensitive case-insensitive

是否有优势,定义一个函数一样(defun hi () "Hi!"),并能够通过调用它(hi)(HI)或者(Hi),或(setf a-number 5)并且能够使用访问数a-number,A-NUMBERA-Number

如果有这样的优势,那么为什么大多数其他语言区分大小写呢?

Rai*_*wig 27

在交互式会话中的代码中使用区分大小写的名称更容易出错.

Common Lisp区分大小写.只是Common Lisp reader功能默认情况下将符号的所有非转义字符转换为大写.这也在Common Lisp标准中定义.预定义的Common Lisp符号在内部也都是大写的.

在旧机器上使用大写是常见的.请记住,Common Lisp的设计始于八十年代初期(1982年),其目标是与早期的Maclisp兼容,并且有更多类型的计算机需要支持(如所谓的迷你计算机和大型机).旧计算机上使用的其他编程语言也使用大写标识符,如COBOL或PL/1.

另请注意,Lisp经常以交互方式使用,因此在交互式编程会话期间获取正确名称的情况更加困难.当Lisp阅读器使用默认情况(此处为大写)并将所有输入转换为此情况时,稍微容易一些.

Common Lisp支持其他阅读器模式,您也可以转义符号:|This is a Symbol with mixed CASE and spaces|.

今天,很多软件都是小写的,甚至是区分大小写的,只有小写首选.一些Lisp供应商提供了Common Lisp的非标准变体,默认情况下所有符号都是小写的,读者是保留的.但这使得它与标准的Common Lisp不兼容,其中期望(symbol-name 'cl:defun)是"DEFUN"而不是"defun".


EuA*_*reh 13

对于交互式会话,在定义Common Lisp标准时,情况不敏感曾经是默认值.

但是,真正发生的是Common Lisp阅读器在实习和评估之前将所有符号转换为upcase.这是默认设置,但如果需要,您可以随时更改它.

所述*readtable*对象具有属性,readtable情况,即控制读实习生和如何评估读出的符号.你可以setf readtable-case:upcase(默认), ,:downcase,.:preserve:invert

默认情况下,readtable-case设置为:upcase,这会导致所有符号都转换为upcase.

如果你想要区分大小写,你应该这样做

(setf (readtable-case *readtable*) :invert)
=> :invert
Run Code Online (Sandbox Code Playgroud)

乍一看,您可能认为最好选择:preserve选项,但它有一些小问题:标准定义的所有符号必须是upcased.因此,您将只对您定义的符号具有区分大小写,并且必须执行写操作:

* (DEFUN hi () "Hi!")
=> hi
* (SETF a-number 5)
=> a-number
* (HI)
=> ;error: the stored function is #'HI in the *readtable*, but by 
   ;       calling (HI) you try to acces a function named #'hi(downcase), which
   ;       gives an error
* A-NUMBER
=> ;error: same for the variable
* (hi)
=> "Hi!"
* a-number
=> 5
Run Code Online (Sandbox Code Playgroud)

:downcase选项与默认选项相反,将所有内容转换为小写,不会出现区分大小写.

:invert,你在源代码中写的符号,如defun,setfhi功能,转换为:upcase,在任何符号CamelCase被保留喜欢它的渊源:

* (setf (readtable-case *readtable*) :invert)
=> :invert
* (defun Hi () "Hi!")
=> Hi
* (Hi)
=> "Hi!"
* (eq 'Hi 'hi)
=> nil
* (eq 'HI 'hi)
=> nil
* (eq 'Hi 'Hi)
=> t
Run Code Online (Sandbox Code Playgroud)


Sva*_*nte 9

(正如其他人所指出的那样,它实际上是区分大小写的,但标准的读者行为是为了取消所有内容.)

至于优点:

  • 你真的想要HashtableHashTable命名不同的东西吗?
  • 由于Common Lisp提供了不同的命名空间,因此您也不需要大写来区分类,变量和函数名称(等等).你可以拥有一个没有歧义的类name和函数name. Name甚至可以是变量的名称.
  • 正如在最后一句中所看到的,您可以像任何其他单词一样将散文中的符号名称大写.

  • @wrongusername:这是明确的.当你有一个被评估的形式`(name foo)`时,它明确地是一个函数`name`; 当你有`(defmethod bar((baz name))...)`时,它明确地是一个类`name`(或者更确切地说是类型......); 当你看到一个评估形式``(quux name)`时,它是一个明确的变量.它就像你可以使用"名字"作为英语中的动词和名词而没有混淆. (3认同)