Here are my current thoughts on keyword arguments in no particular order:


There seems to be consensus by those working on other SRFIs (for example the POSIX ones) that keyword arguments are very much needed for the API. (Personally, I would prefer other abstractions as I have discussed with John once, but I seem to be in a minority here.) Under this assumption it is important that we are able to talk about keyword arguments in R7RS-large.

For the specification of the consumers of the keyword system, the details of the keyword system are, however, not relevant. It is enough if the keyword system fulfills a few axioms. In particular, the exact syntax of the keyword system is not relevant for the specification of the consumers if that specification is written in a way that is transparent to the details. Likewise, it is probably irrelevant whether "procedures" taking keyword arguments are actual procedures or macro keywords. Furthermore, whether the keywords are identifiers, objects of a keyword type or hygienic identifiers doesn't have to play a role for those customers if they are specified with enough care.

For SRFI 177, this means that it can serve as one model for the keyword system that is rich enough for the customers. Example code for the customers can be written in terms of SRFI 177. Depending on the adaption, how this discussion proceeds, and what syntactic transformers will be available in future iterations of R7RS-large, SRFI 177 can then easily be replaced by a successor. In particular, the successor may use a completely different syntax (so that answers to questions like whether it is called lambda/kw or keyword-lambda do not have to be set in stone). In fact, we can leave SRFI 177 can be underspecified, and this may be a good idea. For example, we may leave it open (at least for the time being) whether SRFI 177 keyword "procedures" are actual procedures or just macros.


When keywords are hygienic identifiers, "procedures" with keyword objects *have* to be special forms. This is probably not too bad. With keywords hygienic identifiers, we cannot have a generic `apply' for "procedures" taking keyword objects. This is possibly bad.

When keywords are non-hygienic objects, keyword procedure calls that should in fact be resolved at expand-time have to be resolved at run-time and it needs an intelligent compiler to rewrite the call into a fast one. This may also relevant for procedures with keyword arguments when they are exported from libraries. The Scheme implementation may have no way to look into a compiled library, which would make cross-library calls of procedures with keyword arguments slow.


There should be a way to write wrappers for "procedures" taking keyword arguments. In particular, there has to be a way to pass keyword arguments down to callees. With unhygienic keyword arguments, there may be the problem that keywords conflict with each other. One way to solve it is to make sure that all keywords defined in R7RS-large are disjoint. But the way Scheme has solved these problems until now has been hygiene. So far, the only things that have to be disjoint are the Scheme library names. (The feature identifiers as well but (dummy) library names for this purpose would have been sufficient.)


If keyword arguments are hygienic, macros can easily generate disjoint keyword arguments that do not clash with other keyword arguments.  If keyword arguments are symbols or keywords, something like `gensym' is needed.  Furthermore, there has to be a way to define procedures that take keyword arguments whose names are made on the fly.  The same goes for calls with keyword arguments.


Any macro that distinguishes the function of an identifier argument by its name (for example, whether it begins with ":" or not), is really an ugly hack. It may be used for some implementation, but the final specification should not depend on this.  It won't work together well with the rest of the Scheme system.  I gave one example with `let'.  Another example is a macro, which expands into a call with keyword arguments and that passes down an argument given by the macro user.  Depending on whether this argument is of the form `:x' or just of the form `x' the macro may do completely different things and that would be opaque to the macro user.

As long as the Scheme implementations cannot agree on a new fundamental type together with its syntax, I would rather add a space in between ":" and the identifier and export ":" as auxiliary syntax, e.g. as in `(call/kw 1 2 c : 3 d : 4)'.  For this, even `syntax-rules' is sufficient.  Furthermore, it would allow a syntax like `(call/kw 1 2 ,c : 3 d : 4)', where `c' here is an expression returning a keyword.  This is important, see above, to generate new keywords on the fly for example in macros.  (R7RS records when they are understood with symbols and not hygienic identifiers as field names have the serious deficiency that hidden fields cannot be added transparently; we don't have to repeat the same mistake.)

(6) The whole discussion show to me that the foundations for R7RS-large that is provided by R7RS-small is very beautiful but also quite small.  If we postpone all serious additions to the language that cannot be implemented portably and may need some compromises from the R7RS implementers to the end of the R7RS-large specification process, the majority of the R7RS-large libraries won't use them.  I wonder whether it is a good idea to squeeze an R8RS-small or a R7RS-small+ in between where the foundations are revised (e.g. by changing the meaning of the `:x' syntax).


Lassi, do you have a most current version of your SRFI 177 draft? If you can give it to me, I will try to make it into an (alternative) proposal that addresses some of my points and then we discuss.