In smalltalk, everything happens by sending messages to receiver objects. Its syntax usually follows the format receiver message, in which receiver is an object that the message is sent to. Now I cant stop wondering, what is the sender of smalltalk messages? Consider the following smalltalk statement:
aMorph color: Color yellow
I can see aMorph as the receiver of message, but what about the sender? The standard smalltalk message syntax has only receiver and the message(selecter + arguments), I cannot identify what and where the sender is. Or perhaps, a message can actually send itself?
I remember browsing through an article about reflection in pharo smalltalk in which it mentioned sender of a message, but I cant find or understand what is this 'sender'. Can anyone explain this to me about this? Thanks.
The sender is determined and set at runtime whenever a message is sent. From the perspective of the currently executing method, it answers the question 'how did we get here?' In the most common case, the sender would be whatever method sent the message that resulted in the current method being called. (one exception would be a #doesNotUnderstand: handler that redirects a message to some place other than the originally intended destination) In Squeak for example, if you doIt on aMorph color: Color yellow from a workspace, the sender will be UndefinedObject>>DoIt. If you sent the same message from MyObject>>myTestSender, the sender will be MyObject>>myTestSender.
Now let's say you wrapped aMorph in a proxy object myProxy, an instance of MyProxyObject, and its doesNotUnderstand: method forwards everything it receives to the underlying aMorph object. In this case, when you doIt myProxy color: Color yellow, the sender will be MyProxyObject>>doesNotUnderstand:. (unless your doesNotUnderstand: method further manipulates the runtime... which it can do if it needs to) This is actually a good example of when you might need to look at who the sender of #color: is: it's being invoked but you don't understand from where since the proxy adds a level of indirection that may not be obvious to you.
So in order to see who the sender is, you could add the following to the color: method:
Transcript show: thisContext sender asString.
From the perspective of your code, dealing with sender is implicit and handled for you by the Smalltalk runtime during normal code execution. Unless you're troubleshooting some code or otherwise needing to introspect or alter things at runtime, you won't often be looking at the sender.
Now this may raise the question 'what the heck is thisContext?' It's a special variable representing the top of the callstack and is something that many people have a difficult time wrapping their heads around initially. See How does Smalltalk manipulate call stack frames for more information.
Addendum (hopefully this will clear up any confusion between Leandro's answer and mine)
Leandro's answer is looking at sender as a general term and considers the larger historical context, while mine is a more contemporary Squeak/Pharo-centric one and has a very specific meaning. I agree with Leandro's point that the term sender is ambiguous and not standardized across implementations (as our different answers prove.) Just to muddy the waters even further, in the Blue Book references to sender are talking about the sending context... which is neither self nor thisContext sender. However, the links referred to in the comments on the question were explicit in their meaning (i.e. thisContext sender) as is commonly meant when referring to Squeak/Pharo code. So which answer is correct depends on whether you are looking at a specific Smalltalk implementation (in which case, the correct usage is whatever one the implementation you are using has decided on) or as a more general term when talking about no particular Smalltalk implementation (in which case Leandro is correct: it's subject to interpretation as its usage has been overloaded to near-meaninglessness)
You can think of the sender as being self. In other words, when a method is activated (i.e., during its execution), the object represented by self can be interpreted as the sender of all the messages sent in the method's body.
Consider for instance the method #paint:, defined in OurClass as
paint: aMorph
aMorph color: Color yellow
As soon as this method is executed, the (sub)instance of OurClass receiving the paint: message, will become self. Well, during this activation of the method, self could be attributed the role of the sender of color: to aMorph.
Note however, that this is just a matter of interpretation. For instance, you could also consider the process being executed and identify the sender as the process frame that activated #color:.
While both interpretations are valid, the reality is that in Smalltalk the notion of sender is irrelevant because the act of sending a message is primitive, i.e., implemented in the Virtual Machine, not in the Virtual Image.
Of course, for communication purposes it is useful to assign that role to someone and even speak about the sender. But the object implied depends on the context. For instance, when debugging, you would identify the sender with the calling frame. However, since message sends happen "magically", there is no actual need to attach the role of sender to any object.
Even in Bee Smalltalk, where you can reach the internals of the runtime because there is no VM, the notion of sender is also fussy and rather unnecessary. Technically speaking, every send in Bee has a SendSite object that performs all the steps needed to send the message (PIC, lookup, etc.) And since you can inspect these objects and send messages to them, you could speculate that in Bee the sender is the SendSite. But again, this is subject to interpretation. In fact there is no sender ivar in the SendSite class simply because the Smalltalk semantics doesn't need such a thing.
Addendum
When I say that the notion of sender is subject to interpretation what I mean is that such a notion is not used in any implementation of the send mechanism. More precisely, the (primitive) code that performs the send consists of a cached routine that performs the method lookup, which only takes into account the receiver's behavior and the selector, disregarding the "sender".
Note also that the main piece of "data" that the message send gets from the "caller" are the arguments. And if we dig deeper in the machine code realization of all of this, we could argue that the other one is the return address, which is used to link the frames. This is why I mentioned the notion of "sender" as referred to the caller process frame, which is meaningful for its reification in the implementation of the debugger.
My point is that in Smalltalk there is no clear definition of sender and that's why it is so hard to identify it when compared to relevant notions such as receiver, selector, arguments, behavior and method send.
It is true that you can use the pseudo variable thisContext to get the sender of the current activation. If you do this, you will get the object that impersonated self in the calling frame, which is the other interpretation of sender. And even though by having a reference to that object you could make use of it to provide more features, the sender will remain absent from the Message object and the message send machinery.
If you are interested in how Smalltalk works look at #blihp's and #leandro-caniglia's answers. Also Deep Into Pharo (14.5 Contexts: representing method execution) has information on Context (named MethodContext until Pharo 3).
If you want to experiment with it, at least in Pharo, the pseudo-variable thisContext gives access to the current execution point. You can put:
thisContext copy inspect.
in your method to see what information you can get about a specific execution point. This information includes the sender.
But if you were wondering if you should, on a regular basis, access the sender of a message in your methods, the answer is no. If you need to know the object sending a message in a regular method, pass the sender (self) along as an additional parameter.
You have identified aMorph as the receiver of a message.
Now, what does aMorph do?
It sends messages to various things.
When aMorph is responding to the message it reveived,
It is the sender. It was the receiver, it becomes the sender.
When aMorph is done, it stops being sender, and gives an answer to whatever sent it the message it was working on.
Of course everytime aMorph sends a message, the receiver gets to be the sender while it works out an answer.
And so on.
Below in the message anObject bar is explicit that whoever sent the message was SomeClass instance. But within the method that responds to the message you must resort to the services of thisContext.
SomeClass>>foo
| anObject |
anObject := AnotherClass new.
anObject bar
AnotherClass>>bar
| context senderObject receiver |
context := thisContext.
senderObject := context sender receiver.
receiver := self
Related
I was going through an introduction to Smalltalk.
In C++, the functions declared inside a class can be called by objects of that class, and similarly in Smalltalk a keyword, termed as message, is written adjacent to the name of the object.
(Don't know much but would also like to ask here whether in response to a message a unique method is there to be executed?)
Basically, to my naive mind, this seems to be only a difference in syntax style. But, I wonder if internally in terms of compilation or memory structure this difference in calling holds any significance.
Thanks in advance.
P.S : I bow down to all of you for your time and answers . Thanks a lot.
The fundamental difference is that in Smalltalk, the receiver of the message has complete control over how that message is handled. It's a true object, not a data structure with functions that operate on it.
That means that in Smalltalk you can send any message to any object. The compiler places no restrictions on that, it's all handled at runtime. In C++, you can only invoke functions that the compiler knows about.
Also, Smalltalk messages are simply symbols (unique character strings), not a function address in memory as in C++. That means it's easy to send messages interactively, or over a network connection. There is a perform: method that lets you send a message given its string name.
An object even receives messages it does not implement. The Virtual Machine detects that case and creates a Message object, and then sends the messageNotUnderstood: message. Again, it's the object's sole responsibility of how to handle that unknown message. Most objects simply inherit the default implementation which raises an error, but an object can also handle it itself. It could, for example, forward those messages to a remote object, or log them to a file, etc.
You call a function in C++ because during the compilation time you know which function will be called (or at least you have a finite set of functions defined in a class hierarchy.
Smalltalk is dynamically typed and late bound, so during the compilation time you have no idea which method is going to be evaluated (if one will be at all). Thus you send a message, and if the object has a method with that selector, it is evaluated. Otherwise, the "message not understood" exception is raised.
There are already good answers here. Let me add some details (originally, part of this was in a comment).
In plain C, the target of each function call is determined at link time (except when you use function pointers). C++ adds virtual functions, for which the actual function that will be invoked by a call is determined at runtime (dynamic dispatch, late binding). Function pointers allow for custom dispatch mechanisms to some degree, but you have to program it yourself.
In Smalltalk, all message sends are dynamically dispatched. In C++ terms this roughly means: All member functions are virtual, and there are no standalone functions (there is always a receiver). Therefore, the Smalltalk compiler never* decides which method will be invoked by a message send. Instead, the invoked method is determined at runtime by the Virtual Machine that implements Smalltalk.
One way to implement virtual function dispatching is virtual function tables. An approximate equivalent in Smalltalk are method dictionaries. However, these dictionaries are mutable, unlike typical virtual function tables, which are generated by the C++ compiler and do not change at runtime. All Smalltalk behaviors (Behavior being a superclass of Class) have such a method dictionary. As #aka.nice pointed out in his answer, the method dictionaries can be queried. But methods can also be added (or removed) while the Smalltalk system runs. When the Smalltalk VM dispatches a message send, it searches the method dictionaries of the receiver's superclass chain for the correct method. There are usually caches in place to avoid the recurring cost of that lookup.
Also note that message passing is the only way for objects to communicate in Smalltalk. Two objects cannot access each other's instance variables, even if they belong to the same class. In C++, you can write code that breaks this encapsulation. Hence, message sending is fundamental in Smalltalk, whereas in C++ it is basically an optional feature.
In C++, Java, and similar languages, there is another form of dispatch, called function overloading. It happens exclusively at compile time and selects a function based on the declared types of the arguments at the call site. You cannot influence it at runtime. Smalltalk obviously does not provide this form of dispatch because it does not have static typing of variables. It can be realized nevertheless using idioms such as double dispatch. Other languages, such as Common Lisp's CLOS or Groovy, provide the even more general multiple dispatch, which means that a method will be selected based on both the receiver's type and the runtime types of all the arguments.
* Some special messages such as ifTrue: ifFalse: whileTrue: are usually compiled directly to conditional branches and jumps in the bytecode, instead of message sends. But in most cases it does not influence the semantics.
Here are a few example of what you would not find in C++
In Smalltalk, you create a new class by sending a message (either to the superclass, or to the namespace depending on the dialect).
In Smalltalk, you compile a new method by sending a message to a Compiler.
In Smalltalk, a Debugger is opened in response to an unhandled exception by sending a message. All the exception handling is implemented in term of sending messages.
In Smalltalk you can query the methods of a Class, or gather all its instances by sending messages.
More trivially, all control structures (branch, loops, ...) are performed by sending messages.
It's messages all the way down.
Dumb question on my part, so I apologize for not being able to grasp this.
With an NSArrayController, you can send it a remove: message. If I have objects selected and send it remove:nil, those objects are removed. The docs simply describe the message argument remove:sender where sender is "Typically the object that invoked this method."
Could someone explain (or point me to an explanation) on what sender is or should be used for in this context?
Thank you
You probably do not want to use that. Every action method takes an argument sender for general purpose, even in the concrete case it makes no sense. I. e. you might have one action method for different buttons and decide reading the sender reference, what code to execute.
-remove: (NSArrayController) always removes the selected object(s), even you pass an object reference. It simply does not take care of this parameter. If you want to remove a specific object, use -removeObject:.
I am a newbie so the question might sound silly. But how could I know the sender of a method in Objective-C? In some situations like Target/Action, sender is obvious (a UIControl object). But what about viewDidLoad?
While receiver of an method is usually obvious, sender is not so. For example, I have to read the documentation to know that dealloc's sender is runtime and runtime only. Is there a way to know the sender of a method more easily?
If you aren't passed information from caller then it's not important; this stands for all programming languages; a method is provided with the data/object to work on and it doesn't matter what called the method. This makes the method more useful.
You don't say why it's important to know who the sender is; if it's just curiosity then you can set a breakpoint and examine the stacktrace in the debugger.
It's the first i post to stackoverflow although i always check the forum.
I am looking for a conveniant way to know who sent a message in ObjC without sending the pointer as an argument in the method.
Can anyone help?
Thanks in advance!
This is not possible in the general case (messages can be set from places where there is no self, such as the runtime or the main function), and it's impractical even where it might be technically possible, because it would require you to walk the stack and analyze the bytes there.
In practice, you shouldn't need to know the sender in most cases other than action methods. It's normally a sign of a bad design. And in any case, when you need to get a reference to another object, it should be passed as an argument to a method.
EDIT: I just stumbled on this and noticed the comment. In case anyone is wondering, the reason it's often a sign of bad design is because it creates a tight coupling between components that is almost never necessary (again, outside of action methods). Usually you can take either a delegate or a callback block to accomplish the same purpose.
No, this isn't possible without passing in a pointer to the sender of the message, like this:
- (void) someMethod:(id) sender {
}
[obj someMethod:self];
I guess you could use the hash value of the underlying NSObject (if the object is a subclass of NSObject). As an NSUInteger it's going to be the same size as the pointer, though, so not much space savings there.
Why exactly do you not want to use a pointer?
In C or any ECMAscript based language you 'call a public method or function' on an object. But in documentation for Objective C, there are no public method calls, only the sending of messages.
Is there anything wrong in thinking that when you 'send a message' in ObjC you are actually 'calling a public method on an Object'.?
Theoretically, they're different.
Practically, not so much.
They're different in that in Objective-C, objects can choose to not respond to messages, or forward messages on to different objects, or whatever. In languages like C, function calls are really just jumping to a certain spot in memory and executing code. There's no dynamic behavior involved.
However, in standard use cases, when you send a message to an object, the method that the message represented will usually end up being called. So about 99% of the time, sending a message will result in calling a method. As such, we often say "call a method" when we really mean "send a message". So practically, they're almost always the same, but they don't have to be.
A while ago, I waxed philosophical on this topic and blogged about it: http://davedelong.tumblr.com/post/58428190187/an-observation-on-objective-c
edit
To directly answer your question, there's usually nothing wrong with saying "calling a method" instead of "sending a message". However, it's important to understand that there is a very significant implementation difference.
(And as an aside, my personal preference is to say "invoke a method on an object")
Because of Objective-C's dynamic messaging dispatch, message sending is actually different from calling a C function or a C++ method (although eventually, a C function will be called). Messages are sent through selectors to the receiving object, which either responds to the message by invoking an IMP (a C function pointer) or by forwarding the message to its superclass. If no class in the inheritance chain responds to the message, an exception is thrown. It's also possible to intercept a message and forward it to a wholly different class (this is what NSProxy subclasses do).
When using Objective-C, there isn't a huge difference between message sending and C++-style method calling, but there are a few practical implications of the message passing system that I know of:
Since the message processing happens at runtime, instead of compile time, there's no compile-time way to know whether a class responds to any particular message. This is why you usually get compiler warnings instead of errors when you misspell a method, for instance.
You can safely send any message to nil, allowing for idioms like [foo release] without worrying about checking for NULL.
As #CrazyJugglerDrummer says, message dispatching allows you to send messages to a lot of objects at a time without worrying about whether they will respond to them. This allows informal protocols and sending messages to all objects in a container.
I'm not 100% sure of this, but I think categories (adding methods to already-existing classes) are made possible through dynamic message dispatch.
Message sending allows for message forwarding (for instance with NSProxy subclasses).
Message sending allows you to do interesting low-level hacking such as method swizzling (exchanging implementations of methods at runtime).
No, there's nothing at all wrong with thinking of it like that. They are called messages because they are a layer of abstraction over functions. Part of this comes from Objective C's type system. A better understanding of messages helps:
full source on wikipedia (I've picked out some of the more relevant issues)
Internal names of the function are
rarely used directly. Generally,
messages are converted to function
calls defined in the Objective-C
runtime library. It is not necessarily
known at link time which method will
be called because the class of the
receiver (the object being sent the
message) need not be known until
runtime.
from same article:
The Objective-C model of
object-oriented programming is based
on message passing to object
instances. In Objective-C one does not
call a method; one sends a message. The object to which the
message is directed — the receiver —
is not guaranteed to respond to a
message, and if it does not, it simply
raises an exception.
Smalltalk-style programming
allows messages to go unimplemented,
with the method resolved to its
implementation at runtime. For
example, a message may be sent to a
collection of objects, to which only
some will be expected to respond,
without fear of producing runtime
errors. (The Cocoa platform takes
advantage of this, as all objects in a
Cocoa application are sent the
awakeFromNib: message as the
application launches. Objects may
respond by executing any
initialization required at launch.)
Message passing also does not require
that an object be defined at compile
time.
On a C function call, the compiler replaces the selector with a call to a function, and execution jumps in response to the function call.
In Objective-C methods are dynamically bound to messages, which means that method names are resolved to implementations at runtime. Specifically, the object is examined at runtime to see if it contains a pointer to an implementation for the given selector.
As a consequence, Objective-C lets you load and link new classes and categories while it’s running, and perform techniques like swizzling, categories, object proxies, and others. None of this is possible in C.
Was taught this in my Java class. I would say they only have realistic differences in multithreaded scenarios, where message-passing is a very legitimate and often-used technique.