以前我一直不能理解LISP里引用的作用,感覺引用和字符串沒什么區別。
比如:
> (define (func)
'ok)
> (func)
'ok
這里把引用ok當做了函數func的返回值。
但是我在實現函數式漢語編程的時候,我把代碼構造成了一個多叉的語法樹,這時候對某一段代碼的引用,就是不對代碼Eval,直接返回語法樹的根節點。
類似於:
> '(car (a b))
'(car (a b))
可是LISP中的引用實際上是一個construct,它可以被car、cdr。
即:
> (car '(car (a b)))
可是LISP中的引用實際上是一個construct,它可以被car、cdr。
即:
> (car '(car (a b)))
'car
> (cdr '(car (a b)))
'((a b))
這下子就不科學了,之前說過在我的實現中,引用是代碼的語法樹,而construct是數據中的一個結構, 引用怎么能被當做construct來處理呢。
只能有一個解釋,在LISP中『代碼』也是『數據』。
那么LISP中的『代碼即數據』有什么用呢?
回憶一下元編程的定義:元編程(Metaprogramming)是指某類計算機程序的編寫,這類計算機程序編寫或者操縱其他程序(或者自身)作為它們的數據,或者在運行時完成部分本應在編譯時完成的工作。
所以LISP中的代碼可以用來做元編程!
馬上開始試驗:
在這里『數據』被當做了『代碼』, 所以說『LISP是具備元編程能力的典范語言』。
這下子就不科學了,之前說過在我的實現中,引用是代碼的語法樹,而construct是數據中的一個結構, 引用怎么能被當做construct來處理呢。
只能有一個解釋,在LISP中『代碼』也是『數據』。
那么LISP中的『代碼即數據』有什么用呢?
回憶一下元編程的定義:元編程(Metaprogramming)是指某類計算機程序的編寫,這類計算機程序編寫或者操縱其他程序(或者自身)作為它們的數據,或者在運行時完成部分本應在編譯時完成的工作。
所以LISP中的代碼可以用來做元編程!
馬上開始試驗:
> (define quoteList '(1 2 3 4)) ;定義一個變量,是一個列表(1 2 3 4)的引用
> (define quoteOp '+) ;定義一個+運算符的引用
> (define (gao op exp) ;定義一個函數gao,他接受兩個參數op和exp,把op和exp組合起來,然后把結果的數據當做代碼來運行
(eval (cons op exp)))
> (gao quoteOp quoteList)
傳遞參數給gao,首先(cons op exp),返回'(+ 1 2 3 4),之后『運行』這個『數據』。
在這里『數據』被當做了『代碼』, 所以說『LISP是具備元編程能力的典范語言』。