[plt-scheme] keywords (a backward-incompatible change)

From: Jim Blandy (jimb at redhat.com)
Date: Sun Oct 2 02:18:08 EDT 2005

Eli Barzilay <eli at barzilay.org> writes:
> FWIW, this is what CL does:
>
>   (let ((key :test) (x #'equal)) (member '(1) '((1) (2) (3)) key x))
>
> does what you think it will do.

In other words, it's equivalent to

   (member '(1) '((1) (2) (3)) :test #'equal)

and:

   (apply member '((1) ((1) (2) (3)) :test #'equal))

>> You haven't given examples of the syntax used for calling procedures
>> with keyword arguments. [...]
>
> The change to MzScheme is just the fact that keyword arguments are
> added.  Actually using them is left for a library -- and the current
> plan is to take the Swindle thing and make it into a mzlib library.
> The docs for Swindle should explain what that will do, roughly.  Since
> this will be done in Scheme, then changing it is going to be easier,
> and the effect would be noticeable only when you want to use that
> library.

Right --- what I wrote there was lead-in to the next paragraph,
explaining why I think the CL behavior isn't the greatest.  I didn't
want to presume you guys hadn't found a different approach.

If the feature isn't going to be used in MzScheme core functionality
because it's not well-behaved enough, that argues that perhaps the
syntax shouldn't be enabled by default in the reader.  If someone is
using Swindle, they can always put #k+(begin ...) at the top of their
file.

(How do people writing Common Lisp macros deal with this?  I mean, if
you're operating on code, you've got keyword objects flying around as
normal values all over the place, so they must run into the problem.)


If it's all up to the callee to parse its argument list, and the only
magic associated with keywords is that they're self-quoting, I guess I
don't see why they're so much better than quoted symbols, i.e.:

   (slide 'center? #t 'tall? #t
          contents ...)

I don't know the slide-show syntax; if that's no good, you could
reserve a set of symbol names:

   (slide ':center? #t ':tall? #t
          contents ...)

or whatever suits your taste.

In the end, since the self-quoting isn't really essential, and the
distinct datatype isn't either, it comes down to the value of having a
legible convention that everyone knows about.


For what it's worth, Guile had :keywords for a while, that worked the
way they do in this proposal (without the #k+ and #k- stuff, which is
a nice idea).  We did run into people using symbols whose names began
with colons --- the Functional Postscript library is the example I
remember.  We ended up disabling that syntax by default, and having a
#:keyword syntax always available.


>> I'm not sure how to get around this.  The ideal behavior would be
>> for keywords to affect argument passing only when they appear
>> directly in the call expression.  When an argument's value is a
>> keyword object, that argument should be passed as a positional
>> parameter, like anything else.  So, the second expression above
>> would simply call member with four positional arguments.
>
> This would be the OCaml way, I think.  It sounds like a more sane
> approach if core functions will use keywords.  It has another
> advantage, the fact that you can eliminate run-time costs completely,
> but this comes at a price of being less flexible -- for example, there
> will be no way to do something like:
>
>   (define (my-slide . args) (apply slide :tall? #t args))

You could get that behavior with an adapted version of apply:

      (apply-with-keywords slide '((:tall? . #t)) args)

Or maybe:

      (apply slide args :keywords '((:tall? . #t)))


Posted on the users mailing list.