为什么我们在 Racket shell 中输入(或#t(/ 1 0))时没有看到错误?

Why we do not see an error when input (or #t (/ 1 0)) in Racket shell?

(or #t (/ 1 0))

(/ 1 0) 是非法的,但为什么我们没有看到错误?

我的讲义里有解释。

The identifier or does not refer to a function, but rather a syntactic form that implements short-circuiting.

不过还是不太明白

关键部分是 or 是一种 句法形式 ,如您的讲义中所述。这意味着求值规则不同于普通过程,可以在解释器级别或(更有可能)作为派生表达式或宏来实现。如果我们尝试将 or 作为一个过程来实现,您的示例确实会失败:

(define (my-or a b)
  (if a a b))

(my-or #t (/ 1 0))
=> /: division by zero

程序在将所有参数传递给 body 之前对其进行评估。相比之下,or 评估它的第一个参数,如果它是真实的它 returns 第一个参数的值,否则它 returns 评估第二个参数的结果 - 但它会 never 如果第一个参数为真,则不评估第二个参数。这被称为布尔连接器的 "short circuit" 求值,and.

也会发生类似的事情

为了更好地理解幕后发生的事情,请阅读 SICP 的第 4 章,这里是相关的 link 解释 derived expressions。引用:"Some special forms in our language can be defined in terms of expressions involving other special forms, rather than being implemented directly"。在这种情况下,or 可以使用 if 来实现,这也是一种语法形式,在解释器的评估过程中作为一种特殊情况实现。