From: Andrew Burton
Subject: Semantic question about APPEND
Date: 
Message-ID: <20030712121450.26581.00000265@mb-m18.aol.com>
Assuming that I've already...

(SETF DLS (LIST 1 2 3 4))

Can anyone tell me the reason behind having to use...

(APPEND DLS (LIST 5))

...to get...

(1 2 3 4 5)

...as opposed to just...

(APPEND DLS 5)

...which, if I recall, gives...

(1 2 3 4 . 5)

What was the reason for making it like this?  Did it have anything to do with
CONS?  Thanks!

Andrew Burton - tuglyraisin at aol dot com
Felecia Station on Harvestgain - http://www.darkbeast.com/
"I often question my sanity; it has yet to give me a straight answer."
"And if you're bored, it's because... you're boring." - Matt Drudge

From: Kent M Pitman
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <sfw4r1ryau2.fsf@shell01.TheWorld.com>
···········@aol.commcast (Andrew Burton) writes:

> Assuming that I've already...
> 
> (SETF DLS (LIST 1 2 3 4))
> 
> Can anyone tell me the reason behind having to use...
> 
> (APPEND DLS (LIST 5))
> 
> ...to get...
> 
> (1 2 3 4 5)
> 
> ...as opposed to just...
> 
> (APPEND DLS 5)
> 
> ...which, if I recall, gives...
> 
> (1 2 3 4 . 5)
> 
> What was the reason for making it like this?  Did it have anything to do with
> CONS?  Thanks!


APPEND's job is to append two lists.  5 is not a list. 

(x1 x2 x3 x4 . x5)

means

(x1 . (x2 . (x3 . (x4 . x5))))

Had you given a list such as (x5 . nil) then you'd have gotten

(x1 . (x2 . (x3 . (x4 . (x5 . nil)))))

the shorthand for which is

(x1 x2 x3 x4 x5)

In general, any

 (x1 . nil) is abbreviated  (x1)

and any

 (x1 . (x2 . x3))

is abbreviated

 (x1 x2 . x3)

if that helps you understand things better.

