![](/img/trans.png)
[英]How do lisps that prefer first and rest to car and cdr approach combinations like cdaddr?
[英]Difference between CDR, CAR and REST, FIRST and possible implementation?
我正在學習LISP中的函數式編程,這是我遇到的問題:LISP使用CAR,CDR函數以及FIRST和REST函數。 兩者都與列表有關。
從我到目前為止所學到的,這兩者之間存在差異,但我不太清楚它們之間的區別。
有人可以為我總結一下嗎? 我如何最終使用CDR,CAR實現FIRST / REST?
編輯 :由於接受的答案提到文檔,但沒有鏈接,這里是CAR / CDR文檔的鏈接,這里是FIRST / REST 。
此外 - 重要的說明 - 鏈接文檔是CLISP的“實施說明”,這是一種常用的環境。 一般來說,幾乎不可能找到這種語言的“官方文件”。
就他們所做的而言, 汽車和cdr相當於第一次和休息 。 這在文檔中非常清楚。 HyperSpec在第一個 , 第二個和c的條目上說:
第一,第二,第三,第四,第五,第六,第七,第八,第九和第十函數分別訪問列表的第一,第二,第三,第四,第五,第六,第七,第八,第九和第十元素。 特別,
(first list) == (car list) (second list) == (car (cdr list)) (third list) == (car (cddr list))
...
筆記:
第一個在功能上等同於汽車,第二個在功能上等同於cadr,第三個在功能上等同於caddr,第四個在功能上等同於cadddr。
現在, 是有區別的,而不是功能,而是在風格 ,當你使用這些功能。 這實際上也是在HyperSpec中調用的,例如,在休息條目中:
筆記:
當論證被主觀地視為列表而不是缺點時,休息通常優先於風格而不是cdr。
例如,考慮兩種映射在由cons單元構建的結構上的方法。 在第一個中,我們映射在cons細胞樹上 ,用樹的每個葉子(即,非缺點)調用一些函數。 我們檢查是否有東西是consp的缺點,如果是,我們將它們遞歸到它的汽車和cdr上 。 我們通過調用cons將結果合並到一個新的cons單元中。
(defun map-over-cons (function tree)
(if (not (consp tree))
(funcall function tree)
(cons (map-over-cons function (car tree))
(map-over-cons function (cdr tree)))))
或者,當我們映射列表時,我們通常使用endp檢查終端條件(或null ,但是endp強調我們正在尋找列表的結尾 ,而不只是查找nil ),並且我們調用函數列表的第一個並遞歸到列表的其余部分 。 雖然看到使用cons構造的結果是很常見的,但實際上list *將在使用兩個參數調用時執行相同的任務(通常,它可以執行更多操作),強調正在構造列表 :
(defun map-over-list (function list)
(if (endp list)
'()
(list* (funcall function (first list))
(map-over-list function (rest list)))))
這些函數中的任何一個都可以使用car , cdr和cons ,或者first , rest和list * ,或者它們的任意組合來編寫,但是堅持使用其中一個可以幫助那些可能會在以后讀取代碼的人(包括原始函數)作者),並表明作者的意圖 。
我如何最終使用CDR,CAR實現FIRST / REST?
怎么樣:
(defun first (x) (car x))
(defun rest (x) (cdr x))
或者甚至更好,如果你有符號功能 :
(setf (symbol-function 'first) (symbol-function 'car))
(setf (symbol-function 'rest) (symbol-function 'cdr))
操作first
和rest
表示您正在使用列表:一系列以空列表結尾的對,即它的形式(列表x1 ... xn)
操作car
和cdr
表示您正在使用對構建數據結構,這可能不是列表。
這是first
選擇並在使用列表時rest
,以便讓其他人更容易閱讀代碼。
傳統上,汽車和cdr更多的是面向機器,而第一次和休息是更抽象的功能。 實際上,它們之間沒有區別。 每個人都堅持汽車和司機,所以汽車和司機占了上風。
如果你很難找到汽車和汽車之間的任何差異,那是因為沒有。 首先看一下汽車的別名。
定義?
(defun first (x) (car x))
(defun rest (x) (cdr x))
首先,這些都不是謂詞(或者至少,它們不是Lisp程序員所謂的“謂詞”;在這種情況下,“謂詞”意味着“一個返回布爾值的函數”)。
至於問題,讓我們跳轉到REPL一分鍾。
; SLIME 2014-12-23
CL-USER> (describe #'car)
#<FUNCTION CAR>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Return the 1st object in a list.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
CL-USER> (describe #'first)
#<FUNCTION FIRST>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Return the 1st object in a list or NIL if the list is empty.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
CL-USER> (describe #'cdr)
#<FUNCTION CDR>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Return all but the first object in a list.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
CL-USER> (describe #'rest)
#<FUNCTION REST>
[compiled function]
Lambda-list: (LIST)
Declared type: (FUNCTION (LIST) (VALUES T &OPTIONAL))
Documentation:
Means the same as the cdr of a list.
Known attributes: foldable, flushable, unsafely-flushable
Source file: SYS:SRC;CODE;LIST.LISP
; No value
因此,根據文檔和他們的簽名, car
相當於first
而cdr
相當於rest
。 讓我們測試一下。
CL-USER> (cons 1 2)
(1 . 2)
CL-USER> (car (cons 1 2))
1
CL-USER> (first (cons 1 2))
1
CL-USER> (cdr (cons 1 2))
2
CL-USER> (rest (cons 1 2))
2
CL-USER> (cons 1 nil)
(1)
CL-USER> (car (cons 1 nil))
1
CL-USER> (first (cons 1 nil))
1
CL-USER> (cdr (cons 1 nil))
NIL
CL-USER> (rest (cons 1 nil))
NIL
CL-USER> nil
NIL
CL-USER> (car nil)
NIL
CL-USER> (first nil)
NIL
CL-USER> (cdr nil)
NIL
CL-USER> (rest nil)
NIL
所以,他們似乎是一樣的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.