Re: novice: mapcan use?
- From: Kent M Pitman <pitman@xxxxxxxxxxx>
- Date: Sun, 28 Aug 2005 19:47:25 GMT
Bernd Schmitt <Bernd.Schmitt.News@xxxxxxx> writes:
> ... nconc is a destructive version of append, isnt't it?
> Nconc does change variables,
No, it changes objects, not variables.
> if i
> understand the following in the right way:
>
> CL-USER> (setq x '(1 2) y '(3 4))
> (3 4)
> CL-USER> (nconc x y)
> (1 2 3 4)
> CL-USER> x
> (1 2 3 4)
Before, there is a variable X and the value associated with it is a certain
cons cell, call it #0#, which looks like ( 1 . #1# ) where the #1# is
another cons that is ( 2 . () ) There is also a variable Y which has a
cons cell we'll call #2# and which looks like ( 3 . #3# ) where #3# is
another cons cell that looks like ( 4 . () ).
After, all the same is true except that the cons cell #1# now looks like
( 2 . #2 ), that is, its cdr points into the cons cell that is still
held by Y.
Nothing about the storage of X has changed. It still points to #0#.
Nothing about the storage of Y has changed. It still points to #2#.
But when X is viewed, it will point to ( 1 2 3 4 ) because it points
to #0=( 1 . #1=( 2 . #2=( 3 . #3=( 4 . () )))), while Y still points
to #2=( 3 . #3=( 4 . () )).
> So, when do I know, whether a variable can be used to catch the result
> of a destructive function (or was my example implementation dependent)?
You're using bad terminology because "the result" is what NCONC returns,
and most people will think by "catch the result" you mean
(let ((z (nconc ....))) ...)
where z "catches the result". A side-effect is not a result, it is an effect.
The question you want to ask is when a variable you've used will observe
a side-effect that has been made, and the answer is that it will see that
side-effect when the function is either permitted to make it and happens
to make it, or when the function is required to make it.
NCONC makes a side-effect to the object that is its first arg when the
first arg is not NIL. Any variable pointing to such a non-NULL object
will see that.
But you should pick up the result so you aren't confused by what you'll
perceive as a failure in the case of NIL. e.g.,
(let ((x '()) (y '(a b))) (nconc x y) x) => NIL ; not (A B)
even though
(let ((x '()) (y '(a b))) (nconc x y)) => (A B)
so you should generally prefer to do
(let ((x '()) (y '(a b))) (setq x (nconc x y)) ...)
since then x will really have the "result" of the NCONC. The result is
what's returned. The rest is just an effect.
If you're looking for a rule, focus on results as being returned.
Unlike other languages, which use reference variables to achieve multiple
results, Lisp will return more than one value if it needs to. It doesn't
resort to effects as cheating ways to return multiple values because it
has a first class way to do that.
(floor 5 3) => 1, 2
The values are returned, you don't have to write some goofy
void myfloor(int num, int denom, int& quo, int& rem)
in order to "pick up the result" in quo and rem. You will sometimes see
side-effects on given structures, but it's best early on if you don't
focus on those effects as your principle way of seeing results from
most operations.
.
- References:
- novice: mapcan use?
- From: Bernd Schmitt
- Re: novice: mapcan use?
- From: Pascal Costanza
- Re: novice: mapcan use?
- From: Bernd Schmitt
- novice: mapcan use?
- Prev by Date: Re: novice: mapcan use?
- Next by Date: Re: novice: mapcan use?
- Previous by thread: Re: novice: mapcan use?
- Next by thread: Re: novice: mapcan use?
- Index(es):