Re: John Cowan tries to keep it simple
Lassi Kortela 03 Nov 2019 12:13 UTC
> I'm starting to get lost in all these options. Here's how I think things
> should look:
>
> (call/kw name expr ... marker :kw expr :kw expr ...)
>
> I don't care exactly what the marker is. But this way it looks exactly
> like a normal function call except for the leading call/kw and the marker.
> If a user thinks call/kw is too verbose, it's easy to write a syntax-rules
> macro that lets you use a shorter (or even longer) name.
>
> I also don't care if the keyword identifiers have colons in them or not.
There are two scenarios here: one where we have hygienic keywords, and
one where we don't.
If we don't have hygienic keywords, IMHO it's a no-brainer to have:
(call/kw foo 1 2 :foo 3 :bar 4)
That's immediately obvious to every Schemer/Lisper who has used keyword
arguments in any other Lisp, and is almost equivalent to their native
syntax, only with call/kw at the start. In this situation, something like
(call/kw foo 1 2 : foo 3 bar 4)
or even
(call/kw foo 1 2 (foo 3 bar 4))
would just be gratuitously different (the latter's main excuse is
syntax-rules compatibility, which requirement we have all but ditched).
If, on the other hand, we need hygienic keywords, then it's not obvious what
(call/kw foo 1 2 :foo 3 :bar 4)
means. Are foo and bar non-hygienic global keywords? If so, how does one
write the hygienic versions? You can't do this:
(call/kw foo 1 2 foo 3 bar 4)
Since those look like ordinary symbols. Treating all symbols inside
`call/kw` as keywords would just be too far out even for Lispers :)
We could make it so that one colon is hygienic, and two colons are
non-hygienic (or vice vers):
(call/kw foo 1 2 :foo 3 :bar 4)
(call/kw foo 1 2 ::foo 3 ::bar 4)
But this is starting to look like C++ or Perl in a bad way. And Lispers
have no idea what ::foo means.
We could treat all _quoted_ symbols as unhygienic keywords, but maybe
that's also too far out, and how would we detect the hygienic ones:
(call/kw foo 1 2 'foo 3 'bar 4)
We could combine quotes and a here-come-the-keyword-args marker:
(call/kw foo 1 2 : 'foo 3 'bar 4) ; unhygienic keywords
(call/kw foo 1 2 : foo 3 bar 4) ; hygienic keywords
Or:
(call/kw foo 1 2 ('foo 3 'bar 4)) ; unhygienic keywords
(call/kw foo 1 2 (:foo 3 :bar 4)) ; unhygienic keywords
(call/kw foo 1 2 (foo 3 bar 4)) ; hygienic keywords
That pretty much covers everything we've considered up to this point...
As you can tell, all of the complexity comes from two sources:
* Requiring syntax-rules support
* Requiring a provision for hygienic keywords in the 177 syntax
If we drop both those requirements, things are really simple. Just use
(call/kw foo 1 2 :foo 3 :bar 4)
Where :foo can also be foo: or a native keyword object. Problem solved.
R7RS-large can have more or less magic, as long as the semantics of
keyword lambdas and keyword calls are compatible with 177 under the
hood, so that programmers can mix 177 code and R7RS-large code. But the
above is what would go for 177.