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 3:27 PM, Per Bothner wrote:
On 10/25/2011 12:01 PM, I wrote:
The problem here isn't a problem with your syntax, it's with the
types
you're using. Well, one of them, anyway. I don't know if it's
documented
anywhere,
No - because I never realized this didn't work.
I ran into this like two years ago or so, but I never brought it
up because the workaround (s/int/integer/) was easy enough.
but keyword arguments only work with arguments that are
Objects, not primitives. So, when you use int, things blow up.
You are indeed correct. I'm working on a fix.
Going back to the first example that works... that's fine when it
stands alone, but if this is inside a define-simple-class I get a
problem when I try to invoke it.
I've never tried to use #!key in class methods, so I can't help you
there, sorry. Per?
Getting that to work would be more difficult. The problem is that
class methods are supposed to be Java methods, with a calling
convention
that interoperates well with Java classes. I'm not sure how to do
that.
It's not a priority - but there should be a decent error message.
For functions, it essentially puts everything after #!key into an
Object[] at the end of the argument list, right? It might be reasonable
to do the same in methods, but using the implicit array boxing that
comes with a Java parameter of type "Object...". The real question is
how to conveniently specify the keywords themselves from Java. It would
be annoying to have to put Keyword.make() statements everywhere; perhaps
String literals would suffice?
So the method
((foo x y #!key a b) ...)
on the Java side ends up looking like
public Object foo(Object x, Object y, Object... rest)
and can be called with
o.foo(xVal, yVal, "b:", bVal);
Still ugly, but until the Java language gets real keyword args (which
I'm sure it will, eventually, as it inevitably converges to Lisp),
what can you do.
We probably also want to re-think keyword arguments a bit. Given:
(lambda (a1 a2 #!key k1 k2 #!rest r) ...)
The existing "standard" is that r *includes* the keyword arguments.
Isn't that a syntax error right now? Lambda.java has
tr.syntaxError (restKeyword.toString()
+ " after " + keyKeyword);
at line 125.
Note that (lambda (a1 a2 #!rest r #!key k1 k2) ...) on the other hand
is legal, and will include the keyword args in r.
I'm not sure is this is what is most useful. For a typical "builder"
function (HTML builder, Swing builder, etc) you want keyword arguments
for named properties followed by "child" expressions. You don't want
all the keyword bindings mixed up with the child parameters.
So I think we need a new delimiter - I thought of #!tail. This is
like
#!rest, but it does *not* include any keyword arguments, and if there
are keyword arguments not matched by keyword parameters, then it
is an error.
Does this make sense? Suggestions for a better name than #!tail?
(Note that adding this may not happen soon.)
I like Taylor's suggestion of sticking with #!rest and having the
behavior
depend upon whether #!rest or #!key comes first in the parameter list, a
la Gambit.
Kawa already apparently handles the #!rest-before-#!key case the same
way
that Gambit does:
#|kawa:11|# ((lambda (a #!rest b #!key c) (list a b c)) 1 2 3 c: 5)
(1 (2 3 c: 5) 5)
All that remains is to change the #!rest-after-#!key behavior from
a syntax error to rest-arg-doesn't-include-the-keywords.
It might also make sense to follow Racket in that an unquoted keyword
can *only* be used for a keyword parameter. E.g. if you want a
list of keywords, you have to quote them:
(list 'a: 'b: 'c:)
Contrawise, keyword parameters have to be explicit: You cannot
have a keyword be the result of evaluating an expression *unless*
you use a higher-order function like apply. (A syntax like ,EXP:
could be used for run-time evaluation of keyword names.)
This may avoid some bugs. More importantly, it makes the semantics
of what the compiler can and can't do less mushy, so various
optimizations become less ad hoc. (The compiler basically assumes
that
keyword arguments are explicit anyway when it performs optimizations.)
I have no strong feelings here. But this is reminding me of all the
WG1 discussions about syntax keywords being bound vs. unbound, datums
vs.
identifiers, etc., which just makes my head hurt.
--
Jamison Hope
The PTR Group
www.theptrgroup.com