i'm learning little bit functional programming in lisp , here's i've bumped into: lisp uses car, cdr functions first , rest functions. both related lists.
from i've learned far, there's difference between these two, don't quite see difference is.
could sum me? , how implement first/rest using cdr, car?
edit: since accepted answer mentions documentation, not link, here link documentation car/cdr, here first/rest.
in addition - important note - linked documentation "just implementation notes" clisp, commonly used environment. impossible find "official documentations" languages such one.
in terms of do, car , cdr equivalent first , rest. quite clear in documentation. hyperspec says on entry first, second, &c:
the functions first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, , tenth access first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, , tenth elements of list, respectively. specifically,
(first list) == (car list) (second list) == (car (cdr list)) (third list) == (car (cddr list))
…
notes:
first functionally equivalent car, second functionally equivalent cadr, third functionally equivalent caddr, , fourth functionally equivalent cadddr.
now, there is difference, not in functionality, in style, when you're using these functions. called out in hyperspec well, e.g., in entry on rest:
notes:
rest preferred stylistically on cdr when argument being subjectively viewed list rather cons.
for instance, consider 2 ways of mapping on structures built cons cells. in first, we're mapping on tree of cons cells, calling function each leaf (i.e., non-cons) of tree. check whether cons consp, , if is, recurse onto car , cdr. combine results new cons cell calling 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)))))
alternatively, when map on list, typically check terminal condition endp (or null, endp emphasizes we're looking end of list, not looking nil), , call function on first of list , recurse rest of list. while it's pretty common see result constructed using cons, there's list* perform same task when called 2 arguments (in general, can bit more) emphasizes list being constructed:
(defun map-over-list (function list) (if (endp list) '() (list* (funcall function (first list)) (map-over-list function (rest list)))))
either of these functions written using car, cdr, , cons, or first, rest, , list*, or combination of them, sticking 1 or other helps people may read code later (including original author), , signals intent of author.
and how implement first/rest using cdr, car?
how about:
(defun first (x) (car x)) (defun rest (x) (cdr x))
or possibly better, if have symbol-function:
(setf (symbol-function 'first) (symbol-function 'car)) (setf (symbol-function 'rest) (symbol-function 'cdr))