Why doesn't this code cause an infinite loop? - smalltalk

Let's say I define a new class, and I override class:
class
^self class.
And then I run:
var:=NewClass new.
Transcript show:(var class);cr.
Why doesn't this code cause an infinite loop?
The runtime class is NewClass, so how come the code calls the class defined in Object, and not the class defined in NewClass?

Smalltalk implementations may implement certain shortcuts for special messages. You didn't specify your Smalltalk implementation, but most likely it has a special bytecode to retrieve the class of an object. When the Smalltalk VM encounters that bytecode, it does not really send the message class to the receiver, so your method is never invoked and the infinite recursion does not happen. The Smalltalk compiler will emit that special bytecode instead of the bytecode(s) for a message send if it sees that you use class.
The same typically happens with ifTrue: ifFalse:, instead of compiling message sends to the receiver (boolean) object, the Smalltalk compiler will emit conditional jumps in the bytecode of the "calling" method.
To get such an infinite loop, you could try with perform: #class both in your script and in the implementation of NewClass>>class.
class
^ self perform: #class

Related

What's so special about message passing in smalltalk

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.

Pharo Smalltalk - How can I check if a message conforms to a protocol defined in another object's Class?

I'm looking at this form an Objective-C background so be gentle. The experiment looks like this:
Object1 has an instance variable named delegate.
Object1 receives a message and the proceeds to check if delegate implements a specific protocol (whose name is known beforehand), if it does, then it checks if the message is among the protocol's implemented methods. It then makes a decision on how to interact with the delegate and so on.
In Objective-C one has to define clear Protocols, usually stored in different files, and conforming to a protocol is checked by the compiler. In Pharo I can't seem to find how to check for this kind of information even though the Browser has a whole column dedicated to protocols, and beside grouping methods they seem to do very little.
Here are some few alternatives that could help you with this:
Get the collection of all selectors that populate the object's class:
anObject class selectors
Get the collection of all selectors that populate the object's class and all its superclasses:
anObject class allSelectors
Ask the class whether it implements a given message (for its instances):
anObject class canUnderstand: #putTheSelectorHere
Ask the object whether it understands a given message:
anObject respondsTo: #methodSelectorHere
Use the MessageNotUnderstood mechanism:
(see explanation below)
In 1 and 2 above you can use the returned collections to check whether they include a certain selector you are interested in. Features 3, 4 and 5 have a more dynamic nature. For example, you can refine the #doesNotUnderstand: method in your class as follows:
MyClass >> #doesNotUnderstand: aMessage
(delegate respondsTo: aMessage selector)
ifTrue: [^delegate
perform: aMessage selector
withArguments: aMessage arguments].
^super doesNotUnderstand: aMessage
This way, if your object receives a message that it does not understand, it will first receive the #doesNotUnderstand: message (without you having to do anything for this to happen) and here you could decide (e.g., by using the #respondsTo: message) whether to delegate it or not. If not, you can just relay on the default behavior (super doesNotUnderstand:) which would signal de MessageNotUnderstood exception.
Of course, there is a 6th option, which would be for the sender of the message to handle the MNU exception, but I don't think this is what you are looking for here.
There is the proxies work in Ghost/Marea and the original Smalltalk wrappers to the rescue I'm not sure the proxies have been updated for the latest Pharo version. Latest ghost version seems to be here

How does sending messages to classes work?

