I think there are many use cases that are hard to represent using the current type hierarchy, and changing it would be a very good opportunity to try and address as much of that as possible, while staying as compatible as possible with current code. It seems to me to be quite a big feat so it would probably be smart not to rush it.
That said, while having the full power of newtype
in opaque types would be extremely useful, especially when it comes to IArray
and similar use cases, they are already very useful despite the weaknesses.
For example, many of the use cases in Haskell export the constructor/destructor. This is used all the time to make it possible to safely define multiple given instances. A notable example of this is Monoid:
https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Monoid.html
This use case fits perfectly with opaque types, and isn’t at all diminished by morally dubious pattern matching:
I think the problem of code downcasting from Any
breaking in the future could be solved quite cleanly:
- Even with the addition of
Top
as a supertype ofAny
, opaque types with an upper bound that is a subtype ofAny
will still have the problems described above. One solution to this could be to already now disallow downcasts to opaque types. That way, opaque types can still be converted into the underlying type viaAny
, but not the other way around. Then when the opaque type is changed to haveTop
as it’s upper bound, it will no longer be possible to cast it toAny
. - If in the future someone wants morally dubious type conversions to be possible, they can use
Any
as the upper bound explicitly.
Not allowing downcasting to an opaque type also fits quite nicely with the fact that usually if I define an
opaque type MySpecialBox <: Box = Box
I probably don’t want someone to downcast from any Box
to MySpecialBox
. If on the other hand I have:
opaque type Boxish <: AnyRef = Box
I really see no way to prevent someone from turning something Boxish
into a Box
. A Top
type doesn’t help at all. The only way to prevent that would be by restricting typed patterns quite radically, which would be an interesting move, but probably a bit too extreme. Actually @odersky, do you have an idea of how hard it would be to require a TypeTest
instance for all pattern matching?
TL;DR:
- Opaques are great, they will be even better with
Top
- Considering adding any kind of sugar like
case opaque type
should wait until we haveTop
- Downcasting to opaque types should be illegal (unless using the-method-which-should-not-be-named)
- Let users worry about the other direction until we have
Top