enhanced-multiple-value-bind
An embarassingly trivial wrapper macro in Quicklisp.
| Project Type | Library | |
|---|---|---|
| Programming language | Common Lisp | |
| Status | Ready-to-use | |
| License | Public Domain | |
| Library type | Wrapper macro | |
| Project complexity | Embarassingly trivial | |
| Latest release | Version | 1.0.1 |
| Date | 23 oct 2012 | |
|
Quicklisp
(Nov 2012 dist and later) |
Status | Available |
| Version | Latest | |
External library pages
| Depends on | Depended on by | |
|---|---|---|
| Directly | Nothing | |
| Indirectly | Nothing | Nothing |
enhanced-multiple-value-bind provides an enhanced multiple-value-bind macro that adds support for lambda list keywords by expanding to a multiple-value-call when necessary. This makes catching multiple-value &rest and &key much more lightweight and convenient. A multiple-value-&bind alias is supported.
Some problems with writing out multiple-value-call with an inline
lambda, especially with a big lambda body and trivial form arguments to multiple-value-call, compared to multiple-value-bind, are:
- "unnatural" order of evaluation (skip over
lambda, evaluate values forms, then "come back" forlambdabody); - significant extra indentation for the body.
Multiple-value &rest and &key are currently not being used a lot (as far as I know), but the awkwardness of using them up to now might have something to do with this state of affairs. Their usefulness and convenience should now be reassessed.
If enhanced-mvb:multiple-value-bind is invoked without apparent lambda list keywords (symbols beginning with "&"), then it simply expands to
cl:multiple-value-bind:
(enhanced-mvb:multiple-value-bind (a b c) (values 1 2 3)
...)
==
(multiple-value-bind (a b c) (values 1 2 3)
...)
Else, it simply expands to a multiple-value-call with inline lambda:
(enhanced-mvb:multiple-value-bind (a b &rest rest) (values 1 2 3)
...)
==
(multiple-value-call (lambda (a b &rest rest)
...)
(values 1 2 3))
An interesting consequence of this is that it's easy to accept an exact number of return values (though I'm not sure why you'd want to):
(multiple-value-bind (a b c &optional) (values 1 2 3 4))
error → "Invalid number of arguments: 4"
This follows the same principle as values in function type specifiers.
To use enhanced-multiple-value-bind, either refer to the provided multiple-value-bind directly:
;; A bit long...
(enhanced-multiple-value-bind:multiple-value-bind
(x y &rest others)
(values 1 2 3 4)
(values (* x y) others))
→ 2, (3 4)
;; Much more managable package nickname.
(enhanced-mvb:multiple-value-bind (x y &rest others)
(values 1 2 3 4)
(values (* x y) others))
→ 2, (3 4)
Or (:shadowing-import-from #:enhanced-multiple-value-bind #:multiple-value-bind) in your defpackage (or with the package nickname, again). Don't (:use)!
enhanced-multiple-value-bind also exports multiple-value-&bind, with exactly the same functionality, so you can (:import-from #:enhanced-multiple-value-bind #:multiple-value-&bind) in your defpackage instead if you want.