繁体   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