5 ms·
Huh? Could you give a specific example? Because e.g. C++ and Rust definitely have dynamic dispatch through their vtable mechanisms.
by ImprobableTruth 5y ago
Huh? Could you give a specific example? Because e.g. C++ and Rust definitely have dynamic dispatch through their vtable mechanisms.
- ukj 5y agoDo you understand the difference between compile time and runtime? Neither C++ nor Rust give you static type safety AND dynamic dispatch because all of the safety checks for C++ and Rust happen at compile time. Not runtime.
- detaro 5y ago> Neither C++ nor Rust have dynamic dispatch You appear to be using some other definition of dynamic dispatch than the rest of the software industry...
- ukj 5y agoYou appear to be conflating compilers with runtimes. Dynamic dispatch happens at runtime. C++ and Rust are compile-time tools, not runtimes.
- BoiledCabbage 5y agoYou are wrong. C++ supports dynamic dispatch. Please read about it on Wikipedia https://en.m.wikipedia.org/wiki/Dynamic_dispatch https://en.m.wikipedia.org/wiki/Dynamic_dispatch And for the future to not litter HN with comments like these, next time 10 different people in thread are all explaining to you why you're mistaken, take a moment to try to listen and think through what they're saying instead of just digging deeper. Having an open mind to learning something new, not just arguing a point is a great approach to life.
- ukj 5y agoYou are wrong about me being wrong. C++ is just a compiler. It outputs a binary for a target platform. The compiler does nothing for you at runtime - certainly not "type safety". Sometimes the 10 people on HN are wrong. This is one of those times.
- Jtsummers 5y agoC++ is not a compiler. C++ is a language with a specification from which people derive compilers and standard libraries and runtimes. C++ the language very much does tell you what to expect at runtime, though perhaps not everything you could ever want. I mean, it's not Haskell or Idris with their much richer type systems.
- ukj 5y agoPerfect! Please produce a piece of code (in a language such as Coq or Agda) which proves whether any given piece of random data has the type “C++ compiler” or “C++ program”. That is the epitome of static type-checking, right?
- ukj 5y agoHah! No wonder you don't grok my perspective. If you derive a C++ compiler that accepts file A as valid C++. And I derive a C++ compiler that rejects file A as valid C++, then from the lens of type theory the two compilers have different type-signatures! They are not the same formal language. One, or both compilers implement a language that is not C++.
- detaro 5y agoAnd the compiler generates the code necessary for dynamic dispatch to happen at runtime.
- ukj 5y agoBut it doesn’t static-type-check that particular code-path. Because it can’t.
- dkersten 5y agoDynamic languages do it at runtime too, JUST LIKE rust and C++ do. What's the difference? C++ and Rust let you have compile-time safety, until you choose to give it up and have runtime checks instead. Dynamic languages only allow the latter. Static languages let you choose, dynamic languages chose the latter for you in all cases. Both can have dynamic dispatch. Besides, static languages can have compile-time type safe dynamic dispatch, if you constrain the dispatch to compile-time-known types (eg std::variant). You only lose that if you want fully unconstrained dynamism, in which case you defer type checking to runtime. Which is what dynamic languages always have. So both C++ and Rust DO have dynamic dispatch and the programmer gets to choose what level of the dynamism/safety trade off they want. And yes, these features ARE first class features of the languages.
- ukj 5y ago>until you choose to give it up PRECISELY You have to give up the safety to get the feature. So you "want type-safety". Until you don't. >static languages can have compile-time type safe dynamic dispatch "Compile-time dynamic dispatch" is an oxymoron. Dynamic dispatch happens at runtime.
- deleted 5y ago[deleted]
- jsnell 5y agoI think you might need to define what you mean by dynamic dispatch, because it is very clearly something totally different than how the term is commonly understood.
- ukj 5y agoDeciding which implementation of a function handles any given piece of data at runtime. Trivially, because you don’t have this knowledge (and therefore you can’t encode it into your type system) at compile time.
- justinpombrio 5y agoAha! I think I have debugged your thinking. Wow you made that hard by arguing so much. Apparently you do know what dynamic dispatch is, you're just wrong that it can't be type checked. In Java, say you have an interface called `Foo` with a method `String foo()`, and two classes A and B that implement that method. Then you can write this code (apologies if the syntax isn't quite right, it's been a while since I've written Java): Foo foo = null; if (random_boolean()) { foo = new A(); } else { foo = new B(); } // This uses dynamic dispatch System.out.println(foo.foo()) This uses dynamic dispatch, but it is statically type checked. If you change A's `foo()` method to return an integer instead of a String, while still declaring that A implements the Foo interface, you will get a type error, at compile time.
- ukj 5y agoSo, there is nothing dynamic about that dispatch. Because the implementation details of Foo are actually know at compile time. Which is why you are able to type-check it. You have literally declared all allowed (but not all possible) implementations of Foo. What happens when Foo() is a remote/network call?
- detaro 5y agoso you are using a different definition of dynamic dispatch than the rest of the software industry.
- lexi-lambda 5y agoThis is sort of a perplexing perspective to me. It seems tantamount to saying “you can’t predict whether a value will be a string or a number AND have static type safety because the value only exists at runtime, and static type safety only happens at compile-time.” Yes, obviously static typechecking happens at compile-time, but type systems are carefully designed so that the compile-time reasoning says something useful about what actually occurs at runtime—that is, after all, the whole point! Focusing exclusively on what happens at compile-time is to miss the whole reason static type systems are useful in the first place: they allow compile-time reasoning about runtime behavior. Just as we can use a static type system to make predictions about programs that pass around first-class functions via static dispatch, we can also use them to make predictions about programs that use vtables or other constructions to perform dynamic dispatch. (Note that the difference between those two things isn’t even particularly well-defined; a call to a first-class function passed as an argument is a form of unknown call, and it is arguably a form of dynamic dispatch.) Lots of statically typed languages provide dynamic dispatch. In fact, essentially all mainstream ones do: C++, Java, C#, Rust, TypeScript, even modern Fortran. None of these implementations require sacrificing static type safety in any way; rather, type systems are designed to ensure such dispatch sites are well-formed in other ways, without restricting their dynamic nature. And this is entirely in line with the OP, as there is no tension whatsoever between the techniques it describes and dynamic dispatch.
- ukj 5y agoYou must be strawmanning my position to make this comment. Obviously static type systems are useful. I don't even think my point is contrary to anything you are saying. This is not being said as way of undermining any particular paradigm because computation is universal - the models of computation on the other hand (programming languages) are not all “the same”. There are qualitative differences. Every single programming paradigm is a self-imposed restriction of some sort. It is precisely this restriction that we deem useful because they prevent us from shooting off our feet with shotguns. And we also prevent ourselves from being able to express certain patterns (of course we can deliberately/explicitly turn off the self-imposed restriction! ). Like the restriction you are posing on your self is explicit in "type systems are carefully designed so that the compile-time reasoning says something useful about what actually occurs at runtime" If you could completely determine everything that happens at runtime you wouldn't need exception/error handling! All software would be 100% deterministic. And it isn't. I can say nothing of the structure of random bitstreams from unknown sources. I only know what I EXPECT them to be. Not what they actually are. In this context parsing untrusted data IS runtime type-checking.