I said:
>> E.G., f(...) for non-infix and f{...} for infix, right? Problem is, then
>> people will constantly use the wrong marking. Sigh.
Alan Manuel Gloria replied:
>Actually, I was thinking more of like this:
> f(x + 1) => (infix-fix-function-call f x + 1)
>where infix-fix-function-call would then fix the function call such that it
>*might* have infix.
>But then it loses the ability to reliably detect an undeclared convoke
>operator.
If {...} _always_ meant "this is infix", and was the only way to invoke infix,
then that problem goes away. Then you don't have to mark any operators. In
fact, as long as only one (equivalent) operator was present in the even
positions, a macro isn't needed at all, the reader could do THAT.
In other words, {...} could be interpreted this way:
* If there are an odd # of parameters >=3, and all the even-numbered parameters
are the same non-list value f, transform to (f p1 p3 p5...). So {1 + 2 + 3}
becomes (+ 1 2 3), and {n convoke p} becomes (convoke n p), _in the reader_.
* Otherwise, transform to a standard macro name, followed by the parameters.
Thus, {x convoke a + b} becomes (nfx x convoke a + b).
Basically, the reader can pick up "basic infix" and transform it at read time.
Advantage: ALL macros can work on the results. More complicated infix
expressions are then dumped off to a macro, which can then handle precedence
etc. (the problem with these is that other macros, if they examine the
s-expression before the infix macro executes, will see the unprocessed
version). That infix macro could also just raise an error saying "precedence
not supported".
There are big pluses and minuses for REQUIRING the use of {...} on EVERY infix
operator.
Plus: Might be easier to get existing Lisp users to use and support this. For
them, infix is "not normal", so having a special syntactical marking for it may
be comforting. Remember that ' is already a syntactical marking (some old
LISPs didn't have it!), so having special markings isn't really unknown. It's
easy to implement, easy to control, and easy to see WHERE the infix operations
come in. Rules for pattern-matching become completely unnecessary; ANY atom
could be an infix operator.
Minus: The presentation is a little uglier, as documented in the earlier email
message. E.G.:
n * f(n - 1)
becomes
{n * f({n - 1})}
These are two very different paths for reader-based implementations:
* Require {...} around every infix operator. Then you know where they are, and
there's no need to "disable" infix.
* By default, use infix, and then require special syntax to DISABLE infix.
This requires some technique for detecting them (which is what I used the
patterns for).
Though I think "n * f(n -1)" is prettier, but that may be an extreme case. I'm
certainly willing to forgo that if other advantages are more compelling.
Comments welcome.
--- David A. Wheeler