Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Chained inequality notation in programming languages

Is there a programming language that supports chained notation a < b < c to be used instead of a < b and b < c in conditional statements?

Example:

  1. if ( 2 < x < 5 )
  2. if ( 2 < x && x < 5 )

First statementlooks better to me, it's easier to understand and the compiler could use transitivity property to warn about mistakes (e.g. 5 < x < 2 would give a warning).

like image 898
Davorin Avatar asked Apr 15 '10 09:04

Davorin


3 Answers

Python does that.

like image 161
R. Martinho Fernandes Avatar answered Oct 22 '22 00:10

R. Martinho Fernandes


Icon does this, and it is not part of any hacky special-case "chaining"; it is part of Icon's goal-directed evaluation model. Any comparison either succeeds or fails. If it succeeds, it produces the right-hand side. So you can write

if 0 <= i <= j < n then ...

and it works exactly the way you would expect. But it works not just for comparisons but for any expression; this means you can write your own functions that "chain" in exactly the same way. I love this aspect of Icon and wish more languages could incorporate goal-directed evaluation.

N.B. In Guido's paper introducing Python at VHLL (middle 1990s) he mentions Icon explicitly as a source of inspiration in the design of Python.

like image 37
Norman Ramsey Avatar answered Oct 21 '22 22:10

Norman Ramsey


This sounds like a simple request (and clearly it is simple enough that python implemented it) but it is not necessarily that easy to use. It actually opens up the ability for a lot of errors to be caused.

Specifically, any time that you use functions (or properties in the case of C#, Getters for Java)

So

public int GetX()
{
   return 4;
}

(2 < GetX() < 5);

(2 < GetX() > 5);

(5 < GetX() < 2);

Seems like it would be really simple. But problems occur if GetX() has side effects.

private int val = 10;

public int GetCountdown()
{
   return val--;
}

(2 < GetCountdown() < 5);

(2 < GetCountdown() > 5);

(5 < GetCountdown() < 2);

In this situation, is "GetCountdown()" decremented twice or just once? Would the "chained-if-statement" ever shortcut?

Consider the last statments, which roughly evaluates (in english) to "Is 5 less than some value which is less than 2) which should be impossible, but depending on the implementation and side effects, it is possible that some function (Random.NextInt()) could pass both of those tests.

So, for that reason, it would be required that each of the items is only evaluated once, the saved into a local variable for the next comparison. But then you get into shortcutting problems.

public int GetOne()
{
   return 1;
}

public int GetVar()
{
   return -1;
}

(GetOne() < GetVar() < GetDBVal() < GetUserInput())

Generally, you would want to first check constants and variables before doing a database hit. But if we said (as we said earlier) that all the values must be saved into local variables ahead of time, this means that it might be calling a database hit, and asking the user for information even though "GetVar()" is -1, and so the first comparison fails)

As I said earlier, clearly Python allows this syntax, so it is clearly possible. But, regardless of the technical implications which I have laid out (all of which are easy to design around) it means that your code is less clear because the next person who reads it does not know whether or not you have considered all of this. Whereas, if(x > 2 && x < 5) { } seems clear to me, I know what it does, and I know what the coder intends.

like image 4
DevinB Avatar answered Oct 22 '22 00:10

DevinB