From: Mathieu
Subject: Too many brackets with 'mapcar'
Date: 
Message-ID: <a1uqf7$1l1$1@wanadoo.fr>
    hello everybody !

I should write a function that return all the node of a specified level of a
tree.
In my implementation, the node AND the leaf are consider as tree (leaf is a
tree without children).

Here the function that I write to do it :

(defun get_node (list level)
 (cond ((= level 0) (car list))
       (T (mapcar (lambda (x) (get_node x (- level 1))) (cdr list)))
 )
)

With the tree t1 : ((13)   ((2 4 10)((0))((3))((6 7))((11 12)))   ((30)((15
20))((35 40)))),

(get_node t1 2) return :

(((3) (6 7) (11 12)) ((15 20)(35 40)))

It's good but there are too many brackets. I would rather have :
( (3) (6 7) (11 12) (15 20) (35 40) )

The problem is that the function mapcar is call recursively. So, brackets is
added at each recurrence.

Is it possible to delete its? (may be with an another function than
'mapcar'?)

Mathieu

--
=== Ma citation du mois ===
C'est l'incertitude qui nous charme. Tout devient merveilleux dans la brume.

          Oscar Wilde - Extrait de "Le portrait de Dorian Gray"

From: Nils Goesche
Subject: Re: Too many brackets with 'mapcar'
Date: 
Message-ID: <a1uttl$t4icu$1@ID-125440.news.dfncis.de>
In article <············@wanadoo.fr>, Mathieu wrote:
> With the tree t1 : ((13)   ((2 4 10)((0))((3))((6 7))((11 12)))   ((30)((15
> 20))((35 40)))),
> 
> (get_node t1 2) return :
> 
> (((3) (6 7) (11 12)) ((15 20)(35 40)))
> 
> It's good but there are too many brackets. I would rather have :
> ( (3) (6 7) (11 12) (15 20) (35 40) )
> 
> The problem is that the function mapcar is call recursively. So, brackets is
> added at each recurrence.
> 
> Is it possible to delete its? (may be with an another function than
> 'mapcar'?)

You might want to play around with mapcan.

Regards,
-- 
Nils Goesche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x42B32FC9
From: Fernando Rodr�guez
Subject: Re: Too many brackets with 'mapcar'
Date: 
Message-ID: <v9t54u041gg1nm625viqen8ua1c8ab2496@4ax.com>
On Mon, 14 Jan 2002 15:38:31 +0100, "Mathieu" <·········@hotmail.com> wrote:


>Is it possible to delete its? (may be with an another function than
>'mapcar'?)

Try mapcan and take a look at all the bzillion mapwhatever functions
available.



--
Fernando Rodr�guez
frr at wanadoo dot es
--
From: Kaz Kylheku
Subject: Re: Too many brackets with 'mapcar'
Date: 
Message-ID: <S2G08.4989$ST3.334357@news1.calgary.shaw.ca>
In article <············@wanadoo.fr>, Mathieu wrote:
>Here the function that I write to do it :
>
>(defun get_node (list level)

It's more customary to use the dash symbol in Lisp identifiers: get-node.

> (cond ((= level 0) (car list))
>       (T (mapcar (lambda (x) (get_node x (- level 1))) (cdr list)))
> )

Using if is better if you just have two cases.

>)

Your get_node function returns the result of mapcar, which produces
a list. So, when you use mapcar to recursively combine the results
of calls go get_node, the mapcar will produce a list of lists! It
has to be cause the recursive calls return lists (except for the
leaf cases which return (car list)).

So, the thing to do, firstly, is to unify the leaf cases and nonleaf
cases, so they *both* return lists:

   (if (zerop level) 
     (list (car list))  ; list!
     (mapcar ...))      ; list!

Now, what we want is for the mapping to not produce a list of lists. But
rather there is another mapping function you can use:

   (mapcan (lambda (x) (get_node x (- level 1))) (cdr list))

This mapcan function takes the lists returned by your closure and
destructively catenates them to form a result list. Any empty lists
disappear in the catenation. 

The destructive catenation is usually not a problem, because the
closure returns a brand new list which is not retained anywhere,
so that there is no alternate way to access it.
From: Jochen Schmidt
Subject: Re: Too many brackets with 'mapcar'
Date: 
Message-ID: <3C4349CD.3020203@dataheaven.de>
Kaz Kylheku wrote:
> In article <············@wanadoo.fr>, Mathieu wrote:
> 
>>Here the function that I write to do it :
>>
>>(defun get_node (list level)
>>
> 
> It's more customary to use the dash symbol in Lisp identifiers: get-node.
> 
> 
>>(cond ((= level 0) (car list))
>>      (T (mapcar (lambda (x) (get_node x (- level 1))) (cdr list)))
>>)
>>
> 
> Using if is better if you just have two cases.

I agree in this particular case - but I often use COND instead of IF
when I have multiple forms in one clause.

So I prefer

(cond ((test-something ..) (a b) (c d))
       (t (e f) (g h)))

over

(if (test-something ..)
    (progn
       (a b)
       (c d))
    (progn
       (e f)
       (g h)))


ciao,
Jochen