1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Body/06_aag.htm
2024-04-01 10:24:07 +02:00

103 lines
8.7 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Section 6.1.1.7</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="06_aaf.htm">
<LINK REL=UP HREF="06_aa.htm">
<LINK REL=NEXT HREF="06_aah.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="06_aaf.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="06_aa.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="06_aah.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>
6.1.1.7 Destructuring</H2> <P>
The <I>d-type-spec</I> argument is used for destructuring. If the <I>d-type-spec</I> argument consists solely of the <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>type</I></A> <A REL=DEFINITION HREF="t_fixnum.htm#fixnum"><B>fixnum</B></A>, <A REL=DEFINITION HREF="t_float.htm#float"><B>float</B></A>, <A REL=DEFINITION HREF="t_t.htm#t"><B>t</B></A>, or <A REL=DEFINITION HREF="a_nil.htm#nil"><B>nil</B></A>, the <TT>of-type</TT> keyword is optional. The <TT>of-type</TT> construct is optional in these cases to provide backwards compatibility; thus, the following two expressions are the same: <P>
<PRE>
;;; This expression uses the old syntax for type specifiers.
(loop for i fixnum upfrom 3 ...)
;;; This expression uses the new syntax for type specifiers.
(loop for i of-type fixnum upfrom 3 ...)
;; Declare X and Y to be of type VECTOR and FIXNUM respectively.
(loop for (x y) of-type (vector fixnum)
in l do ...)
</PRE>
</TT> <P>
A <A REL=DEFINITION HREF="26_glo_t.htm#type_specifier"><I>type specifier</I></A> for a destructuring pattern is a <A REL=DEFINITION HREF="26_glo_t.htm#tree"><I>tree</I></A> of <A REL=DEFINITION HREF="26_glo_t.htm#type_specifier"><I>type specifiers</I></A> with the same shape as the <A REL=DEFINITION HREF="26_glo_t.htm#tree"><I>tree</I></A> of <A REL=DEFINITION HREF="26_glo_v.htm#variable"><I>variable</I></A> <A REL=DEFINITION HREF="26_glo_n.htm#name"><I>names</I></A>, with the following exceptions: <P>
<P><DL><DT>* When aligning the <A REL=DEFINITION HREF="26_glo_t.htm#tree"><I>trees</I></A>, an <A REL=DEFINITION HREF="26_glo_a.htm#atom"><I>atom</I></A> in the <A REL=DEFINITION HREF="26_glo_t.htm#tree"><I>tree</I></A> of <A REL=DEFINITION HREF="26_glo_t.htm#type_specifier"><I>type specifiers</I></A> that matches a <A REL=DEFINITION HREF="26_glo_c.htm#cons"><I>cons</I></A> in the variable tree declares the same <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>type</I></A> for each variable in the subtree rooted at the <A REL=DEFINITION HREF="26_glo_c.htm#cons"><I>cons</I></A>. <P><DD>
<DT>* A <A REL=DEFINITION HREF="26_glo_c.htm#cons"><I>cons</I></A> in the <A REL=DEFINITION HREF="26_glo_t.htm#tree"><I>tree</I></A> of <A REL=DEFINITION HREF="26_glo_t.htm#type_specifier"><I>type specifiers</I></A> that matches an <A REL=DEFINITION HREF="26_glo_a.htm#atom"><I>atom</I></A> in the <A REL=DEFINITION HREF="26_glo_t.htm#tree"><I>tree</I></A> of <A REL=DEFINITION HREF="26_glo_v.htm#variable"><I>variable</I></A> <A REL=DEFINITION HREF="26_glo_n.htm#name"><I>names</I></A> is a <I>compound type specifer</I>. <P><DD>
<P></DL><P>
Destructuring allows <A REL=DEFINITION HREF="26_glo_b.htm#binding"><I>binding</I></A> of a set of variables to a corresponding set of values anywhere that a value can normally be bound to a single variable. During <A REL=DEFINITION HREF="m_loop.htm#loop"><B>loop</B></A> expansion, each variable in the variable list is matched with the values in the values list. If there are more variables in the variable list than there are values in the values list, the remaining variables are given a value of <A REL=DEFINITION HREF="a_nil.htm#nil"><B>nil</B></A>. If there are more values than variables listed, the extra values are discarded. <P>
To assign values from a list to the variables <TT>a</TT>, <TT>b</TT>, and <TT>c</TT>, the <TT>for</TT> clause could be used to bind the variable <TT>numlist</TT> to the <A REL=DEFINITION HREF="26_glo_c.htm#car"><I>car</I></A> of the supplied <I>form</I>, and then another <TT>for</TT> clause could be used to bind the variables <TT>a</TT>, <TT>b</TT>, and <TT>c</TT> <A REL=DEFINITION HREF="26_glo_s.htm#sequentially"><I>sequentially</I></A>. <P>
<PRE>
;; Collect values by using FOR constructs.
(loop for numlist in '((1 2 4.0) (5 6 8.3) (8 9 10.4))
for a of-type integer = (first numlist)
and b of-type integer = (second numlist)
and c of-type float = (third numlist)
collect (list c b a))
=&gt; ((4.0 2 1) (8.3 6 5) (10.4 9 8))
</PRE>
</TT> <P>
Destructuring makes this process easier by allowing the variables to be bound in each loop iteration. <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>Types</I></A> can be declared by using a list of <I>type-spec</I> arguments. If all the <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>types</I></A> are the same, a shorthand destructuring syntax can be used, as the second example illustrates. <P>
<PRE>
;; Destructuring simplifies the process.
(loop for (a b c) of-type (integer integer float) in
'((1 2 4.0) (5 6 8.3) (8 9 10.4))
collect (list c b a))
=&gt; ((4.0 2 1) (8.3 6 5) (10.4 9 8))
;; If all the types are the same, this way is even simpler.
(loop for (a b c) of-type float in
'((1.0 2.0 4.0) (5.0 6.0 8.3) (8.0 9.0 10.4))
collect (list c b a))
=&gt; ((4.0 2.0 1.0) (8.3 6.0 5.0) (10.4 9.0 8.0))
</PRE>
</TT> <P>
If destructuring is used to declare or initialize a number of groups of variables into <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>types</I></A>, the <A REL=DEFINITION HREF="26_glo_l.htm#loop_keyword"><I>loop keyword</I></A> <TT>and</TT> can be used to simplify the process further.
<PRE>
;; Initialize and declare variables in parallel by using the AND construct.
(loop with (a b) of-type float = '(1.0 2.0)
and (c d) of-type integer = '(3 4)
and (e f)
return (list a b c d e f))
=&gt; (1.0 2.0 3 4 NIL NIL)
</PRE>
</TT> <P>
If <A REL=DEFINITION HREF="a_nil.htm#nil"><B>nil</B></A> is used in a destructuring list, no variable is provided for its place. <P>
<PRE>
(loop for (a nil b) = '(1 2 3)
do (return (list a b)))
=&gt; (1 3)
</PRE>
</TT> <P>
Note that <A REL=DEFINITION HREF="26_glo_d.htm#dotted_list"><I>dotted lists</I></A> can specify destructuring. <P>
<PRE>
(loop for (x . y) = '(1 . 2)
do (return y))
=&gt; 2
(loop for ((a . b) (c . d)) of-type ((float . float) (integer . integer)) in
'(((1.2 . 2.4) (3 . 4)) ((3.4 . 4.6) (5 . 6)))
collect (list a b c d))
=&gt; ((1.2 2.4 3 4) (3.4 4.6 5 6))
</PRE>
</TT> <P>
An error of <A REL=DEFINITION HREF="26_glo_t.htm#type"><I>type</I></A> <A REL=DEFINITION HREF="e_progra.htm#program-error"><B>program-error</B></A> is signaled (at macro expansion time) if the same variable is bound twice in any variable-binding clause of a single <A REL=DEFINITION HREF="m_loop.htm#loop"><B>loop</B></A> expression. Such variables include local variables, iteration control variables, and variables found by destructuring. <P>
<P><HR>The following <A REL=META HREF="../Front/X3J13Iss.htm">X3J13 cleanup issue</A>, <I>not part of the specification</I>, applies to this section:<P><UL><LI> <A REL=CHILD HREF="../Issues/iss220.htm">LOOP-AND-DISCREPANCY:NO-REITERATION</A><P></UL><HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>