Scheme中的语法和变量

时间:2019-12-09 03:38:55

标签: scheme

显然,此代码应失败: (define or 5)

但是我想知道为什么这段代码无法运行:

(define apply 
    (lambda (x y f)
        (f x y)
    )
)
(apply #f #t or)

(or #f #t)将按预期工作。

我没有用保存的名称定义任何新变量,只是将函数or作为参数传递。

(apply 1 2 +)在另一方面...

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