From: Francois Aguet
Subject: Simple Question
Date: 
Message-ID: <3b1be99c_3@news.bluewin.ch>
Hello again,

Just a simple question. The following program should merge two tables like
this:

(0 (0 (1 0))) + (0 (1 (0 1))) => (0 (1 (1 1)))

All I would like to know is why it doesn't work the way I prgrammed it.
(Don't worry about the first cond args, just that (t .... ) part)

(defun tmerge (tree1 tree2)
  (cond (((or (null tree1) (null tree2)) nil)
         (and (atom tree1) (atom tree2))
         (if (equal tree1 tree2) tree1 1))
         (t (append (tmerge (car tree1) (car tree2)) (tmerge (cadr tree1)
(cadr tree2))))))

Thanks in advance,

Francois

From: Barry Margolin
Subject: Re: Simple Question
Date: 
Message-ID: <EeSS6.21$5t5.1060@burlma1-snr2>
In article <··········@news.bluewin.ch>,
Francois Aguet <····················@bluewin.ch> wrote:
>Hello again,
>
>Just a simple question. The following program should merge two tables like
>this:
>
>(0 (0 (1 0))) + (0 (1 (0 1))) => (0 (1 (1 1)))
>
>All I would like to know is why it doesn't work the way I prgrammed it.
>(Don't worry about the first cond args, just that (t .... ) part)

How can we not worry about the first part?  A recursive function can only
work if the end cases are written properly.  Your function isn't even
syntactically correct.  Here's your function with proper indentation:

(defun tmerge (tree1 tree2)
  (cond (((or (null tree1) (null tree2))
          nil)
         (and (atom tree1) (atom tree2))
         (if (equal tree1 tree2) tree1 1))
        (t (append (tmerge (car tree1) (car tree2))
                   (tmerge (cadr tree1) (cadr tree2))))))

(and (atom tree1) (atom tree2)) is presumably supposed to be the second
COND close, but because you have too many parentheses at the beginning of
the first clause, it's actually part of that clause.

(defun tmerge (tree1 tree2)
  (cond ((or (null tree1) (null tree2))
	 nil)
	((and (atom tree1) (atom tree2))
         (if (equal tree1 tree2) tree1 1))
	(t (append (tmerge (car tree1) (car tree2))
		   (tmerge (cadr tree1) (cadr tree2))))))

Here it is with the first two clauses fixed.  Now on to the last clause.
(tmerge (car tree1) (car tree2)) returns 0, so you're calling

(append 0 (tmerge (cadr tree1) (cadr tree2)))

APPEND requires that all its arguments except the last one be a list, so
this clearly can't work.  You should call LIST rather than APPEND.

-- 
Barry Margolin, ······@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Francois Aguet
Subject: Re: Simple Question
Date: 
Message-ID: <3b1bf4ec_3@news.bluewin.ch>
Thanks for your answer. The end clauses were false, but I knew that (typed
them in the post without checking syntax). Using list instead of append
cleared things up.

Francois
From: Wolfhard Buß
Subject: Re: Simple Question
Date: 
Message-ID: <m366ebj6ev.fsf@buss-14250.user.cis.dfn.de>
"Francois Aguet" <····················@bluewin.ch> writes:

> Just a simple question. The following program should merge two tables like
> this:
> 
> (0 (0 (1 0))) + (0 (1 (0 1))) => (0 (1 (1 1)))

In Paul Graham's On Lisp on page 54 you'll find a function which
maps a function onto one or more trees.

 (defun rmapcar (fn &rest args)
   (if (some #'atom args)
       (apply fn args)
       (apply #'mapcar
              #'(lambda (&rest args)
                  (apply #'rmapcar fn args))
              args)))
Use it.

-wb