I know that you send messages to objects using [ ], and it is then translated to objc_msgSend()which needs a pointer to object as its first argument and second argument needs a selector.
But what about messaging classes like
[myClass doSomething];
It is not a pointer to object, so how does it work?
I am assuming that myClass is (literally) the name of a class (though usually classes start with a capital letter; I'll assume this is a class that doesn't follow the naming convention).
There are two cases of the message sending syntax in Objective-C. One, which you referred to, is if the left side is an expression which evaluates to a pointer to an object; the message is sent to that object. The second, is if the left side is an identifier which is the name of a class, then the compiler will send the message to the class object for that class. More technically, the compiler will pass a pointer to the class object as the first argument to objc_msgSend(). This is possible since it is the compiler which arranges the structure and location of the class object for each class, so it knows the address of that class object.
Intuitively, you can think of [myClass doSomething]; as similar to
Class foo = objc_getClass("myClass");
[foo doSomething];
or
Class foo = NSClassFromString(#"myClass");
[foo doSomething];
except that it doesn't need to do a runtime lookup to get a pointer to the class object -- the compiler knows the pointer at compile time.
Mike Ash has a great explanation of how objc_msgSend works: Friday Q&A 2012-11-16: Let's Build objc_msgSend.
Actually, when you send a message to a class, you are actually sending that message to a class object, which behaves as any other object with some limitations.
From Apple's reference:
In Objective-C, a class is itself an object with an opaque type called
Class. Classes can’t have properties defined using the declaration
syntax shown earlier for instances, but they can receive messages.
The runtime converts the message to a SEL then checks to see if that class responds to a message with that SEL including superclass inherited methods. If it responds it will perform the method.

Objective-C Find all init (constructor methods)

using the "Method * class_copyMethodList(Class cls, unsigned int *outCount)" function one can get a list of all methods that exist on an objective-C class.
I would like to know how to find which of these methods are constructors as I am writing an IOC container. I would like to determine the constructors and their parameter types.
I would like to know how to find which of these methods are
constructors as I am writing an IOC container. I would like to
determine the constructors and their parameter types.
In short, you can't. Or, at the least, you'll find that down this path lies madness.
First, Objective-C does not have constructors. It has initializers, sometimes many, and -- for a properly written class -- only one of which is the designated initializer. There is no way to identify the designated initializer at compile time or run time.
How do I use this with a Method * and no instantiated member of the
class?
You don't. First you allocate an instance of the class, then you initialize the instance.
Overall, this level of abstraction just isn't done in Objective-C outside of academic investigations. It can be done, but it is generally avoided because of the fragility of the resulting solution and the hairball of code-hell that is trying to dynamically support the underlying C ABI (go look at the source to libffi).
If you want to go down this path, then you are far better off either defining a custom abstract class that all of your containers will subclass that can provide the binding logic to the class behind it.
Or use protocols; i.e. a class could implement an IOCBean protocol and one method would be initIOCGoop that is the designated initializer goo.
Doing this generically for all classes is going to be rife with fragility, special cases, and will require a gigantic mess of code that will be difficult to maintain over time.
You can get the method signature by using the following method:
methodSignatureForSelector:
From the documentation:
An NSMethodSignature object records type information for the arguments and return value of a method. It is used to forward messages that the receiving object does not respond to—most notably in the case of distributed objects. You typically create an NSMethodSignature object using NSObject’s methodSignatureForSelector: instance method (on Mac OS X v10.5 and later you can also use signatureWithObjCTypes:). It is then used to create an NSInvocation object, which is passed as the argument to a forwardInvocation: message to send the invocation on to whatever other object can handle the message. In the default case, NSObject invokes doesNotRecognizeSelector:, which raises an exception. For distributed objects, the NSInvocation object is encoded using the information in the NSMethodSignature object and sent to the real object represented by the receiver of the message.

Objective C message dispatch mechanism [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 months ago.
The community reviewed whether to reopen this question 7 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am just staring to play around with Objective C (writing toy iPhone apps) and I am curious about the underlying mechanism used to dispatch messages. I have a good understanding of how virtual functions in C++ are generally implemented and what the costs are relative to a static or non-virtual method call, but I don't have any background with Obj-C to know how messages are sent. Browsing around I found this loose benchmark and it mentions IMP cached messages being faster than virtual function calls, which are in turn faster than a standard message send.
I am not trying to optimize anything, just get deeper understanding of how exactly the messages get dispatched.
How are Obj-C messages dispatched?
How do Instance Method Pointers get cached and can you (in general) tell by reading the code if a message will get cached?
Are class methods essentially the same as a C function (or static class method in C++), or is there something more to them?
I know some of these questions may be 'implementation dependent' but there is only one implementation that really counts.
How are Obj-C messages dispatched?
Objective-C messages are dispatched using the runtime's objc_msgSend() function. Shown in the Apple docs, the function takes at least 2 arguments:
The receiving object
The selector of the message
[A variable list of arguments to the message being sent.]
Instances of a class have an isa pointer, which is a pointer to their class object. The selectors of methods in each object are stored in a "table" in the class object, and the objc_msgSend() function follows the isa pointer to the class object, to the find this table, and checks whether the method is in the table for the class. If it cannot find it, it looks for the method in the table of the class's superclass. If not found, it continues up the object tree, until it either finds the method or gets to the root object (NSObject). At this point, an exception is thrown.
How do Instance Method Pointers get cached and can you (in general) tell by reading the code if a message will get cached?
From Apple's Objective-C runtime guide on Messaging:
To speed the messaging process, the runtime system caches the selectors and addresses of methods as they are used. There’s a separate cache for each class, and it can contain selectors for inherited methods as well as for methods defined in the class. Before searching the dispatch tables, the messaging routine first checks the cache of the receiving object’s class (on the theory that a method that was used once may likely be used again). If the method selector is in the cache, messaging is only slightly slower than a function call. Once a program has been running long enough to “warm up” its caches, almost all the messages it sends find a cached method. Caches grow dynamically to accommodate new messages as the program runs.
As stated, caching starts to occur once the program is running, and after the program has been running long enough, most of the method calls will run through the cached method. As it also says, the caching occurs as the methods are used, so a message is only cached when it is used.
Are class methods essentially the same as a C function (or static class method in C++), or is there something more to them?
Class objects handle method despatch in a similar manner to that of instances of classes. Each class object has an object that stores its own class methods, in an object called a metaclass. The class object has its own isa pointer to its metaclass object, which in turn has super metaclass objects, which it can inherit class objects from. Method dispatch to class methods is as so:
The dispatch system follows the class object's isa pointer to the metaclass object
The metaclass object's method table is searched for the class method.
If not found, the search continues to the metaclass object's superclass, where the search continues.
This process repeats until either the method is found, or until it gets to the root metaclass, and an exception is thrown.
Dispatch mechanisms
It is used to find a necessary executable code when method was called(message sent)
Inline
Static(Direct)(C, Java final, C++ default, Swift static, final) - compiler knows the necessary method realisation at compile-time.
Dynamic - is based on witness table(virtual table, dispatch table) and it introduce polymorphism
Table, V-Table(C++ virtual, Java default, Swift default) - Every object has a reference to class which has a table with all method addresses(super, overrides, new). SIL contains vtable or witness_table
Message(Objective-C, Swift dynamic) - Every object has a reference(isa) to class which contains a reference to superclass and dispatch table(which contains only realised methods(new and which were overhead)) and don't contain methods from super. If method was not found in current dispatch table, it continue searching in superclass's dispatch table. This process is optimised by caching. SIL contains volatile
Objective-C Message Dispatch
For example
class A {
func foo1() {}
func foo2() {}
}
class B: A {
override func foo2() {}
func foo3() {}
}
Objective-C obc_msgSend
id obc_msgSend(id self, SEL op, ...)
// self - object which receive a message
// op - selector of method
//... - arguments
If method implementation was not found for given selector you see next error
unrecognized selector sent to instance