区分大小写Common Lisp

时间:2015-09-24 18:25:43

标签: windows debugging common-lisp case-sensitive

我试图让sbcl区分大小写但没有成功。 有谁知道问题可能是什么?它是mentions herehere

我正在运行

(setf (readtable-case *readtable*) :invert)
(defun hi () "Hi!")
(HI)
(HI)
"Hi!"

在repl里面,如下所示。

"C:\Program Files\Steel Bank Common Lisp\1.2.15\sbcl.exe" --core "C:\Program Files\Steel Bank Common Lisp\1.2.15\sbcl.core"

编辑:因此,如果您在Common Lisp中调用一个区分大小写的函数,它会恢复到旧的行为,即对于程序的其余部分不敏感,我找不到任何方法当前阻止这种情况。

; in: Hi2
;     (|Hi2|)
;
; caught style-warning:
;   undefined function: Hi2
;
; compilation unit finished
;   Undefined function:
;     Hi2
;   caught 1 STYLE-WARNING condition

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {1002C77BE3}>:
  The function COMMON-LISP-USER::|Hi2| is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

2 个答案:

答案 0 :(得分:5)

Common Lisp 总是区分大小写。符号有名称,只是字符串。但是,很少有东西能让事情看起来像是不区分大小写的。要了解这些是什么,您需要了解一下系统如何读取代码。

当系统读取表单时,它必须从文本表示创建一个Lisp对象。例如,如果读者正在读取类似于(hello world)的字符串,那么结果应该是两个符号的列表。这些符号的名称是什么?那就是读者有一定的灵活性。默认行为是读者 upcase 从输入中读取的名称。读者得到了输入&#34;你好&#34; &#34; world&#34;,然后提升这些&#34; HELLO&#34;和&#34; WORLD&#34;,然后实习生。正如您所发现的,这是由可读案件控制的。有几种不同的可能性,即:upcase,:downcase,:preserve和:invert。 :保留和:反转对于互操作性代码非常方便。

函数具有区分大小写或没有区别是没有意义的。可读案例仅影响读者将文本输入转换为符号名称的方式。听起来你想要做的就是确保readtable-case是:保存或:当你阅读代码时反转。请注意,如果readtable-case为:invert,则所有小写字母名称都会上升,所有大写字母名称都会下降,其他所有内容都会被保留。我指出这一点是因为在你的例子中(defun hi()&#34;嗨!&#34;),文字&#34; hi&#34;将被提升,并且您定义一个函数的符号将具有名称&#34; HI&#34;。然后,当你写(HI)时,读者将生成一个名为&#34; hi&#34;的符号列表,它不能是相同的符号。

到目前为止提供的代码并不像您的示例显示的那样工作,并且它看起来不像复制粘贴REPL脚本。这是我在运行您显示的代码时看到(并期望)的内容:

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

:invert
* (defun hi () "hello")

hi

(hi)有效,因为读者仍然会反转并给出一个名为&#34; HI&#34;的符号,如预期的那样:

* (hi)

"hello"

但写(HI)并不是,因为读者反转并给出一个名为&#34; hi&#34;的符号,如预期的那样:

* (HI)
; in: HI
;     (|hi|)
; 
; caught style-warning:
;   undefined function: HI
; 
; compilation unit finished
;   Undefined function:
;     HI
;   caught 1 STYLE-WARNING condition

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {1002FDE7D3}>:
  The function COMMON-LISP-USER::|hi| is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

("undefined function")

现在,在以交互方式测试时,您需要清楚自己是否会陷入调试器,因为某些设置(如readtable-case)可能会在调试器为方便起见。例如,

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

:invert
* (defun hi () "hello")

hi
* (HI)
; in: HI
;     (|hi|)
; 
; caught style-warning:
;   undefined function: HI
; 
; compilation unit finished
;   Undefined function:
;     HI
;   caught 1 STYLE-WARNING condition

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {1002FDE7D3}>:
  The function COMMON-LISP-USER::|hi| is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

("undefined function")
0] TOP

我们输入 TOP 以退出调试器。您可以输入以获取可用命令列表。现在我们回到顶级REPL,我们可以看到(HI)会有相同的结果。这一次,我们也会尝试在调试器中执行(HI)

* (HI)

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {1002FDE7D3}>:
  The function COMMON-LISP-USER::|hi| is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SYMBOL-FUNCTION |hi|)
0] (HI)                   ;; within the debugger

"hello"                   ;; "HI" must have been read as "HI", not "hi"
0] TOP

在debuger中,(HI)工作得很好。它必须重新设置回一些标准&#34;使程序员的生活更轻松的价值观。输入 TOP 后,我们会返回REPL,(HI)会再次失败:

* (HI)

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "main thread" RUNNING {1002FDE7D3}>:
  The function COMMON-LISP-USER::|hi| is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(SYMBOL-FUNCTION |hi|)
0] 

答案 1 :(得分:3)

您的示例不起作用:

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

:invert
* (defun hi () "Hi!")

hi
* (HI)
; in: HI
;     (|hi|)
;
; caught style-warning:
;   undefined function: HI
;
; compilation unit finished
;   Undefined function:
;     HI
;   caught 1 STYLE-WARNING condition

debugger invoked on a UNDEFINED-FUNCTION:
  The function COMMON-LISP-USER::|hi| is undefined.

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

("undefined function")
0] 

请注意,0]表示我们在0级调试器中,它具有正常的可读大小写。退出调试器,只需查看打印的说明,输入0,然后我们回到顶层监听器 - 可读表格仍为:invert

如果您阅读了SBCL打印的内容:(invokable by number or by possibly-abbreviated name)。然后,您会看到0[ABORT]。所以你用数字来调用它。只需输入0并返回即可。您也可以输入abort

向调试器输入HELP解释它......

如果使用内容

编译文件
(setf (readtable-case *readtable*) :invert)
(defun hi () "Hi!")
(HI)

,然后第一个表单对编译时环境没有影响,因为编译器不执行那段代码。它只是编译它。读者不会改变。加载代码时会更改。请参阅EVAL-WHEN以在编译时执行顶级代码。