Hacker News new | ask | show | jobs
by bad_user 2622 days ago
C++'s vtable is also late binding, since you don't know which implementation you're calling until runtime. And there's no such thing as "extremely late binding".

> In C++, for example, the only kind of late binding that you have is abstract classes and vtables.

That's not true, you can always have a "send_message(string id)". Few people do it because you lose static type safety. And some languages, like C# and Scala, have dynamic types that allows for the "method_missing" protocol and such features are very unpopular.

To be honest I don't see much of a difference. I've worked with a lot of dynamic OOP languages, including with Erlang-style actors and I've never seen the enlightenment of dynamic OOP message passing.

And I actually like OOP, but I don't really see the point of all this hyperbole about Smalltalk.

3 comments

> That's not true, you can always have a "send_message(string id)". Few people do it because you lose static type safety. And some languages, like C# and Scala, have dynamic types that allows for the "method_missing" protocol and such features are very unpopular.

That is the difference. If every class in C++ had only one method - send_message and each object is an independent thread, you will get how Erlang works. That is how you would do the actor model in C++.

Inheritance, Polymorphism is emphasised in Java, C++ and C#, whereas Functional programmers emphasise function objects / lambdas / Command Pattern where you just have one method - calling the function. Infact having just method you no longer need Polymorphism / Interfaces.

What? This has nothing to do with functional programming.

FP needs polymorphism too and as a matter of fact FP tends to be even more static.

In FP we have type classes, built via OOP in static OOP languages.

> Infact having just method you no longer need Polymorphism / Interfaces.

That’s false.

It's not. You can use multiple dispatch.
But then why would you? Isn't ditching type safety a bad idea most of the time ?
> C++'s vtable is also late binding, since you don't know which implementation you're calling until runtime. And there's no such thing as "extremely late binding".

C++'s vtables are determined at compile time. The specific implementation executed at a given moment may not be possible to deduce statically, but the set of possible methods is statically determined for every call site: It consists of the set of overridden implementations of the method with that name in the class hierarchy from the named type and downwards.

No such restriction exists in Ruby or Smalltalk or most other truly dynamic languages. E.g. for many Ruby ORM's the methods that will exist on a given object representing a table will not be known until you have connected to the database and read the database schema from it, and at the same time I can construct the message I send to the object dynamically at runtime.

Furthermore the set of messages a given object will handle, or which code will handle it can change from one invocation to the next. E.g. memoization of computation in Ruby could look sort-of like this:

    class Memo
      def method_missing op
         result = ... execute expensive operation here ...
         define_singleton_method(op) { return result }
      end
    end
After the first calculation of a given operation, instead of hitting method_missing, it just finds a newly created method returning the result.

"Extreme late binding" is used exactly because people think things like vtables represent late-binding, but the ability to dynamically construct and modify classes and methods at runtime represents substantially later binding.

E.g. there's no reason why all the code needs to be loaded before it is needed, and methods constructed at that time And incidentally this is not about vtables or not vtables - they are an implementation detail. Prof. Michael Franz paper on Protocol Extension [1] provided a very simple mechanism for Oberon that translates nicely to vtables by dynamically augmenting them as code is loaded at runtime. For my (very much incomplete) Ruby compiler, I use almost the same approach to create vtables for Ruby classes that are dynamically updated by propagating the changes downwards until it reaches a point where the vtable slot is occupied by a different pointer than the one I'm replacing (indicating the original method has been overridden). Extending the vtables at runtime (as opposed to adding extra pointers) would add a bit of hassle, but is also not hard.

The point being that this is about language semantics in terms of whether or not the languages allows changing the binding at runtime, not about the specific method used to implement the method lookups semantics of each language - you can implement Ruby semantics with vtables, and C++ semantics by a dictionary lookup. That's not the part that makes the difference (well, it affects performance)

> That's not true, you can always have a "send_message(string id)". Few people do it because you lose static type safety. And some languages, like C# and Scala, have dynamic types that allows for the "method_missing" protocol and such features are very unpopular.

If you're working in a language with static typing you've already bought into a specific model; it's totally unsurprising that people who have rejected dynamic typing their language choice will reject features of their statically typed language that does dynamic typing. I don't think that says anything particularly valuable about how useful it is. Only that it is generally a poor fit for those types of languages.

[1] Protocol Extension: A Technique for Structuring Large Extensible Software Systems, ETH Technical Report (1994) http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.42....

The only good thing about OO as a architecture is, that there is nearly no education required to introduce it to the most novice in the field. Its basically the default thinking approach rebranded. It comes with all the benefits of a mental model - quick orientation, and all the negative of a mental model. (Badly adapted to fit to machine execution, after acertain complexity level is reached - god like actorobjects - basically programmers in softwaredisguise- start to appear).
Disagree. The original design patterns book was really about ways oop should be used that don't fit people's everyday conception of objects. (Of course that causes different problems for the novice keen to use the patterns but that's another story)