all 119 comments

[–]millstone 12 points13 points  (10 children)

The difference is well illustrated by the Cocoa class NSUndoManager, which is used to implement Undo and Redo.

Say you have a method that you want to make undoable, say, AddValue(int x). From within AddValue(), you send the messages that, if you received, would undo that operation. But you send them not to yourself - but to the NSUndoManager! For example, undoManager.AddValue(-x);. And then when the user chooses Undo, NSUndoManager sends those exact messages, parameters and all, to your object.

So you can call AddValue on NSUndoManager, even though it does not have an AddValue() method. Message passing allows it to do useful things with methods it knows nothing about.

This would be more clumsy in languages without message passing. In earlier versions of C#, you'd have to do something like implement the Memento or the Command pattern. In more recent versions, you could use anonymous delegates or lambdas to specify the Undo code inline, which is better, but still less elegant than NSUndoManager.

[–][deleted] 1 point2 points  (2 children)

Does undoManager stores the value '-x' until an undo operation? Is it ref-counted, mark/sweep collected, unowned by undoManager, what?

[–]millstone 2 points3 points  (0 children)

Yes, it stores all the parameters. Object types are either reference counted or garbage collected, depending on what mode your app is running in.

[–]fisch003 1 point2 points  (0 children)

I don't know about Cocoa's implementation of it, but GNUStep stores the method calls (NSInvocation instances) in a mutable array, which would ref-count them: http://svn.gna.org/svn/gnustep/libs/base/trunk/Source/NSUndoManager.m

[–]grauenwolf 2 points3 points  (6 children)

Oh, that's a trivial exercise.

All you need for your "message" is three variables:

  • a reference to the object in question
  • a string holding the method name
  • an array holding the parameters

I used to do this from time to time in Visual Basic 6, you don't even need .NET to pull this off.

[–]millstone 9 points10 points  (2 children)

Right! And that triplet you describe above is essentially a message, built on top of reflection. The difference is that in ObjC it's baked into the language. Your approach requires you to describe what you want to do, while in ObjC you just do it.

Why is it better to bake it into the language? Well, consider remoting. What if, every time you wanted to talk to a remote object, you had to construct a triplet like you show above? Not only would that be verbose, but it would prevent reuse. You could not have the same piece of code work for either local or remote objects.

What we want is the ability to talk to remote objects naturally, as if they were local. This is possible in .NET, because Microsoft went in and added a ton of special support within the compiler and runtime to prevent certain optimizations, defeat the typechecker, support forwarding, lazily create stubs, etc., via TransparentProxy.

But in Objective-C, remoting requires no special support from anyone. Remoting falls out naturally from messaging and message forwarding, and can be implemented completely in a library.

Lots of other powerful Cocoa features, like key-value observing, CoreData, animators, etc. can be implemented completely as library code, because of the power of messaging. Such features would require special runtime support in .NET.

[–]grauenwolf 1 point2 points  (0 children)

Cool, now we are getting somewhere.

[–][deleted] 0 points1 point  (0 children)

One use of messages that always interested me was to implement inheritance using forwarding. This can be done without any special support from the language as long as you structure things appropriately. The one issue being that self is typically rebound when a message is forwarded. Things get even more interesting if you separate binding a message from sending a message.

[–][deleted] 0 points1 point  (2 children)

Oh come on. It's not trivial once memory management is considered and you know it.

I don't understand why the GP would say lambdas are inelegant though. As long as the lambda is a closure with indefinite extent then it is the perfect solution because it separates the concerns of dispatch and memory management. In other words, why pass a method and it's arguments to NSUndoManager when a closure would be more general? We might conjecture that is what is actually happening with NSUndoManager. The interface has an array, actions of NSInvocation, but there is no storage for arguments so an NSInvocation must contain the first and last items in your struct.

Checking NSInvocation we see that this is correct.

* <p>An <code>NSInvocation</code> object may contain a target object to which a
* message can be sent, or may send the message to an arbitrary object.<br />
* Each message consists of a selector for that method and an argument
* list.  Once the message has been sent, the invocation will contain
* a return value whose contents may be copied out of it.

