4 ms·
I’m not sure dynamic dispatch is that much of a killer feature. Take C# it default to static dispatch of method and you tend to get very far without explicitly
by CuriousSkeptic 7y ago
I’m not sure dynamic dispatch is that much of a killer feature. Take C# it default to static dispatch of method and you tend to get very far without explicitly making things virtual.
Event when using interfaces many times it’s seems possible to arrange things such that parametric polymorphism would be able to use a static type.
There are some boiling proposals for future versions that will help with exactly this, and indeed some of the latest changes to the languages have included allowing more static dispatching in polymorphic constructs like disposal and enumeration.
I’m beginning to suspect that dynamic dispatch could be entirely dropped without losing to much expressiveness.
Have no experience with Rust but isn’t that kind of the conclusion from that community?
- meheleventyone 7y agoI think that's broadly true but it should at least be pointed out that static dispatch tends to end up inflating binary size and compilation time. Rust also supports dynamic dispatch so you can make a context dependent choice.
- hashmal 7y agoStatic dispatch or monomorphization?
- meheleventyone 7y agoIsn’t using parametric polymorphism to get static dispatch reliant on monomorphization? That’s at least the common case in Rust.
- everettwilson 7y agoNot really anything of an expert with Rust, but I'd say that the language tries to dispatch function calls statically whenever possible, though it certainly has the capacity to provide polymorphism when needed, through the use of trait objects [0]. From using it personally, I've found that I can usually get by with generics and the static dispatch that they provide, but having the option to use trait bounds can be a real boon when you need the flexibility to call on shared pieces of functionality between separate complicated systems. [0] https://doc.rust-lang.org/1.30.0/book/2018-edition/ch17-02-trait-objects.html#trait-objects-perform-dynamic-dispatch https://doc.rust-lang.org/1.30.0/book/2018-edition/ch17-02-t...
- jbjohns 7y agoWhat's more, languages like Smalltalk which only have "virtual" dispatch achieve their performance by recognising that most dispatch is just to one type. And of the remaining cases, most of those are just to 2 types, etc. Pushing this further resulting in Strongtalk which lead to the Hotspot JVM [1]. [1] http://strongtalk.org/index.html http://strongtalk.org/index.html
- AnimalMuppet 7y ago> I’m not sure dynamic dispatch is that much of a killer feature. It's a feature that, when it fits your problem, can be extremely useful. I have rarely had it fit a problem. The ones it fit, though, it was nearly magic.
- uryga 7y agorust has `dyn FooTrait`, which lets you do dynamic diapatch, similarly to `FooInterface x = foo();` in e.g. java. even Haskell has a way of doing this via existential types like `(forall a. FooTypeclass a => a)`. both of these predominantly statically-dispatched langs added ways to do dynamic dispatch later on, which seems to go against "dynamic dispatch could be entirely dropped without losing to much expressiveness". i prefer static-by-default as well, but it looks like it's hard to do without sometimes. (of course you can always roll your own vtable-ish thing, so technically you could drop DD from the language without loss of expressiveness, but then you'd likely get multiple incompatible libraries for that...) and i'd guess that some sort of dynamic dispatch is unavoidable if you want to do some kind of plugin architecture
- CuriousSkeptic 7y agoAre you sure that Haskell thing is dynamic? I was under the impression that the type you have there is resolved statically by finding a type class for a
- uryga 7y agoexistential types allow you to make it dynamic. see https://wiki.haskell.org/Existential_type https://wiki.haskell.org/Existential_type, there's a section comparing it to OOP-style dynamic dispatch simple example copied from the linked article: data Obj = forall a. (Show a) => Obj a xs :: [Obj] xs = [Obj 1, Obj "foo", Obj 'c'] doShow :: [Obj] -> String doShow [] = "" doShow ((Obj x):xs) = show x ++ doShow xs we can have a "heterogenous" list of `Obj`s, like a java `ArrayList<IPrintable>`. each `Obj` is basically a pointer to the actual value of some type T and a pointer to T's Show dictionary (vtable). Which is afaik analogous to how OOP languages do it