为什么 Lisp 中的单引号总是 return 大写?

Why does single quote in Lisp always return upper case?

我希望能够通过单引号设置大小写,但这似乎不可能。

(format nil "The value is: ~a" 'foo)
"The value is: FOO"

(format nil "The value is: ~a" 'FOO)
"The value is: FOO"

(format nil "The value is: ~a" "Foo")
"The value is: Foo"

Lisp 符号,如 'a,不区分大小写。您可以通过执行...

来检查
(eq 'a 'A)

它们是相同的符号。

如需区分大小写,应酌情使用字符串或字符。

为了使format在特定情况下打印符号,您可以根据需要从set the *print-case* global variable:upcase:downcase:capitalize .

好的,这有效:

(format nil "The value is: ~a" (string-downcase 'foo))
"The value is: foo"

更好(来自 Rainer)

 (format nil "The value is: ~(~a~)" 'foo)

我仍然认为,如果要表示字符串,则不应使用 'foo 而不是 "foo"。

引用

引用与大小写无关。 quote 阻止计算。

引用符号:

CL-USER 1 > 'foo
FOO

引用列表:

CL-USER 2 > '(1 2 3 foo)
(1 2 3 FOO)

你可以在很多东西前面加上引号。比如前面一个字符串:

CL-USER 3 > '"a b c"
"a b c"

由于字符串对自身求值,因此是否引用它们没有区别:

CL-USER 4 > "a b c"
"a b c"

符号默认为大写:

CL-USER 5 > 'FooBar
FOOBAR

CL-USER 6 > (symbol-name 'FooBar)
"FOOBAR"

但这与引用无关,是 reader.

特征
CL-USER 7 > (read-from-string "foo")
FOO
3

小写

如果你想要小写的字符串,你需要将字符串转换为小写:

CL-USER 8 > (string-downcase (symbol-name 'FooBar))
"foobar"

大小写混合的符号

但是您可以使用小写名称或混合大小写来创建符号。你需要逃避他们:

CL-USER 9 > '|This is a symbol With spaces and mixed case|
|This is a symbol With spaces and mixed case|

CL-USER 10 > 'F\o\oB\a\r
|FooBar|

使用 FORMAT

缩小输出

您还可以告诉 FORMAT 以小写形式打印:

CL-USER 11 > (format nil "The value is: ~(~a~)" 'foo) 
"The value is: foo"

'foo 表示 "suppress the evaluation of the symbol FOO, leaving only the symbol FOO"。 Common Lisp 默认倾向于大写符号名称(因此表示为 'foo'Foo'FOO 的符号都是相同的符号,符号名称为 "FOO")。

要准确了解您的实现将做什么,您可以通过调用 (readtabe-case *readtable*).

检查当前可读表 see CLHS, ch 23.1.2, effect of readtable case 的可读大小写

一些 lisp 实现将以 readtable-case 开头,如 :preserve

至于是否应该使用符号或字符串,这是其中之一 "it depends"。如果您不担心 cse 保存,使用 interned 符号可以减少存储空间并加快比较速度,但代价是大小写处理(可能)。但如果大小写很重要,天平可能会更接近天平的 "use strings throughout" 端。

要了解发生了什么,请参阅 Rainer Joswigs 的回答。只需添加一件事:您可以使用 *print-case*:

控制打印符号(没有竖线语法)的大小写
CL-USER 1 > (let ((*print-case* :downcase))
              (format nil "The value is: ~a" 'foo))
"The value is: foo"

CL-USER 2 > (let ((*print-case* :capitalize))
              (format nil "The value is: ~a" 'foo))
"The value is: Foo"

CL-USER 3 > (let ((*print-case* :upcase)) ; default
              (format nil "The value is: ~a" 'foo))
"The value is: FOO"