Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

As a fairly new rustacean myself, I can confirm that the pre-syntax examples are incomprehensible gibberish to me. The bits with `await` are much simpler to make sense of.


You'd be doing something similar with the task library in C# or Promises in Javascript (or in ES5-land, callback hell).

I'd recommend just opening up an IDE in any of these and seeing the types and parameters that come in and out of these calls. The sync vs async worlds really to clash with each other but at least we have strongly typed languages to help with writing the code. In javascript you could be mixing callbacks and promises and encounter bits where you'd never know that the next line would never be executed because of some nonexistent callback, etc etc.


You'll still need to write enum state machines if you want to implement custom Streams (since libstd is only adding Future at the moment).

Even with Futures there can be times when you need the fine-grained control over execution that you don't get with async-await. Eg if you want to implement a `struct TimeOut<F: Future> { inner: F, timeout: std::time::Instant }` from scratch, you can't do that with async-await.


Now being able to just dig into the lower level of Futures at work, I'd say even that is not that hard. You just write the `poll` function and then pattern match inside. There are even nice macros, such as the `ready!` that helps you with some of the boilerplate.

The trickiest thing for me to grasp first was the `Pin` type. Like how does this prevent the value to be moved... Until I realized it's `Pin<&mut T>` and then I had my a-ha moment.


It's slightly more complicated than just pattern-matching.

- In general you have to be careful that if you're returning Poll::Pending, it's after something has registered a wakeup, otherwise your future is going to just stop.

- As a specific case, your match has to be inside a loop so that a state transition results in the new state being polled immediately. You can't just return and expect the caller to poll() you since there will be no wakeup registered that triggers the caller to do so.

- Because futures receive `&mut Self` rather than `Self`, it's difficult to do a state transition where the new state needs to own some properties of the current state. Eg `State::Foo { id: String } -> State::Bar { id: String }` Instead you have to do Option::take / std::mem::replace shenanigans on the state fields, or have an ugly State::Invalid that you can std::mem::replace the whole state with.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: