我不知道你是否会把它称为规范公式,但绑定一个本地函数我被GNU手册建议使用'flet':
(defun adder-with-flet (x)
(flet ( (f (x) (+ x 3)) )
(f x))
)
Run Code Online (Sandbox Code Playgroud)
然而,偶然我尝试(在使用Scheme之后)下面的表达式,其中我使用'let'将lambda表达式绑定到变量,并且如果我将函数传递给mapcar*它也可以工作:
(defun adder-with-let (x)
(let ( (f (lambda (x) (+ x 3))) )
(car (mapcar* f (list x)) ))
)
Run Code Online (Sandbox Code Playgroud)
这两个功能都有效:
(adder-with-flet 3) ==> 6
(adder-with-let 3) ==> 6
Run Code Online (Sandbox Code Playgroud)
为什么第二个有效?我找不到任何文档,其中'let'可用于将函数绑定到符号.
小智 42
与Scheme不同,Emacs Lisp是一个2-lisp,这意味着每个符号都有两个独立的绑定:值绑定和函数绑定.在函数调用中(a b c d),a使用函数绑定查找第一个符号()b c d,使用值绑定查找rest().特殊表单let创建一个新的(本地)值绑定,flet创建一个新的函数绑定.
请注意,值或功能是否用于查找绑定依赖于位置的(a b c d)函数调用,而不是在类型查找到的价值.特别是,值绑定可以解析为起作用.
在第一个示例中,您将函数绑定f(via flet),然后执行函数查找:
(f ...)
Run Code Online (Sandbox Code Playgroud)
在第二个示例中,您将值绑定f到函数(via let),然后使用值查找:
(... f ...)
Run Code Online (Sandbox Code Playgroud)
两者都有效,因为在每种情况下都使用相同类型的绑定和查找.
http://en.wikipedia.org/wiki/Common_Lisp#Comparison_with_other_Lisps
Tre*_*son 19
我做了快速搜索的Emacs口齿不清手动和找不到任何提及'flet,这并不令人惊奇,因为这是一部分cl-的共LISP封装.
let也将进行局部绑定,但它不会绑定到该符号的"功能单元".
即这是有效的:
(let ((myf (lambda (x) (list x x))))
(eval (list myf 3)))
Run Code Online (Sandbox Code Playgroud)
但
(let ((myf (lambda (x) (list x x))))
(myf 3))
Run Code Online (Sandbox Code Playgroud)
失败并出现错误:"Lisp error:(void-function myf)"
flet 另一方面,确实绑定到功能单元,所以这工作:
(flet ((myf (x) (list x x)))
(myf 3))
Run Code Online (Sandbox Code Playgroud)
注意区别是flet允许你myf直接使用符号,而let不是 - 你必须使用一些间接来从"值单元格"中获取函数并适当地应用它.
在你的例子中,' mapcar'相当于我的使用'eval.
小智 8
为了这个目的,@ d11wq有`funcall'.以下作品:
(defun adder-with-let (x)
(let ((f #'(lambda (x) (+ x 3))))
(funcall f 3)))
(adder-with-let 3) ;=> 6
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8940 次 |
| 最近记录: |