Lisp可以完成哪些其它語言難以實現的功能?最好能夠舉一些例子
網上有很多說Lisp很強大很靈活的,但是都沒有具體給出例子,難以理解。
準時下班。
ps:我真的不騙你。謝邀
Lisp 與非 Lisp 語言最大的不同恐怕要算他是一個可編程的編程語言。
Lisp 可以用代碼生成代碼、給 Lisp 添加新語法。你可以分分鐘就用 Lisp 寫出一種新的編程語言出來。這讓 Lisp 非常適合進行元編程,我們一般寫代碼的過程是先弄清問題,然後設計相應的數據結構,最後編寫操作數據結構的代碼。無論你用什麼高大上的語言基本都是這個思路。元編程的思路完全不同,它是針對特定問題領域先發明一種新的編程語言,然後用這個語言解決這個領域的具體問題。這種編程方法強大到什麼程度?舉個栗子:比如 HTML 就是一種專門用於編寫網頁的語言,很少的代碼就可以寫出有漂亮排版的頁面來,同樣的頁面讓你用C++、Java 這種語言去編寫需要多久?前者的開發效率可能是後者的上百倍。
如果你遇到一個很新的問題領域,沒有合適的語言表達它,那你可能自己發明一種語言出來(發明新語言沒你想的那麼難),用一般的編程語言實現一種新語言是很難的,而 Lisp 天成就有這種能力。餓了,例子就不舉了,如果感興趣可以看看維基百科:元編程Lisp 的宏讓你可以自己動手擴展語言而不必等標準委員會漫長的流程。
比如你可以自己實現指針……; Making a pointer -- a corresponding Scheme closure, to be precise.
; The original paper had the following low-level macro
;(define-macro ( x)
; `(lambda (action)
; (case action
; ((ref) ,x)
; ((set) (lambda (new-val) (set! ,x new-val))))))
; The same macro as a syntax rule
(define-syntax
(syntax-rules ()
(( x)
(lambda (action)
(case action
((ref) x)
((set) (lambda (new-val) (set! x new-val))))))))
; Dereferencing the pointer to an R-value
(define (p-ref ptr)
(ptr "ref))
; Dereferencing the pointer to an L-value and updating the pointed
; variable
(define (*= ptr)
(ptr "set))
; Overloading the * operation with C-style dereferencing
; so we could write (* p) rather than (p-ref p)
(let ((old-* *))
(set! *
(lambda args
(if (and (pair? args) (null? (cdr args)) (procedure? (car args)))
(p-ref (car args))
(apply old-* args)))))
Lisp的優點只有一條,就是其eval無須parse input,同時構造eval的input的方式也被簡化到了極致
因此可以說Lisp是最適合meta-programming的語言
除開這點,Lisp和其他語言並無本質分別
你沒見過具體例子是因為根本就沒有這樣的例子。lisp 沒那麼神。只有兩種人會以為 lisp 神。一種是只看軟文,如黑客與畫家,的人,一種是對 lisp 和編程都一知半解的人。這兩種人都以為 宏 能怎樣怎樣。
lisp 確實強大,但是在工廠模式下的開發, 不是很適合規劃化作業, 因為代碼的性能,表達,語法,是程序員自己決定,在沒有嚴格的開發規範的約束下,代碼很難維護,
還有,在一般應用領域,lisp 並沒有多大優勢。「誒,這個功能不錯,可是 Lisp 里沒有,我用宏實現看看……搞定!」
用lisp就是把自己變成人肉編譯器
「在讀取期編譯或運行代碼,也可以在編譯期讀取或運行代碼,還可以在運行期讀取或者編譯代碼。「
可以參看《黑客與畫家》的附錄,《編程能力》,摘錄如下:
Common Lisp的寫法如下:
(defun foo (n)
(lambda (i) (incf n i)))
Javascript的寫法稍微長一點,因為Javascript依然區分語句和表達式,所以你需要明確指定return語句,來返回一個值:
function foo (n) {
return function (i) {
return n += i } }
Python高手看來也同意,這是解決這個問題的比較好的方法,寫法如下:
def foo (n):
class acc:
def _ _init_ _ (self, s):
self.s = s
def inc (self, i):
self.s += i
return self.s
return acc (n).inc
Ken Anderson說,Java只能寫出一個近似的解法:
public interface Inttoint {
public int call (int i);
}
public static Inttoint foo (final int n) {
return new Inttoint () {
int s = n;
public int call (int i) {
s = s + i;
return s;
}};
}
這種寫法不符合題目要求,因為它只對整數有效。
完整版在這裡:為什麼Lisp語言如此先進?(譯文)
推薦閱讀:
※函數式語言中如何實現while true?
※學習 LISP 有哪些網站或書籍推薦?
※如何評價 Racket 這門編程語言?
※為什麼著名的輪子很少有用 Lisp 寫的?
※精通 Lisp 是一種怎樣的體驗?
TAG:編程語言 | 函數式編程 | Lisp | CommonLisp |