Subject: *** general mapping function
Date: Wed, 6 Mar 96 22:08:40 PST
From: Vladimir Nesterovsky 

Hi Reini --
I am forwarding you my post to comp.cad.autocad from yesterday.
It lets you map arbitrary function onto each atom in your list,
building the list of the results in the same structure as the
original one ---

;; Created (1995) by Vladimir Nesterovsky 
;;    e-mail me for any questions or requests.
;; YOU MAY USE THIS FUNCTION AS IT IS FOR ANY NON-PROFITABLE
;; PURPOSE AT YOUR OWN RISK IF YOU RETAIN THIS NOTICE COMPLETE
;;     AND UNALTERED. NO WARRANTIES GIVEN WHATSOEVER.
;;;; IN NO WAY IS THE AUTHOR RESPONSIBLE FOR ANY CONCIQUENCIES
;;;;       OF WHATEVER USE OF THIS PROGRAM WHATSOEVER.

;; helper func. Maps function on each atom inside list. Recursive.
(defun maplist ( f l ) ;; map func(x) on l; x == one atom
  (cond
    ((atom l)(f l))
    ((and (cdr l)(atom (cdr l)))(cons (maplist f (car l))(f (cdr l))))
    (T (mapcar '(lambda(subl)(maplist f subl)) l))
))
;;;;;;;;;;;end;;;;;;;;;;;;;;;;;

Enjoy,
===============================================
 Vladimir Nesterovsky      LISP/C/C++ etc.
   03/06/96 22:08:40
===============================================

Additional notes by Reini:

1) "maplist" is a misnomer. In Common Lisp maplist is like mapcar except that the
function is applied to the lists and successive cdr's of those lists than to
successive elements (the car's) of the lists.

For example:

(maplist #'list '(1 nil nil) '(2 2 nil) '(3 3 3))
=> (((1 nil nil) (2 2 nil) (3 3 3))
    ((nil nil) (2 nil) (3 3))
    ((nil) (nil) (3)))

I suggest the name "mapatom" because it applies a function to each atom
only in trees.


2)  (f l)

better do a (apply f (list l)) here, because it will work only with
not quoted functions then.

(maplist '1+ '(1 2 (3 4) 5 6))             ;ERROR: bad function: 1+
(maplist 1+ '(1 2 (3 4) 5 6))
=> (2 3 (4 5) 6 7)

mapping functions should always take quoted functions as argument because
a) all the others do
  (mapcar in AutoLISP and
  map, mapc, mapl, mapcar, mapcon, maplist, mapcon, map-into in Lisp)
b) a true lisp wouldn't accept this definition:
  LPP even writes after defun maplist:
  *** ERROR: Lexically bound funarg: f

So my proposal would be:

;;; MAPATOM - maps function on each atom inside list.
;;; Keeps list structure intact. Recursive.
;;; Ex: (mapatom '1+ '(1 2 (3 4) 5 6)) => (2 3 (4 5) 6 7)
(defun mapatom (f l)  ; map func(x) on l; x == one atom
  (cond
    ((atom l) (apply f (list l)))
    ((and (cdr l) (atom (cdr l)))
     (cons (mapatom f (car l)) (apply f (cdr l))))
    (T (mapcar '(lambda (subl) (mapatom f subl)) l))
  )
)