Re:Understanding Rust futures by going way too deep
by greenshackle2 on Monday July 26, 2021 @11:25AM
(#27960587)
I'm used to the convention of giving short all-caps acronym names to type parameters, so this is less readable to me, because I automatically assume that something named `Error` is a type, not a type parameter.
Re:Understanding Rust futures by going way too deep
by scoutt on Monday July 26, 2021 @11:12AM
(#27960406)
Oh god. I guess Rust designers have not foresee a function taking 5 parameters.
At this point, somehow, I'm starting to consider C++ templates beautiful! Perhaps a signature form like:
template <FutureA, FutureB, ValueA, ValueB, Error>
pub fn try_join() ... etc.
would be clearer at this point.
- The example you gave at the bottom won't really work, because enum variants aren't fully-fledged types on their own and they can't impl `Future`. Therefore, you can't `.await` them on their own. Furthermore, the point of `try_join` is to poll both futures until one fails, which you can't do with `async` syntax.
- Rust requires that you spell out all generic parameters like this at function boundaries. It's technically possible to infer types across such boundaries, but that has the potential for significant changes to the typing of a function to go entirely unnoticed. In fact, I believe some of Rust's documentation specifically calls out problems Haskell had with inferring function signatures like this.
That being said, you are correct that we could do this instead:
```pub fn try_join<FutureA, FutureB, ValueA, ValueB, Error>(future_a: FutureA, future_b: FutureB> -> impl Future<Output = Result<(ValueA, ValueB), Error> where FutureA: Future<Output = Result<ValueA, Error>>, FutureB: Future<Output = Result<ValueB, Error>>,```
That is slightly more readable.