45

What are the key differences between OO in Smalltalk and Java?

Please note that I am a Java programmer trying to expand his horizons by exploring Smalltalk. Currently I know almost nothing about Smalltalk except that it's purer than Java. Therefore I'll prefer the answer that shows how various Java concepts map to corresponding Smalltalk concepts and then introduces the Smalltalk concepts that don't exist in Java at all.

Jim
  • 633
  • 1
  • 6
  • 9

7 Answers7

42

Message passing

Smalltalk uses message passing, not method invocation. The distinction is subtle, but enormously powerful.

Some terminology: Given foo bar: baz, #bar: is a selector, foo is the receiver of a message called #bar: (the # indicates a symbol, much like Common Lisp would say 'bar (or even more appropriately, :bar)), and baz is an argument or parameter. When the line's executed, foo is sent the message #:bar: with argument baz. So far, it's pretty normal. In Java it would look like foo.bar(baz);.

In Java, the runtime system would figure out foo's actual type, find the most appropriate method, and run it.

Things look almost the same in Smalltalk. When you send an object a message, it searches in its method dictionary for a method whose name matches that of the selector of the message. If it can't find one, it searches in its superclass' method dictionary, and so on. Pretty normal stuff.

If it can't find any matching method, it sends itself the #doesNotUnderstand: message, with the original message as a parameter. (Yes, a message send is an object.) But #doesNotUnderstand: is also just a method. You can override it.

For instance, you can have an object that responds to some set of messages while forwarding any other messages it receives to some delegate object. Override #doesNotUnderstand: and hey presto, you have a proxy that will need no maintenance to keep its protocol in sync with the delegate.

Trivial syntax

No, I'm not joking. Smalltalk's entire grammar's maybe 15 lines long. The JLS is... not. Why care? A simple syntax makes it simple to tear a chunk of code apart. Metaprogramming! Refactoring!

No syntax for:

  • conditional statements: (n < 3) ifTrue: ['yes'] ifFalse: ['no']
  • for loops: 1 to: 10 do: [:i | Transcript show: i asString]
  • try-catch: [i := i / 0] ifError: ['oops!']
  • try-finally: [i := i / 0] ensure: [stream close]

And notice all those []s - first-class closures with a clean syntax.

Nate W.
  • 9,141
  • 6
  • 43
  • 65
Frank Shearar
  • 17,012
  • 8
  • 67
  • 94
  • I think the point of Frank is that a message send is reified into a first-class object when using #doesNotUnderstand:. In Java this corresponds to overriding InvocationHandler#invoke(Object, Method, Object[]). In Smalltalk this can happen on any object, in Java only on dynamic proxy classes. Other than that I don't see a difference between method invocation and message sends. – Lukas Renggli Mar 22 '12 at 18:08
  • Indeed. But there's a world of difference between "you can have #doesNotUnderstand: in these limited circumstances" and "you can have #doesNotUnderstand: everywhere". The real question is this: does #doesNotUnderstand: make a language strictly more expressive (in the Felleisen sense) than a language without it? I _think_ it does, but I don't know. – Frank Shearar Mar 23 '12 at 11:30
  • 2
    `Smalltalk uses message passing, not method invocation` Can we say that method invocation is a very limited from of message passing ? – user1720897 Jun 25 '13 at 19:38
  • 1
    @user1720897 - IMO no. Method or subroutine invocation is a lower level construct, which Smalltalk *does* use - once it has determined if the message **can** be processed, and where the method which implements the message resides. In Java and most other languages the method/subroutine to be invoked is commonly determined at compilation time. In Smalltalk the method to be invoked is determined (remarkably efficiently) at runtime. This is not to say that Smalltalk is not compiled - it is, but the compilation process creates message sends, not create subroutine calls. – Bob Jarvis - Слава Україні Mar 30 '19 at 17:23
19
  1. Object Model. In Smalltalk every thing, is an object. Java has primitive types like int and float whose representation and behavior are different from complex objects.
  2. Behavior invocation. Behavior of a Smalltalk object is invoked by sending it a message. Java has methods, which are basically function calls, with the destination object being a special first argument called this.
  3. Encapsulation. Smalltalk has strict encapsulation. An object's fields can be exposed only through messages. In contrast, Java allows public fields.
  4. Dynamism. Smalltalk is extremely dynamic. All types are identified at runtime. A class can be introspected and modified at runtime (dynamic meta-programming!). New classes can be created and instantiated at runtime. Java has static type checking along with runtime polymorphism. There is introspection and reflection, but classes and objects cannot be modified from within a running program.
  5. Syntax. Smalltalk do not have a syntax. Instead it has a simple, consistent format for sending messages. Java, like other languages of the C family, has a complex syntax.
  6. Environment. Most Smalltalk implementations provide a complete, standalone, live computing environment with image based persistence. Some of these environments can even be booted on bare metal. The JVM in turn is usually dependent on an underlying operating system for threading, networking etc. Source code must be entered into text files, compiled and explicitly loaded into the JVM for execution.
