On Sun, Oct 20, 2019 at 8:50 PM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:

If, say, `f', `f1', `f2', and `g' all intend to implement the same
`test:' protocol, then it makes sense for their respective libraries
to import the same `test:' identifier from a common library. Passing
down any value through such a `test:' argument by, say, `g', makes
only sense if the callee understands this particular type of value. In
other words, they have to cooperate beforehand anyway.

They should in the ideal world, but I'm highly skeptical that it will work in practice.  

Because when one start writing library for 'f1', he can't foresee which keyword arguments
would be shared with future libraries, nor is able to know if there's someone developing
independent library that uses the same keyword with the same purpose.  The same applies
to 'f2'.  And they may not care each other's library---their interest isn't there.

It's only the user who cares compatibility of f1 and f2.  Would the user ask the author
of f1 and f2 to change their code to import the same binding?  But which library should
they import from?  You don't want to introduce extra dependency, which means extra burden
of mentenance, just to make a particular user happy.

Or, suppose there's a huge library that provides 'f1' and keyword bindings.
You write an independent library 'f2', but knows the meaning of 'f1's keyword argument and
want to implement the same protocol.  But you don't want to depend on the entire 'f1' library
just to share one keyword binding.  Would you ask the author of 'f1' to split their keyword bindings
to a separate library?  It's not only just an extra libary, but they should also split the distribution
package for them, since if a dependency tool tries to fetch the (f1 keyword) library you
don't want it to pull entire f1 library. 

And then, the maintainer of f1 library decided to create an entire new version and changed
the keyword name, and decided to drop support of old version.  You, on the other hand, need to
want to keep old keyword name for your users.  You and the f1 author should coopetate
and move the binding of original keyword from (f1 keyword) package to your f2 package.

Oh wait, there's another f3 package that also depended on (f1 keyword) package, and they
want to do the same!  Now you have to talk to f3 package author, to create a new common
library to be used by f2 and f3 libarries.

Nowadays, your software can depend on tens or even more than hundred of libraries, all of
them evolves mostly independently.  I don't think it is feasible to create a common library
for common meaning of each keywords.

One can argue that, if you want to share interface, you should import from the same libary---
but when people talk about such interface, it is a whole interface---procedure signature or
common slots.  Each keyword is just a piece of it.  However, using hygiene to solve
the problem, you have to keep your eye on every pieces, not on the interface as a whole.
That makes the mentenance far more difficult.

What hygiene allows is to have two different, independently created
test protocols in the same program. This won't be possible if `test:'
is a mere identifier.

Anyway, I have also proposed on this list to allow other types than
identifiers as markers for keyword arguments. Only when you want
hygiene, you would use an identifier. Otherwise, you would use, say, a
keyword object as in SRFI 88. Macro writers can do the same.

> That's why I'm claiming keyword arguments isn't much about identifiers but just an extension
> of ordinary arguments.  For positional parameters, the semantics of the first parameter differs
> completely among procedures, but we don't think it's conflating the protocol.  It is ok that the first
> argument of procedure f and the first argument of procedure g has completely different meanings,
> and it's callers responsibility to pass appropriate one.  If g takes a procedure that takes filename
> as the first argument, then it's caller's responsibility to pass such procedure to g.
> The same applies to keyword argument.  If g takes a procedure that takes logger: argument of
> a specific type of object, then it's caller's responsibility to pass such procedure.

Keyword arguments could/would make it possible to treat some procedure
arguments in a uniform way. For position arguments, this is only
possible when we do whole-program transformations (see my CPS example
from somewhere above).