I've read both Graham's explanation and the Hyperspec's of
destructuring-bind, but it still makes no sense. As far as I
understand, the function takes a pattern of variables and then
applies that pattern to "an actual tree." That explanation makes
zero sense. Graham gives the following example:
(destructuring-bind (w (x y) . z) '(a (b c) d e) (list w x y z))
=> (A B C (D E))
So, if everthing in the actual tree is matched with the pattern in
the first argument, I'd assume that w in the actual list becomes a,
while (x y) becomes (b c), etc., but that's obviously not it
otherwise the resulting list would be (a (b c) e). How is
(A B C (D E)) achieved? I just can't make sense of this function. Can
someone explain?
Thanks a lot,
--
Jordan Katz <ka...@underlevel.net> | Mind the gap
w <- 'a
x <- 'b
y <- 'c
z <- '(d e)
The example really shouldn't put w x y z into a list at the end because
it just confuses things.
HTH
-- Bruce
You're close.
In the code above, destructuring-bind binds
the symbol w to the value a (i.e. (car '(a (b c) d e))),
the symbol x to the value b (i.e. (car (cadr '(a (b c) d e)))),
the symbol y to the value c (i.e. (cadr (cadr '(a (b c) d e)))),
and the symbol z to the value (d e) (i.e. (cddr '(a (b c) d e))).
Then, (list w x y z) generates a list equal to (list 'a 'b 'c '(d e)).
Similarly,
* (setq lst
'((1 2 3)
((4 5 6) (7 8 9))
(10 11 12) 13 14 15 16))
((1 2 3) ((4 5 6) (7 8 9)) (10 11 12) 13 14 15 16)
* (car lst)
(1 2 3)
* (car (cadr lst))
(4 5 6)
* (cadr (cadr lst))
(7 8 9)
* (cddr lst)
((10 11 12) 13 14 15 16)
* (destructuring-bind (w (x y) . z) lst
(list w x y z))
((1 2 3) (4 5 6) (7 8 9) ((10 11 12) 13 14 15 16))
Also, just by the by, you need the dot before the z:
* (destructuring-bind (w (x y) z) lst
(list w x y z))
Error while parsing arguments to DESTRUCTURING-BIND in COMMON-LISP::DO-ARG-COUNT-ERROR:
Invalid number of elements in:
((1 2 3) ((4 5 6) (7 8 9)) (10 11 12) 13 14 15 16)
to satisfy lambda-list:
(W (X Y) Z)
Expected exactly 3, but got 7.
Restarts:
0: [ABORT] Return to Top-Level.
Debug (type H for help)
("Top-Level Form")[:TOP-LEVEL]
Source: (DESTRUCTURING-BIND (W (X Y) Z) LST (LIST W X Y Z))
0]
The " . z)" is sort of equivalent to an &rest.
Does that help?
-- Larry
I think it is just a confusion with the call to list at the end. It is the
first two arguments to destructuring-bind that share the same structure. So
(w (x y) . z) matches (a (b c) . (d e)) After that you can do whatever you
want with your w x y z vars. In this case he justs returns them in a list.
--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
Jordan Katz <ka...@underlevel.net> writes:
> (destructuring-bind (w (x y) . z) '(a (b c) d e) (list w x y z))
> => (A B C (D E))
(w (x y) . z) == (w . ((x . (y . nil)) . z ))
(a (b c) d e) == (a . ((b . (c . nil)) . (d . (e . nil)) ))
w <- a
x <- b
y <- c
z <- (d . (e . nil)) == (d e)
(list w x y z) => (a b c (d e))
> So, if everthing in the actual tree is matched with the pattern in
> the first argument, I'd assume that w in the actual list becomes a,
> while (x y) becomes (b c),
^^^^^^^ `is matched with', then X becomes B and Y becomes C,
so (LIST X Y) => (B C), and (LIST W X Y) => (A B C), *not* (A (B C)).
Regards,
Alexey Dejneka
---
Web-site owner! Protect your Intellectual Property! Do not allow all
those "visitors" see your genius creations!
> Hi,
>
> I've read both Graham's explanation and the Hyperspec's of
> destructuring-bind, but it still makes no sense. As far as I
> understand, the function ...
^^^^^^^^
Ain't a function.
Cheers,
M.
--
I have no disaster recovery plan for black holes, I'm afraid. Also
please be aware that if it one looks imminent I will be out rioting
and setting fire to McDonalds (always wanted to do that) and
probably not reading email anyway. -- Dan Barlow
Let me start with the simplest example there is, a single variable:
(destructuring-bind (<variable>) <list>
<body>)
destructuring-bind hacks up <list> suck that the first (and probably
only) element in that list becomes the value of <variable> in <body>,
almost exactly like
(let ((<variable> (car <list>)))
<body>)
Now, suppose you make this a tad more complex, with a list of variables
and a list of values:
(destructuring-bind (<var1> <var2> <var3>) <list>
<body>)
(let ((<var1> (car <list>))
(<var2> (cadr <list>))
(<var3> (caddr <list>)))
<body>)
Finally, let us try with this "tree" notion, not just with a list of
variables:
(destructuring-bind (<var1> <var2> <var3> (<var4> <var5>)) <list>
<body>)
(let ((<var1> (car <list>))
(<var2> (cadr <list>))
(<var3> (caddr <list>))
(<var4> (car (cadddr <list)>))
(<var5> (cadr (cadddr <list)>)))
<body>)
So far, I have only mimicked the results of macroexpand on the
destructuring-bind form, but to macroexpand is intimately tied with the
function of destructuring-bind. There is another construct that uses
destructuring-bind in Common Lisp and that is macros, so if we do
(defmacro foo (<var1> <var2> <var3> (<var4> <var5>))
<body>)
we get exactly the same kind of destructuring when you evaluate the form
with a <list> equal to (1 2 3 (4 5)) as when you invoke (foo 1 2 3 (4 5)).
I hope this made it somewhat clearer what this binding form does and why
it is available to you as a Common Lisp programmer.
///
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.
> How is (A B C (D E)) achieved? I just can't make sense of this
> function. Can someone explain?
Look at the shape of the last form. He is returning a "flattened"
tree. To get the result you evidently expected, you'd need to do
(destructuring-bind (w (x y) . z)
'(a (b c) d e) (list w (list x y ) z))
^^^^^^^^^^
Note
--
Håkon Alstadheim, hjemmepappa.
OK. What you start with is a pattern and then try to match that against
the incoming actual argument. What I didn't see explained in some of
the other responses is the role of the "." in the pattern. This
introduces a "dotted list" notation. You may not be familiar with it.
In essence what it does in the simple example (a . b) is make a match
the CAR of a form and b match the CDR (or FIRST and REST). This differs
from (a b) where a matches the CAR and b the CADR (or FIRST and SECOND).
(a b) a -> 1 ; b -> 2
| |
V V
(1 2)
(a . b) a -> 1 ; b -> (2 3 4 5)
| / \_
V V \
(1 2 3 4 5)
This is also done recursively, so that in the example from Graham:
(w (x y) . z) w -> a ; x -> b ; y -> c ; z -> (d e)
| | | /\
V V V V V
(a (b c) d e)
If the dot were not there, then the destructuring would fail, since the
pattern would not be able to match the actual input.
--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu
"Thomas A. Russ" wrote:
>
> Jordan Katz <ka...@underlevel.net> writes:
>
> > Hi,
> >
> > I've read both Graham's explanation and the Hyperspec's of
> > destructuring-bind, but it still makes no sense. As far as I
> > understand, the function takes a pattern of variables and then
> > applies that pattern to "an actual tree." That explanation makes
> > zero sense. Graham gives the following example:
> >
> > (destructuring-bind (w (x y) . z) '(a (b c) d e) (list w x y z))
> > => (A B C (D E))
> >
> > So, if everthing in the actual tree is matched with the pattern in
> > the first argument, I'd assume that w in the actual list becomes a,
> > while (x y) becomes (b c), etc., but that's obviously not it
> > otherwise the resulting list would be (a (b c) e).
I am wondering how you get the match of of z to 'e. Were you thinking
the dot (.) matched 'd?
> How is
> > (A B C (D E)) achieved? I just can't make sense of this function.
Don't feel bad, I have been doing Lisp for quite a while now and I was
stumped by this example's use of a dot where I would have used &rest. To
my taste it was a mistake to confuse an introduction to one bit of
syntax (destructuring-bind) by throwing in a stumper like that.
Aside to Lisp veterans: y'all familiar with that usage? I can see how it
is mad faster than typing &rest...a harbinger of Arc to come?
--
kenny tilton
clinisys, inc
---------------------------------------------------------------
"Be the ball...be the ball...you're not being the ball, Danny."
- Ty, Caddy Shack
Everybody has given good explanations, I just thought I'd throw
in an ASCII diagram of the lists in case it wasn't clear.
Select a monospace font if you haven't already.
+---+---+ +---+---+
| | | | | |
| * | *---->| * | *----> Z
| | | | | | | |
+-|-+---+ +-|-+---+
| |
V V
+---+---+ +---+---+
W | | | | | |
| * | *---->| * | *----> nil
| | | | | | | |
+-|-+---+ +-|-+---+
| |
V V
X Y
+---+---+ +---+---+ +---+---+ +---+---+
| | | | | | | | | | | |
| * | *---->| * | *----->| * | *---->| * | *---->nil
| | | | | | | | | | | | | | | |
+-|-+---+ +-|-+---+ +-|-+---+ +-|-+---+
| | | |
V | V V
|
a | d e
V
+---+---+ +---+---+
| | | | | |
| * | *---->| * | *----> nil
| | | | | | | |
+-|-+---+ +-|-+---+
| |
V V
b c
> Don't feel bad, I have been doing Lisp for quite a while now and I was
> stumped by this example's use of a dot where I would have used &rest.
> Aside to Lisp veterans: y'all familiar with that usage? I can see how it
> is mad faster than typing &rest...a harbinger of Arc to come?
I'm no veteran, but I doubt you can use (a &key b c . d) to mean the
same thing as (a &key b c &rest d). Also, it's probably an issue of
style, as you seem to have essentially asserted above. But considering
what I've seen of Arc so far, I would be surprised if it would add
lambda-list keywords in let-like binding forms when it doesn't (?)
have them in lambda-like ones.
--
-> -/- - Rahul Jain - -\- <-
-> -\- http://linux.rice.edu/~rahul -=- mailto:rj...@techie.com -/- <-
-> -/- "I never could get the hang of Thursdays." - HHGTTG by DNA -\- <-
|--|--------|--------------|----|-------------|------|---------|-----|-|
Version 11.423.999.221020101.23.50110101.042
(c)1996-2002, All rights reserved. Disclaimer available upon request.
> Kenny Tilton <kti...@nyc.rr.com> writes:
>
> > Don't feel bad, I have been doing Lisp for quite a while now and I was
> > stumped by this example's use of a dot where I would have used &rest.
>
> > Aside to Lisp veterans: y'all familiar with that usage? I can see how it
> > is mad faster than typing &rest...a harbinger of Arc to come?
I'm not a veteran, but I use it all the time.
> I'm no veteran, but I doubt you can use (a &key b c . d) to mean the
> same thing as (a &key b c &rest d).
You're right; it's not a valid construct. Mixing &key and . isn't
allowed, for I hink pretty obvious reasons. I would expect D in
(a &key b c . d) to always be NIL (because after all the keys, there's
nothing left in the list). However, what would you do with:
(destructuring-bind
(a &key b c &allow-other-keys . d)
'(1 :foo "foo" :bar "bar" :b 2 :c 3)
d)
Should it be (:foo "foo" :bar "bar")? Or what? It doesn't really
make sense to have a dot after a &key.
--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'