[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

28. "Destructuring"

.setq loop-destructuring-section css-number .setq loop-destructuring-page page Destructuring provides one with the ability to "simultaneously" assign or bind multiple variables to components of some data structure. Typically this is used with list structure. For example,
 
(loop with (foo . bar) = '(a b c) ...)
has the effect of binding foo to a and bar to (b c). loop's destructuring support is intended to parallel if not augment that provided by the host Lisp implementation, with a goal of minimally providing destructuring over list structure patterns. Thus, in Lisp implementations with no system destructuring support at all, one may still use list-structure patterns as loop iteration variables, and in with bindings. In NIL, loop also supports destructuring over vectors. One may specify the data types of the components of a pattern by using a corresponding pattern of the data type keywords in place of a single data type keyword. This syntax remains unambiguous because wherever a data type keyword is possible, a loop keyword is the only other possibility. Thus, if one wants to do
 
(loop for x in l
      as i fixnum = (car x)
      and j fixnum = (cadr x)
      and k fixnum = (cddr x)
      ...)
and no reference to x is needed, one may instead write
 
(loop for (i j . k) (fixnum fixnum . fixnum) in l ...)
To allow some abbreviation of the data type pattern, an atomic component of the data type pattern is considered to state that all components of the corresponding part of the variable pattern are of that type. That is, the previous form could be written as
 
(loop for (i j . k) fixnum in l ...)
This generality allows binding of multiple typed variables in a reasonably concise manner, as in
 
(loop with (a b c) and (i j k) fixnum ...)
which binds a, b, and c to nil and i, j, and k to 0 for use as temporaries during the iteration, and declares i, j, and k to be fixnums for the benefit of the compiler. .group
 
(defun map-over-properties (fn symbol)
   (loop for (propname propval) on (plist symbol) by 'cddr
	 do (funcall fn symbol propname propval)))
maps fn over the properties on symbol, giving it arguments of the symbol, the property name, and the value of that property. .end_group In Lisp implementations where loop performs its own destructuring, notably Multics Maclisp and Zetalisp, one can cause loop to use already provided destructuring support instead:
Variable: si:loop-use-system-destructuring?
This variable only exists in loop implementations in Lisps which do not provide destructuring support in the default environment. It is by default nil. If changed, then loop will behave as it does in Lisps which do provide destructuring support: destructuring binding will be performed using let, and destructuring assignment will be performed using desetq. Presumably if one's personalized environment supplies these macros, then one should set this variable to t; there is, however, little (if any) efficiency loss if this is not done.

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Brad Parker on June, 13 2006 using texi2html