teal-language / tl

The compiler for Teal, a typed dialect of Lua
MIT License
2.02k stars 101 forks source link

union type is not inferred with ternary op #705

Closed fperrad closed 8 months ago

fperrad commented 8 months ago
local function foo(f: boolean)
    local bar: integer|string = f and 42 or 'Bar'  -- explicit union type
    io.write(bar, "\n")
    local baz = f and 42 or 'Bar'  -- ERROR: cannot use operator 'or' for types integer and string 'Bar'
    io.write(baz, "\n")
    local baZ = f and 2.718 or 3.14  -- inferred (same type)
    io.write(baZ * baZ, "\n")
end

foo(true)
hishamhm commented 8 months ago

That was by design. Inferring complex types can lead to hard-to-understand error messages. Expressions joining incompatible types are more often a mistake (e.g. an unfinished refactor) than an intended union. If we infer the union in cases where it was a mistake, the user gets a cryptic error message involving union types in the place where the variable is used, even though the user did not intend to use a union anywhere in their code. This gets even more unwieldy if the types "compound".

Basically, the stronger your inference engine is, the worse your error messages are. (See Haskell for a language that goes all the way in the inference direction.) I'm trying to strike a balance between those two needs in language design. Perhaps we could expand the error message to suggest an explicit union if that's the programmer's intention.

fperrad commented 8 months ago

makes sense.

hishamhm commented 8 months ago

@fperrad I've added a warning!