From: Michael Tuchman
Subject: tree-mapping
Date: 
Message-ID: <wkd85ujvvz.fsf@orsi.com>
(defun tree-mapping (fcn x)
  "apply fcn to each atom of tree-structured data x"
  (cond ((null x) ())
	((atom x) (funcall fcn x))
	(t (cons (tree-mapping fcn (car x))
		 (tree-mapping fcn (cdr x))))))

Does anybody know if there is a lisp primitive that does the same as
the above? I tried looking under map and tree in the hyperspec.  I
strongly suspect the answer is "no", but this function I wrote raises
some internal (in my brain, not in lisp) alarms about efficiency.

-- 
Michael Tuchman
A Great way to avoid flame wars: all.SCORE has  ("vs\\.?" -1000 nil r) 

From: Will Fitzgerald
Subject: Re: tree-mapping
Date: 
Message-ID: <74k3o4$sn$1@leol.net-link.net>
If you're interested in side effects only, then
you don't need to CONS. If you want to collect the
values of the function, then you'll have to CONS.
You might just put the results in one list; you
might replace the elements of the tree in place.



(defun map-tree (f tree)
  "calls function F on each element of tree into copy of tree"
  (cond ((null tree) '())
        ((atom tree) (funcall f tree))
        (t (cons (map-tree f (car tree))
                 (map-tree f (cdr tree))))))

(defun map-tree->list (f tree)
  "calls function F on each element of tree, saving result in one list"
  (let ((results '()))
    (labels ((mp (f thing)
               (cond ((null thing))
                     ((atom thing) (push (funcall f thing) results))
                     (t (mp f (car thing))
                        (mp f (cdr thing))))))
      (mp f tree)
      (nreverse results))))

(defun mapc-tree (f tree)
  "calls function F on each element of tree; doesn't save results."
  (cond ((null tree))
        ((atom tree) (funcall f tree))
        (t (mapc-tree f (car tree))
           (mapc-tree f (cdr tree))))
  tree)


(defun nmap-tree (f tree)
  "calls function F on each element of tree, replacing each element"
  (cond ((not (consp tree)) nil)
        ((atom (car tree))
         (setf (car tree) (funcall f (car tree)))
         ;; now do rest...
         (nmap-tree f (cdr tree)))
        (t (nmap-tree (car tree))
           (nmap-tree (cdr tree))))
  tree)

>(defun tree-mapping (fcn x)
>  "apply fcn to each atom of tree-structured data x"
>  (cond ((null x) ())
> ((atom x) (funcall fcn x))
> (t (cons (tree-mapping fcn (car x))
> (tree-mapping fcn (cdr x))))))
>
>Does anybody know if there is a lisp primitive that does the same as
>the above? I tried looking under map and tree in the hyperspec.  I
>strongly suspect the answer is "no", but this function I wrote raises
>some internal (in my brain, not in lisp) alarms about efficiency.
>
>--
>Michael Tuchman
>A Great way to avoid flame wars: all.SCORE has  ("vs\\.?" -1000 nil r)
From: Barry Margolin
Subject: Re: tree-mapping
Date: 
Message-ID: <jLgb2.66$g34.4617@burlma1-snr1.gtei.net>
In article <··············@orsi.com>, Michael Tuchman  <·····@orsi.com> wrote:
>(defun tree-mapping (fcn x)
>  "apply fcn to each atom of tree-structured data x"
>  (cond ((null x) ())
>	((atom x) (funcall fcn x))
>	(t (cons (tree-mapping fcn (car x))
>		 (tree-mapping fcn (cdr x))))))
>
>Does anybody know if there is a lisp primitive that does the same as
>the above? I tried looking under map and tree in the hyperspec.  I
>strongly suspect the answer is "no", but this function I wrote raises
>some internal (in my brain, not in lisp) alarms about efficiency.

No, there's no such standard function.  Your function looks about as
efficient as it could be.  About the only issue I have is that you can't
tell the difference between:

(tree-mapping #'null 1)

and

(tree-mapping #'null '())

The first returns NIL because it's called on a tree with one element, for
which the result of the function is NIL; the second returns () because
you've defined the empty list to be an empty tree.  This also means that:

(tree-mapping #'null '(nil . nil)) => (NIL . NIL)

when it seems like it should be (T . T)

So I suggest removing the NULL case from your COND.  NIL is an atom, so
that case will handle it.

I would also suggest renaming it to MAP-TREE, for consistency with other
mapping functions.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Don't bother cc'ing followups to me.