How can I mark a typedef as async?

860 views
Skip to first unread message

Danny Tuppeny

unread,
Mar 27, 2015, 9:51:16 AM3/27/15
to mi...@dartlang.org
I have a typedef:

typedef Future<ClientGrid> GetAjaxData(){int page});

And I want to await the results:

var g = await _getDataFunc(page: _currentPage);

I'm using 1.9.1 SDK/Dartium. However, I get a nonsense error (semicolon expected), which Google tells me is because of awaiting a non-async method.

How do I make the typedef async? I've tried putting "async" in all places; and none seem to work. This is my very first attempt at changing something to await, and I'm already stuck :(

Günter Zöchbauer

unread,
Mar 27, 2015, 10:03:02 AM3/27/15
to mi...@dartlang.org
There is no need to mark the typdef with async. You can use await for every function which returns a future. You need async for functions where you want to use await, in this case above your_getData(...) line (the function declaration which contains this code line)
Using await in a function not marked async leads to a bunch of weird errors currently like you described.
I hope they find a way to improve this.
When a function is not marked async, await is a valid identifier.

Danny Tuppeny

unread,
Apr 10, 2015, 9:44:48 AM4/10/15
to mi...@dartlang.org
Ok, should this work in a setter?

async set currentPage(int newPage) {
  _currentPage = newPage;
  _setLoading(true);
  var g = await _getDataFunc(page: _currentPage);
  grid.data = g;
  _setLoading(false);
  pagination.totalPages = grid.data.totalPages;
}

Currently Dartium reports:

Internal error: 'package:dart_dms/src/grids/ajax_grid.dart': error: line 26 pos 19: semicolon expected
  var g = await _getDataFunc(page: _currentPage);

My setter obviously doesn't return anything; but that didn't seem to be a problem before. (I know, it might not be good practice to do expensive work in setters, I'm just trying to convert a quick prototype to use await to see how it works)..


--
For other discussions, see https://groups.google.com/a/dartlang.org/

For HOWTO questions, visit http://stackoverflow.com/tags/dart

To file a bug report or feature request, go to http://www.dartbug.com/new

Günter Zöchbauer

unread,
Apr 10, 2015, 9:58:07 AM4/10/15
to mi...@dartlang.org
async is not a return type, it's a modifier for the function body.
If you add async as modifier you always have the return type Future


On Friday, April 10, 2015 at 3:44:48 PM UTC+2, Danny Tuppeny wrote:
Ok, should this work in a setter?
 /*Future*/ set currentPage(int newPage) async { // <= added async before {
  _currentPage = newPage;
  _setLoading(true);
  var g = await _getDataFunc(page: _currentPage);
  grid.data = g;
  _setLoading(false);
  pagination.totalPages = grid.data.totalPages;
}


For short-hand syntax this would look like

 /*Future*/ set currentPage(int newPage) async => ... 

Günter Zöchbauer

unread,
Apr 10, 2015, 10:00:25 AM4/10/15
to mi...@dartlang.org
I commented the /* Future */ because you might not care about the return type.
You can still use it to delay code execution until the setter is done

await x.currentPage = page;
// core here is only executed after currentPage setter is done

Danny Tuppeny

unread,
Apr 10, 2015, 10:09:16 AM4/10/15
to mi...@dartlang.org
I tried this, but it still fails:

 Internal error: 'package:dart_dms/src/grids/ajax_grid.dart': error: line 21 pos 32: setter 'set:currentPage' may not be async, async* or sync*
  set currentPage(int newPage) async {

Are setters not allowed to be async? :-/

Lasse R.H. Nielsen

unread,
Apr 10, 2015, 10:15:35 AM4/10/15
to mi...@dartlang.org
Setters cannot be declared async. From the specification:
"It is a compile-time error if an async, async* or sync* modifier is attached to the body of a setter or constructor. "

The reasoning is that an async function must return a Future, but a setter must have return type void (the return value of the setter is ignored since the value of an assignment is the value of its right-hand side expression).

If you can't await the setter, then it shouldn't be async.

If you really, really want to do async stuff inside a setter, you can still wrap the body in a function expression:

void set x(int y) {
  () async {
     await print(y);
  })();
}

You still can't await the result.

If you have a setter that does asynchronous computations, maybe consider making it a function instead with a name that corresponds to the computation.

/L


To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.



--
Lasse R.H. Nielsen - l...@google.com  
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K - Denmark - CVR nr. 28 86 69 84

Danny Tuppeny

unread,
Apr 10, 2015, 10:18:48 AM4/10/15
to mi...@dartlang.org
On 10 April 2015 at 15:15, 'Lasse R.H. Nielsen' via Dart Misc <mi...@dartlang.org> wrote:
If you really, really want to do async stuff inside a setter, you can still wrap the body in a function expression:

I did think of that, though started to feel more and more like I was doing something smelly!

If you have a setter that does asynchronous computations, maybe consider making it a function instead with a name that corresponds to the computation.

I'll do that. I was just trying to show how await worked without making lots of changes; but it shouldn't really have been in the setter to start with.

Thanks for the info!
 

Günter Zöchbauer

unread,
Apr 10, 2015, 10:29:36 AM4/10/15
to mi...@dartlang.org
I didn't know that. The funny thing is that the analyzer doesn't like "void" as return type, at least when => is used.

Danny Tuppeny

unread,
Apr 10, 2015, 10:29:38 AM4/10/15
to mi...@dartlang.org
Ugh, turns out CDE doesn't support async... :(


Inline images 1

It does now work in Dartium though :)

Günter Zöchbauer

unread,
Apr 11, 2015, 5:35:40 AM4/11/15
to mi...@dartlang.org
Here is an example https://dartpad.dartlang.org/28321d64aa5ed5ec3768

import 'dart:async' show Future, Stream;


class SomeClass {
 
int _someValue;
 
void set someValue(int val) =>
   
new Future.delayed(new Duration(milliseconds: 500), () => _someValue = val);


 
Future set someValue2(int val) =>
   
new Future.delayed(new Duration(milliseconds: 500), () => _someValue = val);


 
int get someValue => _someValue;
}


With return type 

- void 
     The return type 'Future' is not a 'void', as defined by the method 'someValue'

- Future
     The return type of the setter must be 'void'

Somehow this doesn't make sense.
I think this should be changed but I'm not sure how.

Either the setter accepts 'void' even when short-hand syntax is used
or the analyzer always suggests to not have a return type for setters.

Lasse R.H. Nielsen

unread,
Apr 11, 2015, 7:53:03 AM4/11/15
to mi...@dartlang.org
On Sat, Apr 11, 2015 at 11:35 AM, Günter Zöchbauer <gzo...@gmail.com> wrote:
Here is an example https://dartpad.dartlang.org/28321d64aa5ed5ec3768

import 'dart:async' show Future, Stream;


class SomeClass {
 
int _someValue;
 
void set someValue(int val) =>
   
new Future.delayed(new Duration(milliseconds: 500), () => _someValue = val);


 
Future set someValue2(int val) =>
   
new Future.delayed(new Duration(milliseconds: 500), () => _someValue = val);


 
int get someValue => _someValue;
}


With return type 

- void 
     The return type 'Future' is not a 'void', as defined by the method 'someValue'

- Future
     The return type of the setter must be 'void'

Somehow this doesn't make sense.

Remember that 
   foo(x) => e;
is generally equivalent to
   foo(x) { return e; }

If you write:
  void foo(x) { return new Future ... }
you get a warning.

If you write any type except "void" as return type for a setter, you also get a warning.
 
I think this should be changed but I'm not sure how.

If anything, I'd remove the ability to write a return type for setters entirely. They are always void. If you write anything else, you are fooling somebody, most likely yourself.
 

Either the setter accepts 'void' even when short-hand syntax is used
or the analyzer always suggests to not have a return type for setters.

The solution is to stop returning something from a setter. The short-hand isn't just a short way to write a function. It's a short way to write a function *that returns a value*. Setters, being void, should not be returning values.

Returning a future from a setter makes it seem like someone might see that future, and that's likely to just be fooling yourself (or somebody else reading the code).

Just write:
  void set someValue(int val) { 
    new Future.delayed(new Duration(milliseconds: 500), () { _someValue = val; });
  }
or even:
  void set someValue(int val) {
    new Timer(new Duration(milliseconds: 500), () { _someValue = val; });
  }

Both makes it clear that nobody will be seeing the delayed computation - nobody will be able to handle errors on the future.

/L

Günter Zöchbauer

unread,
Apr 11, 2015, 9:23:11 AM4/11/15
to mi...@dartlang.org
I think this would be a good idea. 
Anything else is confusing. 
While I never planned to use the return value of a setter the complaints of the analyzer tricked me into believing there actually is a return value. 
 

Either the setter accepts 'void' even when short-hand syntax is used
or the analyzer always suggests to not have a return type for setters.

The solution is to stop returning something from a setter. The short-hand isn't just a short way to write a function. It's a short way to write a function *that returns a value*. Setters, being void, should not be returning values.

Returning a future from a setter makes it seem like someone might see that future, and that's likely to just be fooling yourself (or somebody else reading the code).

Just write:
  void set someValue(int val) { 
    new Future.delayed(new Duration(milliseconds: 500), () { _someValue = val; });
  }
or even:
  void set someValue(int val) {
    new Timer(new Duration(milliseconds: 500), () { _someValue = val; });
  }

Both makes it clear that nobody will be seeing the delayed computation - nobody will be able to handle errors on the future.


I'm fine with everything. 
I think there should be a way mentioned in the style guides and all tools should print sane hints that point to this preferred style.
Reply all
Reply to author
Forward
0 new messages