Hi Ludovic! Thanks for your review and consent! I have incorporated your suggestions and pushed the improved patch set to stable-2.0.
See below for my thoughts on your comments. l...@gnu.org (Ludovic Courtès) writes: > Regarding SRFI-105, I’m skeptical about a couple of things. > > First, $bracket-apply$, $nfx$, and $bracket-list$ need to be > user-defined, but implementations are allowed to provide a pre-defined > version of these. This sounds like an opportunity for incompatibilities > (which the document describes as a shortcoming of Guile’s infix module.) First of all, I should clarify that $bracket-list$ is not part of SRFI-105; it is part of GNU Kawa. However, since SRFI-105 adopted Kawa's convention for $bracket-apply$ within curly braces, I chose to also adopt Kawa's $bracket-list$ convention when curly-infix is enabled and when no other meaning has been given to square brackets. SRFI-105 says that $nfx$ and $bracket-apply$ "SHOULD NOT" be bound by default (except to something that produces an error), and that they "MUST NOT" be bound to anything that cannot be overridden. The expectation is that if someone writes code that produces $nfx$, they should bind $nfx$ to something that implements their desired policy. Ditto for the others. This should work consistently on any implementation that complies with the SRFI-105 specification. If an implementation provides default bindings for $nfx$ et al (which SRFI-105 says it "SHOULD NOT" do) and a user writes code that depends on this, they are asking for trouble. However, this is no different from any other non-portable extension to Scheme that users rely upon. Certainly Guile already has plenty of non-portable extensions to entice users to rely upon, so this is nothing new. > It’s also unhygienic, in the sense that programs that need it would > typically have to start with a definition of $nfx$ & co., although these > identifiers never appear literally in the neoteric code. I agree that this is not ideal, but I see no way around it without losing the benefits that these (optional) features are meant to provide. Apart from the fact that $nfx$ et are meant to be defined by the user, it is exactly the same situation as for 'quote', 'quasiquote', 'unquote', 'unquote-splicing', 'quasisyntax', etc. The whole point of these shorthand notations is to avoid having to type the associated identifier, and yet this means that an identifier is being referenced without appearing literally in the code. These shorthand notations always involve a tradeoff. It means that the syntax is not quite as simple as the original s-expressions (as printed by 'write'), and the user has to know a few more rules for how to interpret the notation. Experience shows that humans tend to prefer a bit more complexity in their syntax if there is something to be gained from it. I think it's worthwhile to add a few more rules in exchange for the option to use infix notation in selected areas, as long as the resulting notation is homoiconic and the total number of rules is kept small. > Bracket lists (and $bracket-list$) are another opportunity for > incompatibilities, IMO. The SRFI reads: > > several Scheme implementations follow the R6RS specification that > accepts [...] as a synonym for (...), GNU Kawa interprets [...] as the > redefinable constructor ($bracket-list$ ...) > > But I fail to see why R6 syntax would influence SRFI-105 syntax. The excerpt you quoted is part of the rationale for why SRFI-105 does not specify any meaning for square-bracketed lists (except for the neoteric syntax, which only applies within curly braces and when the '[' immediately follows an expression with no intervening whitespace). >> +Guile also implements the following non-standard extension to SRFI-105: >> +if @code{curly-infix} is enabled but the @code{square-brackets} read >> +option is turned off, then lists within square brackets are read as >> +normal lists but with the special symbol @code{$bracket-list$} added to >> +the front. To enable this combination of read options within a file, >> +use the reader directive @code{#!curly-infix-and-bracket-lists}. For >> +example: > > Do you think it would be possible, or even desirable, to be able to turn > off this extension? I definitely think it's desirable to be able to assign some other meaning to square brackets, and indeed SRFI-105 allows us to do whatever we want with them (though they must be delimiters), and by default Guile treats square brackets an equivalent alternative to parentheses. My intent was that this extension would apply only when square brackets have no other meaning, and I changed the documentation to make this more clear. This gives us license to add additional read options to do other things with square brackets in the future. [... skipped several of your suggestions which I incorporated ...] >> + ;;(pass-if (equal? '#1=f(#1#) '#1=(f #1#))) > > Not implemented yet? > >> + ;;(pass-if (equal? '#1={a + . #1#} '($nfx$ . #1=(a + . #1#)))) > > Same? The '#1=' and '#1#' notation is part of SRFI-38 and R7RS (draft 6), which is not yet implemented in Guile. SRFI-105 does not require that we support this notation, but gives those examples of how the two notations should interact if they are both supported. > However, could you add a few tests regarding source location tracking, > by reading from a string port? Done. Thanks again for your careful review. The final result certainly benefitted greatly from your input :) Mark