This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: Questions about #!key arguments
On Oct 25, 2011, at 4:38 PM, Per Bothner wrote:
On 10/25/2011 01:14 PM, Taylor Venable wrote:
I haven't been using Kawa for very long, so I don't know much about
its
internals, but I humbly submit that there might be another option to
implement #!rest like Gambit does. If #!rest appears before #!key
then
it contains the keywords; if #!rest appears after #!key then it
does not.
That's a neat idea, but there is at least one problem: What if there
are no keyword parameters, but there is a #!rest? In that case Gambit
allows keyword actual arguments, putting them in the #!rest parameter.
That is sometimes what you want (when you want to allow general
keyword parameters), but usually you don't want keywords, and you
want to treat keyword arguments as an error.
[citation needed]
If there's no #!key but there is a #!rest, then the programmer would
seem
to be indicating that all trailing arguments should go in the rest list.
For instance, the definition of menu in swing.scm. That could be written
differently if #!key-before-#!rest were valid in Kawa, but I don't think
it should stop working (perhaps with an added annotation, see below).
You could write #!key #!rest - i.e. an empty list of keyword
formats, but that seems clumsy and confusing.
Agreed about that.
I think we want two separate things:
- Bind a variable to the remaining keyword-value pairs.
- Bind a variable to the remaining non-keyword arguments.
Then perhaps keep #!rest compatible with Gambit's usage, and add
new specials #!rest-key and #!rest-non-key or something like that.
Not sure what the answer is, but I do know we want to be stricter
than Kawa is, so the *compiler* can emit an error about bad keyword
use.
Probably true. But a keyword that doesn't correspond to a named
parameter
in the function definition isn't necessarily a "bad" keyword. They're
super handy in object instantiation expressions (in which the class
object
is effectively coerced to an implicitly-defined function which invokes
the
constructor and then magically turns keyword args into setXxx/addXxx
calls).
I can imagine wanting a function to be able to perform similar magic
with
arbitrary keyword args.
Perhaps an annotation (@SuppressWarnings "keyword") could help.
(Though I
don't think annotations work outside of classes yet, right?)
(define (do-awesome-things-with-arbitrary-keywords #!rest
args ::object[])
(@SuppressWarnings "keyword")
::void
...)
(do-awesome-things-with-arbitrary-keywords some-random-name: value) ;;
no error here
On the other hand, passing an unlisted keyword to a function without a
#!rest arg (and perhaps without the annotation) should signal an error.
(define (foo #!key a b) ...)
(foo c: 0) ;; this one should probably signal an error, but currently
does not
As you say, it's tricky and there are lots of corner cases to consider.
--
Jamison Hope
The PTR Group
www.theptrgroup.com