This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]