License: Public Domain , Load it with Quicklisp: (ql:quickload "enhanced-multiple-value-bind")
Library type: Wrapper macro , Project complexity: Embarrassingly trivial

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.


Overview » Motivation

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" for lambda body);
  • 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.

Overview » Examples

If multiple-value-bind is invoked without apparent lambda list keywords (symbols beginning with "&"), then it simply expands to cl:multiple-value-bind:

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

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

Another example:

(multiple-value-bind (x y &rest others)
    (values 1 2 3 4)
  (values (* x y) others))
→ 2, (3 4)


Dictionary » enhanced-multiple-value-bind

Package enhanced-multiple-value-bind


Simply (:shadowing-import-from #:enhanced-multiple-value-bind #:multiple-value-bind) from your defpackage. Don't (:use)!

Dictionary » multiple-value-bind

Macro multiple-value-bind

lambda-list values-form &body body => results

Arguments and Values

  • lambda-list -- A list of symbols.
  • values-form -- A form.
  • body -- An implicit progn, possibly preceded by declarations.
  • results -- the values returned by the body.


If lambda-list has no apparent lambda list keywords (symbols beginning with "&"),
then directly expand to a standard multiple-value-bind with the same arguments.

Else, expand to `(multiple-value-call (lambda ,lambda-list ,@body) ,values-form).