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 的条目上说:
第一,第二,第三,第四,第五,第六,第七,第八,第九和第十函数分别访问列表的第一,第二,第三,第四,第五,第六,第七,第八,第九和第十元素.特别,
Run Code Online (Sandbox Code Playgroud)(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)))))
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,cdr和cons,或者first,rest和list*,或者它们的任意组合来编写,但是坚持使用其中一个可以帮助那些可能会在以后读取代码的人(包括原始函数)作者),并表明作者的意图.
我如何最终使用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)
您正在使用列表的操作first
和rest
信号:一系列以空列表结尾的对,即它的形式为 (list x1 ... xn)
您正在处理的数据结构的操作car
和cdr
信号是成对构建的,这可能不是列表。
这就是选择first
,rest
当您使用列表时,使代码更易于其他人阅读。