How does this compare to "Accept interfaces, return structs" in Go?
How does this compare to "Accept interfaces, return structs" in Go?
Posted Apr 26, 2024 0:56 UTC (Fri) by wahern (subscriber, #37304)In reply to: How does this compare to "Accept interfaces, return structs" in Go? by davecb
Parent article: Existential types in Rust
>
> Yes, it does
This doesn't sound right with respect to either Go or Rust. In Go interfaces are statically resolved to concrete types only opportunistically. It can't always do this because a function might choose which concrete implementation to return based on runtime logic.
IIUC, the same is true of Rust. In Rust you can return a `impl Trait` directly only if there's a single concrete implementation it could possibly return, otherwise it has to be boxed. Named existential type are just as strict: a named existential type can only have a single concrete implementation, period. The concrete type appears to be inferred from the usage context, but IIUC if the second context can't be coerced to the same concrete type as in the first context, then compilation will fail.
It couldn't be any other way, at least as a practical matter. (Though I could imagine a system of symbolic execution where the compiler generates code for all the alternations, but if you thought compile times were crazy now....) People seem to get all exited about various Rust features based on the fancy technical jargon and assume Rust is performing something magical. But people's memories are short, apparently. IIUC, existential types here are quite useful largely as a syntactic sugar when writing implementations, but otherwise more a boon to the compiler in circumscribing the complexity of the type resolution expected of it. The hype over what it offers async code seems overblown; it's not going to magically make opaque interface-like types with multiple distinct concrete implementations magically statically dispatchable when they're returned from a function which could return one or the other dynamically.
