dart-lang / dart-lang/language
Static extension methods
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
## Motivation
Currently, extension methods do not support adding static methods/factory constructors. But this is a missed opportunity!
There are many situations where semantically we want a static method/factory, but since the type is defined from an external source, we can't.
For example, we may want to deserialize a `String` into a `Duration`.
Ideally, we'd want:
```dart
extension ParseDuration on Duration {
factory parse(String str) => ...;
}
Duration myDuration = Duration.parse('seconds: 0');
```
But that is currently not supported.
Instead, we have to write:
```dart
Duration parseDuration(String str) => ...;
Duration myDuration = parseDuration('seconds: 0');
```
This is not ideal for the same reasons that motivated extension methods. We loose both in discoverability and readability.
## Proposal
The idea is to allow `static` and `factory` keyword inside extensions.
### Factory
Factories would be able to capture the generic type of the extended type, such that we can write:
```dart
extension Fibonacci on List {
factory fibonacci(int depth) {
return [0, 1, 1, 2, 3, 5];
}
}
```
Which means we'd be able to do:
```dart
List.fibonacci(6);
```
But not:
```dart
List.fibonacci(6);
```
Factories would work on functions and typedefs too (especially after #65):
```dart
typedef MyEventHandler = void Function(Event event);
extension MyShortcut on MyEventHandler {
factory debounced(Duration duration, MyEventHandler handler) {
return (Event event) { .... }
}
}
```
### Static members
Using extensions, we would be able to add both static methods and static properties.
They would _not_ have access to the instance variables, nor the generic types.
On the other hand, static constants would be allowed.
We could, therefore, extend Flutter's `Colors` to add custom colors:
```dart
extension MyColors on Colors {
static const Color myBusinessColor = Color(0x012345678);
}
```
Or `Platform` to add custom `isWhatever`:
```dart
extension IsChrome on Platform {
static bool get isChrome => ...;
}
```
which, again, would work on functions and typedefs
```dart
typedef MyEventHandler = void Function(Event event);
extension MyShortcut on MyEventHandler {
static void somePremadeHandler(Event event) {}
}
```
Contributor guide
Research direction
Start by reading the proposal and its 128-comment discussion, paying attention to unresolved questions about factories, static members, generic types, functions, and typedefs. Done means reaching agreement on the language behavior and documenting or implementing the resulting design, though this issue names no files or tests to run.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- dart
- Domain
- compilers
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100