From: Jason
Subject: cons and list behaviour
Date: 
Message-ID: <1140982927.189126.226890@j33g2000cwa.googlegroups.com>
Please excuse me if this has been addressed before. I searched the
recent posts and the FAQ and did not see find the answer I am seeking.

I am learnin LISP (actually elisp ;)), and have written the following:

;; here I am using cons notation
(setq node-1 (cons 'a 'b))
(setq node-2 (cons 'c 'd))
(setq node-3 (cons 'e node-1))
(setq node-4 (cons node-3 'f))
(setq node-5 (cons node-2 'g))
(setq tree (cons node-4 node-5))
;; (((e a . b) . f) (c . d) . g) <<<<< value

;; here we can see that a cons is *not* the same as a list
(setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
(setq tree3 (copy-sequence tree)) ;; <<<<<<<< generates an error!

;; now I am redefing the above using list notation
(setq node-1 (list 'a 'b))
(setq node-2 (list 'c 'd))
(setq node-3 (list 'e node-1))
(setq node-4 (list node-3 'f))
(setq node-5 (list node-2 'g))
(setq tree (list node-4 node-5))
;; (((e (a b)) f) ((c d) g)) <<<<< value

;; however, here we see that a list *is* the same as a cons!
(setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
(setq tree3 (copy-sequence tree)) ;; <<<<<<<< also works fine!

It seems that the list notation works well with the cons notation, but
the reverse is not the case. I am wondering why is this? Also, if a
list is a cons, but a cons is not a list, then why do we have cons?

-Jason

From: Eric Lavigne
Subject: Re: cons and list behaviour
Date: 
Message-ID: <1140986203.247785.299540@v46g2000cwv.googlegroups.com>
> I am learnin LISP (actually elisp ;)), and have written the following:

I have used only Common Lisp, but I think I can answer your question.

In summary, a list can be built out of conses.
Here is a cons of a and b: (a . b)
(in this case, a is the car and b is the cdr)
Here is a list of a, b, and c: (a b c)
Now to show how to represent that list as conses:
(a . (b . (c . NIL)))
NIL is equivalent to an empty list and can be represented like this:
'()
You can also get NIL with this command: (list)

A recursive definition of a list:
A list can be either NIL (empty list) or a cons whose cdr is a list.

> ;; here I am using cons notation
> (setq node-1 (cons 'a 'b))

Now node-1 is (a . b), a cons that includes a and b. It is not a list.

> It seems that the list notation works well with the cons notation, but
> the reverse is not the case.

Your compiler doesn't care which notation you use. You just
misunderstood the notation. Instead of saying the same thing two
different ways, you said different things in different ways. The
following two commands give different results:
(list 'a 'b) -> (a b) or (a . (b . NIL))
(cons 'a 'b) -> (a . b)

To build the list '(a b) using conses, you could do this:
(cons 'a (cons 'b NIL))

> I am wondering why is this? Also, if a
> list is a cons, but a cons is not a list,

Most lists are conses. NIL is the only exception.

A cons is a list if and only if its cdr (the second element) is a list.

> then why do we have cons?

For one thing, cons is the building block of a list. Without cons there
would be no list. Cons can also be used for other thing, but building
lists is the main reason.

I don't know if elisp has NIL or if it has some other way to represent
the same thing. Aside from that, everything I said here probably
applies. Good luck with your studies.

Eric Lavigne
From: Kenny Tilton
Subject: Re: cons and list behaviour
Date: 
Message-ID: <cZoMf.5738$uV6.4897@news-wrt-01.rdc-nyc.rr.com>
To the OP, I suggest you disregard what Eric wrote, who meant well but 
has a few things to learn. (Sorry, Eric.)

Eric Lavigne wrote:
<The OP wrote:>
>>I am learnin LISP (actually elisp ;)), and have written the following:
> 
> 
> I have used only Common Lisp, but I think I can answer your question.
> 
> In summary, a list can be built out of conses.
> Here is a cons of a and b: (a . b)
> (in this case, a is the car and b is the cdr)
> Here is a list of a, b, and c: (a b c)
> Now to show how to represent that list as conses:
> (a . (b . (c . NIL)))
> NIL is equivalent to an empty list and can be represented like this:
> '()
> You can also get NIL with this command: (list)
> 
> A recursive definition of a list:
> A list can be either NIL (empty list) or a cons whose cdr is a list.

That would be a "proper list".

(listp '(1 . 2)) -> t


> 
> 
>>;; here I am using cons notation
>>(setq node-1 (cons 'a 'b))
> 
> 
> Now node-1 is (a . b), a cons that includes a and b. It is not a list.

Again, this is wrong, see above.

Note that I am not quibbling here. It is not just that the function 
LISTP returns t. '(a . b) is indeed understood to be a list. And (again) 
what you can say is that it is not a /proper/ list.

> 
> 
>>It seems that the list notation works well with the cons notation, but
>>the reverse is not the case.
> 
> 
> Your compiler doesn't care which notation you use. You just
> misunderstood the notation. Instead of saying the same thing two
> different ways, you said different things in different ways. The
> following two commands give different results:
> (list 'a 'b) -> (a b) or (a . (b . NIL))
> (cons 'a 'b) -> (a . b)
> 
> To build the list '(a b) using conses, you could do this:
> (cons 'a (cons 'b NIL))
> 
> 
>>I am wondering why is this? Also, if a
>>list is a cons, but a cons is not a list,
> 
> 
> Most lists are conses. NIL is the only exception.

A list is a cons? I know what you mean: listp could be written as:

   (defun listp (x) (or (null x) (consp x)))

I just think saying "a list is a cons" is confusing to someone such as 
the OP, who thinks the /functions/ LIST and CONS are interchangeable.


> 
> A cons is a list if and only if its cdr (the second element) is a list.

I know I am repeating myself, but so are you <g>. Wrong as per the above.

> 
> 
>>then why do we have cons?
> 
> 
> For one thing, cons is the building block of a list. Without cons there
> would be no list. Cons can also be used for other thing, but building
> lists is the main reason.

This bit jumps back and forth between CONS and LIST as noun and verb, 
not good for someone already confused.

I'll take a crack at the question separately.

kenny
From: Pascal Bourguignon
Subject: Re: cons and list behaviour
Date: 
Message-ID: <87u0al98qk.fsf@thalassa.informatimago.com>
"Jason" <·······@gmail.com> writes:

> Please excuse me if this has been addressed before. I searched the
> recent posts and the FAQ and did not see find the answer I am seeking.
>
> I am learnin LISP (actually elisp ;)), and have written the following:
>
> ;; here I am using cons notation
> (setq node-1 (cons 'a 'b))
> (setq node-2 (cons 'c 'd))
> (setq node-3 (cons 'e node-1))
> (setq node-4 (cons node-3 'f))
> (setq node-5 (cons node-2 'g))
> (setq tree (cons node-4 node-5))
> ;; (((e a . b) . f) (c . d) . g) <<<<< value
>
> ;; here we can see that a cons is *not* the same as a list
> (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> (setq tree3 (copy-sequence tree)) ;; <<<<<<<< generates an error!
>
> ;; now I am redefing the above using list notation
> (setq node-1 (list 'a 'b))
> (setq node-2 (list 'c 'd))
> (setq node-3 (list 'e node-1))
> (setq node-4 (list node-3 'f))
> (setq node-5 (list node-2 'g))
> (setq tree (list node-4 node-5))
> ;; (((e (a b)) f) ((c d) g)) <<<<< value
>
> ;; however, here we see that a list *is* the same as a cons!

This is not entirely true either:

(consp '()) --> nil

A list is either a cons, or the symbol nil, which can also be printed as: ()

A proper-list is either a cons whose cdr is a proper-list, or the symbol nil,
without circles.

copy-sequence wants a proper-list.
copy-tree wants a non-circular data structure.


> (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> (setq tree3 (copy-sequence tree)) ;; <<<<<<<< also works fine!
>
> It seems that the list notation works well with the cons notation, but
> the reverse is not the case. I am wondering why is this? Also, if a
> list is a cons, but a cons is not a list, then why do we have cons?

The cons cell is the basic lego(TM) block; the list or the tree is the
walls you build from the basic lego(TM) blocs.  Then you can use walls
to build houses.  Sometimes, what you want to build is cars, then you
don't use walls, but you build car elements from the basic lego(TM)
blocs, the cons cells.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

HANDLE WITH EXTREME CARE: This product contains minute electrically
charged particles moving at velocities in excess of five hundred
million miles per hour.
From: Jason
Subject: Re: cons and list behaviour
Date: 
Message-ID: <1140988853.914285.241010@i39g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:
> "Jason" <·······@gmail.com> writes:
>
> > Please excuse me if this has been addressed before. I searched the
> > recent posts and the FAQ and did not see find the answer I am seeking.
> >
> > I am learnin LISP (actually elisp ;)), and have written the following:
> >
> > ;; here I am using cons notation
> > (setq node-1 (cons 'a 'b))
> > (setq node-2 (cons 'c 'd))
> > (setq node-3 (cons 'e node-1))
> > (setq node-4 (cons node-3 'f))
> > (setq node-5 (cons node-2 'g))
> > (setq tree (cons node-4 node-5))
> > ;; (((e a . b) . f) (c . d) . g) <<<<< value
> >
> > ;; here we can see that a cons is *not* the same as a list
> > (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> > (setq tree3 (copy-sequence tree)) ;; <<<<<<<< generates an error!
> >
> > ;; now I am redefing the above using list notation
> > (setq node-1 (list 'a 'b))
> > (setq node-2 (list 'c 'd))
> > (setq node-3 (list 'e node-1))
> > (setq node-4 (list node-3 'f))
> > (setq node-5 (list node-2 'g))
> > (setq tree (list node-4 node-5))
> > ;; (((e (a b)) f) ((c d) g)) <<<<< value
> >
> > ;; however, here we see that a list *is* the same as a cons!
>
> This is not entirely true either:
>
> (consp '()) --> nil
>
> A list is either a cons, or the symbol nil, which can also be printed as: ()
>
> A proper-list is either a cons whose cdr is a proper-list, or the symbol nil,
> without circles.

Ok, this is becomming a little less muddy... A list can have a single
element, the cdr of which is implicitly nil? For example:

(setq my-single-list (list 'a)) ;; ok
my-single-list ;; (a)
(car my-single-list) ;; a
(cdr my-single-list) ;; nil

However, a cons *cannot* have only a single element. Example:

(setq my-single-cons (cons 'a)) ;; error!

I'm looking at the elisp manual and it says: A "list" represents a
sequence of zero or more elements (which may be any Lisp objects).
Whereas the definition of cons is: A cons cell is a data object that
represents an ordered pair.  That is, it has two slots, and each slot
"holds", or "refers to", some Lisp object.

I think I understand now. Thanks for your help!

-Jason
From: Frank Buss
Subject: Re: cons and list behaviour
Date: 
Message-ID: <1pgfvof8k78hv.1ky0wm5bur1v7$.dlg@40tude.net>
Jason wrote:

> Ok, this is becomming a little less muddy... A list can have a single
> element, the cdr of which is implicitly nil? For example:
> 
> (setq my-single-list (list 'a)) ;; ok
> my-single-list ;; (a)
> (car my-single-list) ;; a
> (cdr my-single-list) ;; nil
> 
> However, a cons *cannot* have only a single element. Example:
> 
> (setq my-single-cons (cons 'a)) ;; error!

I'm not a Common Lisp expert, but I'll try to explain it as I have
understood it.

As Pascal wrote, cons are the building blocks of lists:

CL-USER > (setq my-single-cons (cons 'a nil))
(A)

CL-USER > (cdr my-single-cons)
A

CL-USER > (cdr my-single-cons)
NIL

A cons, where the cdr is nil, is the same as a list with the same car of
the cons.

You can build lists with cons-objects like this:

(cons 1 (cons 2 (cons 3 nil))))

which is the same as (list 1 2 3)

Perhaps you know other languages, then you can imaging a cons as a linked
list:

struct cons {
	void* car;  // pointer to the data
	cons* cdr;  // pointer to the next cons
};

The cons-function just creates a new cons object and sets the car and cdr
to the supplied two arguments. A car can be a pointer to a cons, too:

(equal
 (list (list 1 2) 3 4)
 (cons (cons 1 (cons 2 nil)) (cons 3 (cons 4 nil))))

But when you store a pointer to an object in the cdr, then it will be
printed as a dotted list:

(cons 1 2) -> (1 . 2)

(car (cons 1 2)) -> 1
(cdr (cons 1 2)) -> 2

Dotted lists are not a proper sequence, which is the reason why copy-seq
fails (at least in Common Lisp, see the definition at
http://www.lisp.org/HyperSpec/Body/fun_copy-seq.html : "Exceptional
Situations: Should be prepared to signal an error of type type-error if
sequence is not a proper sequence").

-- 
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
From: Kenny Tilton
Subject: Re: cons and list behaviour
Date: 
Message-ID: <nkpMf.5739$uV6.3204@news-wrt-01.rdc-nyc.rr.com>
Jason wrote:
> Please excuse me if this has been addressed before. I searched the
> recent posts and the FAQ and did not see find the answer I am seeking.
> 
> I am learnin LISP (actually elisp ;)), and have written the following:
> 
> ;; here I am using cons notation
> (setq node-1 (cons 'a 'b))
> (setq node-2 (cons 'c 'd))
> (setq node-3 (cons 'e node-1))
> (setq node-4 (cons node-3 'f))
> (setq node-5 (cons node-2 'g))
> (setq tree (cons node-4 node-5))
> ;; (((e a . b) . f) (c . d) . g) <<<<< value
> 
> ;; here we can see that a cons is *not* the same as a list
> (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> (setq tree3 (copy-sequence tree)) ;; <<<<<<<< generates an error!

It looks as if elisp's copy-sequence is like the CL copy-seq: it wants a 
proper list, not just any list.

Well, that is what CLHS says:

"17.3.2 copy-seq Function
Syntax: copy-seq sequence    copied-sequence

Arguments and Values:
sequence - a proper sequence.
copied-sequence - a proper sequence. "

But AllegroCL does not mind:

(copy-seq '(((e a . b) . f) (c . d) . g))
-> (((e a . b) . f) (c . d) . g)

I just would not bet on that being portable or even working in the 
future. Anyway....




> 
> ;; now I am redefing the above using list notation
> (setq node-1 (list 'a 'b))
> (setq node-2 (list 'c 'd))
> (setq node-3 (list 'e node-1))
> (setq node-4 (list node-3 'f))
> (setq node-5 (list node-2 'g))
> (setq tree (list node-4 node-5))
> ;; (((e (a b)) f) ((c d) g)) <<<<< value
> 
> ;; however, here we see that a list *is* the same as a cons!

Hmmm, where do see that? I see a big difference between these two lines:
 > ;; (((e a . b) . f) (c . d) . g) <<<<< value
 > ;; (((e (a b)) f) ((c d) g)) <<<<< value

Those dots (full stops) mean a lot. they are the Lisp printer trying to 
tell you that the cdr of a cons is not another cons.

> (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> (setq tree3 (copy-sequence tree)) ;; <<<<<<<< also works fine!
> 
> It seems that the list notation works well with the cons notation, but
> the reverse is not the case. I am wondering why is this? Also, if a
> list is a cons, but a cons is not a list, then why do we have cons?

Start over on this subject, which I encourage you to master fully before 
getting into any interesting Lisp programming. Try to find one of those 
references that has fancy diagrams showing cons cells as two little 
squares, one for the car one for the cdr. Go slow and make sure you get 
what is going on. Focus on CONS (the function) first, then understand 
LIST as a function calling CONS to do its job.

The quick intro is that cons is a function that might have been called 
MAKE-CONS but was not. It takes two arguments and produces a data 
structure known as a cons. This data structure has two attributes known 
as the CAR and the CDR. There are functions of the same name (CAR and 
CDR) that take a CONS as an argument and return what you would hope they 
would return. <g>

So far, so simple, and notive that I have not said anything about lists. 
There is no such thing as a list, really. It is an abstraction over NIL 
and conses.

The /function/ LIST takes any number of arguments and calls CONS to 
generate enough cons data structures to hold them all:

(list 1 2 3) -> (cons 1 (cons 2 (cons 3 nil)))

Likewise:

(list 'a 'b) -> (cons 'a (cons 'b nil)), /not/ (cons 'a 'b)

Like I said, find a good reference that goes into this in detail and 
work any exercises until you can think in CONSese. You will really need 
this as you start writing sometimes even simple Lisp code.

hth, kenny
From: Jason
Subject: Re: cons and list behaviour
Date: 
Message-ID: <1140991185.537100.151550@j33g2000cwa.googlegroups.com>
Kenny Tilton wrote:
> Jason wrote:
> > Please excuse me if this has been addressed before. I searched the
> > recent posts and the FAQ and did not see find the answer I am seeking.
> >
> > I am learnin LISP (actually elisp ;)), and have written the following:
> >
> > ;; here I am using cons notation
> > (setq node-1 (cons 'a 'b))
> > (setq node-2 (cons 'c 'd))
> > (setq node-3 (cons 'e node-1))
> > (setq node-4 (cons node-3 'f))
> > (setq node-5 (cons node-2 'g))
> > (setq tree (cons node-4 node-5))
> > ;; (((e a . b) . f) (c . d) . g) <<<<< value
> >
> > ;; here we can see that a cons is *not* the same as a list
> > (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> > (setq tree3 (copy-sequence tree)) ;; <<<<<<<< generates an error!
>
> It looks as if elisp's copy-sequence is like the CL copy-seq: it wants a
> proper list, not just any list.
>
> Well, that is what CLHS says:
>
> "17.3.2 copy-seq Function
> Syntax: copy-seq sequence    copied-sequence
>
> Arguments and Values:
> sequence - a proper sequence.
> copied-sequence - a proper sequence. "
>
> But AllegroCL does not mind:
>
> (copy-seq '(((e a . b) . f) (c . d) . g))
> -> (((e a . b) . f) (c . d) . g)
>
> I just would not bet on that being portable or even working in the
> future. Anyway....
>
>
>
>
> >
> > ;; now I am redefing the above using list notation
> > (setq node-1 (list 'a 'b))
> > (setq node-2 (list 'c 'd))
> > (setq node-3 (list 'e node-1))
> > (setq node-4 (list node-3 'f))
> > (setq node-5 (list node-2 'g))
> > (setq tree (list node-4 node-5))
> > ;; (((e (a b)) f) ((c d) g)) <<<<< value
> >
> > ;; however, here we see that a list *is* the same as a cons!
>
> Hmmm, where do see that? I see a big difference between these two lines:
>  > ;; (((e a . b) . f) (c . d) . g) <<<<< value
>  > ;; (((e (a b)) f) ((c d) g)) <<<<< value
>
> Those dots (full stops) mean a lot. they are the Lisp printer trying to
> tell you that the cdr of a cons is not another cons.
>
> > (setq tree2 (copy-tree tree)) ;; <<<<<<<<<<<< works fine
> > (setq tree3 (copy-sequence tree)) ;; <<<<<<<< also works fine!
> >
> > It seems that the list notation works well with the cons notation, but
> > the reverse is not the case. I am wondering why is this? Also, if a
> > list is a cons, but a cons is not a list, then why do we have cons?
>
> Start over on this subject, which I encourage you to master fully before
> getting into any interesting Lisp programming. Try to find one of those
> references that has fancy diagrams showing cons cells as two little
> squares, one for the car one for the cdr. Go slow and make sure you get
> what is going on. Focus on CONS (the function) first, then understand
> LIST as a function calling CONS to do its job.
>
> The quick intro is that cons is a function that might have been called
> MAKE-CONS but was not. It takes two arguments and produces a data
> structure known as a cons. This data structure has two attributes known
> as the CAR and the CDR. There are functions of the same name (CAR and
> CDR) that take a CONS as an argument and return what you would hope they
> would return. <g>
>
> So far, so simple, and notive that I have not said anything about lists.
> There is no such thing as a list, really. It is an abstraction over NIL
> and conses.
>
> The /function/ LIST takes any number of arguments and calls CONS to
> generate enough cons data structures to hold them all:
>
> (list 1 2 3) -> (cons 1 (cons 2 (cons 3 nil)))
>
> Likewise:
>
> (list 'a 'b) -> (cons 'a (cons 'b nil)), /not/ (cons 'a 'b)
>
> Like I said, find a good reference that goes into this in detail and
> work any exercises until you can think in CONSese. You will really need
> this as you start writing sometimes even simple Lisp code.
>
> hth, kenny

Thanks, Kenny. I'm working through "ANSI Common Lisp" by Paul Graham.
He's using those boxes and such to describe conses and lists. I'm
having a lot of fun since I've got clisp running in a terminal, and
elisp running in emacs, and the commands are not always the same. :(

Cons threw me for a loop, since I've never known a language to be built
around such a concept before. The closest I've experieced is TCL, where
the command is the basic unit, and everything is arranged around that.
When I saw cons used in examples, then list used, and the output seemed
similar, I did not immediately realise how important the change in
subject was!

I'm sure I'll have a lot more questions. I'll come back here with 'em
when I do. :)

-Jason
From: Kenny Tilton
Subject: Paging emacs experts? [was Re: cons and list behaviour]
Date: 
Message-ID: <tbqMf.5741$uV6.2966@news-wrt-01.rdc-nyc.rr.com>
Jason wrote:

> Thanks, Kenny. I'm working through "ANSI Common Lisp" by Paul Graham.
> He's using those boxes and such to describe conses and lists. I'm
> having a lot of fun since I've got clisp running in a terminal, and
> elisp running in emacs, and the commands are not always the same. :(

Hmmm. From time to time certain denizens of this group post ascii art 
nicely illustrating cons structure. I get the impression they are using 
a tool to do that, not agonizingly typing those in by hand.

Perhaps some Emacs guru can help here? (If my guesswork is right.)


> 
> Cons threw me for a loop, since I've never known a language to be built
> around such a concept before. The closest I've experieced is TCL, where
> the command is the basic unit, and everything is arranged around that.

I will quibble with that: the linked list as offered by Lisp (with all 
sorts of functions to manage them, as well as using lists to present 
&rest args) turns out to be a terrific tool to have at hand while 
programming, but!....

Common Lisp is a lot more than /just/ lists.

So (a) master them, but (b) don't forget defstruct, make-array, 
make-mash-table, and CLOS.

kt
From: Jason
Subject: Re: Paging emacs experts? [was Re: cons and list behaviour]
Date: 
Message-ID: <1140997912.266882.125760@v46g2000cwv.googlegroups.com>
Kenny Tilton wrote:
>
> Common Lisp is a lot more than /just/ lists.
>
> So (a) master them, but (b) don't forget defstruct, make-array,
> make-mash-table, and CLOS.
>

Say what? I'm  only on page 45. But, once I *learn* about defstruct,
make-array, make-hash-table, and CLOS, *then* I'll make it a point to
not forget them! :)

-Jason
From: Kenny Tilton
Subject: Re: Paging emacs experts? [was Re: cons and list behaviour]
Date: 
Message-ID: <jFrMf.5763$QL4.3432@news-wrt-01.rdc-nyc.rr.com>
Jason wrote:
> Kenny Tilton wrote:
> 
>>Common Lisp is a lot more than /just/ lists.
>>
>>So (a) master them, but (b) don't forget defstruct, make-array,
>>make-mash-table, and CLOS.
>>
> 
> 
> Say what? I'm  only on page 45. But, once I *learn* about defstruct,
> make-array, make-hash-table, and CLOS, *then* I'll make it a point to
> not forget them! :)
> 

If you were reading Practical Common Lisp you would be streaming video 
from a Lisp web application by now. :)

And not even know CONS existed. :):)

kenny (exaggerating <g>)
From: Peter Seibel
Subject: Re: Paging emacs experts?
Date: 
Message-ID: <m2r75pwr82.fsf@gigamonkeys.com>
Kenny Tilton <·············@nyc.rr.com> writes:

> Jason wrote:
>> Kenny Tilton wrote:
>> 
>>>Common Lisp is a lot more than /just/ lists.
>>>
>>>So (a) master them, but (b) don't forget defstruct, make-array,
>>>make-mash-table, and CLOS.
>>>
>> Say what? I'm  only on page 45. But, once I *learn* about defstruct,
>> make-array, make-hash-table, and CLOS, *then* I'll make it a point to
>> not forget them! :)
>> 
>
> If you were reading Practical Common Lisp you would be streaming video
> from a Lisp web application by now. :)
>
> And not even know CONS existed. :):)
>
> kenny (exaggerating <g>)

Not by much. ;-)

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/