I have found the corresponding CLHS section - 6.1.1.7. It says: "Destructuring allows binding of a set of variables to a corresponding set of values anywhere that a value can normally be bound to a single variable. During loop expansion, each variable in the variable list is matched with the values in the values list. If there are more variables in the variable list than there are values in the values list, the remaining variables are given a value of nil. If there are more values than variables listed, the extra values are discarded".
Our LOOP expansion uses DESTRUCTURING-BIND directly through LOOP-DESTRUCTURING-BIND, so the problem occurs (because DESTRUCTURING-BIND does not allow the pattern mismatch). Consider this macroexpansion:
* (macroexpand '(loop with (a b) = (list)))
(BLOCK NIL
(LET ((#:LOOP-DESTRUCTURE-608 (LIST)))
(SB-LOOP::LOOP-DESTRUCTURING-BIND (A B) #:LOOP-DESTRUCTURE-608 (SB-LOOP::LOOP-BODY NIL NIL NIL NIL NIL))))
I have found the corresponding CLHS section - 6.1.1.7. It says: "Destructuring allows binding of a set of variables to a corresponding set of values anywhere that a value can normally be bound to a single variable. During loop expansion, each variable in the variable list is matched with the values in the values list. If there are more variables in the variable list than there are values in the values list, the remaining variables are given a value of nil. If there are more values than variables listed, the extra values are discarded".
Our LOOP expansion uses DESTRUCTURING-BIND directly through LOOP-DESTRUCTUR ING-BIND, so the problem occurs (because DESTRUCTURING-BIND does not allow the pattern mismatch). Consider this macroexpansion:
* (macroexpand '(loop with (a b) = (list)))
(BLOCK NIL DESTRUCTURE- 608 (LIST))) LOOP::LOOP- DESTRUCTURING- BIND (A B) #:LOOP- DESTRUCTURE- 608
(SB- LOOP::LOOP- BODY NIL NIL NIL NIL
NIL)) ))
(LET ((#:LOOP-
(SB-
SB-LOOP: :LOOP-DESTRUCTU RING-BIND code is below:
(sb!int: defmacro- mundanely loop-destructur ing-bind gensyms- for-nil lambda-list))) (destructuring- bind ,d-var-lambda-list
,arg- list
(lambda-list arg-list &rest body)
(let ((*ignores* nil))
(declare (special *ignores*))
(let ((d-var-lambda-list (subst-
`
(declare (ignore ,@*ignores*))
,@body))))
IMHO, LOOP-DESTRUCTUR ING-BIND macro is a place where the fix should be implemented.
Also, note that CCL has this bug too (and CLISP does not).