While I’m no expert with regards to how the JVM works, I’m almost certain that the implementation in scala must ultimately boil down to some form of dynamic dispatch.
Not only that, I imagine that Java/Scala generics also perform dynamic dispatch (at least, when you do stuff like
<T extends SomeClass> or
<T implements SomeInterface> or whatever the syntax is). Hence, there is probably little disadvantage to letting
FnMut work just like
<T implements FnMut>. (again, though: don’t take it from me)
In contrast, Rust’s generics are statically dispatched, so there actually is something to be gained by encouraging their use.
One note: You can actually do dynamic dispatch in Rust.
You see, the reason the compiler is giving an error about an “unsized type” (rather than, say, an “invalid type”) is because there actually is a type called FnMut. In fact, every trait has a corresponding type. But similar to
[T], they’re unsized, which means you can only pass around borrowed forms of the type (i.e.
I seldom ever use them, because (a) the standard library doesn’t, and (b) dynamically dispatched types are just not as powerful as generics (iirc you can have at most one non-standard-ibrary trait, so
&(Clone + Eq + Foo) is okay but
&(Foo + Bar) isn’t).