Vijay Mathew
  • 26,737
  • 4
  • 62
  • 93
  • 1
    (2) There is no difference in how Java and Smalltalk invoke instance methods (putting #doesNotUnderstand: aside). (3) Java supports creating and changing classes and objects at runtime using the class-loader and the reflection API. – Lukas Renggli Mar 22 '12 at 18:17
  • 4
    @Lukas: "putting `#doesNotUnderstand:` aside" can change things quite a bit. You don't get to say something like that and expect to be taken seriously -- if we cut out everything that's different, of course stuff's going to be similar. :P – cHao Mar 26 '12 at 20:22
  • 1
    Smalltalk has syntax, just not very much. – Dave Newton Mar 10 '18 at 22:42
  • 1
    @cHa But `#doesNotUnderstand` is not related to "message sending". Python has similar mechanism, but Python is working through method calls, just like Java. I do not get what is real semantic difference between messages passing and methods calling, and this answer is not explaining this point. – uhbif19 Mar 06 '19 at 15:09
  • @uhbif19: The semantic difference is that a message is more abstract. It's not shackled to the running of a particular function. Besides opening up the idea of queuing up messages, it also means that if you want, you can have a handler (like, say, `doesNotUnderstand`) that intercepts messages, and ideally, the sender of the message doesn't know or care whether that's happening. You can implement a limited form of "message sending" via function calls, but you're missing out on most of the benefits. – cHao Mar 07 '19 at 13:17
  • @cHao Python has similar handler intercepting method calls too, named `__getattribute__` (see for example http://code.activestate.com/recipes/496741-object-proxying/). Name of method will be string, but as far as i understand, Smalltalk uses symbols for that purpose, that is not so much different. I am not sure what is "queuing up" messages. Can you please explain or provide example, what do you mean by other benifits? – uhbif19 Mar 10 '19 at 16:51
  • @uhbif19: The difference between symbols and strings is trivial, and frankly, dynamically typed languages sidestep most of the problems a language like Java has. (Strict static typing imposes a lot of arguably stupid limitations in return for huge gains.) But that's just scratching the surface. Semantically, a message is a thing all its own. It can not only be processed; it can be *stored* and processed later. Stick it in a queue and let targets handle messages at their own pace, and suddenly you have Actor Model-style concurrency. – cHao Mar 11 '19 at 00:39
18

A key difference between Java and Smalltalk is that Smalltalk has first-class class (no pun intended).

A class in Smalltalk is an object. The closest thing to static method and variable is then class-side method and variable, as mentioned by Frank Shearer.

But this difference is more profound as soon as inheritance is used. In java class-side inheritance does not exists, while it is possible in Smalltalk.

If class A inherits from B, and if you have a and b which are instances of A and B, in Smalltalk, b class inherits from a class. This would not be the case in Java where a getClass() and b getClass() return instances of Class, which are not related with each other.

Let's say now that class A implements the singleton pattern: it has a class-side field instance and an getter method instance. Class B is another object with its own instance field. As a consequence, A instance and B instance will return different object.

This is clearly one of the major difference between Smalltalk and Java from a OO standpoint.

Other difference include the existence of metaclasses, extension methods, duck typing vs static typing, reification of doesNotUnderstand and few other things that make coding in Smalltalk or Java completely different.

And of course, Smalltalk has closure which Java still lacks.

See also Why doesn’t Java allow overriding of static methods ?

Community
  • 1
  • 1
ewernli
  • 38,045
  • 5
  • 92
  • 123
  • Not that java is not completely statically typed since it perform some runtime check. – mathk Jun 23 '10 at 15:58
  • 1
    @mathk No, Java is statically typed. The type of all variables are known at compile-time. You're probably thinking about either casting, dynamic dispatch, or reflection, none of which violate static typing. – Quelklef May 30 '18 at 14:16
12

trying to expand his horizons by exploring Smalltalk

If you are actively trying to explore Smalltalk then you need to know how to read Smalltalk -

"I Can Read C++ and Java But I Can’t Read Smalltalk" pdf

cori
  • 8,666
  • 7
  • 45
  • 81
igouy
  • 2,547
  • 17
  • 16
8

One Smalltalk concept that doesn't exist in Java but has become increasingly popular in recent years is blocks. Blocks are a form of anonymous functions that include the context they were defined in. Importantly, blocks are also objects. Smalltalk actually lacked any kind of built-in if-statement or for-loop or anything like that, but managed to create the same effect just with message-passing and blocks.

object isBig ifTrue: [self runIntoObject:object] 
            ifFalse: [self katamariBall absorbObject:object].

1 to: 10 do: [:number | number print]
Chuck
  • 234,037
  • 30
  • 302
  • 389
7

In Smalltalk everything is the object while in Java things like small integers are still not the first class objects. Also, to continue with numbers, in Smalltalk due to its pure OO nature and strong reflective capabilities we never need to care about the number size, like if an integer is small or large and what happens when small integer overflows to large.

Janko Mivšek
  • 3,954
  • 3
  • 23
  • 29
5

When @Janko Mivšek mean everything he really mean everything. :)

Even up to message send, what your are doing is creating an object that is the context.

Also what you don't have in smalltalk is access modifier (private/ protected / public) You don't have package in some Smalltalk implementation and in most Smalltalk implementation package don't have the same semantic than Java.

In smalltalk you don't have control structure like for, if, try/catch... The cool things is that you don't need them because you have block closure in smalltalk.

In smalltalk you don't have static member instead you have Class that are object(you can send message to class, you also can hold class in a variable).

In smalltalk you don't have nested class.

...

mathk
  • 7,973
  • 6
  • 45
  • 74
  • 1
    Re control structures, Carl Hewitt's "Viewing Control Structures as Patterns of Passing Messages" (http://dspace.mit.edu/handle/1721.1/6272) is a real eye-opener. – Frank Shearar Jun 23 '10 at 18:40
  • 1
    >> In smalltalk you don't have control structure like << Smalltalk compilers usually do something special with the control structure methods - they aren't ordinary methods. – igouy Jun 24 '10 at 17:19
  • 4
    True, but that's (just) an optimisation. – Frank Shearar Oct 22 '10 at 16:29