关于elisp 文件最前面lexical-binding: t 的疑问

这个lexical-binding:t 的作用是啥啊,和let有啥区别

https://www.emacswiki.org/emacs/DynamicBindingVsLexicalBinding

我也不是非常懂,好像是一个变量的作用域的问题。我的理解是,Emacs是默认Dynamic Binding的,而写程序的时候使用Lexical Binding会更好一点。

1 个赞

Lisp 已死,Lisp 万岁!

王垠这篇比官方手册好很多倍.

实际上,我没用那个lexical-binding: t 的时候 用Let声明的变量在let外面也是访问不到的。就很迷惑。。。。

(let ((a 1))                            ; binding (1)
      (let ((f (lambda () (print a))))
        (let ((a 2))                        ; binding (2)
          (funcall f))))
    ==> ?

wiki说动态绑定会打印2,词法绑定会打印1。

所以我认为应该是动态作用域只是会按照嵌套层级给你调用最近的绑定。

而词法作用域会构建局部环境把局部环境包含到闭包中。

这么一看,我又疑惑了。。。。怎么感觉和common lisp 里面的不太一样呢

我原本以为elisp里面的Let也是词法的。现在看来好像不是的。common lisp 里面的let是词法的

也许lexical-binding: t 的作用就是开启let的词法绑定?

不要想太多,只要你想写 Elisp 的时候,就加上 lexical-binding:t ,加上后按你从 Common Lisp 那里学来的去用就行了。

我emacs里面看了下文档。

就是说elisp默认是动态作用域,你想要词法作用域就在需要的文件第一行加上lexical-binding: t

刚巧我这两天在写一篇和emacs相关的论文(我学校研学课作业的选题),无意间爬到了一篇教主早年在MIT写的emacs安利论文,第5.2节,里面非常简单易懂地说明了lexical binding是怎么一回事,不愧是教主 :rofl:

在scratch里(默认lexical binding)试试下面的代码(原文中的例子):

(defun foo1 (x) (foo2))
(defun foo2 () (+ x 5))
(foo1 2)

默认会报错,(setq lexical-binding nil)后返回结果7 :rofl:这下连我编程小白都懂了

1 个赞

Common Lisp 用 defvar defparameter 定义的变量都是 dynamic 的。

加行 (defvar x),不管是不是 lexical-binding t 都能得到结果。

1 个赞

let定义局部变量. 如果你有c系基础应该不难理解.