Guile Mailing List Archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

optargs questions




I have a few questions/comments about the (ice-9 optargs) module from the
current CVS tree. It seems that the version in CVS does not comply with the
specification given in the optargs.scm file. Maybe all these errors have
been found already ... but where do I find a newer version of optargs ?? 

Keyword args
============
I think it would be neat to change the way a procedure with keyword
arguments is called slightly to make it possible to intersperse keyword
arguments in any place with mandatory and optional arguments.  Example:

guile> (define* (test x #&key (w 'w)) `((x ,x) (w ,w)))

At the moment, the correct way to call test is

guile> (test 'xx #:w 'ww)
((x xx) (w ww))

whereas interchanging the arguments at the moment yields incorrect results: 

guile> (test #:w 'ww 'xx)
((x #:w) (w w))

The last call should either produce the same result as (test 'xx #:w 'ww)
or throw an error (the additional args ('ww 'xx) are just silently ignored,
although the declaration of test does not allow for them)

I would much prefer the first alternative, although that would require the
parsing of the whole argument list of a function that takes keyword
arguments, not only the non-mandatory ones as it is done right now. I think
it would be better if functions that take keyword arguments would proceed
in two steps:
(1) Pull all keyword arguments from the argument list and bind them to
    local variables
(2) Process the remaining arguments as mandatory/optional/rest arguments
This might slow calls to those functionsdown a bit, but makes the semantics
of keywords much cleaner.

Errors
======

It seems there's something fishy going on with rest arguments. The normal
define does what is expected:

guile> (use-modules (ice-9 optargs))
guile> (define (test w . rest) `((w ,w) (rest ,rest)))
guile> (test 'ww 'rest1 'rest2) 
((w ww) (rest (rest1 rest2)))

as expected, but with define* one gets an error:

guile> (define* (test w #&rest rest) `((w ,w) (rest ,rest)))
ERROR: In procedure lambda in expression (lambda (w # rest . rest) (quasiquote #)):
ERROR: bad formals
ABORT: (misc-error)

or, using the equivalent . notation, one gets a different error

guile> (define* (test w . rest) (list w rest))
ERROR: In procedure quasiquote in expression (quasiquote (lambda # #)):
ERROR: Wrong type argument: rest
ABORT: (wrong-type-arg)

Rest arguments and keywords don't seem to mix well, either:

guile> (define* (test #&key (w 'w) #&rest rest) `((w ,w) (rest ,rest)))
guile> (test #:w 'ww 'rest1 'rest2)
((w ww) (rest (#:w ww rest1 rest2)))

instead, as expected ((w ww) (rest (rest1 rest2)))

What does everybody think ? 

David

Guile Home | Main Index | Thread Index