Am Di., 3. März 2020 um 16:00 Uhr schrieb Lassi Kortela <xxxxxx@lassi.io>:
> 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.