-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Safe typing involving variance #213
Comments
@munificent and I discussed the use site and declaration site variance ideas on the board today, I wanted to record a few thoughts. We both had the sense that declaration site co and contra-variance are probably useful. We discussed the question of whether or not to allow a class with invariant type parameter
I think it's reasonable to allow, but there is something distasteful about it. We both had the thought that perhaps one could require instead that the superclass be the invariant projection, to mark the fact that there is a transition from the statically safe to the statically unsafe space.
I don't think this actually has any practical effect on how this class is used, since Where this becomes especially interesting is if you add the
My expectation would be that in general we would have:
So extending Does this make any sense? Something worth exploring? |
I more like the Scala one. with |
I know the current focus of the team is null-safety, but was there any progress on this? |
It would not be unlikely that we will add sound declaration site variance; much of it is implemented. But no firm dates yet, and not even a firm promise that we will do it. |
Thanks for your answer. I am actually trying to implement a reader monad, but can't do something like: class Functor<A> {}
class Reader<A, B> implements Functor<B Function(A)> {} This is the error I'm getting:
I think this issue would solve my problem, so I would really appreciate if you consider implementing this. Also, AFAIK, there's no workaround for what I am trying to do... |
If you're aiming at something similar to this class Functor<out A> {}
class Reader<in A, out B> implements Functor<B Function(A)> {} |
I see, didn't know about these |
The |
In Dart, a parameterized class type is covariant in every type parameter; for example,
List<int>
is a subtype ofList<num>
becauseint
is a subtype ofnum
(so the list type and its type argument "co-vary").This is sound for all covariant occurrences of such type parameters in the class body (for instance, the getter
first
of a list has return typeE
, which is sound). It is also sound for contravariant occurrences when a sufficiently exact receiver type is known (e.g., for a literal like<num>[].add(4.2)
, or for a generative constructorSomeClass<num>.foo(4.2)
).However, in general, every member access where a covariant type parameter occurs in a contravariant position may cause a dynamic type error, because the actual type annotation at run time—say, the type of a parameter of a method—is a subtype of the one which is known at compile-time.
For example: Assume that a variable
xs
has declared typeList<num>
, and consider the invocationxs.add(4.2)
. This invocation will fail if the value ofxs
is aList<int>
, but it will succeed with aList<num>
and with aList<double>
. Still, the static type ofxs
allows them all.This issue is a request for improvements in the amount of control that developers have over this kind of dynamic checks. In particular, it should be possible to establish a guarantee at compile time that such a dynamic type error cannot occur.
The text was updated successfully, but these errors were encountered: