Skip to content
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

A #24149

Closed
mehaase opened this issue Aug 20, 2015 · 3 comments
Closed

A #24149

mehaase opened this issue Aug 20, 2015 · 3 comments
Labels
closed-not-planned Closed as we don't intend to take action on the reported issue

Comments

@mehaase
Copy link

mehaase commented Aug 20, 2015

Related to #2231:

It's not possible to have a Future because void is not a type. Okay, that's understandable. We can use Future<dynamic> instead, but that leads to awkward code, e.g.:

Future doInFuture() {
    Completer c = new Completer();
    ...do something with completer...
    return c.future;
}

void doSomethingElse() {
    print('i did something');
}

Later on...

doInFuture().then(doSomethingElse);

This doesn't work:

Closure call with mismatched arguments: function 'doSomethingElse'

NoSuchMethodError: incorrect number of arguments passed to method named 'doSomethingElse'
Receiver: Closure: () => Future from Function 'doSomethingElse@499176765':.
Tried calling: doSomethingElse(null)
Found: doSomethingElse()

Either doSomethingElse() needs to be declared with a single, throw-away argument, or else pass a lambda to then() that disposes of the useless argument:

doInFuture().then((_) => doSomethingElse());

I find this latter syntax a bit more difficult to understand, particularly to others not familiar with futures in Dart.

I think a simple solution would be to add a class (e.g. in dart:async) that is a sentinel indicating a future with no return value. The implementation can check if the type is this sentinel class and invoke the callback without any arguments.

@lrhn lrhn added the closed-not-planned Closed as we don't intend to take action on the reported issue label Aug 20, 2015
@lrhn
Copy link
Member

lrhn commented Aug 20, 2015

That suggestion would effectively mean that there are two types of Futures, one where then has signature Future then(callback(T value)) and one where it has signature Future then(callback()). Those two types of futures are incompatible, and every async function would have to pick one or the other. That's not viable in practice.

A more useful version would be to change the signature of then to Future then(Function callback) and allow both nullary and unary callbacks. We have considered that before and rejected it for a number of reasons, including performance, simplicity and documentability.

If you use the var x = await expression syntax instead of expression.then((x) { ...}), then it's much easier to ignore the future result - you just write await expression;

All in all, we don't think the gain from such a feature is worth the complication it introduces.

@lrhn lrhn closed this as completed Aug 20, 2015
@harryterkelsen
Copy link
Contributor

Why not add another method on Future?

Future after(callback()) => then((_) => callback());

It's like how Haskell's Monad has both >>= and >>.

@lrhn
Copy link
Member

lrhn commented Aug 20, 2015

Changing Future at this point will likely make a lot of existing Future implementations suddenly be incorrect (and crash when someone tries to call the missing after function on them).
There are probably not that many new implementations of Future, but I think there's quite a lot of wrappers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-not-planned Closed as we don't intend to take action on the reported issue
Projects
None yet
Development

No branches or pull requests

3 participants