Search code examples
common-lispelisp

Mapping a function to a dotted pair


I want to map a function, (lambda (x) (+ x 1)), to a dotted pair '(1 . 2), to get another dotted pair, '(2 . 3). I have tested the below code to no avail:

(defun mapdot (func coll)
  ((funcall func (car coll)) . (funcall func (cdr coll))))
ELISP> (mapdot (lambda (x) (+ x 1)) '(1 . 2))
*** Eval error ***  Invalid function: (funcall func (car coll))

How can I achieve such behavior?


Solution

  • You had problems with your first attempt because it tries to use (funcall func (car coll)) as the name of a function to call - which of course doesn't work. To make the mistake clearer, it's as if you were doing this:

    ELISP> ((list))
    *** Eval error ***  Invalid function: (list)
    

    The solution would be to either use cons or a quasiquote:

    ELISP> (defun mapdot (func coll)
             (cons (funcall func (car coll)) (funcall func (cdr coll))))
    mapdot
    ELISP> (mapdot (lambda (x) (+ x 1)) '(1 . 2))
    (2 . 3)
    
    ELISP> (defun mapdot (func coll)
             `(,(funcall func (car coll)) . ,(funcall func (cdr coll))))
    mapdot
    ELISP> (mapdot (lambda (x) (+ x 1)) '(1 . 2))
    (2 . 3)