Project author Jean-Philippe Paradis
Project type Library
Programming language Common Lisp
Status Ready-to-use
License Public Domain
Library type Wrapper macro
Project complexity Embarrassingly trivial
Latest release Version 1.0.1
Date 23 oct 2012
(Nov 2012 dist and later)
Status Available
Version Latest

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:

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...
      (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.