[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: case-lambda* question
From: |
Daniel Llorens |
Subject: |
Re: case-lambda* question |
Date: |
Wed, 14 Nov 2012 11:20:21 +0100 |
On Nov 13, 2012, at 03:46, Daniel Hartwig wrote:
> On 12 November 2012 21:54, Daniel Llorens <address@hidden> 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.