Ticket Created
over 2 years ago

CIQQA-1383

New type checker doesn't allow comparisons between unknown types

I'm currently validating boolean config settings by comparing the result against true. If the config is a boolean (as it should be) its a no-op, it just converts false and true to themselves. If the config contains any other type (which actually seems to happen) it converts it to false.

so basically:

var sanitized = Application.Properties.getValue("foo") == true;

and the type checker errors out

Cannot perform operation 'eq' on types 'PolyType<Null or $.Toybox.Lang.Object>' and '$.Toybox.Lang.Boolean'.

This doesn't really make sense. You can compare any two types (and the runtime supports doing so). If their types are the same, then they might compare equal. Otherwise they shouldn't. I don't want to have to check "instanceof Boolean &&" for code size reasons. Its already a shame that I can't rely on Properties having their declared types, but I've seen instances where it happens, so now I validate everything.

  • "Right, and I already agreed with you on that point."

    Sorry, I typed that comment before I saw your comment lol. That's what I get for typing long comments.

  • I would disagree here. If the type checker *knows* for sure that two types don't overlap

    Right, and I already agreed with you on that point. But this *absolutely is not* one of those cases. The comparison *might* be true and it might not. the type checker has no information whatsoever about the result. Otoh, the type checker (should) be absolutely certain that the result is a Boolean, and that the expression won't produce an error at runtime. So it *should* accept it.

  • "In the world of Monkey C Types, Bob's statement is absurd because he should have said "If it's a fruit, is it an apple?" But everyone else would understand what he meant."

    To be more accurate, in Monkey C, Bob has to say "Is it a fruit and an apple?"

  • "There is nothing incorrect about comparing null and true for equality. They're not equal. And there's nothing incorrect about comparing *any* two things for equality."

    I would disagree here. If the type checker *knows* for sure that two types don't overlap, then it's beneficial to return an error or warning. We can see this in languages like Java and C#, and in the typescript linter.

    However, in this case we have two values with *overlapping types*, so there should be nothing wrong with comparing them.

    Alice: "You're going to get a fruit or a vegetable for dessert".

    Bob: "Is it an apple?"

    In the world of Monkey C Types, Bob's statement is absurd because he should have said "If it's a fruit, is it an apple?" But everyone else would understand what he meant.

    OTOH:

    Alice: "You're going to get a vegetable for dessert".

    Bob: "Is it an apple?"

    We can say that Bob's statement is absurd in this case, assuming both of them know that an apple is not a vegetable.

  • The code isn't literally null == true, it's x == true, where x *may* be null

    Right. I accept that telling me that my comparison is an error because it will *always* be false or it will *always* be true isn't and unreasonable thing for a type checker to do. It can sometimes be annoying, but its generally good because it forces me to remove redundant code (its annoying when I'm preserving the code structure for potential future changes, or for debugging etc).

    But, as you said, this *isn't* that case. The comparison could return true or false at runtime, and its the most efficient way to get that true or false value.

    This is pretty clearly a mistake in the type checker (eg it makes sense for <, <=, >=, >, and someone probably got overzealous without thinking it through).