免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 4633 | 回复: 24

请教基本概念 [复制链接]

论坛徽章:
0
发表于 2012-11-14 16:44 |显示全部楼层
对于(setq b 1)
可以理解定义了一个变量b值为1

但是
quote究竟该怎么理解呢?
比如
(cons 'a 1)

a究竟是什么?


论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
发表于 2012-11-14 19:11 |显示全部楼层
symbol 就好像在 C 里面字符串常量要写做 "string" 没有双引号就成个变量,quote 也就相当于双引号,是个语法。

论坛徽章:
46
15-16赛季CBA联赛之四川
日期:2018-03-27 11:59:132015年亚洲杯之沙特阿拉伯
日期:2015-04-11 17:31:45天蝎座
日期:2015-03-25 16:56:49双鱼座
日期:2015-03-25 16:56:30摩羯座
日期:2015-03-25 16:56:09巳蛇
日期:2015-03-25 16:55:30卯兔
日期:2015-03-25 16:54:29子鼠
日期:2015-03-25 16:53:59申猴
日期:2015-03-25 16:53:29寅虎
日期:2015-03-25 16:52:29羊年新春福章
日期:2015-03-25 16:51:212015亚冠之布里斯班狮吼
日期:2015-07-13 10:44:56
发表于 2012-11-14 19:22 |显示全部楼层
比如你在代码中写

a

lisp 就知道你想要的是变量 a 的值,如果写作

'a

lisp 就会理解为你想要 a 这个 symbol。

论坛徽章:
0
发表于 2012-11-15 11:59 |显示全部楼层
回复 1# sanbiangongzi

'a 即 (quote a) 表示"a"这个表示定义成了一个symbol。
从理论上来说,symbol和string的区别在于是否intern,翻译成人话就是:把该string放到一个特殊的表里面成为一个不变量,然后我们称这种方式处理过的string为symbol,这个处理过程叫intern。

这种处理最大的好处在于,由于symbol在全局是唯一的,所以比较两个symbol的时候只需要比较其值字符串的首地址就可以了,所以类lisp里面会大量使用symbol来提高效率。
比如:
(define a 'asdfadsfsadfashfjasfsdfadsfasdf)
(define b 'adsjsjfalkdsjfasjsafjiwjrwerper)
当比较a和b的时候,不会像string那样去逐个比较,而是直接比较两个字符串的首地址(该地址存在于一个全局表中,任何函数都可以引用)。

坏处在于,symbol搞得太多你就有很多无法回收的字符串数据,占用内存。

PS:这只是理论,实际上各种实现会根据自己的策略做了优化处理,并不是所有symbol都会intern并且未必保证immutable。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-11-15 19:11 |显示全部楼层
这是functional版,不是某种lisp的版。。。 lisp有很多种的。。。  即使是同一种lisp语言,也有不同实现的。。。
LZ你给的代码不能区分到底是emacs lisp还是common lisp或者是其他什么没那么出名的lisp。。。

一般来说,有一些关键点:
1. symbol是一个独立的类型
2. 只是大多数lisp恰好用它来满足变量的用途
3. 当symbol被求值时, 就是当作变量
4. 当symbol不被求值时, 就是当作symbol本身
5. 少数的operator —— 就是可以出现在list的第1元素上的东西, 各种lisp对这个东西的叫法也不一样 —— 对参数的求值有特殊规定
6. quote就是这样的operator之一, 对(quote a)求值得到a这个symbol本身, 对a求值得到的是a变量的值。
7. cons会对所有参数求值, 所以 (let ((a 12)) (cons a (quote a))) 的结果就是一个con cell, car是12这个number, cdr是a这个symbol
8. ’是一个reader marker —— 各种lisp里的叫法也有不同 —— 'a 会被reader 读取为 (quote a)。 所以(cons 'a 1) 和 (cons (quote a) 1)是相同的, 被求值后都得到一个con cell, car是a这个symbol, cdr 是 12 。
9. (setq b 1) 不会对第1个参数,即b求值, 但会对 第2个参数, 即1求值。
产生的效果就是b这个symbol如果被求值就会得到1。
(setq b (+ 12 26)) 的话, 如果b被求值就会得到38, 而不是(+ 12 26), 因为第2个参数是会被求值的。
10. setq 中的 q 就是 quote 的意思。。。

论坛徽章:
0
发表于 2012-11-16 09:30 |显示全部楼层
OwnWaterloo 发表于 2012-11-15 19:11
这是functional版,不是某种lisp的版。。。 lisp有很多种的。。。  即使是同一种lisp语言,也有不同实现的。 ...



感谢楼上几位的回复,比以前明白了些,
但是还是很模糊, 向通过一种lisp的实现
来理解这些概念
看了一下emacs的C源码,实在不好读懂,
有没有其他lisp的比较容易理解的实现推荐一下。





TO OwnWaterloo: 是Emacs lisp

论坛徽章:
0
发表于 2012-11-16 10:10 |显示全部楼层
回复 6# sanbiangongzi

你最好从Scheme开始,Scheme本来就是适合于教学的。
一个可实用的Scheme只需要6千行不到的代码(或许还能更精简),你想从源码级别开始研究推荐tinyScheme。
各种Lisp方言风格各异,从主流的入手会比较靠谱,资料和标准都有。

或者你想尽快上手一门可以马上用来做事的语言,可以考虑这个:
https://www.coursera.org/course/progfun

PS:我建议你还是先完成SICP。

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-11-16 14:14 |显示全部楼层
回复 6# sanbiangongzi

个人认为无论什么语言,实现方式并不是理解语言的唯一途径,甚至是一条很差的途径。
呃,如果目的就是语言实现而不是语言本身那就是另外一回事了。

至于lisp的推荐。。。
如果你要用emacs,肯定学emacs lisp是最实用的。


如果要general purpose programming。。。
推荐clojure。。。  它的缺点就是依赖java,所以java的一些缺点就没法避免。。。 比如体积。。。 JRE是必须的。。。


如果是语言研究,可以从scheme开始。
这货在很多方面概念都很简单。
比如没有emacs lisp和common lisp那样的function cell和value cell之分, 没有lexical scope和dynamic scope之分。
但又有很多其他lisp不支持的continuation, 完爆common lisp里的各种乱得死人的(包括goto)控制结构。

但最好还是再搭配一个别的lisp来学。。。  因为scheme和其他的lisp太不一样了。。。很多人都不把scheme算到lisp里的。
lisp最独特的地方,宏,scheme恰好复杂得像一坨屎。
scheme在作用域控制上也复杂得一坨。。。  但又不支持el,cl,clojure都支持的动态作用域(它们三者都是混合型的)。
而且,scheme这语言没有实用性。racket这语言实现也没有实用性。完全是渣渣。
scheme被很多人夸大了(我以前也是其中一员),直到真正用racket开始写点东西后发现scheme适合讲学,也只适合在学院里讲学。

说到functional programming,很多人就想到scheme。。。而scheme在这方面除了continuation,就没其他优势了。
first class function? scheme支持, 但谁不支持?
列表操作、immutable value、pure function、lazy evaluation, 它哪样支持了?
哦,它不是不支持, 而是 1) roll your own 2) implementation detail 。

