Each chain produces a different static type. If you want to do a dynamic amount of chains (which seems strange to me? Got an example?) you would need to allocate and use dynamic dispatch, yes.
This is obviously disgusting to expose to users, which is one of the reasons this post uses the `impl Trait` syntax to cover it up and say "well it's something with the right interface, the compiler knows it (so no need to do dynamic dispatch), don't worry about it".
Thanks for your answer. Here's a more realistic example. Say we have a file.close() function that returns a Future<Void>, indicating when the close is complete. Now we want to make a Future for closing a list of files:
let fut = Future<void>::new();
let v = vec![file, file2, file3];
for file in v.into_iter() {
fut = fut.and_then(file.close());
}
Is this possible with this API, or would the assignment to `fut` break because we now have a different type?
With traditional Futures I'd expect this to look like a sort of linked-list of closures (definitely lots of allocation). What does it end up looking like under the hood with zero-cost Rust futures?
As discussed elsewhere in this thread, the most direct translation of that code would also be a linked list of futures, but I don't see an alternative for that sort of structure in general (i.e. every scheme for this sort of asynchrony will have a dynamic chain of allocations).
Basically
`MyFuture.map(x)` => `Map<MyFuture, X>`
`MyFuture.map(x).map(y)` => `Map<Map<MyFuture, X>, Y>`
This is obviously disgusting to expose to users, which is one of the reasons this post uses the `impl Trait` syntax to cover it up and say "well it's something with the right interface, the compiler knows it (so no need to do dynamic dispatch), don't worry about it".