> For 177, I would go with the simplicity of:
>
> (define map
> (let ((standard-cons cons))
> (lambda/kw (proc lst cons)
> (let ((cons (or cons standard-cons)))
> (fold-right ...)))))
>
> I think it looks clearer than:
>
> (define/kw (map proc lst ((user-cons cons))
> (let ((user-cons (or user-cons cons)))
> (fold-right ...)))
>
> Your version needs a sufficiently intelligent compiler to provide the
> same performance.
I don't think I understand this. It only adds an `or`.
You have one more local variable/indirection. The compiler needs to beta-reduce it.
> Furthermore, what would you do if a keyword argument
> is not named after a procedure but after a syntactic keyword. Do you
> want to wrap everything inside `let-syntax'??? (For example, it is
> reasonable to use "cond" as a name for a keyword.)
I'm not sure I agree that it's reasonable :)
Why not? You may want to add a condition as an optional parameter.
If we argue with the simplicity and the beauty of Scheme, it should not matter which name the user chooses for their keyword arguments.
If identifier syntax is added Scheme, this would become quite interesting.
> adding an optional sublist at the end of the keyword list
> makes the full syntax of lambda/kw and define/kw more complex for
> people reading in the manual about how to use it.
>
> If you care about these people, it is easy to make two entries. One that
> describes the base version, and one that describes the general one.
That's why I'd like to have a simple and complex version of lambda/kw
(and define/kw) separately importable.
What is the purpose of this? Apart from the fact that the version, which allows to choose the identifier names, is only an epsilon more complicated, this seems to be analogous to when you have `(scheme base)' exporting `assoc' without the optional third argument and `(scheme assoc)' exporting a version with the optional third argument.
Users for which the third argument is too complicated to grasp can still use the three argument version, but just with two arguments.
> > (map proc lst1 lst2 lst3 lst4 cons: ipair)
>
> I would prefer to avoid a feature like this. The semantics are more
> complex and ambiguous, as can be witnessed in Common Lisp.
>
> Can you explain to me in what sense the semantics are ambiguous?
In the sense that if you go by your knowledge of Lisp, Scheme and
programming languages in general, it's not clear how the language parses
it. You can always read the details in the spec, but if you regularly
switch between languages, you tend to forget the details of language
features with intricate semantics. A conscientious programmer verifies
things instead of making assumptions, but if there are too many things
to verify, it's no longer fun and productive. I think Common Lisp and
Racket went overboard in many places. Good software can be written, and
more fun can be had, in a vastly simpler language.
The core of the Scheme language is very small. Keyword arguments would have to be added to this core that is to grasp. Any programmer worth their name should at least have read and understood this core.
Scheme's raison d'être is that it is sufficiently different to other programming languages.
> I agree and still my conclusions seem to be different. :) The less
> artificial restrictions, the simpler the language. You may prove me
> wrong, but the concept of rest arguments seems to be orthogonal to the
> concept of keyword arguments as in SRFI 177. It is an artificial
> restriction to have one exclude the other.
You're right that it is orthogonal in principle. Common Lisp proves it
(177 is a small subset of Common Lisp's supported behavior).
I haven't thought about how rest arguments given to a keyword procedure
should work in R7RS-large. It may be complex because there are already
three flavors of Scheme in the wild:
- Kawa and Racket (keywords are markers)
- The other keyword Schemes (keywords are self-evaluating objects)
- The rest of Schemes have no keywords at all
So -large will probably have to make some compromise.