-
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
Allow covariant
to be used for arbitrary function types?
#477
Comments
The State reducer<A extends Action>(State state, A action) {
...
} FWIW, I think the design pattern above is a terrible fit for Dart (it relies on dynamic dispatch, lots of runtime checks, storing untyped functions in Maps, etc). I have seen a lot of APIs that look (and likely perform) a lot better for Dart/Flutter. |
Agreeing with @matanlurey that this is not a good fit, I'd add a couple of extra considerations. The language team has had discussions about allowing The semantics would be (1) the reified type of the function would use a top type ( void foo(void Function(Object) g) {
g(42); // Dynamic check for invocation from `main` does succeed.
}
main() {
foo((covariant int i) => print(i.isEven));
} The point is that this allows the function body to be checked using the type The original example would use it as follows: State foo(State state, covariant FooAction action) {
...
}
State bar(State state, covariant BarAction action) {
...
} However, putting covariance into function types is a different matter; see this comment for some reasons why that would probably be a bad idea. However, you could also just switch to use an actual subtype relationship: Use a You'd then have to call the function dynamically (in order to avoid a failure due to a dynamic check based on the statically known parameter type State foo(State state, FooAction action) {...} // No special tricks here.
State bar(State state, BarAction action) {...} // Ditto.
...
State reducer(State state, dynamic action) {
final handler = reducerTable[action.runtimeType];
if (handler != null) {
return (handler as Function)(state, action);
}
return state;
} [Edit: Avoid the type case in #295 is concerned with a change whereby you would be able to use a plain |
Do you mean that the @eernstg: Thanks! I presume that your last example was meant to be: State reducer(State state, dynamic action) {
final handler = reducerTable[action.runtimeType];
if (handler != null) {
return (handler as Function)(state, action);
}
return state;
} because |
Both IMO. This would be totally just bypassing Dart's type system. I'd consider using something like the Visitor pattern instead of dynamic registration of handlers. |
@jamesderlin wrote:
That's right, thanks! Using the concise That allows for an architecture which is extensible with respect to the kinds of actions supported, because actions can be added without editing @matanlurey wrote:
I agree that this technique involves some elements which are potentially costly in terms of static analyzability. In particular, using However, the use of a We won't have dependent types in Dart, so we cannot rely on modeling the situation using dependent types. But I think it makes sense to consider the trade-off between benefits like having an architecture which is extensible in certain ways, at the cost of emulating a new kind of types (which requires some manual discipline, because the type checker can't see it), versus having an architecture which is less extensible (here: we must edit some core framework code like |
Currently this is rejected by dartanalyzer:
which complains:
I admit that I have little experience with covariance, but why is
covariant
restricted to instance methods? What is intrinsically safer about instance method overrides when the covariant type isn't related to the instance's class?Motivation:
A common redux pattern is implementing a reducer like:
I instead want to store this in a
Map<Type, State Function(State, dynamic)>
so it can be used like:This works, but it has the disadvantage that the handlers must all be declared with
dynamic action
instead of with more specific types:The text was updated successfully, but these errors were encountered: