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

发布于 2024-12-04 03:13:04 字数 253 浏览 2 评论 0原文

定义像 (defun hi () "Hi!") 这样的函数并能够使用 (hi)(HI )(Hi),或 (setf a-number 5) 并能够使用 a-numberA-NUMBERA 号码

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

Is there an advantage to defining a function like (defun hi () "Hi!") and be able to call it by using (hi) or (HI) or (Hi), or to (setf a-number 5) and be able to access that number using a-number, A-NUMBER, or A-Number?

If there is such an advantage, then why are most other languages case-sensitive?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

行至春深 2024-12-11 03:13:04

在交互式会话中的代码中使用区分大小写的名称更容易出错:不仅必须获取字符,还必须正确区分大小写,并且可能存在多个名称仅大小写不同的标识符。

Common Lisp 区分大小写。只是 Common Lisp 阅读器功能默认将符号的所有未转义字符转换为大写。 Common Lisp 标准中也对此进行了定义。预定义的 Common Lisp 符号内部也都是大写的。

符号在内部是大写的:

CL-USER 3 > 'defparameter
DEFPARAMETER

默认情况下输入大小写无关紧要:

CL-USER 4 > 'deFParameTER
DEFPARAMETER

CL-USER 5 > 'DEFPARAMETER
DEFPARAMETER

符号的名称是大写的:

CL-USER 6 > (symbol-name 'defparameter)
"DEFPARAMETER"

CL 包中有多少个符号:

CL-USER 7 > (length (apropos-list "" "CL"))
978

CL 包中的每个符号都是大写的吗?

CL-USER 8 > (every (lambda (symbol)
                     (every (lambda (c)
                              (eql c (char-upcase c)))
                            (symbol-name symbol)))
                   (apropos-list "" "CL"))
T

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

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

Common Lisp 支持其他阅读器模式,您还可以转义符号:|这是一个混合 CASE 和空格的符号|

如今,许多软件要么是小写的,要么是区分大小写的,并且优先考虑小写。一些 Lisp 供应商提供了 Common Lisp 的非标准变体,其中所有符号默认均为小写,并且读者保留大小写。但这使得它与标准 Common Lisp 不兼容,其中期望 (symbol-name 'cl:defun) 是“DEFUN”而不是“defun”。

Using case sensitive names in code within an interactive session is just more error-prone: one not only has to get the characters, but also their case right and there might be several identifiers whose names only differ in case.

Common Lisp is case sensitive. It is just that the Common Lisp reader functionality by default converts all unescaped characters of symbols to uppercase. This is also defined in the Common Lisp standard. The predefined Common Lisp symbols are also all uppercase internally.

a symbol is internally upcase:

CL-USER 3 > 'defparameter
DEFPARAMETER

The input case by default does not matter:

CL-USER 4 > 'deFParameTER
DEFPARAMETER

CL-USER 5 > 'DEFPARAMETER
DEFPARAMETER

a symbol has an upcase name:

CL-USER 6 > (symbol-name 'defparameter)
"DEFPARAMETER"

how many symbols are in the CL package:

CL-USER 7 > (length (apropos-list "" "CL"))
978

Is every symbol in the CL package upcased?

CL-USER 8 > (every (lambda (symbol)
                     (every (lambda (c)
                              (eql c (char-upcase c)))
                            (symbol-name symbol)))
                   (apropos-list "" "CL"))
T

Using uppercase was common on old machines. Remember, the design of Common Lisp started in the early eighties (1982) and a goal was compatibility with earlier Maclisp and when there were more types of computers to support (like the so-called Mini Computers and Mainframes). Other programming languages used on older computers also use uppercase identifiers, like COBOL or PL/1.

Also note that Lisp often was used interactively, so that during an interactive programming session getting the case of names right is more difficult. It is slightly easier when the Lisp reader uses a default case (here uppercase) and converts all input to this case.

Common Lisp supports other reader modes and you can also escape symbols: |This is a Symbol with mixed CASE and spaces|.

Today a lot of software is either lowercase or even case sensitive with lowercase preferred. Some Lisp vendors provide a non-standard variant of Common Lisp, where all symbols by default are lowercase and the reader is case preserving. But this makes it incompatible with standard Common Lisp, where the expectation is that (symbol-name 'cl:defun) is "DEFUN" and not "defun".

梦中楼上月下 2024-12-11 03:13:04

对于交互式会话,在定义 Common Lisp 标准时,不区分大小写曾经是默认设置。

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

*readtable* 对象有一个属性,readtable-case,它控制读取器如何实习和评估读取的符号。您可以将 setf readtable-case 设置为 :upcase(默认)、:downcase:preserve:反转

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

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

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

乍一看,你可能认为选择 :preserve 选项会更好,但它有一些小问题:标准定义的所有符号都必须大写。因此,您只对您定义的符号区分大小写,并且必须编写:

* (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 时,您在源代码中编写的符号,例如 defunsetfhi 函数,转换为大写,并且 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

For interactive sessions, the case unsensitivity used to be the default when the Common Lisp standard was defined.

But, what truly happens is that the Common Lisp reader converts all symbols to upcase before interning and evaluating it. That is the default, but you can always change it if you want.

The *readtable* objects has an attribute, readtable-case, that controls how the reader interns and evaluates the symbols read. you can setf readtable-case to :upcase(default), :downcase, :preserve, :invert.

By default, the readtable-case is set to :upcase, which causes all symbols to be converted to upcase.

If you want case sensitivity, you should do

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

At a first glance, you might think that it would be better to choose the :preserve option, but it has some minor issue: all the symbols, as defined by the standard, must be upcased. So, you would have case sensitivity to the symbols defined by you only, and would have to do write:

* (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

The :downcase option is the opposite of the default, converting everything to downcase, giving you no case sensitivity.

But with :invert, the symbols you write in the source code, like defun, setf the hi function, get converted to upcase, and any symbol in CamelCase is preserved like it is originaly:

* (setf (readtable-case *readtable*) :invert)
=> :invert
* (defun Hi () "Hi!")
=> Hi
* (Hi)
=> "Hi!"
* (eq 'Hi 'hi)
=> nil
* (eq 'HI 'hi)
=> nil
* (eq 'Hi 'Hi)
=> t
长亭外,古道边 2024-12-11 03:13:04

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

至于优点:

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

(As others have pointed out, it is actually case-sensitive, but standard reader behaviour is to upcase everything.)

As to the advantages:

  • Do you really want Hashtable and HashTable to be naming different things?
  • Since Common Lisp provides different namespaces, you also do not need capitalization to tell class, variable, and function names apart (among others). You can have a class name and a function name with no ambiguity. Name can even be the name of a variable, on top of that.
  • As seen in the last sentence, you can capitalize symbol names in prose just like any other words.
深海蓝天 2024-12-11 03:13:04

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

By default the reader in CL is case converting, all escaped characters get turned into uppercase. You can customize this behavior with readtable-case. This is because its easy to interface with other languages that follow the same conventions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文