显然,此代码应失败:
(define or 5)
但是我想知道为什么这段代码无法运行:
(define apply
(lambda (x y f)
(f x y)
)
)
(apply #f #t or)
(or #f #t)
将按预期工作。
我没有用保存的名称定义任何新变量,只是将函数or
作为参数传递。
和(apply 1 2 +)
在另一方面...
答案 0 :(得分:2)
or
是一种特殊形式。这不是功能。因此,不能像这样将其作为参数传递。您必须使用:
(apply #f #t or)
(apply #f #t (lambda (a b) (or a b)))
(define or 5)
不会失败。它遮盖了or
特殊形式。一些实现可能不允许在模块内或给定符号内重新定义。因此,在询问Scheme时,重要的是具体实现。
这是因为特殊形式只能在第一个位置出现。特殊形式被实现为宏扩展。例如:(or a b)
=> (let ((v a)) (if v v b))
答案 1 :(得分:1)
当您想重新定义特殊格式时,需要使用thunk,否则将对参数进行求值,而特殊格式的参数将按特殊格式内部的顺序求值。
相反,要获得与特殊形式的语义相同的行为,可以通过使用thunk强制和延迟参数求值。例如,
(define (or-sp-form a b) (if (a) 'ok (b)))
并调用类似的功能
(or-sp-form (lambda () false) (lambda () true))
定义了这样的特殊形式,现在可以将其作为参数传递给其他函数,例如
(f or-sp-form)
并注意f
内部,将延迟的参数传递给or-sp-form
。