json-logic
json-logic copied to clipboard
Null >= 0 weird behavior
When comparing null values to 0 with the >=
operator , I get the following result:
{">=" : [null,0]} //result is true
However, these operators yield the results:
{">" : [null,0]} //result is false
{"==" : [null,0]} // result is false
{"===" : [null,0]} // result is false
I would expect the result of {">=" : [null,0]}
to be false as well, is there any reason that it is not the case?
(null >= 0) === true
in both JavaScript and PHP (the two reference languages I was worried about when I started writing JsonLogic).
In fact, both the implementations I maintain just use the language behavior without any checks around it.
There are other places we've decided to forge a brand "JsonLogic way" -- especially Truthy and Falsy. http://jsonlogic.com/truthy.html Arguably we could do the same thing for null behavior, but I think you're the first person to ask about it.
Interestingly, PHP and JavaScript disagree on whether null == 0
(PHP says true, JS says false) which means in some cases JsonLogic isn't as portable as I'd like.
I don't think that this behavior is logically consistent. null
represents an absence of a value and not 0
or true/false
, so when comparing I would expect that nothing is == null
except for null == null
.
Making a decision on this is much better then depending on quirks of the language to determine the result.
Yep, this just bit me aswell:
{ "<=": [ null, 1 ] } // returns true
{ "<=": [ "", 1 ] } // returns true
I've fixed it (for my application, might not work for yours) by checking the value too (and making an exemption for 0
, since the number is falsy), e.g.
{
"if": [
{ "===": [ { "var": "data" }, 0 ] },
{ "<=": [ { "var": "data" }, 5 ] }, // true
{ "and": [ // false
{ "!!": [ { "var": "data" }, true ] },
{ "<=": [ { "var": "data" }, 5 ] } // same rule as when the if was true
]
}
]
}
Data:
{
"data": 0 // any number <= 5
}
Well, there has been some heat in other places around building type-safe language implementations, where { "<=": [ null, 1 ] }
would throw a runtime error instead of bumbling along. I think it would be popular, but I don't think it should crowd out type-agnostic implementations entirely.
I'm struggling to come up with a "successful" example JL could look up to. We could make null "infectious" so every comparison with null returns null... I think this is SQL's answer to the problem, and it has the virtue of being self-consistent. https://dev.mysql.com/doc/refman/8.0/en/working-with-null.html
That way we don't have to write a giant comparison matrix (is null greater than or equal to an object with no properties?)