Implement safe enums: literals + poly variants gen#152
Conversation
585f7c0 to
a0e4290
Compare
96028b2 to
9f6da16
Compare
6bdb6e6 to
f852e72
Compare
|
Why need new syntax? we know from type that enum is expected. |
because type inference is based on syntax itself. much of the simplicity of the hm for example type system is that it allows types to be automatically inferred from syntax. in this case when we don't have special syntax we make our
got it |
|
take for example SELECT .. FROM .. WHERE enum_field = 'A'in this case I test the left side of the binary operator for the field type, this is a later stage then SELECT .. FROM .. WHERE enum_field = SPECIAL_SYNTAX_'A'but if you insist I can do it this way checking the left part and the contents each time |
|
special syntax is definitely not a requirement by HM |
178710e to
06df0c8
Compare
06df0c8 to
77e4db1
Compare
82c6bf7 to
fded51e
Compare
|
@ygrek I considered your comment, it now doesn't require writing special syntax for the user it's regular strings. I am going to merge it, I will back and fix if there are any other comments |
Description
This PR introduces two main enums related features:
1. String Literal Types and Unions
The primary feature is that any string literal now has a StringLiteral type. When used in expressions like:
or any other cases where
StringLiteralcan accept multiple values, the type will be inferred as a Union.There are two types of Unions:
Open Union (resulting from combining StringLiterals or other Unions)
Closed Union (literal/Enum)
The relationships between these types can be seen here
Also check tests
This PR adds a new flag
type-safe-enums(name is negotiable). When this flag is enabled parameters to enum fields and enum literals (new syntax too) now are checked.Type Inference and Subtyping Example
Enum Type Inference
In this case, the matching values are inferred as:
StringLiteral 'A'
StringLiteral 'B'
StringLiteral 'C'
These are then combined into an enum type A | B | C. The system verifies that this enum is either the same type as or a subtype of the closed enum A | B | C
Subtyping Rules
For example, this would be valid:
@param3 { A { 'A' } | B { 'B' } }Because A | B is a valid subtype of A | B | C - you can safely write a value of type A | B where A | B | C is expected.
String Operations and Type Coercion
String operations work naturally:
This is valid because Enum is a subtype of Text, so the enum value is automatically coerced to text. The reverse operation (text to enum) is not allowed.
Here's a complete example demonstrating insertion with string concatenation:
This will fail type checking because:
col3 expects an enum of type A | B | C
CONCAT() produces a Text type
You cannot assign a Text value to an enum field - even if the text matches one of the enum variants (like 'A', 'B', or 'C')
2. Optional and flag-controlled. It adds the ability to generate polymorphic variants when a parameter is inferred as an enum.
Let's make an example.
DDL:
Example (flag is disabled)
Here nothing is changed
This is what is generated
Example (flag is enabled)
This is the result