Re: Procedures with keyword arguments should be macros not procedures Lassi Kortela 17 Oct 2019 20:33 UTC
> Apart from efficiency concers, classic Common Lisp-style keyword args >> are also hard to type-check statically. > > Actually they aren't, as long as the keywords are apparent at the point of > call. That seems true, but there has to be a reason why Kawa and Racket both have keywords as syntax markers instead of actual keyword objects. The reason was discussed in that big keywords thread in July but escapes me. > Of course, you probably should know there are going to be *some* options in > advance, and then you go with an alist argument or plist arguments. The problem is the "or": it soon becomes an inclusive or. Many Schemes already offer keyword arguments for this problem as do CL, Clojure, Emacs Lisp (partially), Ruby, Python, etc. We can choose to stay with a traditional rest argument, but then it would be good to agree on its interpretation (how to parse optional and/or key-value args out of the tail, whether to use alists or plists, and how to interoperate with existing native kw-args if at all). Keyword args are such an agreement, plus they lend syntactic support and opportunities for compiler optimization. They also unpack the arguments at the callee. I'm obviously biased, but SRFI 177 needs only standard RnRS read syntax while being fully compatible with all known existing native solutions. Implementation is 20-30 lines of macros per Scheme. I find it a better deal than thinking about alists, plists vs records for new SRFIs and libraries. If people hate the current syntax we can find another one so long as it's equally portable. I'd just like to have some standard that portable code can use. > Or > else you decide that sticking to the RFC is enough, and anything else > should be done in a separate prettyprinter. That's what I plan to do with > CSV, where the CSV operations will implement just the RFC (modulo character > and newline encoding) and I'll a separate DSV parser/formatter for handling > arbitrary delimiters, escaped tabs and newlines, and everything else. If > the options interact in complex ways, a builder procedure may even be the > right thing, even though it's inherently imperative. Builder procedures do have their uses when the configuration starts to resemble a configuration language. Unless I misunderstand what you mean, they are not inherently imperative. Roda (for Ruby) is one example of a delightful API made mostly by stacking builders on top of each other. Each builder returns a fresh object with the changes you want instead of mutating the object you gave. Recursive functions are a lot like builders, especially when consing onto an accumulator.