Prefix and Apology
I went down the wrong track in #2 and rust-embedded/embedded-hal#13. My error was because I was not familiar enough with the inner workings of futures and I used the incorrect terminology.
I do NOT think we should return a Future, but rather that our asyncronous functions should return a type identical to futures::Poll (or possibly futures::Poll itself)
Issue at hand
I suggest that although this is not futures, we should try and keep the API as similar as possible to futures. Future::poll returns the type Poll which is just Result<Async<T>, E>. See: Async.
These types are mathematically identical:
futures:
type Poll = Result<Async<T>, E>;
pub enum Async<T> {
Ready(T),
NotReady,
}
nb:
type MyResult = Result<T, nb::Error<E>>;
enum Error<E> {
Other(E),
WouldBlock,
}
We have simply moved the WouldBlock/NotReady around from Ok to Err.
However, Result<V, nb::Error<E>> is much less ergonomic for a function that is supposed to be asyncronous:
- When someone creates a function that is non blocking, they should be returning a type that specifies the function as non-blocking. That type is the
Poll type (although it doesn't have to come from futures).
- Having the function return a
Result that could have an Error::WouldBlock is much more difficult to follow -- you have to dig into what the error type is to understand that this is an async function!
Summary
An async function should return Poll type -- not have an "async error." In general, it should mimick the API of Future::poll. Fundamentally this is a usability/readability question, but it will also make it easier to reason about what futures::Poll::from::<nb::Poll>() does, as well as allow us to more easily leverage futures.
I posit that it would be better if we used the futures::Poll type directly, as that type really is zero cost by definition (futures::Poll<T, E> is mathenatically identical to Result<T, nb::Error<E>>) and would make converting async functions to futures much more readable and streamlined (they would automatically implement Future::poll!)
Prefix and Apology
I went down the wrong track in #2 and rust-embedded/embedded-hal#13. My error was because I was not familiar enough with the inner workings of futures and I used the incorrect terminology.
I do NOT think we should return a
Future, but rather that our asyncronous functions should return a type identical tofutures::Poll(or possiblyfutures::Pollitself)Issue at hand
I suggest that although this is not futures, we should try and keep the API as similar as possible to futures.
Future::pollreturns the typePollwhich is justResult<Async<T>, E>. See:Async.These types are mathematically identical:
futures:
nb:
We have simply moved the
WouldBlock/NotReadyaround fromOktoErr.However,
Result<V, nb::Error<E>>is much less ergonomic for a function that is supposed to be asyncronous:Polltype (although it doesn't have to come fromfutures).Resultthat could have anError::WouldBlockis much more difficult to follow -- you have to dig into what the error type is to understand that this is an async function!Summary
An async function should return
Polltype -- not have an "async error." In general, it should mimick the API ofFuture::poll. Fundamentally this is a usability/readability question, but it will also make it easier to reason about whatfutures::Poll::from::<nb::Poll>()does, as well as allow us to more easily leverage futures.I posit that it would be better if we used the
futures::Polltype directly, as that type really is zero cost by definition (futures::Poll<T, E>is mathenatically identical toResult<T, nb::Error<E>>) and would make converting async functions to futures much more readable and streamlined (they would automatically implementFuture::poll!)