help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Adding Lists/Sequences


From: Tim X
Subject: Re: Adding Lists/Sequences
Date: Thu, 25 Sep 2008 15:27:48 +1000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux)

Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:

> David Kastrup <dak@gnu.org> writes:
>
>> Thierry Volpiatto <thierry.volpiatto@gmail.com> writes:
>>
>>> Nordlöw <per.nordlow@gmail.com> writes:
>>>
>>>> Is there a general function, say foo, that adds lists or, even better,
>>>> sequences together?
>>>>
>>>> I want this
>>>>   (foo '("a" "b") '("c" "d"))
>>>> to evaluate to
>>>>   '("a" "b" "c" "d")
>>>
>>> ,----
>>> | ELISP> (nconc '("a" "b" "c") '("d" "e" "f")) 
>>> | ("a" "b" "c" "d" "e" "f")
>>> `----
>>>
>>> Note: `append' is not destructive
>>
>> This is so bad that I can't believe it.
>>
>> (defun ugh () (nconc '("a" "b" "c") '("d" "e" "f")))
>> (ugh) -> ("a" "b" "c" "d" "e" "f")
>> (ugh) -> ("a" "b" "c" "d" "e" "f" . #3)
>>
>> The latter is a tail-cyclic list.
>>
>> (ugh) -> hangs
> We speak of what is bad and very bad but didn't answer to what is good
> or not, i send here a bad exemple as i constat i never used that in my
> programs (nconc), idem for `nreverse'.And when i read again my commonlisp
> book it say that is very delicate to use destructives functions.
> So can you explain when it is good (if it is) to use these destructive
> functions.
>
> Here an example of the use of append that is safe.
>
>
> ,----
> | ELISP> (setq A '(a b c))
> | (a b c)
> | 
> | ELISP> (setq B '(1 2 3))
> | (1 2 3)
> | 
> | ELISP> (defun quite-good (beg tail)
> |          (append beg tail))
> | quite-good
> | ELISP> (quite-good A B)
> | (a b c 1 2 3)
> | 
> | ELISP> (setq C (quite-good A B))
> | (a b c 1 2 3)
> | 
> | ELISP> A
> | (a b c)
> | 
> | ELISP> B
> | (1 2 3)
> | 
> | ELISP> C
> | (a b c 1 2 3)
> `----

I think there are possibly two different issues here that need to be
considered. 

1. Modifying 'literal' lists is usually risky. Weird things can happen
because on some levels, you are modifying what is best considered a
constant. This is the difference between '(1 2 3) and (list 1 2 3). 

2. The destructive operators manipulate the structure of the list rather
than creating a new copy with its own structure. This can have two
problems. Firstly, you can create circular lists as David points out and
more generally, you can get unexpected 'side effects' if that structure is
also bound to another symbol. In general, I think yo should only use the
destructive operators on a structure which you know is not shared. For
example, you could define your function so that it makes a copy of the
list and then applies a distructive operation to the list and return the
new list rather than just applying the destructive operation to the list
that is passed in. Of course, the problem with tis is that often the
destructive functions are used for performance reasons and having to
make a copy each time may cause its own performance problems.

HTH

Tim


-- 
tcross (at) rapttech dot com dot au


reply via email to

[Prev in Thread] Current Thread [Next in Thread]