In general, just avoid APPEND altogether.  Its "algorithmic complexity"
(read "speed"  if you don't know what that is) is bad.

You're better off to CONS things on the head of the list (and then REVERSE
the list at the end if needed) than to do a bunch of appends.
Someone else will surely explain why.  I have errands to run.
From: synthespian
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <bepvit$7ncna$1@ID-78052.news.uni-berlin.de>
Andrew Burton wrote:
> Assuming that I've already...
> 
> (SETF DLS (LIST 1 2 3 4))
> 
> Can anyone tell me the reason behind having to use...
> 
> (APPEND DLS (LIST 5))
> 
> ...to get...
> 
> (1 2 3 4 5)
> 
> ...as opposed to just...
> 
> (APPEND DLS 5)
> 
> ...which, if I recall, gives...
> 
> (1 2 3 4 . 5)
> 
> What was the reason for making it like this?  Did it have anything to do with
> CONS?  Thanks!
> 
> Andrew Burton - tuglyraisin at aol dot com
>
Hi Andrew --

  CL-USER 13 > (append dls '(5))
(1 2 3 4 5)

  There's a book that you can download for free called
"Common Lisp: A Gentle Introduction to Symbolic Computation" by David S. 
Touretzky

           http://www-2.cs.cmu.edu/~dst/LispBook/

  It has nice diagrams explaining this point to you.

  Regs

  Henry
From: Edi Weitz
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <877k6nny1o.fsf@bird.agharta.de>
synthespian <···········@uol.com.br> writes:

> Hi Andrew --
> 
>   CL-USER 13 > (append dls '(5))
> (1 2 3 4 5)

Not a good idea because you're using a literal object:

  * (defun frob ()
        (let* ((list (list 1 2 3 4))
               (foo (append list '(5))))
          foo))

  FROB
  * (defun no-frob ()
        (let* ((list (list 1 2 3 4))
               (foo (append list (list 5))))
          foo))

  NO-FROB
  * (no-frob)

  (1 2 3 4 5)
  * (setf (nth 4 (no-frob)) 42)

  42
  * (no-frob)

  (1 2 3 4 5)
  * (frob)

  (1 2 3 4 5)
  * (setf (nth 4 (frob)) 42)

  42
  * (frob)

  (1 2 3 4 42)

Did you expect that?

Edi.
From: synthespian
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <beq5ta$7h4ro$1@ID-78052.news.uni-berlin.de>
Edi Weitz wrote:
> synthespian <···········@uol.com.br> writes:
> 
> 
>>Hi Andrew --
>>
>>  CL-USER 13 > (append dls '(5))
>>(1 2 3 4 5)
> 
> 
> Not a good idea because you're using a literal object:
> 
>   * (defun frob ()
>         (let* ((list (list 1 2 3 4))
>                (foo (append list '(5))))
>           foo))
> 
>   FROB
>   * (defun no-frob ()
>         (let* ((list (list 1 2 3 4))
>                (foo (append list (list 5))))
>           foo))
> 
>   NO-FROB
>   * (no-frob)
> 
>   (1 2 3 4 5)
>   * (setf (nth 4 (no-frob)) 42)
> 
>   42
>   * (no-frob)
> 
>   (1 2 3 4 5)
>   * (frob)
> 
>   (1 2 3 4 5)
>   * (setf (nth 4 (frob)) 42)
> 
>   42
>   * (frob)
> 
>   (1 2 3 4 42)
> 
> Did you expect that?
> 
> Edi.

Hi --

  That's esoteric knowledge, isn't it? I'm deeply frobbled! ;-)
  How come foo was easily fooled in accepting 42 in one case, and not in 
the other?
  Why on earth did /that/ happen? Any pointers, or is it something you 
found out the "long and hard way"? Is this common knowledge?

  Regs,
  Henry
From: Gareth McCaughan
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <87d6gf47gf.fsf@g.mccaughan.ntlworld.com>
"synthespian" wrote:

> Edi Weitz wrote:
> > synthespian <···········@uol.com.br> writes:
> >
> >>Hi Andrew --
> >>
> >>  CL-USER 13 > (append dls '(5))
> >>(1 2 3 4 5)
> > Not a good idea because you're using a literal object:
...
> >   * (no-frob)
> >   (1 2 3 4 5)
> >   * (frob)
> >   (1 2 3 4 5)
> >   * (setf (nth 4 (frob)) 42)
> >   42
> >   * (frob)
> >   (1 2 3 4 42)
> > Did you expect that?
> 
> Hi --
> 
>   That's esoteric knowledge, isn't it? I'm deeply frobbled! ;-)
>   How come foo was easily fooled in accepting 42 in one case, and not
> in the other?
>   Why on earth did /that/ happen? Any pointers, or is it something you
> found out the "long and hard way"? Is this common knowledge?

It's quite common knowledge. The HyperSpec (all hail the Hyperspec!)
does say things that imply that this can happen, but not necessarily
in ways that are obvious to the newcomer :-).

The key here is understanding what goes on when your Lisp system
evaluates things.

  1 First the characters you type in (or the characters it reads
    from a file) are parsed to produce a Lisp object -- typically
    a list.

  2 Then this object is evaluated to produce an answer (perhaps
    with some side-effects like setting variables).

The first of these happens "at read time". The second actually
happens, at least notionally, in several phases: "macroexpansion
time", "compilation time", "run time".

So, what happens when you type in (APPEND DLS '(5)) ? The first
thing that happens is that the Lisp reader builds a list that
looks like (APPEND DLS (QUOTE (5))). And the point now is that
lurking in there is the list (5), and *that very same object*
built by the reader is what gets passed to the APPEND function
at run time. Or, at least, it's allowed to be.

What if you define a function with a quoted form in it? Something
rather similar. If you say (DEFUN FOO () '(1)) then the function
you create by doing that will contain a reference to the *very same
object (1)* that the reader makes. So now when you call FOO you
get hold of the exact same object that it returns, and if you
mutate it using SETF then that can change its contents, so that
subsequent calls to FOO will give different-looking results.
Different-*looking* because it's still the same cons cell; it's
just its contents that have changed.

Note that as soon as you try to mutate something that was built
using QUOTE, you are invoking undefined behaviour and your Lisp
interpretation is allowed to
  - mutate the object
  - make a copy and mutate that instead
  - change the value of every variable in your program to
    the symbol WALRUS
  - delete all your files and send obscene e-mail to your boss
  - cause the sun to go supernova
  - consign your soul to eternal perdition while laughing
    diabolically

So don't do that.

-- 
Gareth McCaughan
.sig under construc
From: Daniel Barlow
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <87znjioev1.fsf@noetbook.telent.net>
Gareth McCaughan <·····@g.local> writes:

> Note that as soon as you try to mutate something that was built
> using QUOTE, you are invoking undefined behaviour and your Lisp
> interpretation is allowed to
[...]
>   - cause the sun to go supernova

This happened to me once.

> So don't do that.

What he says.


-dan

-- 

   http://www.cliki.net/ - Link farm for free CL-on-Unix resources 
From: Edi Weitz
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <871xwuolhh.fsf@bird.agharta.de>
synthespian <···········@uol.com.br> writes:

> Edi Weitz wrote:
> > synthespian <···········@uol.com.br> writes:
> >
> >>Hi Andrew --
> >>
> >>  CL-USER 13 > (append dls '(5))
> >>(1 2 3 4 5)
> > Not a good idea because you're using a literal object:
> >   * (defun frob ()
> >         (let* ((list (list 1 2 3 4))
> >                (foo (append list '(5))))
> >           foo))
> >   FROB
> >   * (defun no-frob ()
> >         (let* ((list (list 1 2 3 4))
> >                (foo (append list (list 5))))
> >           foo))
> >   NO-FROB
> >   * (no-frob)
> >   (1 2 3 4 5)
> >   * (setf (nth 4 (no-frob)) 42)
> >   42
> >   * (no-frob)
> >   (1 2 3 4 5)
> >   * (frob)
> >   (1 2 3 4 5)
> >   * (setf (nth 4 (frob)) 42)
> >   42
> >   * (frob)
> >   (1 2 3 4 42)
> > Did you expect that?
> > Edi.
> 
> Hi --
> 
>   That's esoteric knowledge, isn't it? I'm deeply frobbled! ;-) How
>   come foo was easily fooled in accepting 42 in one case, and not >
>   in the other?
>   Why on earth did /that/ happen? Any pointers, or is it something
>   you found out the "long and hard way"? Is this common knowledge?

Gareth McCaughan has explained it much better than I could so let me
just add a slightly wrong (or over-simplified) but maybe intuitive
version:

In NO-FROB the function call (LIST 5) will guarantee that you get a
_new_ list every time you call NO-FROB. On the other hand, the literal
'(5) in FROB becomes a part of the definition of FROB and thus the
SETF above modifies the function FROB itself.

As I said, this is not to be taken literally (pun intended) but rather
to give you an intuitive idea about what's going on. The important
thing to remember is that you cannot rely on this behaviour - your
Lisp can do things like CMUCL did above but it can do whatever it
wants and still be ANSI-compliant.

I'd not say that this is esoteric knowledge - something like this
comes up here quite often. Also, it is not that much different from
other languages:

  ···@bird:/tmp > cat foo.c
  char *foo () {
    char* s = "Hello World!";

    printf("%s\n", s);
    return s;
  }

  int main (int argc, char* argv[]) {
    char* t;

    t = foo();
    t[0] = 'X';
    foo();

    return 0;
  }
  ···@bird:/tmp > gcc -fwritable-strings foo.c
  ···@bird:/tmp > ./a.out
  Hello World!
  Xello World!
  ···@bird:/tmp >

Cheers,
Edi.
From: synthespian
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <bet0p1$8ne7a$1@ID-78052.news.uni-berlin.de>
Edi Weitz wrote:

> 
> Gareth McCaughan has explained it much better than I could so let me
> just add a slightly wrong (or over-simplified) but maybe intuitive
> version:
(...)
> 
> As I said, this is not to be taken literally (pun intended) but rather
> to give you an intuitive idea about what's going on. The important
> thing to remember is that you cannot rely on this behaviour - your
> Lisp can do things like CMUCL did above but it can do whatever it
> wants and still be ANSI-compliant.
> 

Ok, a lesson to be remembered! (Maybe there should be some such example 
in The Cookbook, IMHO).
Thanks to you and Gareth for sorting out this interesting aspect of CL.

Thanks very much,

Henry
From: Andrew Burton
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <20030713110309.01238.00000217@mb-m26.aol.com>
> There's a book that you can download for 
> free called "Common Lisp: A Gentle 
> Introduction to Symbolic Computation" 
> by David S. Touretzky

Yeah, I've got the PDF on my machine. :)  I was just playing around, um,
Friday, I think, at work and didn't have access to it.  The strain of my code
bugging out like it did and then finally working when I discovered how APPEND
actually worked just prompted me to ask.



Andrew Burton - tuglyraisin at aol dot com
Felecia Station on Harvestgain - http://www.darkbeast.com/
"I often question my sanity; it has yet to give me a straight answer."
"And if you're bored, it's because... you're boring." - Matt Drudge
From: Kenny Tilton
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <3F10A572.9010307@nyc.rr.com>
Andrew Burton wrote:
> Assuming that I've already...
> 
> (SETF DLS (LIST 1 2 3 4))
> 
> Can anyone tell me the reason behind having to use...
> 
> (APPEND DLS (LIST 5))
> 
> ...to get...
> 
> (1 2 3 4 5)
> 
> ...as opposed to just...
> 
> (APPEND DLS 5)

Because if:
   (append (list 1 2) 3) => (1 2 3)

then:

   (append (list 1 2) (list 3 4)) => (1 2 (3 4))

and (the real problem) there would be no way to get (1 2 3 4).

But the way things are:

   (append (list 1 2) (list 3 4)) => (1 2 3 4)

and if you happen to have just an atom to append you have a workaround: 
(list <atom>)


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Everything is a cell." -- Alan Kay
From: Matthew Danish
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <20030713080114.GU17568@lain.mapcar.org>
On Sat, Jul 12, 2003 at 04:14:50PM +0000, Andrew Burton wrote:
> Assuming that I've already...
> 
> (SETF DLS (LIST 1 2 3 4))

Assuming that DLS is some previously declared variable...

> Can anyone tell me the reason behind having to use...
> 
> (APPEND DLS (LIST 5))
> 
> ...to get...
> 
> (1 2 3 4 5)

(defun append (a b)
  (if (null a) 
     b
     (cons (first a)
           (append (rest a) b))))

-- 
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Andrew Burton
Subject: Re: Semantic question about APPEND
Date: 
Message-ID: <20030713110837.01238.00000221@mb-m26.aol.com>
> (defun append (a b)
>   (if (null a) 
>      b
>      (cons (first a)
>            (append (rest a) b))))

I believe that makes a good bit of sense.  I am going to have to digest it in
more detail, but it gives me a grand inkling how APPEND works.  Thanks!

Andrew Burton - tuglyraisin at aol dot com
Felecia Station on Harvestgain - http://www.darkbeast.com/
"I often question my sanity; it has yet to give me a straight answer."
"And if you're bored, it's because... you're boring." - Matt Drudge