7

Is it possible to overload operators in Smalltalk?

I am looking for tutorials/examples.

Thanks.

Frank Shearar
  • 17,012
  • 8
  • 67
  • 94
Zakaria
  • 983
  • 15
  • 24

5 Answers5

18

Method overloading is not possible in Smalltalk. Instead, a combination of method overriding and a technique called double dispatch is used to implement the same behavior as operator overloading in other languages.

You can find an example implementation in the mathematical operators +,*,/,- (which are binary messages in Smalltalk). Here is the idea: the implementation of Integer>>+ sends a message #addWithInteger: to its argument. The implementation of #addWithInteger: is implemented on each Magnitude subclass, such as to specialize addition of Int+Int, Float+Int, etc...

Johan B
  • 2,461
  • 14
  • 16
  • I think you meant "Operator overloading is not possible" in the first paragraph? – Frank Shearar Apr 14 '13 at 17:47
  • 3
    No, I meant "method overloading" since Smalltalk does not have any operators (only methods). Overloading methods (i.e. defining methods with the same selector but different input/output 'types') is not possible. Mind that 'ad hoc polymorfism' is possible (i.e. defining methods with the same selector on different classes). – Johan B Apr 14 '13 at 18:05
  • So "method overloading" refers to what's often called "ad hoc" polymorphism, where you have, say, `int foo()`, `int foo(int)`, and so on: same name, different parameter signature. – Frank Shearar Apr 15 '13 at 06:14
  • Except that in Smalltalk, the names of the functions you mention would be different: #foo and #foo:. But the point is that Smalltalk method dispatch is based on the receiver of the message only, while "method overloading" involves method dispatch that involves the method arguments as well. – Johan B Apr 17 '13 at 20:34
12

For most part, things that are operators in other languages are in Smalltalk unary or binary messages like +, *, /, ... etc. Classes are free to respond to those messages as they seem fit, so yes, you can redefine behavior of +, and you can also make instances of some non number classes understand and respond to it.

For instance look at the implementation of + in Point class.

One thing to note, := and ^ are not messages, so they can not redefined in a way described above.

Btw, for learning Smalltalk, one of the greatest resources of examples and code is the Smalltalk image. So I recommend that you fire up Smalltalk, and learn your way to browse through vast amount of examples that it contains.

Davorin Ruševljan
  • 4,353
  • 21
  • 27
  • 1
    := and ^ aren't messages but, as Lukas Renggli points out, you can replace them with messages. See his comment on this answer: http://stackoverflow.com/questions/5638052/is-it-really-all-about-message-passing-in-smalltalk/5638259#5638259 – Frank Shearar Jun 30 '11 at 08:22
6

There's no operators in smalltalk, except assignment. Everything is implemented in classes as methods. So if you want to change behaviour of = or + / - methods, just look at their implementors. Or if you want to make instances of your class to understand those messages, just implement them.

Igor Stasenko
  • 1,037
  • 5
  • 8
1

The operator-overloading tag is defined on Stack Overflow as

a feature of a programming language that allows custom implementations for operators depending on the types of the operands involved. Some languages allow new operators to be defined while others only allow redefinition of existing ones.

In Smalltalk
All types are defined as classes of object *
All operators are methods *
All methods are executed by the receiver of the message with the method's name
All methods can be over-ridden

So any operator, operating on any operand, can be over-ridden by any developer.

Here are some examples:
Objects of Class Float, Class SmallInt, Class Fraction and Class Point can all respond to a + message. They can interroperate with one another, too.
aFloat := 3.1415 . aSmallInt := '6' . aPoint := 3@3 . aFraction := 22/7 .

"send the + aSmallInt message to aFraction"
aSum := aFraction + aSmallInt Evaluates to: 64/7

"send the + aFraction message to aSmallInt"
aSum := aSmallInt + aFraction Evaluates to: 64/7

aSum := aFloat + aFraction aSum := aFraction + aFloat These evaluate to: 6.284357142857143

aSum := aFloat + aSmallInt aSum := aSmallInt + aFloat These evaluate to: 9.1415

aSum := aPoint + aSmallInt aSum := aSmallInt + aPoint These evaluate to: 9@9

In effect, we have 8 different implementations of the + operator on display here, each customised to deal with the types of the operands involved.

The caveats: * Objects are not strongly typed. Any variable of one type can be changed to any other type, and the system will not raise an exception. An object can start as an object of Class SmallInt and then be changed to a ByteString or a Dictionary, and the system will not raise the slightest warning. Until it is sent a message that it does not understand.

There are 6 primitives that are not an object or Class of object: true, false, nil, etc.

There are two operators which are, in effect, syntactic sugar for named methods.

Euan M
  • 1,126
  • 11
  • 20
  • 1
    To avoid confusion: you should say that "variables are not strongly typed", because in fact objects are. An object has a very strong idea of which class it is an instance of (although even that can be changed by the changeClassTo: hack). And you should also write: "any variable can refer to any object", to emphasize on the fact that variables are just holding "pointers" (are bindings). Especially the part: "an object can start as... and then be changed to..." is wrong and confusing. – blabla999 Sep 27 '16 at 12:22
  • Finally: the sentence: "there are 6 primitives..." is wrong. true is an instance of True, false of the False-class, nil of the UndefinedObject class etc. – blabla999 Sep 27 '16 at 12:22
0

Smalltalk doesn't have operators but you can achieve a similar thing via method definition/overriding:

Object subclass: Foo [ 
  + anObject [
    "define new behavior for + here"

  ]
]
David Farrell
  • 427
  • 6
  • 16