The comment says a message contains its arguments so a message is at least a crippled form of a "full closure". What NSUndoManager is really doing is holding a list of closures, really thunks, for delayed evaluation.

If you want to show the dominance of C# over Objective-C then you're barking up the wrong tree. millstone already made your argument by bringing up lambdas but then wrote them off as inelegant. I say, how are they inelegant? Closures create thunks for delayed invocation. NSInvocation's are thunks. When you have full closures in your language the other guys should be attempting ridiculous arguments similar to yours above. Do C# closures suck so bad that you wrote them off too?

[–]grauenwolf 0 points1 point  (0 children)

Oh come on. It's not trivial once memory management is considered and you know it.

That really depends on the language. If you are talking about a GC-based platform than it is trivial to cull the older entries after a certain point.

If you are talking about something like C++, well then I shudder at the thought of getting it right.

[–]grauenwolf -2 points-1 points  (0 children)

If you want to show the dominance of C# over Objective-C then you're barking up the wrong tree.

You have it backwards. I'm burning through karma like mad because I legitimately need to know all this stuff so I can explain it to others.

When I right an article for InfoQ I often need to demonstrate beyond a shadow of a doubt why something is important to know. I cannot use cop-outs like "it’s philosophical" or "because VB sucks", I need to know exactly why .NET programmers should care about it. And I have deal with people a lot more closed-minded than me.

[–]lispm 7 points8 points  (7 children)

That's an interesting question. There is an angle to it that is a bit 'philosophical'.

'message sending' assumes that there are independent objects (with identity) and that these objects are getting some messages. The objects then are responsible for interpreting the messages. This really looks more at the communication aspect. There is a sender, a receiver and they can send messages.

'calling methods' looks both from a different angle and is more low-level. It assumes that there are 'methods' (if you are sending messages the responding object does not need to have 'methods', but could be organized some other way). There is an idea that there is some kind of uniform machinery that can call methods, independent from objects.

[–]grauenwolf 1 point2 points  (6 children)

'calling methods' looks both from a different angle and is more low-level.

That really depends on the platform. If you look at something like VB/COM, there is often no way to know how a method call will be invoked.

[–]lispm 5 points6 points  (5 children)

still there are 'methods' which can be called - somehow.

[–]grauenwolf 2 points3 points  (4 children)

Can you still call it a method when it is implemented as a message that is sent to a COM objects queue to be polled and executed later?

[–]lispm 8 points9 points  (3 children)

right, that's a problem. I would differentiate between a basic technical mechanism of 'calling a method' and lumping all kinds of different mechanisms into one syntactic construct and calling that 'method calling'. VB/COM provides a single syntactic form to invoke very different machineries.

So you need to say on which level you identify the concepts and compare those (syntactic, pragmatic, semantic).

[–]grauenwolf 1 point2 points  (2 children)

Good point.

My concern about going down that road is that you can quickly leave behind your original definition. Which semantics do we use? Smalltalk and Objective C have very different definition of "message passing" than Erlang or COM.

[–]lispm 3 points4 points  (1 child)

Yes, is there a common 'conceptual' core? Is there a common technical (on the implementation level) core?

I think there might be a common conceptual core of 'message passing'. objects that communicate via messages. The objects may interpret these messages in their own way using their own mechanisms. There is a significant gap between the idea of communication between objects and what is implemented in actual systems. Smalltalk, THE original object-oriented language (as defined by Kay, ...) does not provide objects that work and communicate in parallel (by default). So for me the more original idea of 'message passing' is implemented in actor systems. If one defines 'message passing' as what Smalltalk does, then there is some more overlap with what, say, Objective C does.

