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

时间:2011-09-11 00:25:03

标签: common-lisp case-sensitive case-insensitive

定义像(defun hi () "Hi!")这样的函数是否有优势,并且可以使用(hi)(HI)(Hi)(setf a-number 5)来调用它并且能够使用a-numberA-NUMBERA-Number访问该号码?

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

4 个答案:

答案 0 :(得分:26)

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

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”。

答案 1 :(得分:13)

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

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

*readtable*个对象有一个属性readtable-case,用于控制阅读器如何实现内容并评估读取的符号。您可以setf readtable-case:upcase(默认),:downcase:preserve:invert

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

如果您想要区分大小写,则应该

(setf (readtable-case *readtable*) :invert)
=> :invert

乍一看,您可能认为最好选择: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

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

但是使用:invert,您在源代码中编写的符号(如defunsetf hi函数)将转换为upcase,以及CamelCase中的任何符号{1}}保留原样:

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

答案 2 :(得分:9)

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

关于优势:

  • 您真的希望HashtableHashTable命名不同的东西吗?
  • 由于Common Lisp提供了不同的命名空间,因此您也不需要大写来区分类,变量和函数名(除其他外)。您可以拥有一个类name和一个没有歧义的函数nameName甚至可以是变量的名称。
  • 如最后一句所示,您可以像散文一样将散文中的符号名称大写。

答案 3 :(得分:3)

默认情况下,CL中的阅读器是大小写转换,所有转义字符都变为大写。您可以使用readtable-case自定义此行为。这是因为它易于与遵循相同约定的其他语言进行交互。