Haskell is right. Sugaring in the conjunction like Python violates non-associativity, which exists for predicate relations in human languages. And it's not a type error; it's a syntax error.
Note that in mathematics one sees things that look like "1 < i < n", which seems similar to what Python allows. But, if you ask a mathematician to read this aloud, they will say "some i between one and n", or in certain contexts "all i between one and n". This is an entirely different thing; it is not a predicate at all.
[...]
So with <, it's non-associative and bad to sugar up the error you get if you try to use it associatively.
Hmmm... but by the same argument, Ruby is also doing it right, by correctly crashing at runtime (there is no way for a language without a type-system and with redefinable operators to discover the error at compile time).
Somehow the author isn't clear on whether he wants "1 < 2 < 3" to return true or to be rejected; if it's the latter, then most languages get it right (except Python and Matlab, as far as I know).
I think he's actually quite clear on rejecting it as a syntax error. Ruby isn't doing it right in that it throws a type error: 1 < 2 < 3 becomes lt(lt(1, 2), 3), then lt(true, 3) which doesn't check.
I know nothing about Ruby so I don't know how its operator overloading works, but I think that could be a problem if < was redefined with an a -> a -> a signature, or a -> a -> b with b comparable to a, since in this case you wouldn't get the type error. The proper solution, according to the author, would probably be to simply refuse any expression with more than one < (or any other non-associative operator).
It doesn't seem possible to consistently make "1 < 2 < 3" a syntax error in a language powerful enough to redefine <. (Including Haskell, where you could easily hide the Prelude definition and define your own, also changing the fixity declaration.)
So I guess a fair compromise would be if the default implementation rejects "1 < 2 < 3" at either compile-time or run-time, whichever is possible.
Not really. As pointed out above, the author doesn't appear to understand that the associative/non-associative distinction is literally undefined unless we're talking about a binary operator from a set to itself. Saying that < is a non-associative operator is wrong, something like saying that a vector is a non-odd number; as long as we're complaining about parenthesization, I'd suggest the author rephrase his statement and say that < is a non-(associative operator), which at least means something.
An expression like a < b < c should be a type error - no possible parenthesization could make it a valid statement.
It's easy enough to come up with a way to make < work like this, though, by changing the signature of < so that it takes and returns a helper class instead of a numerical value, with automatic type coercions to that helper class from numerical values on both ends and booleans on the right edge. This should be easy in a language like Scala, probably a 10 minute exercise if you know what you're doing.
If we make this helper class hold both the left edges of the chain and the right edges, and use the appropriate edge for each comparison, then the thing is associative.
((a > b) > c) > d is the same as a > (b > (c > d)), since in either case, each element will at some point be checked with > against both of its neighbors, and only those neighbors, and the overall expression will be coerced to true if and only if the strict ordering is preserved at each check. Process left to right, and it works out. Even if we get messier and allow >, >=, <, <=, and == into the mix, we can mix and match everything, and the whole thing will only be true if every neighboring check is true. The author's worry in the blog comments about '1 < 2 > 1' evaluating to true strike me as odd: that should evaluate to true under any reasonable definition of those operators.
So even if we do make < into an operator such that it makes sense to talk about its associativity, it turns out to be associative. Which is why mathematicians don't bother parenthesizing their chained < expressions, there's just no ambiguity.
Haskell is right. Sugaring in the conjunction like Python violates non-associativity, which exists for predicate relations in human languages. And it's not a type error; it's a syntax error.
Note that in mathematics one sees things that look like "1 < i < n", which seems similar to what Python allows. But, if you ask a mathematician to read this aloud, they will say "some i between one and n", or in certain contexts "all i between one and n". This is an entirely different thing; it is not a predicate at all.
[...]
So with <, it's non-associative and bad to sugar up the error you get if you try to use it associatively.