Re: Keyword arguments in procedures specified in SRFIs Lassi Kortela 22 Jul 2019 09:07 UTC
Thank you for clearly outlining the solutions. > 1) A backwards incompatible change to Scheme's syntax by which certain > symbols are no longer treated as identifiers but as self-quoting > datums. If we do that, we might as well allow both :foo and foo: with > exactly the same meaning. > > 2) Adding a wholly new syntax for self-quoting datums that does not > overlap with the syntax for identifiers, in which case #:foo is the > natural syntax. > > 3) We could make #:foo not an expression at all, but part of the syntax > of procedure calls. In that case, #:foo would be a datum but not an > expression, whereas '#:foo would be both. > > All this is quite independent of how keywords would actually be used in > procedure definitions, which could be managed in a variety of ways. Indeed, if we pick approach 1 or 2 then we don't have to say anything about procedure definitions. That would make our job a lot easier. The spec could just talk about keyword objects and syntax for them, and leave the parsing of keyword arguments to some future spec once we have rested a bit from this effort :) Meanwhile, Scheme programmers could already start to use the consing dot to append a property list of keyword arguments to their positional args: (define (foo a b c . kwargs) (let-values (((d e f) (parse-kwargs kwargs d: e: f:))) (list a b c d e f))) (foo 1 2 3 e: 4 f: 5 d: 6) where (parse-kwargs) would just be a procedure from that particular programmer's favorite library. The calling convention would not be optimized by the implementation, but keyword args are most urgently needed in big procedures that do so many things that they don't need to run fast anyway (the performance is I/O bound or the inner loops are factored off into smaller procedures that don't take keyword arguments). > Speaking with my editor's hat /off/, I don't like the idea of the > inevitable complexity that would result. Thanks for looking out for the interests of simplicity :) Like John I find the complexity reasonable. It does seem weird to have three different syntaxes for the same task, and reader flags for toggling them, but every language community has historical baggage like that. We just have to take it in stride. If Scheme wants to seriously tackle the issue of writing big portable programs, we need to move forward with keyword args as a community (at least I don't see a way around it; I'll listen to arguments to the contrary). Of course, if implementors want to agree on one keyword syntax right away, that would be terrific. It just seems easier to provide a transitional option that makes the existing approaches interoperate. Now, how to _eventually_ get the community to favor one keyword syntax over others is a very good question. I fully agree with you that that's definitely a worthy goal. One way to tackle this would be to add one (and only one) keyword syntax to R7RS-large. That would send a strong signal. Meanwhile, implementations that support R7RS-large could also opt to implement the compatibility SRFI that provides all of the syntaxes, giving more transitional options for their users. How does this sound? > Getting Schemes that don't support either 1 or 2 > to accept either or both would be hard, as it involves completely new > lexical syntax as well as a new primitive type. I think this is fine. Tiny Schemes can opt to go with R7RS-small and no keyword objects of any kind if it makes sense for their niche. Lack of keywords doesn't really matter when writing small programs, for which those Schemes are well suited.