guile-user
[Top][All Lists]
Advanced

[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.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]