4 ms·
Multimethods and overloading are completely different beasts, despite the syntactic similarity. Overloading is resolved at compile time by looking at the compil
by jules 15y ago
Multimethods and overloading are completely different beasts, despite the syntactic similarity. Overloading is resolved at compile time by looking at the compile time types. Multimethods are dispatched at run time, by looking at the run time values. This makes overloading much less powerful. Multimethods are in fact problematic in statically typed languages; they are difficult (but not impossible) to type check.
- groovy2shoes 15y agoOverloaded functions are only partly resolved at compile time. The dispatch itself happens at run time using only one function parameter (single dispatch), which can be any of any compatible type. Single dispatch turns out to be super fast to implement with vtables; multiple dispatch tends to be slower, but it's sometimes worth it for the added expressiveness.
- barrkel 15y agoOverload resolution is entirely a compile-time task. But the method resolved may itself be virtual, and so use dynamic dispatch in its invocation. (Overload resolution is a pattern matching task, selecting a signature from a list of signatures, given a tuple of candidate value types[1]. It's not just used for invocation, but also when e.g. determining which overload of a function to assign to a function pointer.) [1] The set of value types is usually larger than the set of types available for use in signatures. For example, most static languages don't have a name for the type of the 'null' or 'nil' value, so you usually can't refer to it in a signature (and nor would it be particularly useful to do so).
- barrkel 15y agoThey are only completely different beasts if you think the distinction between compile time and run time is very important. That's not necessarily the case. There is the text of the program at one end, and pushing electrons at the other. At exactly which point this thing we call "compiling" occurred is just a detail that may or may not help us in other - typically human factor - goals. Multimethods, to a first approximation, is overload resolution at run time rather than compile time. They are not just syntactically similar; they are semantically similar too. Multimethods is the dynamic language analogue to overloading in static languages.
- riffraff 15y ago> Multimethods is the dynamic language analogue to overloading in static languages. This implies that multimethods are not possible in statically typed languages, which is trivially disproven by stuff like the Nice programming language. The difference between compile and run time is a red herring, since the actual distinction is between a statically _declared_ type and a dynamic type (which FWIW could be determined statically within AOT compilation).
- barrkel 15y agoNo, it doesn't imply that, because static and dynamic are not mutually exclusive. A static language with polymorphism[1] has both static and dynamic aspects. A purely static language does not need (and thus won't have) runtime type tags of any kind, so any kind of dynamic dispatch (including multimethods) would be impossible at the level of the language (i.e. you'd have to implement it all explicitly as a library). [1] It shouldn't need to be said, but this is HN so it does need to be said, but I mean OO-style runtime polymorphism here (or, with a stretch, sum types), not parametric polymorphism.
- igouy 15y agoWhy haven't you told us what you mean by the notoriously vague terms "static" and "dynamic"?
- barrkel 15y agoBecause defining every word one uses in a forum post is incredibly tedious, and even when you try to do so preemptively, someone still comes in and asks you for definitions of more words. I'm using them in a colloquial rather than rigorous sense, because that's the lowest friction way of communicating in a casual setting. But at core, when I say 'static', I mean something determined before execution, by means of static scopes and compile-time types; when I say dynamic, I mean something determined at the point of execution, by means of dynamic scopes and run-time values. When I say 'static scopes', I mean scopes determined through lexical nesting and static types. When I say 'static type', I mean types determined without need for any execution of the target program. When I say 'dynamic scopes', I mean scopes determined through dictionary lookup at runtime (vtables are dictionaries too), possibly even including dynamic scopes (cf Lisp, Javascript eval, etc.). Most languages have both dynamic and static aspects, but the mixes vary greatly. Languages designed to be compiled typically use far more statically resolved features, because if you can afford the time to put into analysis, and you have all the source immediately available, you can find a lot of common bugs and generate faster code. Languages designed to be interpreted typically use far more dynamically resolved features, because that gives less latency to execution, more expressiveness, more flexibility with modularity and program composition, and is also easier to implement.