gpt4 book ai didi

lambda - 为什么在函数位置禁止函数对象(但允许 lambda 形式)?

转载 作者:行者123 更新时间:2023-12-03 18:25:31 26 4
gpt4 key购买 nike

函数位置的 lambda 形式表达式
函数位置中的 lambda 表达式编译得很好:

> ((lambda (n) (> n 10)) 42)
T
从函数位置的 lambda 构建的闭包
另一方面:
> (defun greater-than (x)
(lambda (n) (> n x)))
GREATER-THAN

> ((greater-than 10) 42)
Compile-time error: illegal function call
不起作用。
(我显然需要调用 FUNCALL 使其工作: (funcall (greater-than 10) 42) => T
为什么要这样设计?
我理解为什么将函数对象作为值绑定(bind)的 SYMBOL 不能工作,例如: (let ((foo (lambda () 42))) (foo)) .单独的命名空间等等。
但是为什么要在函数位置禁止一个函数对象本身呢?这个决定背后的理由是什么?

最佳答案

什么是 lambda 形式?

A lambda-form in function position compiles just fine:



在 Common Lisp 措辞中是 lambda expression不是 form .具有 lambda 表达式和零个或多个参数的列表是一种形式,特别是 lambda 形式。可以评估表单,但不能评估 lambda 表达式。注意:还有一个宏操作符 lambda , 它扩展了宏形式 (lambda ...)进入 (function (lambda ...)) - 这是一个有效的形式,使用特殊运算符 function .
(                       ; the whole list is a valid lambda form

(lambda (n) (> n 10)) ; a lambda expression, not a form

42) ; 42 is a form, too

上面的 lambda 形式大多类似于:
(let ((n 42))
(> n 10))

运行时调用评估结果的函数对象

But why prohibit a function object itself in function position? What was the rationale behind this decision?



Common Lisp 更喜欢在函数位置有已知(或未知)的函数。
(sin 3)
((lambda (x) (sin 3)) 3)
(unknown-function 3)

最重要的是,这三个函数不能是其他任何东西:它们不能是数字、字符串或其他数据对象。没有办法将另一个数据对象放在那里。运营商如 DEFUN , FLET和其他人拒绝定义其他数据类型(数字,字符串,...)的函数。

如果我们要在函数位置进行计算,我们可以这样写:
((if (> foo bar) 42 #'sin) 3)

取决于 (> foo bar)的评价这可能类似于 (sin 3)(42 3) ,后者不是有效形式,因为数字不是函数。

Common Lisp 需要一个显式使用 FUNCALL 之一, APPLY , MULTIPLE-VALUE-CALL调用函数对象。这在源代码中清楚地表明正在计算/检索和调用函数对象。他们还进行必要的检查,确保传递的东西确实是一个函数或表示函数的符号。

背景

一些细节见 Technical Issues of Separation in Function Cells and Value Cells by Gabriel/Pitman .

关于lambda - 为什么在函数位置禁止函数对象(但允许 lambda 形式)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45245642/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com