简单 Lisp Case 语句问题 - 与 nil 比较的问题

发布于 2024-11-09 15:29:44 字数 792 浏览 5 评论 0原文

我正在尝试使用 case 语句来使某些代码更具可读性。它似乎作为一系列 if 语句工作,但由于某种原因,case 语句总是接受与 nil 的比较,即使它不正确。有人可以澄清为什么会出现这种行为吗?

示例:

> (case 'a            
    (nil nil)         
    (otherwise 'b))   
NIL                   
> (case 'a            
    ('a 'b)           
    (otherwise nil))  
B                       

在上面的示例中,第一个实例返回 nil,即使 'a 显然不是 nil。尝试对 if 语句做同样的事情,其行为正如我所期望的:

> (if (eq 'a nil) nil 'b)    
B                            
> (if (eq 'a 'a) 'b nil)     
B                            

我假设 case 语句有一些我不理解的行为。任何帮助将不胜感激。

编辑: 只是为了澄清,我知道 'a 不会被评估。我只是模拟了这个例子来创建一个 case 语句的目标绝对不为零的情况。

我正在使用 xlisp-plus,但我将尝试真正的 clisp 安装,看看它的行为是否有所不同。

编辑(再一次): 安装了 CLISP 并且运行良好。确实不值得费心去研究 xlisp 为何不同。谢谢大家的健全性检查。

I'm trying to use a case statement to make some code more readable. It seems to work as a series of if statements, but for some reason the case statement always accepts a comparison to nil even if it is not true. Can someone clarify why this behavior occurs?

Example:

> (case 'a            
    (nil nil)         
    (otherwise 'b))   
NIL                   
> (case 'a            
    ('a 'b)           
    (otherwise nil))  
B                       

In the above example, the first instance returns nil, even though 'a clearly is not nil. Trying to do the same thing with if statements behaves as I would expect:

> (if (eq 'a nil) nil 'b)    
B                            
> (if (eq 'a 'a) 'b nil)     
B                            

I'm assuming there is some behavior about the case statement I do not understand. Any help would be appreciated.

Edit:
Just to clarify, I know that 'a won't be evaluated. I just mocked up this example to create a situation in which the target of the case statement was definitely NOT nil.

I'm using xlisp-plus, but I'm going to try a real clisp install and see if it behaves differently.

Edit (one more time):
Installed CLISP and it works fine there. Not really worth the trouble to investigate why xlisp is different. Thanks for the sanity check, everyone.

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

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

发布评论

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

评论(5

烟柳画桥 2024-11-16 15:29:44

CASE 中的每个关键规范可以是文字列表或单个原子。然而,CLtL 表示原子不能是NIL 因为它是不明确的,它是文字 NIL 还是空列表。使用 NIL 列表代替:

> (case 'a
    ((nil) nil)         
    (otherwise 'b))
B
> (case nil
    ((nil) nil)         
    (otherwise 'b))
NIL

Each of the key specifications in a CASE may be either a list of literals or a single atom. However, CLtL says that the atom must not be NIL since it is ambiguous as to whether it is the literal NIL or an empty list. Use a list of NIL instead:

> (case 'a
    ((nil) nil)         
    (otherwise 'b))
B
> (case nil
    ((nil) nil)         
    (otherwise 'b))
NIL
紅太極 2024-11-16 15:29:44

Common Lisp 期望 CASE 测试的项目是一个原子或一个原子列表。测试也是函数EQL。

(case 'a
  (a 'b)    ; EQL a
  (otherwise 'foo))

(case 'a
  ((a b c) 'foo)   ; EQL to one of a, b or c
  (otherwise 'bar))

引用的内容只是偶然发生的。不要使用它:

; don't use this:
(case 'a
  ('a 'foo)    ; <- bad!  , EQL to QUOTE or A
  (otherwise 'bar))

上面与以下相同:

; don't use this:
(case 'a
  ((quote a) 'foo)   ; <- bad! ,  EQL to QUOTE or A
  (otherwise 'bar))

Common Lisp expects for CASE the item to test to be an atom or a list of atoms. The test also is the function EQL.

(case 'a
  (a 'b)    ; EQL a
  (otherwise 'foo))

(case 'a
  ((a b c) 'foo)   ; EQL to one of a, b or c
  (otherwise 'bar))

The quoted for only works by accident. Don't use it:

; don't use this:
(case 'a
  ('a 'foo)    ; <- bad!  , EQL to QUOTE or A
  (otherwise 'bar))

Above is the same as:

; don't use this:
(case 'a
  ((quote a) 'foo)   ; <- bad! ,  EQL to QUOTE or A
  (otherwise 'bar))
情仇皆在手 2024-11-16 15:29:44

我认为这取决于你的 LISP 版本。
我在 Mac 上安装了 LispWorks,结果如下:

CL-USER 2 : 1 > (case 'a            
    (nil nil)         
    (otherwise 'b))   
B

i think that it depends on your LISP version.
I have LispWorks on Mac and my result :

CL-USER 2 : 1 > (case 'a            
    (nil nil)         
    (otherwise 'b))   
B
§对你不离不弃 2024-11-16 15:29:44

与 SBCL 相同:

CL-USER> (case 'a
           (nil nil)
           (otherwise 'b))
B

也就是说,'a 是一个符号,因此永远不可能是 nil

Same here with SBCL:

CL-USER> (case 'a
           (nil nil)
           (otherwise 'b))
B

That said, 'a is a symbol and as such can never be nil.

橘味果▽酱 2024-11-16 15:29:44

case 表单中的值是隐式的带引号的文字列表,因此: 这

(case 'a
  ((a) 'b)
  (otherwise nil))

就是您想要的。 否则应该可以工作(正如其他人所说)——尝试t代替。

顺便说一句,当您使用 'a 时,阅读器将其读取为 (quote a) 这意味着当值为 quote 时它也会选择它, 例如:

(case 'quote
  ('a 'b)
  (otherwise nil))

The values in a case form are implicitly quoted lists of literals, so this:

(case 'a
  ((a) 'b)
  (otherwise nil))

is what you want. otherwise should work (as others have said) -- try t instead.

BTW, when you used 'a the reader reads it as (quote a) which means that it will also choose it when the value is quote, for example:

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