-
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
Remove dynamic type #3192
Comments
This is a language change request. Moving it to the language repository. |
I don't use I see no downsides except for the fact that this is a very breaking change. I fully support this change, but I find it hard to believe that the Dart team would go through this route, as they are pretty conservative about breaking changes. |
Same here. I've stopped using dynamic forever ago. The only use-case I can think of today is mocking, which currently often relies on dynamic invocation with noSuchMethod. There's also how dart:convert does a dynamic invocation of So removing it could be quite breaking. Although not impossible. |
I am also in favor of this change. As far as I know, the |
A stepping stone to removing dynamic from the language would be to ban dynamic calls in the recommended (or core) lint rule sets. You can upvote here: dart-lang/lints#44 😁 |
I like it. I have been using strict type checks and explicit casting from the beginning using the Dart language. |
Is it the What if the only expression that could have type Dynamism would then be an opt-in feature, with a clear syntactic marker everywhere it's used. The alternative is that there are existing features which cannot be retained. Like It might encourage introducing new, simple, interfaces and force existing code to implement those, in order for existing dynamic code to keep working. (Not saying we cannot remove |
This would be better than what we have today and less breaking, so it may be an alternative path. From there we can think if it's really valuable to remove
Honestly, I would also ask to remove |
It is even the existence of
In my opinion,
For
|
You never need a cast, you can do an That's just cumbersome, in the cases where you do know that the value will definitely have the assumed type. Implicit downcast from |
Using |
I think the idea of having dynamic be more explicit is a good one. Changing type inference to instead rely on Object? instead of dynamic would be great. There are also a bunch of APIs which promote dynamic. |
For me, it is the accidental use. If you'd have to be very very explicit every time you want to do a dynamic invocation it wouldn't be a problem anymore.
Wondering if you have any examples where Flutter is using dynamic. We try very hard not to and I'd be open to removing any remaining instances. |
@goderbauer here is the report of |
Honestly I grouped flutter and Dart SDK together. It could be that Flutter doesn't really use it, I don't remember. The sdk uses it quite often I think. In part with error handling or json |
Mainly JSON, because JSON is inherently untyped, and Dart 1 used Some async error handling uses But there are places in the SDK libraries where some raw type gets instantiated with |
Could be related: dart-lang/sdk#50874 |
Well, yes, I guess that when there's a breaking change, one would try to fit in good counter measures as much as possible. I guess that rarely you'd release, say, "Dart 4" just because of a single feature like this one. If anything, I wish a potential "Dart 4" version would remove
I can't see how this is insurmountable. By definition, a breaking change un-supports ..stuff! Folks would need to adapt to it. SDK / Flutter / core libraries included. ... But I sincerely can't wait to do so! If there's a fair amount of benefits that indirectly affect or bring other features, I'd quickly transition to this. As many others, I don't use |
I don't think dynamic should go away entirely, but it should be made safer. A form of structural typing can be introduced to make dynamic a bit more ergonomic. For example, toJson in // Interface that can be explicitly or implicitly implemented by a type
// as long as it contains all matching members.
typedef interface ToJson {
Object toJson();
}
// ... json innards in dart:convert when handling an unknown type:
// assume object is declared as `dynamic object;`.
if (object is ToJson) {
object = object.toJson();
} Downstream consumers can choose to use an implements clause for ToJson. But otherwise it can be omitted. class MySerializableClass implements ToJson {
Map<String, dynamic> jsonEncode() => {"foo": "bar"};
} Then warn when dynamic is used unexpectedly. Tell the developer to use an explicit type or a structural interface instead. The difference between |
This sounds like a method to prepare for the breaking change, but not to prevent a breaking change. Here, one would continue to support something that is officially not recommended. You could throw out the support for calling |
(I'd rather just stop calling |
Flutter has various usages of dynamic, notably: https://github.com/flutter/flutter/blob/5d4a1f1f5fe1d0d0191c691eb60b6814654d6929/packages/flutter/lib/src/animation/tween.dart#L339 Which is intended to avoid having to make N different implementations of Tween to support all kinds of numeric-like classes (Offset for example, maybe Vector2/3/4 from vector_math). Could be supplanted by structural interfaces. |
Discussion in dart-lang/language#3192 indicates a general move away from dynamic.
Proposal
Dart should remove the
dynamic
type for stricter type-safety, better performance and less support for bad practices.Justification
The use of
dynamic
is a bad practice, often even referred to as such in the documentation:dynamic
: Indicates that you want to disable static checking. Usually you should useObject
orObject?
instead." (https://dart.dev/language/built-in-types)However, there are ways to bypass
dynamic
calls and implicit casts for your own projects using lints (e.g. with strong-mode).But this does not solve the problems that the support for
dynamic
has for the Dart language in general.Firstly, it results in worse performance of the compiled code, since more inefficient runtime checks are required. (I'm not an expert on Dart compilers, so correct me if I'm wrong on this point).
Secondly, the support of
dynamic
prevents other features that many developers would like to use in a type-safe object-oriented language. For example,private
,protected
andpublic
modifiers are not possible because they could not supportdynamic
types except through very inefficient runtime checks (dart-lang/sdk#33383).In general, Dart tries to be as type-safe as possible. But on the other hand there is this relict
dynamic
, which stands against it.dynamic
generally feels like a concession to JavaScript developers to get more of them to switch to Dart/Flutter. Developers who have moved from Java/Kotlin/Swift/C++,... are just disturbed bydynamic
and it also doesn't bring any benefits except more opportunities to apply bad practices.Impact
All code that currently uses
dynamic
would have to be changed toObject?
or subtypes and implicit casts would be required. Also, method calls would no longer be possible without knowing the type of an object.Mitigation
Since this would be a null-safety level change, it would have to be made optional at first and fully introduced with the next major release.
The text was updated successfully, but these errors were encountered: