Elisp和CommonLisp的闭包的区别

都说了看起来是,你跑跑我上面的代码就知道了,eq可是只有引用相等的时候才能返回t的。(把list换成hash-table之流也一样)

你问为啥这么诡异?要序列化的嘛

你在回复我吗?我在提醒列表里收到了Notification。。。

这鬼论坛的回复机制有问题:

只回一楼或楼上不提示,但如果一楼和楼上不是同一个人的时候,无法区分到底回复的是谁。。。

是回复你,紫薯补丁

三楼是回复楼主的。

我在5楼反驳你是因为你觉得Elisp是值捕获,然而人家是正版的引用捕获。

你解答错了。那一句算是我自问自答

那你3楼是回复谁的?

这论坛我真看不懂。。。

我不清楚你这个代码想描述什么?

另外还有个问题,就是:楼主说Elisp和Common Lisp的实现有区别。

这里Elisp是跑Emacs里的(Emacs本身就是运行时环境),而Common Lisp是另一个语言,应该在别的运行时环境里(Emacs只是作为编辑器)。但是ELisp又支持CL宏,这导致问题复杂化。

你让我跑这段代码,到底是要我在Emacs里跑,还是在CL的专有环境里跑?

楼主的情况也类似。

我只是说听起来。。。

这么说的话Elisp也是引用捕获。

换句话说是楼主的实验结果有问题。。。

不是,你大概不懂啥叫序列化。

我之前做了点实验

说明一个闭包打印/序列化成 (closure ...) 是损失了额外的信息的。

你还不知道 Emacs 24 开始就有了 (setq lexical-binding t) 吧。

我知道有,但默认不开。

刚才测试了一下,你的这个实验在ELisp上确实没Crash。

但这并不能说明ELisp就是capture by reference,因为如果是capture by value的话,结果也是一样的。

注意:a的值实际上是list的地址,即使是capture by value,它照样获得list的地址。所以打印出来地址一样并不能说明什么。

以下证明Elisp是capture by reference

(setq lexical-binding t)
(let ((x "1" ))
  (progn
    (message x)
    ((lambda () (setq x "2" )))
    (message x)))

如果是Java的话(capture by value),则对局部lambda里面的那个x修改,不会影响到外面。

1 个赞

有图有真相

hello

#1 才是关键所在

Capture by value 就不会有 eq 这玩意了

好的,#1说明是capture by reference

到公司我就不用再验证了

歪楼请教个问题

里面的 “一只满嘴名言的牛” 有一句

A LISP programmer knows the value of everything, but the cost of nothing.

该如何理解这句话。

不知道,因为 LISP 是五十多年前的事了,不是当时的硬件就没有什么实感。老夫都没到五十岁。

现在应该是60多年前了吧

http://wiki.c2.com/?LispLanguage

序列化,基本上所有语言都有。你这里指的是list或object转化为可打印形式,还是指其它的什么?

你的实验倒是和我昨晚留作今天要确认的问题相关

我现在正在看Practical Common lisp,每天能抽出来的时间不多,就一天一章的消化吧。好在一章内容才十几页 :joy:

指的是 closure 转化为可打印形式,我的意思是打印出来的 (closure ...) 并不代表 closure 的实际结构,至少引用是丢失了的。

Common Lisp 里任何物件都有地址,closure 自然也有。打印成 ,#<TYPE ADDRESS> 是所有没有设置如何打印的物件的模式行为,只要设置 pprint dispatch 就算把 clsoure 物件打印成 "fuc*" 都可以。

为什么Capture by value 就不需要eq ?

比如:Java就是Capture by value,但它还是有 == 。

eq 有点特殊

他会认为 1 == 1 但 #xFFFFFFFFFFFFFFFF != #xFFFFFFFFFFFFFFFF

他会认为 ?c == ?c 但 “hello” != “hello”

而且 (eq '(1) '(1)) 返回的居然是nil 但是 '() == '()

(eq nil '()) ;; => t