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

Reply via email to