【问题标题】:Case Sensitivity Common Lisp区分大小写 Common Lisp
【发布时间】:2015-12-22 11:19:36
【问题描述】:

我试图让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.

【问题讨论】:

  • 作为旁注,我知道(|Fun| args) 语法,我不希望将其作为答案。
  • 出于好奇,为什么?
  • @Linuxios 因为我正在尝试将代码与区分大小写的 c 接口。
  • 您的第一个示例无法运行。您需要写 (hi) 来调用该函数。
  • @RainerJoswig 我的意思是它确实有效,这意味着它不尊重区分大小写的设置。

标签: windows debugging common-lisp case-sensitive


【解决方案1】:

Common Lisp总是区分大小写。符号有名称,它们只是字符串。但是,几乎没有什么东西可以让事情看起来不区分大小写。要掌握这些是什么,您需要对系统如何读取代码有所了解。

当系统读取一个表单时,它必须从文本表示中创建一个 Lisp 对象。例如,如果阅读器正在读取如下字符串:(hello world),那么结果应该是两个符号的列表。这些符号的名称是什么?这就是读者有一些灵活性的地方。默认行为是让读者大写从输入中读取的名称。读者获得输入“hello”和“world”,然后将它们大写为“HELLO”和“WORLD”,然后将它们实习。正如您所发现的,这由 readtable 案例控制。有几种不同的可能性,即:upcase、:downcase、:preserve 和:invert。 :Preserve 和 :invert 可以方便地用于互操作性代码。

函数是否区分大小写是没有意义的。 readtable case 仅影响阅读器如何将文本输入转换为符号名称。听起来您想要做的是确保在您阅读代码时 readtable-case 是 :preserve 或 :invert 。请注意,如果 readtable-case 是 :invert,则所有小写名称都会大写,所有大写名称都会小写,其他所有内容都将保留。我指出这一点是因为在您的示例 (defun hi () "Hi!") 中,文本“hi”将被大写,并且您定义函数的符号将具有名称“你好”。然后,当你写(HI)时,阅读器会生成一个名为“hi”的符号列表,不能是同一个符号。


目前提供的代码与您的示例显示的工作方式不同,而且它看起来不像是复制粘贴的 REPL 脚本。这是我在运行您显示的代码时看到(和期望)的:

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

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

hi

编写 (hi) 有效,因为阅读器仍然会反转并给您一个名为“HI”的符号,正如预期的那样:

* (hi)

"hello"

但写成 (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 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

在调试器中,(HI) 工作得很好。它必须重置为一些“标准”值,以使程序员的生活更轻松。但是,进入 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] 

【讨论】:

  • 问题是它似乎不尊重设置。
  • @William 我认为您到目前为止显示的代码并未说明情况似乎如此。您能否附上一份说明问题的 REPL 的实际成绩单?
  • 第二次运行(HI),你就会明白我的意思了。 pastebin.com/raw.php?i=YYhw7Nze
  • @William 再次运行(HI),我得到了同样的错误。但那是 离开调试器之后。我想你可能在第二次运行(HI) 而你仍然调试器中?
  • 大概就是这样,调试器怎么退出?
【解决方案2】:

你的例子不起作用:

* (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 以在编译时执行顶级代码。

【讨论】:

  • 第二次运行(HI),你就会明白我的意思了。 pastebin.com/raw.php?i=YYhw7Nze
  • @William:退出调试器,它使用自己的可读案例,然后重试。没问题。
  • 加一个,虽然 Joshua 回答了第一个并且可能首先找到了根,所以我要把它给他。
猜你喜欢
  • 2011-11-14
  • 2011-07-27
  • 2012-03-10
  • 2020-09-08
  • 2012-12-01
  • 2013-03-06
  • 2020-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多