3 ms·
This is an excellent, very insightful post. When Erik Meijer worked with Gilad Bracha and others on the Dart team to bring async to Dart, he approached with a
by munificent 4y ago
This is an excellent, very insightful post.
When Erik Meijer worked with Gilad Bracha and others on the Dart team to bring async to Dart, he approached with a very similar "lets look at the table of all the combinations and make sure we didn't leave any holes". In this case, the two axes (effects) he considered were asynchrony and iteration. So Dart supports all four combinations:
* Synchronous single-value functions are just normal function declarations. Within one, you use `return` to yield the one value.
* Synchronous multi-value functions are generators, marked `sync`, which return a `Iterable<T>`. Within one, you use `yield` and `yield` to emit values.
* Asynchronous single-value functions are marked `async` and return a `Future<T>`. Within on, you use `await` to pause on asynchronous operations and consume values. A `return` valued is implicitly wrapped in a future.
* Asynchronous multi-value functions are marked `async` and return a `Stream<T>`. Within one, you can use both `yield` and `yield` to emit values and `await` to suspend and consume asynchronous values.
We also have an asynchronous `await for` statement that can be used to imperatively consume a stream.
There's no third axis for fallibility, because Dart chooses to comprehensively use exceptions for operations that fail (which I quite like).
Overall, it's a really rich, comprehensive approach to the problem. I have mixed feelings about it. It really does cover all the bases. But, in practice, `async` functions and `await for` are very* rarely used but add a lot of complexity to the language and engineering burden to the implementations.
- couchand 4y ago> There's no third axis for fallibility, because Dart chooses to comprehensively use exceptions for operations that fail (which I quite like). Can you catch exceptions? Can you catch them when thrown iterating an Iterable, awaiting a Future, or iteratively awaiting values from a Stream? It doesn't seem like you can get around needing fallibility. What if I have an asynchronous operation that can fail? What if I need a sequence of possibly-empty values?
- klodolph 4y ago> It doesn't seem like you can get around needing fallibility. There’s no axis for fallability because all operations are fallible. Yes, you can catch exceptions when iterating, awaiting, or iteratively awaiting. You have fallibility. What you don’t have is a way of marking operations as non-fallible.
- munificent 4y agoAs klodolph says, there's no axis for fallibility because the language doesn't offer different choices of fallibility strategy. There's just one: exceptions. You can catch exceptions. If an iterator throws, you can catch that by surrounding the for loop in a try catch block. Futures are sort of like Result types in that a Future can complete with either a value or an error. Exceptions inside asynchronous functions are automatically caught and wrapped into error futures, which then propagate out through the returned future object. When you await a future, if the future completes with an error, that then gets unwrapped back into a thrown exception.
- steveklabnik 4y ago> Futures are sort of like Result types in that a Future can complete with either a value or an error. Incidentally, for curious readers, the first version of the Future trait in Rust always returned a Result<T, E> from its poll method. The second version decided to instead return T directly, since T could be Result<T, E> too, making things a bit more general, but also leading to a tiny bit of type tetris. Doesn't mean that I'm saying anything about whatever Dart does here, just that I also think there's a connection here :)
- satvikpendem 4y agoIf you use something like fpdart, you have the more functional Either type (called Result in Rust). https://pub.dev/packages/fpdart#eitherlibsrceitherdart https://pub.dev/packages/fpdart#eitherlibsrceitherdart
- withoutboats3 4y agoThanks for the nice comment.
- howinteresting 4y agoHi Saoirse, I've admired you for a long time. Thanks for all you've done and this blog post, which I emphatically agree with.
- saurik 4y agoI believe you can use a backslash to escape stars, but either way: it took me a while to realize there were a ton of missing stars in this comment that has been parsed as italics (in case this doesn't get fixed before the edit window times out).
- munificent 4y agoOops, sorry about that. Still waiting for the day that HN supports Markdown for inline code. :(
- Jtsummers 4y ago\* ** Either one works to get an * into your non-code block text.
- Serow225 4y agoNow I'm interested to make the chart to compare that list to C#, given the common Erik influence/heritage :) It has IAsyncEnumerable now
- kid-icarus 4y agoWhile these points may hold true, I’ve often seen the statement thrown around in chats and various forums that, “dart sux.” I don’t understand the hate, nor the juvenile phrasing.