Package enhanced-multiple-value-bind
Description
Simply (:shadowing-import-from #:enhanced-multiple-value-bind #: from your defpackage. Don't multiple-value-bind)(:use)!
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.
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:
lambda, evaluate values forms, then "come back" for lambda 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 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)
Simply (:shadowing-import-from #:enhanced-multiple-value-bind #: from your defpackage. Don't multiple-value-bind)(:use)!
lambda-list values-form &body body => results
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).