簡體   English   中英

CDR,CAR和REST,FIRST和可能的實施之間的區別?

[英]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)))))

這些函數中的任何一個都可以使用carcdrcons ,或者firstrestlist * ,或者它們的任意組合來編寫,但是堅持使用其中一個可以幫助那些可能會在以后讀取代碼的人(包括原始函數)作者),並表明作者的意圖

我如何最終使用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))

操作firstrest表示您正在使用列表:一系列以空列表結尾的對,即它的形式(列表x1 ... xn)

操作carcdr表示您正在使用對構建數據結構,這可能不是列表。

這是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相當於firstcdr相當於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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM