#599 &whole binds wrong form

closed-rejected
Bruno Haible
clisp (525)
5
2011-05-01
2011-04-30
belovedeagle
No

In both destructuring-bind forms and macro calls, twice-nested &whole variables bind to the wrong value:

(destructuring-bind (a (&whole b c . (&whole d e . f)) . g)
'(u (w x . y) . z)
(list a b c d e f g))
=> (u (w x . y) w (w x . y) x y z)

(defmacro test (a (&whole b c . (&whole d e . f)) . g)
(list a b c d e f g))
(macroexpand-1 '(test u (w x . y) . z))
=> (u (w x . y) w (w x . y) x y z)

but expected is: (u (w x . y) w (x . y) x y z)

In the macroexpand-1 for the destructuring-bind form:
(let ((system::<destructuring-form> '(u (w x . y) . z)))
(if (not (system::list-length-in-bounds-p system::<destructuring-form> 2 2 t))
(system::destructuring-error system::<destructuring-form> '(2))
(let*
((a (car system::<destructuring-form>))
(#:g3375 (cadr system::<destructuring-form>))
(#:g3376
(if (not (system::list-length-in-bounds-p #:g3375 2 2 t))
(system::error-of-type 'ext:source-program-error :form
system::<destructuring-form> :detail #:g3375
(system::text "~S: ~S does not match lambda list element ~:S")
'destructuring-bind #:g3375 '(&whole b c &whole d e . f))
#:g3375))
(b #:g3376) (c (car #:g3376)) (d #:g3376) (e (cadr #:g3376))
(f (cddr #:g3376)) (g (cddr system::<destructuring-form>)))
(values a b c d e f g))))
d should be given the value (cdr #:g3376)

Discussion

  • Bruno Haible
    Bruno Haible
    2011-05-01

    • status: open --> closed-rejected
     
  • Bruno Haible
    Bruno Haible
    2011-05-01

    Your lambda list (a (&whole b c . (&whole d e . f)) . g)
    is the same as (a (&whole b c &whole d e . f) . g)
    This is invalid: For macro lambda lists, CLHS 3.4.4 says
    "If &whole and a following variable appear, they must appear first in lambda-list, before any other parameter or lambda list keyword."
    Similarly, for destructuring lambda lists, CLHS 3.4.5 also
    allows &whole only at the beginning of the list.

    SBCL gives an error message:
    &WHOLE may only appear first in DESTRUCTURING-BIND lambda-list.
    &WHOLE may only appear first in DEFMACRO lambda-list.

    I have added a similar error to clisp now.