V version: V full version: V 0.1.29 35a8346.30588e4
OS: linux, Debian GNU/Linux 9.13 (stretch) (VM)
What did you do?
$ cat microkanren-buggy2.v
// Steve Phillips / elimisteve
// 2020.10.05
module main
type Var = int | string
fn main() {
println(is_num(5))
println(is_num('Hello'))
}
fn is_num(v Var) bool {
match v {
int { return true }
else { return false }
}
}
$ v run microkanren-buggy2.v
What did you expect to see?
5
Hello
What did you see instead?
$ v run microkanren-buggy2.v
microkanren-buggy2.v:8:10: error: cannot use type `any_int` as type `Var` in argument 1 to `is_num`
6 |
7 | fn main() {
8 | println(is_num(5))
| ~~~~~~~~~
9 | println(is_num('Hello'))
10 | }
I'll note that this works for strings just fine; so far I just see ints as problematic when combined with sum types in this way.
If you explicitly type cast it to int i.e. do println(is_num(int(5))) then it will work.
As far as I know, the reason why this fails/hasn't been fixed yet is because of this case:
type Var = u16 | u64
fn is_num(v Var) bool {
match v {
u16 { return true }
else { return false }
}
}
println(is_num(5))
Should that print true or false? There is no way to tell unless you explicitly cast the literal into either type.
I guess one option would be automatically making literals int if that's a valid subtype, and require an explicit cast otherwise
@Delta456 Yes, or doing
five := 5
println(is_num(five))
also works, thanks... but this is still a bug :slightly_smiling_face: .
@spaceface777 Good point, and yes that sounds good.
I guess one option would be automatically making literals int if that's a valid subtype, and require an explicit cast otherwise
I think if an integer literal could be more than one of a sum type's elements, then it should require a cast. If there's only one possible element match then it should work without a cast.
Speaking with @danieldaeschle about potential fixes for this issue (and #6748), we came up with the following solution:
- if the only integer subtype of a sumtype is
int(or if the only float subtype of a sumtype isf64), then cast literals to those types automatically- if not, require a cast, and show a better error message (i.e. "error: sumtype has multiple integer variants, please cast the literal to a specific integer type")
We thought it would offer a nice balance between convenience and explicitness, any suggestions?
@spaceface777 Sounds perfect :+1:
Most helpful comment
As far as I know, the reason why this fails/hasn't been fixed yet is because of this case:
Should that print true or false? There is no way to tell unless you explicitly cast the literal into either type.
I guess one option would be automatically making literals
intif that's a valid subtype, and require an explicit cast otherwise