Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

this distinction is something i have been struggling with for some time. i am coming from pike which only uses method invocation terminology (in pike it's actually called "function call"), and never even hints at message passing, yet in pike objects can take control over the target of a function call and even dynamically create functions based on arguments given.

when learning smalltalk i could not see the what was so special about message passing, and why it is even called that.

consequently, i find the distinction between message passing vs function or method calling academic. more interesting are distinctions like static vs dynamic dispatch and early vs late binding and whether things are defined at compile time or runtime.

the term "message passing" always made me feel like this should be something completely different and not even remotely similar to function calling. yet i couldn't see that difference and that left me irritated because i felt like i was missing something.



The language is made a lot more confusing by the fact that most of the time you can improve performance of a conceptually message-passing implementation by implementing it as much as possible in terms of invocation, so it's totally reasonably why even very dynamic implementations would end up spoken of as method invocation.

E.g. my long-languishing partial Ruby compiler uses C++ style vtables because they're fast and the "only" challenge is that you need to propagate method re-definitions down a chain of descendant classes (and avoid overwriting overridden versions in the descendants). In practical terms, pseudo-code for a method dispatch is ob->class_ptr.vtable[method_slot](args...) and all of the dynamism happens with a combination of dynamically overwriting and propagating method pointers down the vtable chain (I was worried it'd lead to way too much memory spent on sparse vtables and having to fall back on a hash table for less-used method names, but in practice the number of classes is usually very constrained) and filling in thunks that forwards to method_missing for names that are seen in the system but not implemented by the current class.

Effectively you can consider the vtables as perfect pre-filled caches. To someone casually looking at them to get an idea of Ruby, it'll look like Ruby's object model is almost the same as C++'s.

So I agree with you that the key practical difference is static vs. dynamic dispatch and early vs. late binding. With those distinctions you don't really even need to make the compile vs. runtime distinction. That is, you can statically compile something that includes dynamic calls to modify the object model, like my prototype compiler.

Elsewhere I suggested one way of looking at it is that to distinguish the C++/Java etc. and Smalltalk model of OO, the key test is how common it is for there to be code where determining which method body will be invoked by a given call devolves to the halting problem if you don't have the precise inputs ahead of time (e.g. in Ruby, almost every ORM would cause this).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: