- 論壇徽章:
- 2
|
回復(fù) 6# sanbiangongzi
一吐槽scheme就忘主題了。。。
具體到emacs lisp就很好說明了。el的執(zhí)行是完全分為兩步的。
代碼文件中的: (cons 'a 1) , 如果該文件被加載, 就與(eval (read "(cons 'a 1)")) 等效。
首先是將代碼文件中的字符流"(cons 'a 1)" —— 左括號, c, o, n ... 右括號 —— 讀取為內(nèi)存中的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求值就有點類似函數(shù)調(diào)用, 第1個元素的解釋還比較復(fù)雜, 具體到這個問題其實只與后續(xù)元素的求值(即"參數(shù)")有關(guān)。
大多數(shù)時候,參數(shù)會被從左往右依次求值,并傳遞這個求值結(jié)果。
少部分special form對參數(shù)求值有特殊規(guī)定, macro對所有參數(shù)都不求值。
4. intern還有這一個關(guān)鍵概念前面忘記說了。
a, cons, b 等等都是interned symbol的read syntax。 讀取,即(read "a")等,得到的是interned symbol。
不需要被它的名字嚇到, lisp里有許多奇奇怪怪的名字。。。 它的目的就是保證代碼中的所有a,讀取后得到的都是同一個symbol object。
與之對應(yīng)的是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 又會對它的參數(shù) —— (setq b 1), b —— 依次求值,并返回最后一個參數(shù)的求值結(jié)果。
對(setq b 1)求值,就是將b這個symbol的value cell設(shè)置為1; 再對b求值,就是將同一個symbol的value cell取出, 就得到1了。
所以symbol 就可以用作變量 —— 一些地方用set, setq等設(shè)置symbol object的value cell, 另一些地方對同一個symbol object求值就取出value cell。
|
|