virtual types
See original GitHub issueToday I decided to waste some time experimenting with virtual types, which is something we’ve discussed often before. A virtual type is a formal
member alias
belonging to a class or interface, that is refined and assigned a value by concrete subclasses. For example:
interface Foo {
shared formal alias Type;
shared formal Type val;
shared [Type] getIt() => [val];
shared void takeIt(Type it) {}
}
class Bar() satisfies Foo {
shared actual alias Type => String;
val = "hello";
shared void useIt() {
print("got: " + getIt().first);
takeIt(val);
}
}
Now, this is strictly less powerful than parametric polymorphism, since we don’t have a syntax for expressing refinements, e.g. something like what Scala has, approximately Foo { Type=>String; }
. So, when referring to plain Foo
, we get a wild-carded Type
, analogous to Foo<out Anything>
with generics.
On the other hand, looking at some of the code in ceylon-ide-common
, it strikes me that this could be a more convenient syntax to handle what look like type families we have going on there.
Anyway, after some experimentation, it doesn’t look completely trivial from a typechecker / model point of view. But it’s certainly not impossible. OTOH, I’m not going to spend any more time on this, at least not for now.
Issue Analytics
- State:
- Created 8 years ago
- Comments:6 (5 by maintainers)
Top GitHub Comments
@sol50 Not true. BETA pioneered virtual types, but there were lots of problems with BETA’s virtual types, in terms of safety, in terms of expressiveness, and in terms of decidability. In fact, virtual types is still an open research area.
Regarding decidability, I believe the restrictions @gavinking imposed makes this form of virtual types decidable. In particular, not allowing refinements prevents virtual types from introducing the infinite digressions that happen with Scala and with wildcards.
Yeah, the system I’m thinking of is something that can be pretty directly re-expressed using parametric polymorphism, so I don’t think it would cause huge problems in terms of decidability.
And I wouldn’t introduce refinements like in Scala. If you need refinements, then regular generics is the thing you should be looking at.