2

While writing a Perl statement like if ( $foo >= X && $foo <= Y ) yet again, I wondered why many programming languages do not support the more comfortable form if ( X <= $foo <= Y ) and what this is called. I came up with "3-legged comparison" but no results when searching for it. By the way there is also the "element-of-set" form if ( $foo in X..Y ) which I only consider more readable when provided via a short keyword.

Is there a term for X <= $foo <= Y comparison? Which languages support it?

3
  • 3
  • 1
    Thanks @dan04. In this question it's called "chained comparison operator" with Perl 6, Python, Mathematica, BCPL, and Icon mentioned.
    – Jakob
    Aug 27, 2012 at 8:17
  • most lisps would support that with as many arguments as you want. ie. (<= 3 foo bar 6)
    – WuHoUnited
    Aug 27, 2012 at 20:52

5 Answers 5

8

I'd call it an n-ary comparison.

Operators that work on arbitrary numbers of operands are called "n-ary" operators:

n-ary

From a mathematical point of view, a function of n arguments can always be considered as a function of one single argument which is an element of some product space. However, it may be convenient for notation to consider n-ary functions, ...

The same is true for programming languages, where functions taking several arguments could always be defined as functions taking a single argument of some composite type such as a tuple, or in languages with higher-order functions, by currying.

  • Binary means 2-ary.
  • ...
  • n-ary means n operands (or parameters), but is often used as a synonym of "polyadic".

Python has an n-ary < operator. Section 5.6 of the language docs says:

Unlike C, all comparison operations in Python have the same priority, which is lower than that of any arithmetic, shifting or bitwise operation. Also unlike C, expressions like a < b < c have the interpretation that is conventional in mathematics:

Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.

10

SQL has a native bounds/range check operator:

SELECT * FROM foo WHERE foo.bar BETWEEN 1 AND 100

Checking whether a value is within a certain range makes sense in SQL due to the algebraic nature of relational databases.

When it comes to programming languages though, there's an order of operations and ( X <= $foo <= Y ) would normally be interpreted as ( ( X <= $foo ) <= Y ) ), which is a quite different than ( $foo >= X && $foo <= Y ). To get a sweet & simple range check operator we would have to tell the parser to ignore the order of operations for this very specific case, and that would go against the principle of least astonishment.

Not worth the trouble and the potential confusion for something that's of extremely little benefit, just syntactic sugar really. If you find yourself doing range checks very often and don't care for typing a few extra characters, you can always write a short function to take care of the comparisons for you.

1
  • I can see the benefit. It's not just syntactic sugar or readability, it's also more straightforward in terms of program logic if $foo is a complicated expression rather than a simple var. To avoid doing the calculation twice, or having side-effects twice, you have to do the calculation first, put it in a variable and then check the variable against both boundaries. With a "between" operator, you wouldn't have to.
    – Mr Lister
    Aug 27, 2012 at 6:29
2

Most PLC languages include some kind of instruction that does this. In RSLogix it's called the LIM instruction (see pg 3-5). It takes 3 inputs: a Low Lim, Test, and High Lim value and returns a true/false output.

Note that you can provide parameters where Low Lim is higher than High Lim then it changes to an OR condition. That is, the output is true if the input is higher than Low Lim OR lower than High Lim. This makes sense when you consider many times you might have a 12 or 16-bit encoder on a rotary axis so the value zero is adjacent to the highest possible value.

Also, other languages, e.g. TwinCAT, have a LIMIT instruction that outputs a coerced value instead of a boolean. That is, its purpose is to give you an output within the specified limits, or one of the limits themselves if the input is outside the specified limits. I believe this function is similar to the saturation function in Matlab/Simulink.

In both cases you could just create your own function to do this from the available primitives, so I can see why including such an operator might be considered superfluous.

1

In languages like C, a < b < c is compiled as

  (a<b) < c  
  a<b evaluates to 0 or 1, so you end up executing 
  (1 < c) or (0 < c)

which is almost certainly not what you want.

In languages less brain damaged than C, you can be saved by the type system, because (a < b) returns true or false, and (false < c) is not a valid expression.

I can't think offhand of any languages that implement this ternary operator the way you expect, but it would be dangerous to use it if it exists, if only because so many other languages will screw you.

1
  • 4
    Python does. 1 < 2 < 3 == True, but 1 < 4 < 3 == False. Aug 27, 2012 at 20:07
1

In english it's called "between inclusive".

Microsoft's T-SQL gives special syntax for it

select * from User where Age between 18 and 25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.