为什么我们在 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
来实现,这也是一种语法形式,在解释器的评估过程中作为一种特殊情况实现。
(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
来实现,这也是一种语法形式,在解释器的评估过程中作为一种特殊情况实现。