Take the 2-minute tour ×

I have written a decimal floating point unit for LaTeX3 (pure macros... that was tough). In particular, I have to decide how x < y < z should be parsed. I see three options:

  • Treat < as a left-associative binary operator, so x < y < z would be equivalent to (x < y) < z. This is what C does: -1 < 0 < 1 becomes (-1 < 0) < 1, thus 1 < 1, which is 0.

  • Treat < as a right-associative binary operator, so x<y<z would be equivalent to x < (y < z). I see no advantage to that option.

  • When encountering <, read ahead for more comparison operators, and treat x < y < z as equivalent to (x < y) && (y < z), where y would be evaluated only once. This is what most non-programmers would expect. And quite a few LaTeX users are non-programmers.

At the moment I am using the first option, but it does not seem very natural. I think that I can implement the second case whithout too much overhead. Should I?

Since that question is subjective, let me ask an objective question: what mainstream languages pick option 3? I'm interested in the details of what happens with mixed things like a < b > c == d < e != f. I'm also interested in other choices if they exist.

share|improve this question
add comment

3 Answers 3

up vote 3 down vote accepted

Short answer: it only makes sense to parse comparison sequences if they are "pointing into the same direction", and when you don't use !=.

Long answer: In Python, 3 > 2 > 1 evaluates to True. However, I have to say that the implementation used is overly simplistic, because it allows for expressions like a < b > c == d < e != f, which are nonsensical in my opinion. The expression would be interpreted as (a < b) and (b > c) and (c == d) and (d < e) and (e != f). It's an easy rule, but because it allows for surprising results, I don't like that interpretation.

I propose a more predictable option:

  • Consider a proposition xAyBzCw. If this proposition is "sensical", it is equivalent to xAy and yBz and zCw. For "sensicality", it is necessary that...

    • the values (x, y, z, w) are part of the same set X (or their types can be unified as such), and
    • the relations (A, B, C) are transitive binary relations on X, and
    • for every ordered pair of relations A and B, there exists a relation C, such that xAy and yBz implies xCz for all x, y, z; this relation is also subject to these restrictions.

Regarding the last rule, you want to be able to say that 1 < 2 = a < 4 is equivalent to 1<2 and 2=a and a<4, but also that 1<2 and 1<a and 1<4. To say the latter, you must know how = and < interact.

You can't use != in my option, because it isn't transitive. But you also can't say 1 < 3 > 2, 2 < 3 > 1, or 1 < 3 > 1, unless you have a relation ? such that 1?2, 2?1 and 1?1 (basically, it would be a relation allows any pair).

From a syntactical standpoint: you want to treat relational operators as special operators (+ is more of a functional operator), kind of like in your third option.

share|improve this answer
Interesting. In my case, I only have one type available ---floating points (integers are automatically converted to floats when the target is a float)--- so there will be no issue with types. I presume that your approach would be to produce a NaN as the result for 1 < 3 > 2, probably after raising the invalid operation flag (cf IEEE 754 2008)? –  Bruno Le Floch Aug 23 '12 at 14:25
Probably, if you don't want to implement this type checking statically and if you also don't want to have boolean logic values (True, False, and a boolean counterpart of NaN; again, only if you don't want to implement a proper type system). –  Rhymoid Aug 23 '12 at 14:31
LaTeX is an interpreted macro language. In particular, since it's not compiled, there is no way AFAIK to do static checking of those comparison relations. I think that Python would also have to raise an exception in case it decided to forbid 1 < 3 > 2. –  Bruno Le Floch Aug 23 '12 at 16:08
Because Python has a very limited set of suitable relational operators, that might even be caught by the grammar. When implemented, it would result in a syntax error. TeX (and thus LaTeX) is Turing-complete, so you can implement a type checker. I would advise against it, though ;) –  Rhymoid Aug 23 '12 at 17:34
You're right about Python. About TeX, Turing completeness does not mean "can do anything" but rather "can compute anything": you could implement a type-checker for your favorite typed language in TeX. However, there is really only one type in TeX: macros (think strings). Static type checking is then checking that the content of those strings is compatible with a given structure (float, int), which looks a lot more uncomputable to me (statically) than type checking normally is. Run-time type checking is doable, but I need to produce some kind of result: invalid operation is as good as any. –  Bruno Le Floch Aug 24 '12 at 3:58
show 3 more comments

Python chains relational operators. Which gets interesting when you hit in and is, since they're considered relational as well.

>>> 1 < 2 in [True, False]
>>> 1 < 2 in [2, 4]
share|improve this answer
add comment

J evaluates statements right-to-left so that:

3 > 2 > 1

Becomes first

2 > 1

Which resolves to true, represented as 1, thus:

3 > 1

Which also resolves to true, thus 1. The opposite operator < would result in false, whereas the whole statement happens to be true. So you're no further with J.

Your main issue is that your initial representation:

3 > 2 > 1

is human shorthand for

(3 > 2) AND (2 > 1)

So while reading ahead seems icky, it's really what the representation needs. Unless of course there's some Python magic, as others have stated.

share|improve this answer
add comment

Your Answer


