Relational calculations are used to compare whether two values have a specific relation to each other or not. For example, an <<<Equality>>> check is a relational calculation and checks if two values are equal to each other. Simorg uses familiar operators to perform relational calculations BUT with a fundamentally different approach.
As you saw so far, data is the king. Now, relational operators are another proof of this fact. In CPLs, when a relational expression succeeds, the result falls back either to a <<<true>>> or <<<false>>> value. Leaving the philosophical aspects of this wrong behavior aside, this usually causes extra effort for engineers. Of course in many use cases the implicit behavior kicks in, reducing the effort, but it is still not quite the right decision.
The above behavior is no longer the case in simorg. When a relational expression is used, the result is no longer a boolean value (as you know simorg even doesn't have this type) but the data itself that triggers the expression.
All relational operators will return a value as soon as they are able to vibrate—meaning as soon as the operands are available. The result is always the left-hand side operand which is the subject of the expression. The right-hand side operand is the object which is being checked against.
All relational operators are binary, meaning they need an operand.
If for any reason the operator is not able to execute, for example, when an operand is holding an invalid data type, then the operator will never vibrate and there will be an <<<Error>>> or <<<Warning>>> log depending on the severity of the case.
Equality Check
The equality check operator <<<=>>> is a quite useful relational operator. It is used to check whether two values are equal or not.
Simorg is not using the classical assignment operator <<<=>>> as data itself is flowing and it doesn't need manual assignment hence <<<=>>> operator is embracing back its mathematical beauty and acting as expected.
When it comes to numbers, simorg's equality check follows implicit data rules, meaning a value of <<<1>>> is considered equal to <<<1.0>>>, and <<<10=10.0>>>.
Values which represent emptiness are not considered equal. So <<<0x>>> which represents empty <<<buffer>>> is not equal to <<<"">>> which represents empty string. There will be no vibration and a warning log will be registered by engine.
Also, a <<<string>>> value of <<<"1">>> is not equal to a numeric value of <<<1>>> and the same is true about a buffer value of <<<0x01>>> which is not equal to either one of them. Primitive variable types are respected. Although a warning will be logged by the engine if this happens. Please refer to the engine logs chapter for a more detailed list.
If you need any different behavior, it's always a good idea to check plugin artifacts for more advanced behaviors dedicated to specific use cases. For example, if the string conversion logic is needed then the <<<string>>> plugin can be used.
20 = 20 $x
x? // 20
20 = 10 $y
y? // will never vibrate
Using the <<<!>>> operator instead of <<<=>>> performs a not-equal check,
20 ! 10 $x
x? // 20
20 ! 20 $y
y? // will never vibrate
Equality check of two <<<string>>> values will only pass if they are completely equal, including character casing.
Equality check of two <<<buffer>>> values will only pass if they are exactly the same, byte by byte.
Now, finally, let's talk about the concept of <<<subject>>> and <<<object>>>. This fact applies to all relational operators. From left to right the incoming data is considered <<<subject>>> and the operand is considered <<<object>>>. So if the condition holds true, then the subject passes through the expression.
It is important to remember always subject is the driver, lets see the following example,
[1;2;3] $x
2 $y
x > y ? // will log only 3
But by switching them,
[1;2;3] $x
2 $y
y > x ? // will log only 2
The reason is simple, relational operator will be executed as soon as both subject and object are available. In first example our operator runs three times but in second example it only runs once because the subject is vibrating only once. This is enough to log <<<2>>> because according to <<<XOR>>> the first vibration is <<<1>>> and the relation holds true so passing <<<2>>>.
Comparison
Use it to compare the relation between numbers. Passing <<<buffer>>> or <<<string>>> values will lead to an <<<INVALID_ARGUMENT>>> error log.
Greater than
Checks if a number is greater than another one.
20 > 10 $x
x? // 20
20 > 20 $y
y? // will never vibrate
To check equality at the same time:
10 >= 10 $x
x? // 10
Less than
Checks if a number is less than another one.
20 < 10 $x
x? // will never vibrate
20 <= 20 $y
y? // 20