Am Mo., 21. Okt. 2019 um 09:53 Uhr schrieb Shiro Kawai <xxxxxx@gmail.com>: > > 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. While I understand your points that it is hard to develop a stable interface independently, I don't see how this is an argument against the possibility of hygienic keywords: With only non-hygienic keywords, it just gets harder and one has no chance to rename identifiers when libraries step on each other's toes. On the other hand, if `f1'. `f2', and `f3' are developed by the same authors, hygiene will be useful. Or, a library, say `f0', exporting the keyword and on which `f1', `f2', and `f3' are based, can come from a future SRFI. But let me try to give a better example than the `test:' example. Consider a version of `map' that takes a keyword argument `reverse:'. When true, the resulting list will be reversed. Furthermore, `map' shall take optional keyword arguments that are opaque to `map' and passed down to the procedure called by `map'. For example: (map f ls reverse: #t foo: 42) Here, `f' shall be called with the list item and the keyword argument `foo:' bound to `42'. However, how can `map' whether to pass down a keyword argument `reverse:' to `foo:' or whether to change its own behavior? If at least `reverse:' is hygienic, the problem is far less urgent. -- Marc > > > > >> >> 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). >> >> Marc