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

consider a way to call await as a method to facilitate fluent or functional style APIs #3464

Closed
insinfo opened this issue Nov 12, 2023 · 5 comments
Labels
feature Proposed language feature that solves one or more problems state-duplicate This issue or pull request already exists

Comments

@insinfo
Copy link

insinfo commented Nov 12, 2023

I really like the style of Dart's async/await syntax, but I think it could use some syntactic sugar without breaking the existing style, a way to use await as a method call to facilitate fluent or functional style APIs,
It makes it a lot easier when you want to solve some things in a single line

import 'dart:async';
import 'dart:convert';
import 'dart:isolate';

class FluentAPI {
  FluentAPI from(String table) {
    return this;
  }

  FluentAPI select([List<String> cols = const ['*']]) {
    return this;
  }

  FluentAPI where(String col, String operator, dynamic val) {
    return this;
  }

  FluentAPI orderBy(String col, String dir) {
    return this;
  }

  FluentAPI limit(int limit) {
    return this;
  }

  FluentAPI offset(int offset) {
    return this;
  }

  Future<List<Map<String, dynamic>>> getAll() {
    return Future.value([
      {'name': 'a'}
    ]);
  }
}

extension ListMapExtension on List<Map> {
  Future<String> toJsonAsync() async {
    final receivePort = ReceivePort();
    await Isolate.spawn(_isolateListMapToJson, [receivePort.sendPort, this]);
    final completer = Completer<String>();
    receivePort.listen((message) {
      completer.complete(message);
      receivePort.close();
    });
    return await completer.future;
  }

  static void _isolateListMapToJson(List args) {
    SendPort sendPort = args.first;
    List<Map<String, dynamic>> map = args[1];
    final json = jsonEncode(map);
    sendPort.send(json);
  }
}

// today
void main() async {
  final json = await (await FluentAPI.new()
          .select()
          .from('table')
          .where('name', 'like', 'a')
          .limit(10)
          .getAll())
      .toJsonAsync();

  print('json $json');
}
// proposal
void main() async {
  final json = await FluentAPI.new()
          .select()
          .from('table')
          .where('name', 'like', 'a')
          .limit(10)
          .getAll()
          .await // <- allow this
          .toJsonAsync();

  print('json $json');
}

@insinfo insinfo added the feature Proposed language feature that solves one or more problems label Nov 12, 2023
@rubenferreira97
Copy link

I think #25 is related

@lrhn
Copy link
Member

lrhn commented Nov 13, 2023

Functional style is why #25 is there.

Returning this like the example suggests is discouraged in Dart, where you should use cascades instead.

Allowing await inside selector chains would be nice, not only because it is over thing that doesn't work on cascades today.

I'm closing this issue, deferring to #25.

@lrhn lrhn added the state-duplicate This issue or pull request already exists label Nov 13, 2023
@lrhn lrhn closed this as not planned Won't fix, can't repro, duplicate, stale Nov 13, 2023
@insinfo
Copy link
Author

insinfo commented Nov 13, 2023

Glad you already have this feature request. I failed to find issue with this feature request.

@lrhn
Why is "Returning this as the example suggests discouraged in Dart"?

@lrhn
Copy link
Member

lrhn commented Nov 13, 2023

Why is "Returning this as the example suggests discouraged in Dart"?

Because you're expected to use cascades instead. It's even in the style guide:
https://dart.dev/effective-dart/design#avoid-returning-this-from-methods-just-to-enable-a-fluent-interface

@insinfo
Copy link
Author

insinfo commented Nov 13, 2023

@lrhn
I thought there was some performance or depreciation problem, but I see that it's just a question of code style, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems state-duplicate This issue or pull request already exists
Projects
None yet
Development

No branches or pull requests

3 participants