Scheme中的语法和变量

Scheme中的语法和变量,scheme,Scheme,显然,此代码应该失败: (定义或5) 但我想知道为什么这段代码无法运行: (define apply (lambda (x y f) (f x y) ) ) (apply #f #t or) (或#f#t),将按预期工作 我没有用保存的名称定义任何新变量,只是将函数或作为参数传递 另一方面,(apply 1 2+)工作…或是一种特殊形式。它不是一个函数。因此,它不能作为一个论点那样通过。您必须使用以下内容,而不是(应用#f#t或): (apply #f #t

显然,此代码应该失败:
(定义或5)

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

(define apply 
    (lambda (x y f)
        (f x y)
    )
)
(apply #f #t or)
(或#f#t)
,将按预期工作

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


另一方面,
(apply 1 2+)
工作…

是一种特殊形式。它不是一个函数。因此,它不能作为一个论点那样通过。您必须使用以下内容,而不是
(应用#f#t或)

(apply #f #t (lambda (a b) (or a b)))
(定义或5)
不会失败。它隐藏了
特殊表单。某些实现可能不允许在模块内或给定符号内重新定义。因此,在询问方案时,重要的是具体实施


这是因为特殊形式只能出现在第一个位置。特殊表单作为宏扩展实现。例如:
(或ab)
=>
(let((va))(如果v b))

当您想要重新定义特殊表单时,您需要使用thunks,否则参数将被计算,而特殊表单的参数将按照在特殊表单中施加的顺序进行计算

相反,要获得与特殊形式的语义相同的行为,可以使用thunks强制和延迟参数计算。比如说,

(define (or-sp-form a b) (if (a) 'ok (b)))
调用这样一个函数,比如

(or-sp-form (lambda () false) (lambda () true))
定义这样一个特殊的形式,它现在可以作为参数传递给其他函数,如

(f or-sp-form)

并在
f
中小心地将延迟参数传递给
或sp form

(定义或5)
失败并不明显。这没有多大意义,但它是合法的Scheme代码。此外,您不应该将函数命名为
apply
,这与同名的内置过程相冲突。完全脱离主题:我个人没有使用Scheme和Lisp,直到我放弃了从花括号语言中养成的布局习惯。我认为这是因为他们(至少对我来说)提出了一种不符合现实的结构。它是否会失败并不明显。例如,
(define-define 5)
完全可以,在相同的词法范围内,除了获得绑定
5
之外,您不能再为任何事情定义
define