2016-08-23 71 views
6

我正在閱讀Paul Graham的Roots,他聲稱任何lisp函數都可以與這7個基本函數的組合構建:quote,atom,eq,cond,cons ,汽車,司機。lisp的自定義'+'(總和)函數

問題:Lisp方言是完全基於這些函數嗎?我們如何使用上述7個基本函數來定義'sum'或'plus'函數?例如我們自己的(+ 1 2)功能

注意:我對Lisp是全新的,但我也開始對語言感到非常興奮。這個問題的目的純粹是真正的興趣

+0

這七個函數的Lisp沒有數字。沒有1,沒有2.因此(加1 2)將不起作用。 –

+2

這是1:'(())'。這是2:'(()())'。 –

回答

12

作者指的是1960年由圖靈獎和Lisp發明人約翰麥卡錫「Recursive Functions of Symbolic Expressions and Their Computation by Machine」寫的一篇非常着名的論文,其中他將Lisp的語義定義爲一種新的計算形式主義,向圖靈機供電。

在論文中(和在Lisp 1.5 Manual)麥卡錫描述了語言的解釋器,可以完全使用Graham提到的七個原始函數來編寫。

該語言主要用於符號計算,而論文中介紹的解釋器只涉及那些計算,而不訴諸於與原子和配對不同的數字或其他數據類型。正如Graham在Lisp Root的第11頁上的一篇文章中所說的那樣,「在McCarthy的1960 Lisp中可以用例如, n個原子的列表以表示數字n「,因此執行總和等於追加兩個列表。

當然這種做法是非常低效的:它只是爲了顯示與其他計算形​​式的等價性,而在真正的解釋器/編譯器中,整數表示像平常一樣,並且具有通常的操作符。

+0

Lisp 1.5有號碼。見第24頁(PDF中的32) – Sylwester

+0

@Sylwester,你是對的。我指的是第1.6節「通用LISP函數」(PDF的第10-14頁),其中定義了Lisp的「通用函數」,即元語言解釋器,不涉及數字,稍後介紹,以「真實」的語言。 – Renzo

3

據我所知,還有一種使用列表嵌套級別(不記得,在哪裏)做到這一點的方法。從()開始爲零,(()) == 1等等。然後,你可以簡單地定義爲inclistdeccar

CL-USER> (defun zero? (x) (eq() x)) 
ZERO? 

CL-USER> (zero? nil) 
T 

CL-USER> (zero? 1) 
NIL 

CL-USER> (defparameter *zero*()) 
*ZERO* 

CL-USER> (defun inc (x) (list x)) 
INC 

CL-USER> (defun dec (x) (car x)) 
DEC 

CL-USER> (defun plus (x y) 
      (if (zero? y) x (plus (inc x) (dec y)))) 
PLUS 

CL-USER> (plus *zero* (inc (inc *zero*))) 
((NIL)) 

CL-USER> (defparameter *one* (inc *zero*)) 
*ONE* 

CL-USER> (defparameter *two* (inc *one*)) 
*TWO* 

CL-USER> (defparameter *three* (inc *two*)) 
*THREE* 

CL-USER> (plus *two* *three*) 
(((((NIL))))) 

CL-USER> (equal *two* (dec (dec (dec (plus *two* *three*))))) 
T 
3

TL; DR:不需要。現代lisp系統比第一個lisp有更多的原語,每個新的基元數據類型都需要一個新的基元。

第一個Lisp沒有數字,但它是完整的。這意味着它可以用任何其他語言進行任何可能的計算,但這並不意味着這樣做可行。數字並不難模擬,但計算速度緩慢。今天有一些關於慢速算術的流行者可以追溯到Lisp 1.5之前。

當我做了第一個lisp解釋器的時候,我對數字並不在乎。這不是口譯員真正有趣的一面。然而,我沒有實現fibonacci作爲一個例子,這是它的樣子:

;; This is NOT Common Lisp code. It's Zozotez 
(setq + (lambda (x y) 
    (if x (cons (car x) 
       (+ (cdr x) y)) 
     y))) 

(setq - (lambda (z w) 
    (if w (- (cdr z) 
      (cdr w)) 
     z))) 

(setq fibonacci 
    (lambda (n a1 a2) 
    (if n 
     (fibonacci (- n '(1)) 
        a2 
        (+ a2 a1)) 
     a1))) 

(fibonacci '(1 1 1 1 1 1 1 1 1)() '(1)) 
; ==> (1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1) 

沒有數字!(1在我的語言是一種符號,因此需要加引號,否則它會像一個變量進行評估)

作爲替代數字系統我已經實現一種位置,很像我們如何寫號使用相同的規則用於加法/乘法等等。也許有點比長度n的更快,但更復雜。

如果Lisp有閉包,你可以做教會的數字。使用與lambda微積分相同的東西,你可以用閉包來計算任何東西。您只需要一個基元,lambda。 (同樣,不是最簡單的工作)