算了,打住。。。 scheme不是不好, 而是被吹捧得太过, 不值那个价。
总之, scheme的哲学 —— 将语言限制降低 —— 是对的。
但因为语言限制尽可能低,所以语言就可以只提供极少的feature,因为不够的程序员可以自己加 —— 这是学院派的天真想法, 也只适合教学。 教你怎么在一个简单的语言内核上实现各种feature。
投入实际环境中时, 就会出现各种不兼容的feature的实现, 就没有scheme语言, 只有racket, gambit, guile。。。 甚至在同一个语言里, 也有不同不兼容的风格。。。
本来scheme就很小众了, 再这么折腾, 还搞个屁啊。

论坛徽章:
0
发表于 2012-11-16 14:26 |显示全部楼层
笑而不语   (padding for posting 000000000)

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
发表于 2012-11-16 14:59 |显示全部楼层
回复 6# sanbiangongzi

一吐槽scheme就忘主题了。。。

具体到emacs lisp就很好说明了。el的执行是完全分为两步的。

代码文件中的: (cons 'a 1) , 如果该文件被加载, 就与(eval (read "(cons 'a 1)")) 等效。
首先是将代码文件中的字符流"(cons 'a 1)" —— 左括号, c, o, n ... 右括号 —— 读取为内存中的lisp object, (cons (quote a) 1) —— 一个三元素的列表,元素依次是cons(symbol), (quote a)(又一个列表,元素是quote符号和a符号), 1(number)。

然后就是求值,eval。不同类型的lisp object求值方式不同。
1. self evaluating, 比如number, string, vector。。。
对它们求值,返回这个lisp object本身。
2. symbol
el中的symbol有4个域, function cell, value cell, property list, 以及symbol name。对symbol求值就得到它的value cell。
3. list
对list求值就有点类似函数调用, 第1个元素的解释还比较复杂, 具体到这个问题其实只与后续元素的求值(即"参数")有关。
大多数时候,参数会被从左往右依次求值,并传递这个求值结果。
少部分special form对参数求值有特殊规定, macro对所有参数都不求值。
4. intern还有这一个关键概念前面忘记说了。
a, cons, b 等等都是interned symbol的read syntax。 读取,即(read "a")等,得到的是interned symbol。
不需要被它的名字吓到, lisp里有许多奇奇怪怪的名字。。。 它的目的就是保证代码中的所有a,读取后得到的都是同一个symbol object。
与之对应的是unintened symbol, 它们也都是symbol, 也有那4个域, 但可能就是不同的symbol object。

(read "(progn (setq b 1) b)") 得到一个list。 这个list中的两个b symbol是同一个symbol object。
如果对这个list求值, 即(eval (read "(progn (setq b 1) b)")), 首先是对progn求值。 progn 又会对它的参数 —— (setq b 1), b —— 依次求值,并返回最后一个参数的求值结果。
对(setq b 1)求值,就是将b这个symbol的value cell设置为1; 再对b求值,就是将同一个symbol的value cell取出, 就得到1了。
所以symbol 就可以用作变量 —— 一些地方用set, setq等设置symbol object的value cell, 另一些地方对同一个symbol object求值就取出value cell。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP