CDR,CAR和REST,FIRST和可能的实施之间的区别?

Fan*_*icD 7 lisp list common-lisp cdr

我正在学习LISP中的函数式编程,这是我遇到的问题:LISP使用CAR,CDR函数以及FIRST和REST函数.两者都与列表有关.

从我到目前为止所学到的,这两者之间存在差异,但我不太清楚它们之间的区别.

有人可以为我总结一下吗?我如何最终使用CDR,CAR实现FIRST/REST?


编辑:既然接受的答案中提到的文件,但没有链接,这里是链接的文档CAR/CDR话,这里FIRST/REST.

此外 - 重要的说明 - 链接文档是CLISP的"实施说明",这是一种常用的环境.一般来说,几乎不可能找到这种语言的"官方文件".

Jos*_*lor 11

就他们所做的而言,汽车cdr相当于第一次休息.这在文档中非常清楚.HyperSpec在第一个,第二个和c 的条目上说:

第一,第二,第三,第四,第五,第六,第七,第八,第九和第十函数分别访问列表的第一,第二,第三,第四,第五,第六,第七,第八,第九和第十元素.特别,

(first list)    ==   (car list)
(second list)   ==   (car (cdr list))
(third list)    ==   (car (cddr list))
Run Code Online (Sandbox Code Playgroud)

...

笔记:

第一个在功能上等同于汽车,第二个在功能上等同于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)))))
Run Code Online (Sandbox Code Playgroud)

另外,当我们在地图列表中,我们通常用来检查与终端条件ENDP(或,但ENDP强调,我们要寻找的最终一的名单,并不只是寻找),我们就调用函数列表的第一个并递归到列表的其余部分.虽然看到使用cons构造的结果很常见,但实际上list*在使用两个参数调用时执行相同的任务(通常,它可以执行更多操作),强调正在构造列表:

(defun map-over-list (function list)
  (if (endp list)
      '()
      (list* (funcall function (first list))
             (map-over-list function (rest list)))))
Run Code Online (Sandbox Code Playgroud)

这些函数中的任何一个都可以使用car,cdrcons,或者first,restlist*,或者它们的任意组合来编写,但是坚持使用其中一个可以帮助那些可能会在以后读取代码的人(包括原始函数)作者),并表明作者的意图.

我如何最终使用CDR,CAR实现FIRST/REST?

怎么样:

(defun first (x) (car x))
(defun rest (x) (cdr x))
Run Code Online (Sandbox Code Playgroud)

或者甚至更好,如果你有符号功能:

(setf (symbol-function 'first) (symbol-function 'car))
(setf (symbol-function 'rest) (symbol-function 'cdr))
Run Code Online (Sandbox Code Playgroud)


soe*_*ard 5

您正在使用列表的操作firstrest信号:一系列以空列表结尾的对,即它的形式为 (list x1 ... xn)

您正在处理的数据结构的操作carcdr信号是成对构建的,这可能不是列表。

这就是选择firstrest当您使用列表时,使代码更易于其他人阅读。