What do I extend on when extending functions?
Dart has a Function
type. This can be extended on and you can pass type parameters if you want.
Here is an example from the changelog:
extension CurryFunction<R, S, T> on R Function(S, T) { ... }
Furthermore, you can extend any typedef
of a function.
For adding the toAsync
and callAsync
functionality a generic return type R
will do. Note that this will only extend functions without parameters as Function()
takes no parameters:
extension FancyFunction<R> on R Function() {
Future<R> Function() toAsync() => () async => this();
}
Now, this could be used like this:
void syncHello() => print('Hello');
void main() {
final asyncHello = syncHello.toAsync();
asyncHello().then((_) => print(', World!'));
}
How do I implement calling?
Every class in Dart can implement the call
method. You can either execute this method simply using parentheses or with .call()
.
Here is an example implementation:
extension FancyFunction<R> on R Function() {
Future<R> call() async => this();
}
Since every Function
already implements call
, the extension member cannot be called implicitly.
Instead, you will have to explicitly declare your function as a FancyFunction
to be able to call it:
void syncHello() => print('Hello');
void main() {
FancyFunction(syncHello)()
.then((_) => print(', World!'));
}
Note that FancyFunction(syncHello)()
is the same method call as FancyFunction(syncHello).call()
.
However, now we have two problems:
We have to explicitly declare our function to be a FancyFunction
, which somewhat defeats the purpose of having an extension.
The call
method will always return a Future
as the regular call method cannot be accessed anymore when we declare a FancyFunction
.
Instead, adding a method like callAsync
seems like a better solution:
extension FancyFunction<R> on R Function() {
Future<R> callAsync() async => this();
}
Now, callAsync
can be used implicitly again:
void syncHello() => print('Hello');
void main() {
syncHello.callAsync()
.then((_) => print(', World!'));
syncHello(); // regular call
}