Since the rule engine is supposed to be as correct as possible, and it might be configured by someone who doesn't know the idiosyncrasies JS (even if they might have some programming knowledge), I think the evaluator (at least by default, if we want to make it configurable) should use a 'high strict mode', which would differ in the following:
== and != are equivalent to === and !== respectively
The weird behaviour of == and != with their implicit casting makes predicting what will happen not easy (which is very bad for a rules engine)
If a user wanted to compare numbers and strings for value, then simply providing Number() and String() would make the expression more explicit and less error-prone
It would also allow us to check that the strings actually represent a valid number, since otherwise this error would be suppressed and bypassed
To keep to a subset as closely as possible, === and !== would still be available (but do the same thing)
This should be considered further if it's the right approach
The alternative could be to simply ban the operators instead, and only allow === and !==
All mathematical operations can only be done on numbers
+, -, *, /, %
This prevents errors around the weird inconsistencies between them
+ will concatenate numbers to strings, but * will try to cast the string to a number
Bitwise operators can only be done on numbers
&, |, ^, ~
Similar reasoning as above
Cardinality comparison operators can only be done on numbers
<, <=, >, >=
Similar reasoning as above
Some examples of the weirdness with the default behaviour (all of them return true):
'0o432' >= 0
'0o144' == 100
'0o145' > 100
'0x100' > 100
I think there might be more things to restrict, but these are the primary ones.
Since the rule engine is supposed to be as correct as possible, and it might be configured by someone who doesn't know the idiosyncrasies JS (even if they might have some programming knowledge), I think the evaluator (at least by default, if we want to make it configurable) should use a 'high strict mode', which would differ in the following:
==
and!=
are equivalent to===
and!==
respectively==
and!=
with their implicit casting makes predicting what will happen not easy (which is very bad for a rules engine)Number()
andString()
would make the expression more explicit and less error-prone===
and!==
would still be available (but do the same thing)===
and!==
+
,-
,*
,/
,%
+
will concatenate numbers to strings, but*
will try to cast the string to a number&
,|
,^
,~
<
,<=
,>
,>=
'0o432' >= 0
'0o144' == 100
'0o145' > 100
'0x100' > 100
I think there might be more things to restrict, but these are the primary ones.