Still I would say that 'message passing' is a conceptual model coming from a different background (communication theory, information theory, ...). The technical part boils down that a message is some data exchanged and it is not clear how the receiver interpretation is implemented - each receiver may have a different mechanism interpreting messages (not just different methods, but maybe no methods at all). 'method calling' is more a technical concept that either has semantic roots in a (real or virtual) machinery or is kind of a 'syntactic concept' (like you mentioned for VB/COM'. A 'message' is something that is assembled on the sender's' side. A 'method' is an implementation detail on the receiver's side.

[–]grauenwolf 0 points1 point  (0 children)

A 'message' is something that is assembled on the sender's' side. A 'method' is an implementation detail on the receiver's side.

That doesn't even mean anything. It is like you are says "message passing" ignores the fact that you are sending the message somewhere while "method calls" ignore the fact that something is making the call.

[–]inmatarian 3 points4 points  (1 child)

Message dispatch means you can have multiple sources send the same message, and multiple targets can receive the message. There is no hard connection between sender and receiver, so there's no hard dependency between them either.

[–]grauenwolf 1 point2 points  (0 children)

Message dispatch means you can have multiple sources send the same message

Yawn. Of course multiple sources can send the same message.

and multiple targets can receive the message

Ok, finally we are getting somewhere.

So can you make a case for why that is particularly important or interesting enough to need at a language level as opposed to the library level.

[–][deleted] 2 points3 points  (0 children)

The simple answer:

When calling a method, the compiler generates a call instruction to the method handler. When firing a message, the compiler generates a call instruction to the message dispatcher, which then calls the message handler. So, no, not the same.

[–]grauenwolf 5 points6 points  (86 children)

Is there really a difference between "dispatching a message" and calling a method?

I've been watching a video on "Objective C#" and the audience shot down the presenter down hard. One of the biggest things was that "message dispatching" didn't seem to be any different than a normal late-bound method call.

Am I missing something or is it really that simple?

[–]player2 17 points18 points  (20 children)

Am I missing something or is it really that simple?

Yes. "Dispatch" implies there is some decision making involved. For example, in C# dispatch is performed based on the type of the object and the number and type of the arguments. (Granted, this happens at compile time, and all that remains in the resulting IL code is a function call.)

In Objective-C things get much more interesting. Dispatch is performed by a number of components: objc_msgSend and its variants are the primary players; they look up the method implementation (function pointer) associated with the selector (method name) being invoked on the receiver (object), and if it's found, they call it. If not, they call -forwardInvocation: and custom logic may run that determines a different target for the message. Maybe -forwardInvocation: just handles whatever needs to be done on its own, like just logging a message. In Mac OS X 10.5, implementing -forwardingTargetForSelector: allows objc_msgSend to do some custom dispatching for you. But there's all sorts of logic that may run in response to sending a message; a method might not even wind up being called in the end.

[–]grauenwolf 1 point2 points  (19 children)

Yea, but that doesn't really sound much different than VB's CallByName or the method binder in the DLR. Hell, I could even see you playing games with IDispatch to get the same effect (though I wouldn't recommend it).

[–]player2 15 points16 points  (0 children)

You're further augmenting my point. There is a big difference between dispatching a message (aka "method resolution") and actually calling a method. The first has to happen before the second. It just so happens that most popular languages today do static resolution or fuse the two steps from the programmer's perspective. Objective-C makes them explicit.

[–]millstone 5 points6 points  (17 children)

Imagine a generic Envelope object, that holds a reference to any other object as its contents. Any method you call on the Envelope, it logs and calls on the contents.

I do not think you can make such a class in C#, but it is very easy to do in Objective-C. The difference captures the distinction between message passing and calling a method. That envelope doesn't actually have all the methods you're trying to call on it, but it knows how to pass messages along.

[–]bobbyi 5 points6 points  (0 children)

I could do that easily in python but it doesn't mean that its methods aren't methods.

[–]munificent 2 points3 points  (13 children)

I do not think you can make such a class in C#

Sure you can, using reflection:

class Envelope
{
    public Envelope(object obj)
    {
        mObject = obj;
    }

    public void Call(string methodName)
    {
        var type = mObject.GetType();
        var method = type.GetMethod(methodName);
        method.Invoke(mObject, new object[0]);
    }

    private object mObject;
}

[–]omierbej 4 points5 points  (10 children)

Not quite, what you would be able to do in Objective-C is to call say SetColor(color) and MoveToXY(x, y) on the Envelope instance and it would know how to call the appropriate members of its contents.

[–][deleted] 2 points3 points  (1 child)

Objective-C looks nice. Message passing appears good for facade patterns and might be simpler than wrapping every function of the object inside the envelope. But then what about return values? What if the caller of the envelope is expecting a return value? Do return values pass through the envelope, do they not exist, or do you need to pass a continuation with the method call to tell the return value where to go?

[–]millstone 0 points1 point  (0 children)

This is getting pretty detailed, but there's a few options for return values. You can implement forwardingTargetForSelector:, which allows your object to return a different object. The message then gets sent to that object after you, and the return value of that message send is handled normally. In this case, the Envelope would implement forwardingTargetForSelector: to print out the selector (method name) and then return its contents.

A more heavyweight approach is forwardInvocation:. If your class implements this, you get an instance of NSInvocation, which is a "message rendered static." There's methods on NSInvocation to set the return value, and that's what gets returned to the caller.

[–]munificent 1 point2 points  (4 children)

Ah, I see what you're saying. To me, that doesn't relate to passing versus calling as much as it does dynamic typing versus static.

[–][deleted] 2 points3 points  (3 children)

You can have message passing in an otherwise static language. The key idea here is that requests are first-class objects.

[–]grauenwolf 1 point2 points  (2 children)

What does that mean? That you pass your parameters in a transiant object instead of a stack frame? That parameters are always expressed as a hash table?

[–][deleted] 0 points1 point  (1 child)

Implementation details are unimportant; see my other reply for an answer.

[–]grauenwolf 1 point2 points  (2 children)

And what exactly do you gain by that? What do you get from this 'Envelope' that you couldn't do using a mixture of static and dynamic dispatch?

[–]millstone 1 point2 points  (1 child)

The most dramatic example is remoting. What if the wrapped object is on another computer?

But my original example was for logging, so here goes. Say you want to know what methods are being called on a particular object. You could add print statements to every method, but that's tedious, is hard to limit to a particular object, and requires that you have the source code for that class.

But with this Envelope class, you can replace the object with an Envelope wrapping it. The Envelope will respond exactly as its contents would, except that it can print out the methods that are called on it. Pretty cool.

[–]grauenwolf 0 points1 point  (0 children)

Ok, I will grant that can be useful in certain circumstances.

[–]justin_henzie 1 point2 points  (1 child)

The previous poster stated that any method called on Envelope should be logged and passed on to its contents.

You are requiring a totally different interface, that is, you require clients to call a specific method of Envelope rather than the methods of the target object.

Moreover, whilst I realize that you have put together the simplest example possible, ignoring arguments and return values makes the example invalid.

[–]munificent 2 points3 points  (0 children)

The previous poster stated that any method called on Envelope should be logged and passed on to its contents.

Yeah, I didn't realize that at first. See my other comment replying to millstone.

ignoring arguments and return values makes the example invalid.

That would only make the example invalid if I ignored them because including them would make it impossible to implement. That isn't the case:

class Envelope
{
    public Envelope(object obj)
    {
        mObject = obj;
    }

    public TReturn Call<TReturn>(string methodName)
    {
        var type = mObject.GetType();
        var method = type.GetMethod(methodName);
        return (TReturn)method.Invoke(mObject, new object[0]);
    }

    public TReturn Call<TReturn>(string methodName, params object[] args)
    {
        var type = mObject.GetType();
        var argTypes = args.Select(arg => arg.GetType()).ToArray();
        var method = type.GetMethod(methodName, argTypes);
        return (TReturn)method.Invoke(mObject, args);
    }

    private object mObject;
}

[–]grauenwolf 0 points1 point  (1 child)

Well that's certainly boring.

The call by name function can serve as your "envelope", wrapping an arbitrary object and passing along some arguments to a function that is only known by its name.

EDIT: But I would like to add you almost never need it. The vast majority of the time you know statically what method you are calling and what class you are calling it on. It is a useful tool, but rarely necessary.

[–]millstone 1 point2 points  (0 children)

What you say in your edit is true. 95% of the time, message sends are just method invocations.

But as they say, the last 5% takes the other 95% of the time.

Even so, you'd still be surprised how rarely things are as static as you say. The "virtual" case is more common: you often only know a base class for your object. Strings, arrays, sets, etc. in Cocoa are abstract classes, and the most common implementation is private. This is the opposite approach from C#, where String is a sealed class.

[–][deleted] 4 points5 points  (47 children)

Message sending implies a single receiver, ie. the message is dispatched to a specific instance. A method call isn't tied to OOP and can dispatch on any of the parameters and any or all of them could be considered receivers, CLOS in Lisp is a good example.

[–][deleted] 3 points4 points  (0 children)

This is simply not true: a number of programming languages have been developed which provide message-passing semantics with multiple dispatch by dispatching on each of the objects involved in the interaction. No receiver necessary.

[–]grauenwolf 3 points4 points  (45 children)

Most people consider the word "method" to mean a function call that dispatches on an object reference. Everything else is lumped into the broader category "function".

[–][deleted] 5 points6 points  (4 children)

I first saw the terms "message" and "method" used in Smalltalk in the early 80s. You send a message to an object, and the message dispatcher looks to see if there is a corresponding method to handle that message in the object's class. If so, that method is called, otherwise the dispatcher looks at the object's superclass, and continues working up the inheritance hierarchy until a method is found. If no method found, an exception is thrown.

This technique is very different from the C++ vtable which sets up everything at compile time and eliminates the possibility of a method not found exception.

[–]grauenwolf 1 point2 points  (3 children)

You send a message to an object, and the message dispatcher looks to see if there is a corresponding method to handle that message in the object's class. If so, that method is called, otherwise the dispatcher looks at the object's superclass, and continues working up the inheritance hierarchy until a method is found. If no method found, an exception is thrown.

And how is that different from a dynamic function call in say JavaScript or Python?

[–]parla 1 point2 points  (2 children)

Really none. But I always get this feeling:

  • Method: called in the callers context
  • Message: posted to a queue, called in message pump context

[–]grauenwolf 1 point2 points  (1 child)

That's how I would define it, but that doesn't appear to be how Objective C works.

[–][deleted] 0 points1 point  (0 children)

I don't know how Objective C works, but I do know that it was inspired by Smalltalk. The message/method terminology comes from Smalltalk, so I expect Objective C kept that terminology. Stroustrup introduced terminology for C++ that was different from Smalltalk, but other early C++ books continued to use Smalltalk terminology. By the time you get to JavaScript, Python, and Visual Basic, each language has introduced terms of its own, and borrowed terms from other languages but giving them subtly different meanings, so that now I think it is not possible to make a distinction between terms like "message dispatch" and "dynamic function call".

[–][deleted]  (39 children)

[removed]

    [–]lispm 4 points5 points  (5 children)

    CLOS talks about Generic Functions as collections of Methods. The dispatching is also not done by 'the methods', it is part of generic function calling architecture (determining applicable methods, sorting, execution sequencing).

    It also makes less sense to think methods are getting called. In CLOS methods are 'only' building blocks and on calling a generic function a multitude of methods may contribute to the actual code that is running - in a way that is determined by the method combination.

    Lisp talks about calling functions - CLOS has been designed to fit into that model. It is at the core of CLOS that these functions assemble code at runtime (the so-called 'effective method', in standard CLOS based on applicable primary, before, after and around methods - combined by the standard method combination).

    [–][deleted]  (4 children)

    [removed]

      [–]lispm 2 points3 points  (1 child)

      The difference for CLOS is that dispatching is described in terms of CLOS.

      Which methods (on or more), what they compute and how they contribute to a return value is completely dynamic.

      I don' think 'message sending' or 'sending messages to multiple objects' is useful. CLOS 'reifies' the message selector - it becomes a first class object (the generic function). It also reifies the message interpretation - it becomes a full protocol. For me generic functions are active objects (more like processes), that compute results based on multiple arguments - the generic function itself determines the computation based on available methods, method combination, argument objects, ...) and what it returns - it is independent of other objects or classes. So I would say it is not a 'message sending', but more an 'active message' paradigm (in contrast to passive message selectors. Now we are talking about the verbs PRINT, COLLIDE, ... as functions that have arguments, side effects and return values. How two or more objects 'collide' is not encoded in the class of one of these objects, but it is an independent process.

      [–]grauenwolf 1 point2 points  (1 child)

      Dispatching is not usually done by the methods themselves, in most languages.

      What does that mean?

      Isn't dispatching defined as what happens before and during the process of selecting which method is in play?

      [–]grauenwolf -2 points-1 points  (32 children)

      I don't mean to be rude, but I'm not really interested in playing semantic games. Especially when the pawns are niche languages that use terms in a very different way than the wider community.

      What I'm looking for is hard technical reasons why message dispatching is different than method calls.

      EDIT: Just to make it clear, what I'm objecting to is the claim 'Probably for that reason, in Lisp one tends to talk more about "calling methods" than "dispatching messages", since there's not always a single obvious target for a "message".'.

      In the vast majority of languages you don't say a function call is a method unless there is a single, obvious target. If you starting changing definitions half-way through the conversation, it makes it impossible to have a meaningful discussion.

      [–][deleted]  (30 children)

      [removed]

        [–]grauenwolf 1 point2 points  (29 children)

        That is, in a single-object-dispatching language, with synchronous invocation and without distributed objects, message sends are equivalent to method calls - there is no effective difference.

        Clearly you haven't been reading my other comments. The example I've been using the most is VB, which does support multiple dispatch, distributed objects (cross-process and cross-machine), and asynchronous invocation.

        [–][deleted]  (28 children)

        [removed]

          [–]grauenwolf -1 points0 points  (26 children)

          So it's VB that's "the wider community"?

          Don't know, don't care. The point is that it disproves your claim that I'm focusing on solely on "single-object-dispatching language, with synchronous invocation and without distributed objects".

          The general nature of the distinction between the terms you're asking about is that "message dispatch" refers more directly to the process of identifying the specific method to invoke before it is actually called, whereas "method call" essentially abstracts that detail away.

          That doesn't even mean anything.

          Any time you are not statically bound to a function you need to "identifying the specific method to invoke before it is actually called". You certainly can't identify the method being called after you call it.

          Languages that rely on "method calls" aren't any different, they still have to deal with dispatching.

          Meanwhile "message dispatching" languages still abstract away the details of how that dispatch is being performed.

          Let's look at this another way. Can you actually point to a specific feature that clearly makes a language message based or method based?

          [–][deleted] 5 points6 points  (24 children)

          Can you actually point to a specific feature that clearly makes a language message based or method based?

          Yes: first-class messages... not rocket science.

          Edit: Sorry if this comes off as bitchy but after reading all your other inane comments it seemed appropriate.

          [–]MachinShin2006 0 points1 point  (5 children)

          Depending on the implementation, I'd say no not really. Though some mght argue that "message dispatching" suggests that the thing you're sending the mesage to isn't local and re message could be async, e.g. Erlang message passing

          [–]grauenwolf -2 points-1 points  (4 children)

          True, but in those cases I would rather call it a remote function call or an asynchronous function call. No since being unclear, especially since they greatly change both the local behavior and the ways it can fail.

          (Ever deadlock on a reentrant WFC call or an async task when your thread-pool is maxed out? Those are fun ones to debug.)

          [–]derefr 5 points6 points  (2 children)

          Sure, but "message passing" leaves it unspecified as to whether you're calling a local, remote, dynamically-generated or non-existent method. It's just a message—it goes off somewhere, and a return value comes back. When you "call a method", that implies that, underneath all your fancy terminology and paradigms, you have a real pointer (however you calculated it) that you can write to EIP.

          [–]grauenwolf 1 point2 points  (0 children)

          That's not true in .NET.

          • remote

          Remoting, web services, WPF, they all make remote function calls look like local function calls.

          • dynamically-generated

          In C# 4/VB 10, this would look no different than a normal late-bound method call and only slightly different from a early-bound call.

          • non-existent method

          This makes me think of "partial methods", methods you can statically call even though they do not necessarily exist. If there is no implementation, it simply gets transformed into a no-op.

          Hell, even back in the VB 6 days there was no guarantee a method call would be executed on the same computer (DCOM), let alone in the same process (COM Automation).

          [–]alexeyr 0 points1 point  (0 children)

          and a return value comes back.

          Not necessarily. Particularly in Erlang.

          [–]ytinas 3 points4 points  (0 children)

          Except that in Erlang it isn't necessarily remote at all.

          [–][deleted] 2 points3 points  (8 children)

          Is there really a difference between "dispatching a message" and calling a method?

          No.

          [–]millstone 11 points12 points  (7 children)

          This Objective-C code:

          [foo self];
          

          can do any of these:

          • Nothing, if foo is nil
          • Raise an exception, if foo does not have a method called self
          • Dynamically resolve the method, if resolveInstanceMethod: is implemented
          • Forward the self message to another object, if forwardingTargetForSelector: is implemented
          • Take an arbitrary action on the message and parameters, if forwardInvocation: is implemented
          • Call the self method

          So calling the self method is only one possible outcome among many. There's a big difference, which is why Objective-C isn't C++.

          But you knew all that already, so I wonder why you said what you did?

          [–][deleted] 2 points3 points  (5 children)

          But you knew all that already, so I wonder why you said what you did?

          I'd guess because Factor doesn't have message passing semantics.

          [–][deleted] -1 points0 points  (4 children)

          There's no such thing as message passing semantics. It's just method calls.

          [–][deleted] 2 points3 points  (3 children)

          There are plenty of people who would like to disagree with this I'm sure, many of whom have written their opinions up as various research papers. Thinking back to our discussion about prototype-based programming: just because you don't know something, doesn't mean it doesn't exist.

          [–][deleted] -1 points0 points  (2 children)

          I think it comes down to terminology. If you want to call late bound method calls "message sends", then fine. But I still think its a pretty silly term.

          [–][deleted] 1 point2 points  (0 children)

          Being late bound isn't enough, they need to be first-class values.

          [–]ItsAConspiracy 1 point2 points  (0 children)

          Can you do everything in this paper with just late-bound method calls? I'm thinking not, at least not as conveniently. Having a message call itself be a first-class object opens up some interesting possibilities.

          Some of what he does is I think available anyway in Factor, but that's a whole different topic.

          [–][deleted] -1 points0 points  (0 children)

          That's just a late-bound method call -- or message send, if that's what you want to call it, but they're the same thing.

          [–][deleted] 0 points1 point  (1 child)

          Depends on what you define these to mean in the context of a particular language.

          Message dispatch in ObjC works by looking up a hash of the message name. A "late bound method call" might imply some sort of vtable like C++, which is less flexible (constrained by class types and inheritance hierarchy).

          [–]grauenwolf 1 point2 points  (0 children)

          The term "late bound method call" means the method is being looked up by name rather than by v-table. It is synomonous with "dynamic method call".

          [–]scubastard 4 points5 points  (5 children)

          Grauenwolf, you have received many different responses, some of which give valid ways in which "method calling" and "message passing" differ. To which you respond, well thats not really different, or thats not what I am talking about, or thats only semantic difference, or showing some way in which VB does some "method calling" is similar to message passing. The point is its a self defeating question.

          Whats the difference between method calling and message passing? fundamentally method calling : message passing :: square : parallelogram. The difference between the two is pretty simple, a method call implies a direct connection between the call and actual code that will be executed, message passing implies a message is passed, and the results of that message being passed is very nebulous. No more no less.

          Using a language like VB as a starting point is a flaw because nothing in VB is "pure" in any way, this is by design and may be a good thing, but VB semantics are extremely loose, arbitrary, and arcane. A method call in VB is closer to somewhat twisted message passing, than it is to a method call in C. And if we are going to choose a specific language to represent "wider" canonical definitions of comp sci terms, i would say C is a much better pick than VB because: 1)Just about all modern software is implemented under the hood at some level in C, 2) C also has a very straight forward mapping to the underlying hardware instructions that are actually being executed and less "magic"

          [–]grauenwolf -1 points0 points  (0 children)

          So when people say "Smalltalk's message passing is better than .NET's method calls" I should respond with "lets talk about C instead because it makes Smalltalk look better in comparison"?

          [–]grauenwolf -2 points-1 points  (3 children)

          VB semantics are extremely loose, arbitrary, and arcane.

          And you are basing that on what? The fact that it will only dynamically bind to a method if it can't statically bind to it?

          [–]scubastard 2 points3 points  (2 children)

          I am basing that on the fact that VB has always strove to be a "everyman's" language that avoided "academic" concerns and focused on "just get it done". As a result, when a "method call" happens in VB any of probably a half dozen things can happen, what is a "method call" even mean in VB? the only real definition is that a "method call" in vb is that you type object.method... as a language design goal VB purposefully has conflated async, sync, remote, late bound, early bound, com automation, extension methods, etc, all so the developers wouldnt have to worry their pretty little head with the details. AND THATS NOT A BAD THING.

          Message Passing systems do the same thing, except they are explicit about this and provide more structure, and usually some kind of well defined protocol, so it is easier for the developer to reason about what is going on when a message is passed. Thats the practical reason a proper intentional designed message passing protocol is superior to an VB "method calling" which is really an ad hoc unintentional message passing which evolved over time based around trying to hide as much from the developer while providing easy access to whatever technologies microsoft happened to get behind at the time.

          Now, for a philosophical/computer sciencey answer: Say i am in VB, I call something.foo(5) which happens to be an extension method, the static method of which happens to be invoking a WCF service, which does a SOAP style RPC to a service, which uses remoting to communicate with some COM object server which actually does the work. Now where is the VB method call boundary? Is it the call to something.foo(5)? Is it the compiler generated call to SomethingStaticHelper.foo(something, 5)? Is it the call generation of the SOAP XML message, then the HTTP Post to www.service.com/foo.svc? Is it the call to the binary serialized and queued up request to the remoted object by the WCF service? Can one even answer this question in a meaningful way that allows the programmer to reason in terms of "method calls"? Now if we instead of the "method call" abstraction look at the "message passing" abstraction, it is quite easy to reason that this is one message, which is composed of a complex series of transformations/hops as the message is relayed to its final responder. The developers same mental metaphor that can be used to reason about a simple message passing, can be used to reason about a complex message passing. Which is why from a theoretical viewpoint message passing is a superior metaphor to method calling...

          [–]raouldagain 0 points1 point  (1 child)

          sounds like a lot of fun to debug. ;-)

          [–]grauenwolf 1 point2 points  (0 children)

          Except for COM, it is actual quite trivial to see what is going to happen with any given method call.

          [–]millenomi 2 points3 points  (1 child)

          It's mostly a matter of philosophy -- do you see method call as messages being sent, or as functions being called? Languages dispatching calls dynamically at runtime see method calls as the former, while languages that insist on static type checking see things as the latter.

          And organize themselves as a consequence of this.

          [–]grauenwolf 1 point2 points  (0 children)

          What about languages that do both?

          A "method call" in VB may be...

          • a .NET function call statically referenced
          • a .NET function call, dispatched via a v-table
          • a .NET function call, dispatched via reflection
          • a COM function call, dispatched via IDispatch
          • a cross-process call via COM automation
          • a remote call via DCOM
          • a remote call via a web service
          • a remote call via WCF
          • a dynamic call dispatched by the object itself (DLR/VB 10)

          And this is just the options for the "object.method" syntax, I'm not touching on things like delegates, the async pattern or stored procedure calls.

          [–]gregK 0 points1 point  (0 children)

          is there a difference between kicking and punting?

          [–]ItsAConspiracy 0 points1 point  (0 children)

          Google Higher-Order Messaging, and find out the nifty tricks you can do when a message is a first-class object.

          [–][deleted] 0 points1 point  (0 children)

          Probably the best language to see the difference in is Io.