I've got some requests for enhancements to the handling of covariance. Here's a method header in a supertype:
Obj? get(Obj coords)
In a subtype, if I say this:
override Float? get(Obj coords)
I get this error:
Cannot use covariance with value types 'math::Mat.get' - 'sys::Obj?' != 'sys::Float?'
If I say this:
override Obj get(Obj coords)
I get this error:
Return type mismatch in override of 'math::Mat.get' - 'sys::Obj?' != 'sys::Obj'
Side note, what I really want to see here is this:
override Float get(Obj coords)
That presumably hits both of my problems indicated above.
At some level, I think keep the abstract view consistent is more important than filtering up the implementation details, and I think that's what's happening here with the value types issue. Obviously, unless you secretly generate two methods, one performing boxing and the other not, you will obviously have to box the Float as an Obj, but I think that's okay. In the nullable case (first example above), you would need to box anyway, so I'm not sure what the issue is. But whether nullable or not, I think Float should be an acceptable subtype of Obj for covariance purposes. Keeps the type system consistent, I think. Everything still (almost) is just an object, even if it gets optimized in some cases.
Concerning Obj as a subtype of Obj?, I very much recommend supporting that. Basically, Obj is the same set of possible values except for null. This would also mean (for example) that Str is a subtype of Obj?, but Str? is not a subtype of Obj (since null is not a member of Obj).
brianWed 27 May 2009
Promoted to ticket #611 and assigned to brian
I think this makes sense. Covariance came before value-types and nullable types, and I wasn't sure exactly what to do with those, so I just punted.
But I agree the method covariance rules should be:
Value types can override Obj or Obj?
Int/Float types can override Num or Num?
Non-nullable can override a nullable type
In all cases the override is returning a more restricted type than the super-class.
tompalmerWed 27 May 2009
Sounds great.
geoSat 30 Jun 2012
Are there any plans to support covariance with value types?
i.e. Int overriding a return type of Obj
SlimerDudeTue 19 Mar 2013
Just to say I just bumped into this myself:
class A {
virtual Obj cow() { return 6 }
}
class B : A {
override Int cow() { return 9 }
}
gives
Cannot use covariance with value types 'wotever::A.cow' - 'sys::Obj' != 'sys::Int'
As we don't have generics, overriding a return type with a more restricted type would be really useful.
brianWed 20 Mar 2013
As we don't have generics, overriding a return type with a more restricted type would be really useful.
Just to be clear Fantom does support covariance. However it does not handle the special value types Bool, Int, Float since those aren't returned as objects in the JVM.
SlimerDudeWed 20 Mar 2013
So it does, cool!
The trap I fell into was with using inconsistent nullable types:
class Val { }
class A {
virtual Obj? cow() { return Val() }
}
class B : A {
override Val cow() { return Val() }
}
gives
Return type mismatch in override of 'wotever::A.cow' - 'sys::Obj?' != 'wotever::Val'
which I took to mean covariance wasn't supported.
But having cow() return Val? works just fine:
class B : A {
override Val? cow() { return Val() }
}
Would it be possible to make the error message more explicit?
tompalmer Tue 26 May 2009
I've got some requests for enhancements to the handling of covariance. Here's a method header in a supertype:
In a subtype, if I say this:
I get this error:
If I say this:
I get this error:
Side note, what I really want to see here is this:
That presumably hits both of my problems indicated above.
At some level, I think keep the abstract view consistent is more important than filtering up the implementation details, and I think that's what's happening here with the value types issue. Obviously, unless you secretly generate two methods, one performing boxing and the other not, you will obviously have to box the Float as an Obj, but I think that's okay. In the nullable case (first example above), you would need to box anyway, so I'm not sure what the issue is. But whether nullable or not, I think Float should be an acceptable subtype of Obj for covariance purposes. Keeps the type system consistent, I think. Everything still (almost) is just an object, even if it gets optimized in some cases.
Concerning
Obj
as a subtype ofObj?
, I very much recommend supporting that. Basically,Obj
is the same set of possible values except fornull
. This would also mean (for example) thatStr
is a subtype ofObj?
, butStr?
is not a subtype ofObj
(since null is not a member ofObj
).brian Wed 27 May 2009
Promoted to ticket #611 and assigned to brian
I think this makes sense. Covariance came before value-types and nullable types, and I wasn't sure exactly what to do with those, so I just punted.
But I agree the method covariance rules should be:
In all cases the override is returning a more restricted type than the super-class.
tompalmer Wed 27 May 2009
Sounds great.
geo Sat 30 Jun 2012
Are there any plans to support covariance with value types?
i.e.
Int
overriding a return type ofObj
SlimerDude Tue 19 Mar 2013
Just to say I just bumped into this myself:
gives
As we don't have generics, overriding a return type with a more restricted type would be really useful.
brian Wed 20 Mar 2013
Just to be clear Fantom does support covariance. However it does not handle the special value types Bool, Int, Float since those aren't returned as objects in the JVM.
SlimerDude Wed 20 Mar 2013
So it does, cool!
The trap I fell into was with using inconsistent nullable types:
gives
which I took to mean covariance wasn't supported.
But having
cow()
returnVal?
works just fine:Would it be possible to make the error message more explicit?