An example is probably the best way to describe its syntax:
(bind ((a 2) ((b &rest args &key (c 2) &allow-other-keys) '(:a :c 5 :d 10 :e 54)) ((:values d e) (truncate 4.5))) (list a b c d e args)) ==> (2 :A 5 4 0.5 (:C 5 :D 10 :E 54))Bind is especially handy when you have more than one layer of multiple-value-bind or destructuring-bind. Since bind is a single form, you don't end up too far off to the right in editor land.
Bind works by parsing the bindings and rewriting them as nested let, multiple-value-bind and destructuring-bind forms. Bind handles declarations correctly -- putting each at the appropriate level.
Bind is released under the MIT license. The most recent version (as of 1 October 2005) reflects this explicitly.
I like bind because it (a). presents a uniform means of three of CL's most typical binding constructs and (b). because you don't have to worry about nesting! I like the more explicit syntax with "values" because it makes it clear what it is doing and is analogous to something like (setf (values a b) (foo)).
Bind was written by Gary King.
An alternative syntax -- which bind does not support -- that doesn't rely on explicitly saying "values" is:
(bind ((d e (truncate 4.5))) (list d e)) => (4 0.5)Implementation-wise, what it's doing is using the last item in the list, (truncate 4.5), as the form to evaluate. Then the first item, d, gets the primary value, and each item in between gets one of the other values; in this case, that's just e.
This is particularly nice because it makes it possible to combine multiple-value binding and destructuring binding. For example:
(bind (((this &rest that) the-other (values (list 1 2 3 4) 5))) (list this that the-other)) => (1 (2 3 4) 5)