Crystal: Auto infer type for union

Created on 15 Nov 2019  Â·  6Comments  Â·  Source: crystal-lang/crystal

Based from my StackOverFlow question

When I use a type union in Crystal with String and Int32, and then I assigned a value to it , it works fine

test : (String | Int32) = 100
puts "Hello, World! #{test}"

Resulting

~/Projects/learn-crystal î‚° crystal hello.cr
Hello, World! 100

But, when I change the Int32 to UInt32, it will become an error

test : (String | UInt32) = 100
puts "Hello, World! #{test}"

Resulting

~/Projects/learn-crystal î‚° crystal hello.cr
Showing last frame. Use --error-trace for full trace.

In hello.cr:1:1

 1 | test : (String | UInt32) = 100
     ^---
Error: type must be (String | UInt32), not Int32

But this works fine though

test : (String | UInt32) = 100_u32
puts "Hello, World! #{test}"

Resulting

~/Projects/learn-crystal î‚° crystal hello.cr
Hello, World! 100

I think Crystal should be able to infer the number type is UInt32 because it's the only one integer type member.

feature topicsemantic

All 6 comments

test: (Int64 | Int32) = 1 # Int64

That's not going to happen. If there's ambiguity it won't be assigned. It's on the left side for you as a human but the compiler will sort things in a different way. And in any case it's not intuitive that one of them (the leftmost, the rightmost) is picked. Same as if there are multiple possibilities in different overloads it will result in a compile error.

This is actually a bit hard to implement, so for now I won't do it (and I might actually never do it, I don't feel it's a very compelling use case).

Definitely odd that you can do test : UInt32 = 100 but not test : (String | UInt32) = 100 .. FWIW :)

I understand that it's odd. The challenges relay on doing only 1 conversion vs traversing all the possible combinations. And the 1 conversion that is done is more syntactic than semantic.

If the logic becomes more complex there might be even ambiguity and it is better not to force a decision.

This is a case where the example shows a scenario where everybody will agree. But, for example, if the union was floats and ints, neither matching the literal, the expected result is not clear. @andraantariksa for example weight that the order of the union matters, but I for a start don't think so :-), hence the expectation is not the same for everybody.

OK that makes more sense. Yeah if there's ambiguity best to force them to be explicit :)

@rdp I think you're correct. Crystal should return compile error if there's an ambiguity and force the people to be explicit.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lgphp picture lgphp  Â·  3Comments

jhass picture jhass  Â·  3Comments

asterite picture asterite  Â·  3Comments

RX14 picture RX14  Â·  3Comments

pbrusco picture pbrusco  Â·  3Comments