json-logic icon indicating copy to clipboard operation
json-logic copied to clipboard

Null >= 0 weird behavior

Open kph21 opened this issue 5 years ago • 4 comments

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?

kph21 avatar Dec 27 '18 09:12 kph21

(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.

jwadhams avatar Dec 27 '18 16:12 jwadhams

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.

TonyXi avatar Feb 04 '19 19:02 TonyXi

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
}

gerwim avatar Jan 18 '22 00:01 gerwim

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?)

jwadhams avatar Jan 18 '22 15:01 jwadhams