Homogenous prefix notation is a reliable behavior and constraint of Lisp’s
syntax, but is probably also one of the things that trips up most people when
they are trying to read and make sense of long programs. Infix notation is a
very natural form for defining collaboration between terms, whether it’s 1 + 1
or Alice and Bob.
I admit, my opinion of infix may possibly cultural-linguisitically biased as
grammar in other languages could have adopted prefix action words before subject
and object). Mechanistically however, infix operators have the advantage of not
requiring an expression delimiter-set like ( ... ) to indicate expression
completeness too.
In Ruby, the infix operators like +, * and << are all modeled as methods
sent to the left operand with the right operand as argument. In practise this
tends to work out okay most of the time, but without something like refine, it
is not possible to define operators for use with DSLs unless you also define
special objects for those DSLs, which can make embedding the DSL more
cumbersome.
Having worked a lot with Cucumber in the past 2 years to define acceptance tests/executable features, I’ve grown accustomed to and am enjoying the flexibility in begin able to define a library of functions (Step Definitions) with somewhat arbitrary “anyfix” composition properties.
There are technical reasons why this is not easily applicable to typical general imperative programming language design, but apart from the typical “you’ll shoot your eye out” caveat, there are no essential concept violations by providing an “anyfix” expression signature capability for general programming.
Imagine for example a function definition such as:
1 2 3 4 5 | |
…could instead be mapped as…
1 2 3 4 5 6 7 | |
A language with a feature like that could lead to some pretty sweet embedded DSLs. Just sayin’.