language-design

How can I implement Chained Comparison Operator support for my Programming Language?


To begin with, my programming language, named Ignite, is a transpiled programming language and translates the Ignite Source File to a C++ source file.

Chained Comparison Operator is when you have comparison operators (such as <=, !=, >, etc.) that are chained together, meaning that multiple of these operators are used in a single expression without introducing other logical operators to separate them. One example would be: x < y < z.

The question is what black magic do I perform to interpret this expression as a valid expression in C++ IN a way that it aligns with Mathematics?

As of Python, it just simply adds an AND expression in between chained operators, so x < y < z would become x < y && y < z. It works good for simple cases as this one. My initial thought was to allow only one comparison operator at a time, so if you used < for first operator in the chain, you have to use only < in the proceeding ones in the chain. But this is not ideal because you can have this expression x < y <= z as a valid Mathematical expression.

Okay... then if I allow mixing operators, x < y > z is a valid operator chain but has no meaning in Mathematics (correct me if I am wrong). And this will be interpreted as x < y && y > z.

But what if you have expression as x != y != z? This is a valid Mathematical expression that says "x, y and z are not equal to each other". But interpreting it as x != y && y != z would not be best description, as x could still equal z.

What I have came up with is to interpret it as x != y && x != z && x != z, as comparing all the variables with all the others except itself. This works well when you have same type of operator. But quickly becomes problem for x < y <= z. Which of the two (< or <=) would you use to compare x with z when interpreting?

So I have gone ahead and use both of the two operators and OR them, so it would interpret it as x < y && (x < z || x <= z) && y <= z. But now what if you have a valid Mathematical expression x == y == z != 1 which means "x, y and z are all equal but not equal to 1". Using my logic would result in expression x == y && x == z && (x == 1 || x != 1) && y == z && (y == 1 || y != 1) && z != 1... Thinking about it, it works... but is there a better way of doing it?

Thanks.


Solution

  • Simplicity is a feature for a programmation language and I think supporting all the expressions from your question is a level of complexity you do not want.

    As was demonstrated in comments, expression such as x != y != z does not make it obvious if x != z and the reason why it is not obvious is that!= is not a transitive relation.

    What I would recommend to you is:

    1. Only allow to chain operators a <op> b <op> c if it implies a <op> c.
      The operators <op> do not need to be the same BTW, for instance, from a < b = c <= d, you can deduce something for all the pairs of variables:
    1. For the case x < y > z where you mix operators you shouldn't, according to the above, there may be a smarter syntax to support the case.
      The proposed syntax is x, z < y.

    At the end of the day, you could allow some subtle expressions such as: