On Nov 13, 2012, at 03:46, Daniel Hartwig wrote: > On 12 November 2012 21:54, Daniel Llorens <daniel.llor...@bluewin.ch> wrote: >> >> (define f >> (case-lambda* >> ((a b c #:key x) 3) >> ((a #:key x) 1))) >> >> scheme@(guile-user)> (g 0 #:x 1) >> $1 = 3 > > Because “0 #:x 1” is a valid match for “a b c”, you should rearrange > the case-lambda clauses. > > When the doc. states keyword arguments do not contribute to the > success of a match, it refers only to keyword arguments in the > case-lambda clause, not at the call site. This makes sense, otherwise > it would inhibit writing functions that detect keywords internally > from their rest arguments.
Do you mean something like this? (define* (f a #:key x) x) (define (g . args) (apply f args)) (g 0) -> #f (g 0 #:x #t) -> #t i.e. g must accept being called with 3 'arguments' so that it can forward the keyword args. > scheme@(guile-user)> (define g > (case-lambda* > ((a #:key x) 1) > ((a b c #:key x) 3))) > scheme@(guile-user)> (g 0 #:x 1) > $2 = 1 > > However, trying to call with three arguments then triggers an error, > and I am not sure why: > > scheme@(guile-user)> (g 1 2 3) > <unnamed port>:46:1: In procedure g: > <unnamed port>:46:1: In procedure #<procedure g (a #:key x) | (a b c > #:key x)>: Invalid keyword I saw this error too, but I thought it was the same logic as the other case, where '1 2 3' = 3 arguments, so it matches 'a #:key x', just as '0 #:x 1' matches 'a b c'. I think I see the difference now, but I still find the manual unclear, it should at least give some examples of the edge cases. On Nov 14, 2012, at 01:55, Germán A. Arias wrote: > This should be a bug. I tried with the example at test tree-il.test > (line 1073) but I get the same error. [...] Is this the test? (pass-if "case-lambda*" (null? (call-with-warnings (lambda () (compile '(let ((f (case-lambda* ((x #:optional y) 1) ((x #:key y) 2) ((x y #:key z) 3)))) (list (f 1) (f 1 2) (f #:y 2) (f 1 2 #:z 3))) #:opts %opts-w-arity #:to 'assembly))))) I also get an error here. Strangely, I can run make check without anything being reported. I get a warning UNRESOLVED: tree-il.test: warnings: unused-toplevel: used by macro But I still don't understand how case-lambda* works or should work. The error is in the last call (f 1 2 #:z 3). If I remove it I get '(1 1 1), but how can (f #:y 2) match (x #:optional y) ?? I'm running acc1d8… but this test has been in there since 2009 apparently.