I've tried to write down reasonable rules for the "infix default" and "infix 
non-default" alternatives.  Then, I then tried out both rulesets on a number of 
different code fragments. Details, including the code fragments, are here (and 
I encourage everyone to take a look):

http://www.dwheeler.com/readable/version02.html

My experiments found a surprising result... in MOST cases, the two alternatives 
(infix default vs. infix non-default) make little difference.  Instead, it 
appears that the (short) factorial example is something of an anomaly.  With 
many examples, the simpler "must use {...} to mark infix" looks about the same 
as the _much_ more complex ruleset necessary to implement automatic infix 
operator detection.

I still believe that "reasonable defaults" is a good idea, as I expressed in an 
earlier email. But if the defaults are unnecessarily complex, that can create 
problems in reasoning and implementing them.  I expected the automatic 
detection to be more effective than it appears to be in real programs.  I'm a 
big believer in experimentation, and though the experiments so far are showing 
less difference than I expected, that's okay... that's why experiments are 
needed.

There seem to be several reasons that "automatic infix" doesn't actually get 
USED very often in real code, now that I examine the code fragments:
*  When infix operators are used as conditionals (e.g., in "if" and "cond"), it 
seems very natural to put the conditional on the same line as other terms 
(e.g., the "if" or the result of the "cond").  In such cases, you need to 
surround the infix expression with {...} anyway.
* I believe that a _reader_ should avoid preset precedence, at least in most 
cases, but that means if you also want to avoid invoking a macro you need to 
surround subexpressions with {} when you mix operators, e.g., {3 + {4 *5}}.
* When you're sending operators in a function call, if you use f(...), then 
with multiple parameters you need to surround the various infix operators 
somehow anyway... e.g., f({1 + 2} {3 + 4}).  The one special case is the 
one-parameter call using infix, but f{n + 3} handles that case nicely.

So, based on actual experimentation, I'm actually thinking about reversing 
course - using the simple "infix non-default" ("must mark infix with {}") rules 
instead, and even accepting f{...} as a synonym for f({...}).  I didn't like 
this approach much at first, but the experiments so far suggest that it's 
actually a very reasonable way to go.

--- David A. Wheeler 

Reply via email to