Lisp 允许特殊形式被视为正常值会有什么后果?

Lisp 允许特殊形式被视为正常值会有什么后果?,lisp,language-implementation,special-form,Lisp,Language Implementation,Special Form,我发现特殊形式不能作为参数传递或保存在变量中,在Clojure中: user=> (defn my-func [op] (op 1 2 3)) #'user/my-func user=> (my-func +) 6 user=> (my-func if) java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:5) user=>

我发现特殊形式不能作为参数传递或保存在变量中,在Clojure中:

user=> (defn my-func 
         [op] 
         (op 1 2 3))
#'user/my-func
user=> (my-func +)
6
user=> (my-func if)
java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:5)
user=> (def my-if if)
java.lang.Exception: Unable to resolve symbol: if in this context (NO_SOURCE_FILE:9)
在球拍/方案中:

> (define (my-func op)
    (op 1 2 3))
> (my-func +)
6
> (my-func if)
  if: bad syntax in: if
> (define my-if if)
  *if: bad syntax in: if
这很酷,我很好,我知道我可以写一个函数来包装一个特殊的表单,然后传递这个函数


但我想知道为什么Lisps有这种限制,以及允许这种限制会有什么负面后果。它们是否有任何主要方言允许这样做?

特殊形式不是函数:函数以值为参数,而特殊形式以形式。例如,查看您的
示例,如果

(if 1 2 3)
好的,这很简单,因为2和3已经是值了。但是这个呢

(define (modadd a b n)
  (if (zero? n) #f (modulo (+ a b) n)))
在这种情况下,
if
实际接收的是
#f
(模(+ab)n)
的形式,而不是值。这很重要<如果
n
为0,则code>(模xn)
将失败:这就是为什么在我们知道
n
不是0之前,它未被计算的原因

能够将特殊形式作为一级对象传递的问题在于,高阶函数无法使用可预测的语义调用这些对象:它是一个函数对象,以便传递值,还是一个特殊形式,以便传递形式?这真是一团糟


是的,您可以编写一个包装函数,比如my
modadd
,它封装了
if
。但是,如果
仍然保留唯一的求值分支行为,则无法将其作为函数重新实现。

特殊形式不是函数:函数以值为参数,而特殊形式以形式。例如,查看您的
示例,如果

(if 1 2 3)
好的,这很简单,因为2和3已经是值了。但是这个呢

(define (modadd a b n)
  (if (zero? n) #f (modulo (+ a b) n)))
在这种情况下,
if
实际接收的是
#f
(模(+ab)n)
的形式,而不是值。这很重要<如果
n
为0,则code>(模xn)
将失败:这就是为什么在我们知道
n
不是0之前,它未被计算的原因

能够将特殊形式作为一级对象传递的问题在于,高阶函数无法使用可预测的语义调用这些对象:它是一个函数对象,以便传递值,还是一个特殊形式,以便传递形式?这真是一团糟


是的,您可以编写一个包装函数,比如my
modadd
,它封装了
if
。但是,如果将
作为一个函数重新实现,同时仍然保留唯一的求值分支行为,则无法实现。

这使得求值更加复杂,编译也更加困难

如果您有一个表单
(ab c)
,那么您需要在运行时解析
a
的值,然后以某种方式将其应用于表单
b
c

一些数量有限的特殊表单和其他严格评估的简单模型也随之消失


另请参见:

它使评估更加复杂,编译更加困难

如果您有一个表单
(ab c)
,那么您需要在运行时解析
a
的值,然后以某种方式将其应用于表单
b
c

一些数量有限的特殊表单和其他严格评估的简单模型也随之消失

另见: