Opened 11 years ago

Closed 11 years ago

#356 closed defect (wontfix)

#!key and #!rest only work when number of rest arguments is even

Reported by: Christian Kellermann Owned by: felix winkelmann
Priority: major Milestone:
Component: core libraries Version: 4.5.x
Keywords: DSSSL keyword arguments Cc:
Estimated difficulty:

Description

Both should work IMHO:

#;72> (apply (lambda (a #!rest r #!key (f #f)) f) '(something 1 2 3 4 5 f: foo))                                                     
#f                                                                                                                                   
#;73> (apply (lambda (a #!rest r #!key (f #f)) f) '(something 1 2 3 4 f: foo))                                                       
 foo

Change History (6)

comment:1 Changed 11 years ago by felix winkelmann

Milestone: 4.6.0

comment:2 Changed 11 years ago by felix winkelmann

This behaviour seems to match exactly what DSSSL (and the chicken manual) specifiers: if #!key is present, then the remaining arguments must be even-numbered, even if #!rest is used.

comment:3 Changed 11 years ago by Christian Kellermann

It does! So the programmer itself needs to make sure to never violate the rule?

comment:4 in reply to:  3 ; Changed 11 years ago by felix winkelmann

Replying to ckeen:

It does! So the programmer itself needs to make sure to never violate the rule?

Well, yes. The question is, whether this is a real problem, what kind of performance-impact such a check has and whether it makes sense to accept any combination of keyword/argument pairs. What about

((lambda (#!rest r #!key f) ...) 1 f: f:)

This is legal, since keywords are first-class. Is their any advantage in disallowing this? Can there be cases where someone actually wants this behaviour? I couldn't tell, really.

comment:5 in reply to:  4 ; Changed 11 years ago by Christian Kellermann

Replying to felix:

Well, yes. The question is, whether this is a real problem, what kind of performance-impact such a check has and whether it makes sense to accept any combination of keyword/argument pairs. What about

((lambda (#!rest r #!key f) ...) 1 f: f:)

This is legal, since keywords are first-class. Is their any advantage in disallowing this? Can there be cases where someone actually wants this behaviour? I couldn't tell, really.

Beats me. Maybe this is just a nice indication that I am doing things wrong. Since I don't know how to solve this myself I propose that we close this ticket again. We can have a shot at it again when this issue keeps reappearing...

comment:6 in reply to:  5 Changed 11 years ago by felix winkelmann

Resolution: wontfix
Status: newclosed

Replying to ckeen:

((lambda (#!rest r #!key f) ...) 1 f: f:)

This is legal, since keywords are first-class. Is their any advantage in disallowing this? Can there be cases where someone actually wants this behaviour? I couldn't tell, really.

Beats me. Maybe this is just a nice indication that I am doing things wrong. Since I don't know how to solve this myself I propose that we close this ticket again. We can have a shot at it again when this issue keeps reappearing...

Another case:

((lambda (#!rest r #!key f g) ...) f: g: g:)

As the keyword-argument list is parsed dynamically, only the position can be a true indication of whether an argument is a keyword marker or a keyword argument value. I agree that it would probably remove one possible user error to check the rest list of being of even length (I think Gambit does this, but it also extends the DSSSL semantics in other way, IIRC). At this stage my performance paranoia kicks in (which is usually wrong, mind you).

So, if this is ok with you, I'll close the ticket. But doing that check is something that we perhaps should keep in mind.

Note: See TracTickets for help on using tickets.