> But I care to be able to distinguish between a non-supplied argument and
> #f as these are, logically, two different things.
>
> Maybe I would like to handle a tri-state keyword argument:
> true/false/use whatever default value. The default should be the
> default, not #f.
>
> Example:
>
> (parameterize ((default-case-sensitivity #t))
> (foo)
> (foo case-sensitivity: #t)
> (foo case-sensitivity: #f))
>
> Languages become simpler if they do not lump together things that are
> logically different.
A tri-state is a classic example of why I would prefer all default
values to be #f. Programmers love logic puzzles, and Common Lisp's
intricate syntax encourages us to create puzzles that the users of those
procedures then have to solve. Probably most CL programmers go through a
puzzle-happy phase once they discover lambda lists, macros, the
condition system and CLOS. It's fun for them, but less fun for people
who have to use their creations :) Those users usually include
themselves, once a few months have passed and details forgotten.
Emacs is a perfect example of the kind of large, long-lived system that
benefits most from keyword arguments. The usage for a typical (not
pathological) Emacs subsystem is like this:
<https://www.gnu.org/software/emacs/manual/html_node/elisp/Defining-Faces.html>.
When you take into consideration the amount of documentation needed for
these systems, then as a user, I'm happy if there is nothing
sophisticated in those systems that doesn't absolutely have to be there
:) The more "idiot-proof" the usage can be, the better. Not only is the
usage daunting in a clear-headed, well-rested state, but if you're
tired, have little time or other pressures, it gets even more difficult.
Emacs deals with case-sensitivity by having a dynamic variable
`case-fold-search` (it works just like a Scheme parameter object). If a
case-sensitivity argument is needed, I would either go with that, or use
symbols or an abstract case-sensitivity dataytype or something.
Again, my point is total complexity of large systems. It's difficult to
convey using examples, since we can always invent a task that is more
convenient using one kind of syntax or another. But in a system big
enough that you still feel lost after months, simple universal semantics
really pay off.
No one would forbid you or R7RS-large to solely use #f as defaults in their APIs. For most APIs it is possibly a very good idea based on your arguments.
As a Scheme programmer, I value my freedom. :)
Besides, you cannot really force people to write good APIs. Even with keyword arguments, the possibilities to design rotten interfaces are endless...
> Scheme is a better language because '() and #f are different objects.
After a year of intensive Scheme usage, I'm still not sure which way is
better. Coming from CL, the lack of nil-punning took a lot of mental
adjustment.
CL and Scheme look like very different languages to me.
Logically, '() and #f are very different things. Why lump them together? You lose abstraction and expressiveness.