当前位置:  开发笔记 > 开发工具 > 正文

let和flet在emacs lisp中

如何解决《let和flet在emacslisp中》经验,为你挑选了3个好方法。

我不知道你是否会把它称为规范公式,但绑定一个本地函数我被GNU手册建议使用'flet':

(defun adder-with-flet (x)
  (flet ( (f (x) (+ x 3)) )
    (f x))
)

然而,偶然我尝试(在使用Scheme之后)下面的表达式,其中我使用'let'将lambda表达式绑定到变量,并且如果我将函数传递给mapcar*它也可以工作:

(defun adder-with-let (x)
  (let ( (f (lambda (x) (+ x 3))) )
    (car (mapcar* f (list x)) ))
)

这两个功能都有效:

(adder-with-flet 3)   ==> 6
(adder-with-let 3) ==> 6

为什么第二个有效?我找不到任何文档,其中'let'可用于将函数绑定到符号.



1> 小智..:

与Scheme不同,Emacs Lisp是一个2-lisp,这意味着每个符号都有两个独立的绑定:值绑定和函数绑定.在函数调用中(a b c d),a使用函数绑定查找第一个符号()b c d,使用值绑定查找rest().特殊表单let创建一个新的(本地)值绑定,flet创建一个新的函数绑定.

请注意,值或功能是否用于查找绑定依赖于位置(a b c d)函数调用,而不是在类型查找到的价值.特别是,值绑定可以解析为起作用.

在第一个示例中,您将函数绑定f(via flet),然后执行函数查找:

(f ...)

在第二个示例中,您将值绑定f到函数(via let),然后使用值查找:

(... f ...)

两者都有效,因为在每种情况下都使用相同类型的绑定和查找.

http://en.wikipedia.org/wiki/Common_Lisp#Comparison_with_other_Lisps



2> Trey Jackson..:

我做了快速搜索的Emacs口齿不清手动和找不到任何提及'flet,这并不令人惊奇,因为这是一部分cl-的共LISP封装.

let也将进行局部绑定,但它不会绑定到该符号的"功能单元".

即这是有效的:

(let ((myf (lambda (x) (list x x))))
  (eval (list myf 3)))

(let ((myf (lambda (x) (list x x))))
  (myf 3))

失败并出现错误:"Lisp error:(void-function myf)"

flet 另一方面,确实绑定到功能单元,所以这工作:

(flet ((myf (x) (list x x)))
  (myf 3))

注意区别是flet允许你myf直接使用符号,而let不是 - 你必须使用一些间接来从"值单元格"中获取函数并适当地应用它.

在你的例子中,' mapcar'相当于我的使用'eval.


在开始使用Emacs的`cl`扩展之前,人们如何处理需要使用let-like语义声明的函数定义?是否接受了eval是这样做的方式?

3> 小智..:

为了这个目的,@ d11wq有`funcall'.以下作品:

(defun adder-with-let (x)
  (let ((f #'(lambda (x) (+ x 3))))
    (funcall f 3)))

(adder-with-let 3) ;=> 6

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有