如何使 Lisp 输入区分大小写

How to make Lisp input case sensitive

我正在用 lisp 编程。我正在处理的功能是将两个列表附加在一起,并且有效。

但是,输出也以大写字母形式返回,并且何时。我使用转义符号,小写字母被“|”包围符号。这是一个例子:

“输入您的第一个列表”

(a b)

“输入另一个列表”

(\a\b)

输出:(A B |a| |b|)

我希望它是 (a b a b)。

有没有办法以不同的方式输入内容或编写一个函数来解决这个问题? 我当前的 REPL 将输入存储为变量,通过函数运行它,然后输出它。谢谢!

默认情况下,所有符号都以大写形式保留。例如,当您写 defun 时,它在内部被读取为 DEFUN,即带有 symbol-name 字符串 "DEFUN".

的符号

有两种方法 ad hoc 覆盖此阅读行为:您可以使用 \ 转义符号中的单个字符,或者您可以通过将多个字符括起来来转义多个字符在管道 |…| 中。转义字符在输入时被采用,可以是 any 个字符。 |This is a valid symbol.| 而它的 symbol-name 是 "This is a valid symbol.".

因此,每个都成为 symbol-name 为“Abc”的符号:

a\b\c
a|bc|
|Abc|

现在,打印机打印符号的方式使得reader读入时它们是相同的象征。因此,如果符号名称中有任何 lower-case 或 non-constituent 字符,则需要以上述方式之一对它们进行转义。我的 SBCL 使用最后一个选项。

您可以通过可读表自定义 read/print 行为。例如,您可以将 readtable-case 设置为 :preserve:

(defun foo ()
  (let ((*readtable* (copy-readtable *readtable*)))
    (setf (readtable-case *readtable*) :preserve)
    (print (append (read) (read)))))

如果现在运行(foo),然后输入(a b)(A B),先打印(a b A B),然后REPL打印返回列表作为 (|a| |b| A B) 因为我们确保只更改实际可读表的词法范围副本。

您可以在 Hyperspec 中阅读并尝试一下。如果您有实际问题需要解决,我们将不得不看看如何最好地解决它。