HaxeFoundation / haxe-evolution

Repository for maintaining proposal for changes to the Haxe programming language
111 stars 58 forks source link

Type parameter variance of enum #28

Closed shohei909 closed 4 years ago

shohei909 commented 6 years ago

This proposes new variance rule for enum.

Rendered version

Simn commented 6 years ago

Interesting... but I wonder, does this actually solve any problem? I can see your reasoning from a typing theory point of view, but I'm not convinced that the additional complexity actually comes with any advantage.

shohei909 commented 6 years ago

Of course, this has advantages. I added an actual example.

Simn commented 6 years ago

To clarify, this is the failing case:

import haxe.ds.Option;

class Main {
    static public function main() {
        var optionFloat:Option<Float>;
        var optionInt = Option.Some(1);
        optionFloat = optionInt;
    }
}

Your direct assignment works already due to top-down inference.

And yes I can see the point here. Given that enum arguments are read-only, covariance could be allowed.

@ncannasse: Any opinions?

ncannasse commented 6 years ago

The problem is that type parameters variance depends on the way it's used. For instance:

enum Option<T> {
    None;
    Some( f : Void -> T );
}

In this case T is contravariant...

shohei909 commented 5 years ago

If you mean this Option1, yes, the Option1.T is contravariant.

enum Option1<T> {
    None;
    Some( f : T -> Void );
}

However, Option1 is different type from Option2:

enum Option2<T> {
    None;
    Some( f : T );
}

Option2.T is covariant without regard to usage.

This is the list of "A is B" relation:

A B
Int Float
Float -> Void Int -> Void
Option1<Float> Option1<Int>
Option1<Int -> Void> Option1<Float -> Void>
Option2<Int> Option2<Float>
Option2<Float -> Void> Option2<Int -> Void>
nadako commented 4 years ago

We have decided to reject this proposal in our haxe-evolution meeting yesterday.

We concluded that we should approach this in a broader scope, not just for enum, but also in other cases, especially with "read-only" types (e.g. https://github.com/HaxeFoundation/haxe/issues/9611).