0

在“The Little Schemer”中,null用来指代空列表()。但我也看到了 Scheme 的错误消息中提到的空列表nil,例如:

(car ())

原因:

Error: Attempt to apply car on nil [car][1]

这听起来像是指的是()as nil


[1] 使用replit.com 的BiwaScheme Interpreter 0.6.4 版


这个问题类似于What is the exact difference between null and null in common lispnil这是不同的,因为正如这里的答案所指出的那样,Common Lisp 和 Scheme 在处理和方面存在差异null

4

2 回答 2

3

我认为您所看到的是错误消息中的历史产物。

在传统的 Lisps 中,nil既是空列表又是布尔值 false,并且在其他各种方面都相当特殊(例如,它也是一个符号,这很奇怪)。

所以特别是()nil在这样的 Lisp 中是同一个对象,并且(not nil)是真实的,(not '())也是真实的(实际上(not ())既合法又真实)。空列表对象的谓词是null(也许应该是nullp,但历史说它就是这样)并且(null nil)按原样(null '())(null ()).

还有关于(car nil) aka (car '()) aka (car ())应该做什么的问题。传统上的答案是这很好,而且(car nil)nilnil如果你很聪明,这会给你一个非常简洁的实现。

Scheme 现在取消了所有这些双关语:

  • 有一个唯一的假对象是#f/ #false,它不是空列表;
  • 所有其他对象都是真实的,因此(not x)仅对x存在才是真实的#f
  • 有一个唯一的空列表对象,它是(),它不是#f,因此它是真的;
  • 这个对象的谓词是null?,所以(null? '())是真的,但是(null? #f)是假的;
  • carcdrof()是错误;
  • nil只是一个符号,在语言中根本没有特殊地位。

我不认为有一个名字()是标准的,但显然给它一个名字可能很有用,而且null很好:例如,Racket 就是这样做的。

所以在 Scheme 中,nil它就消失了,空列表和布尔值之间的双关语也随之消失。

但是很多实施方案的人都知道这nil就是人们所说的空列表。所以当他们写错误信息nil时,他们会在他们的意思时写(),因为这是每个人长期以来一直在呼吁()的。

我认为,这就是你在这里看到的。

于 2021-12-13T11:34:46.703 回答
1

不同 Lisps 之间的区别在于它们如何处理 true、false 和 nil。

在 Common Lisp 中,我们有ttrue 和nilfalse,尽管除此之外的所有内容nil实际上都是真实的。如果列表是空的,或者find什么都没有,我们有nil,我们可以直接测试。技术术语是nil punning

'() ; => NIL
(= 1 2) ; => NIL
(if '() "full" "empty") ; => "empty"

(find 5 '(1 2 3 4)) ; => NIL
(if (find 5 '(1 2 3 4)) "found" "not found" ; => "not found"

Clojure 的做法不同。有一个正式的真值true,有两个假值,false并且- 除了和之外的nil所有值也是真值。空列表不再是,您需要对空列表使用单独的测试,使用. 该值更像C 中的值。更好还是更差?- 你决定。falsenilnilempty?nilvoid

'() ; => ()
(= 1 1) ; => true
(= 1 2) ; => false
(if '() "full" "empty") ; => "full"
(if (empty? '()) "empty" "full") ; => "empty"
(if nil "full" "empty") ; => "empty"
(if (println "Hello world") "full" "empty") ; => empty

Scheme 在意图上更接近于 Clojure。这里有一个错误值,#f。空列表不再是nil,您需要对空列表使用单独的测试,使用null?.

(= 1 1) ; => #t
(= 1 2) ; => #f
(null? '()) ; => #t
(null? 'nil) ; => #f

所以,null是空列表的另一个名称,但nil不是'nil

null ; => ()
nil  ; =>  cannot reference an identifier before its definition
'nil ; => nil

怎么样(car ())?您的方案nil从评估返回(),这car就是抱怨的地方。我的计划,Racket 博士,根本拒绝演奏,说空列表中缺少表达式。

于 2021-12-12T12:44:19.163 回答