The
(defmacro cl:multiple-value-bind (symbols expr &rest body)
(and (or (not (consp symbols))
(eq 'quote (first symbols))
(dolist (symbol symbols)
(or (symbolp symbol) (return t))))
(error "not a list of symbols" symbols))
(setq cl:*multiple-values* nil)
(let* ((result (eval expr))
(values (if cl:*multiple-values*
*rslt*
(list result)))
(number-of-symbols (length symbols))
(number-of-values (length values))
(bindings nil))
(dotimes (index number-of-symbols)
(push (if (< index number-of-values)
(list (nth index symbols)
(list 'quote (nth index values)))
(nth index symbols))
bindings))
(setq bindings (reverse bindings))
`(let ,bindings ,@body)))
The 'values' expression is evaluated, and each of the symbols is bound to
the respective value returned by the evaluation.
The
> (macroexpand-1 '(cl:multiple-value-bind (a b c)
(cl:values 1 2 3)
(list a b c)))
(LET ((A (QUOTE 1))
(B (QUOTE 2))
(C (QUOTE 3)))
(LIST A B C))
The quotes are necessary to prevent 'unbound variable' and 'unbound function' errors with symbols and lists.
Examples:
1. The
(defun multiple-value-function ()
(cl:values 1 2 3)) ; multiple return values
> (cl:multiple-value-bind (a b c)
(multiple-value-function)
(list a b c))
(1 2 3)
2. If there are no values returned in the Nyquist
*rslt* variable, the normal
function return value is bound to the first symbol and all remaining symbols
are bound
(defun normal-lisp-function ()
(+ 1 1)) ; normal return value
> (cl:multiple-value-bind (a b c)
(normal-lisp-function)
(list a b c))
(2 NIL NIL)
3. If there are less values than symbols, the extra symbols are
bound
(defun not-enough-values-function ()
(cl:values 1 2)) ; multiple return values
> (cl:multiple-value-bind (a b c)
(not-enough-values-function)
(list a b c))
(1 2 NIL)
4. If there are more values than symbols, the extra values are ignored:
(defun too-many-values-function ()
(cl:values 1 2 3 4 5)) ; multiple return values
> (cl:multiple-value-bind (a b c)
(too-many-values-function)
(list a b c))
(1 2 3)