From Java to Smalltalk: My Journey into Pure Object-Oriented Programming

Sneha RajSneha Raj
5 min read

Diving into Smalltalk: A Pure Object-Oriented Journey

Introduction

When I first set out to contribute to Pharo, I was excited about working on an open-source project. But as I started exploring the codebase, I quickly realized that Pharo is written in Smalltalk—a language I had never used before. That meant I needed to learn Smalltalk first. What started as a prerequisite soon turned into an eye-opening journey into one of the purest object-oriented languages ever created.

Coming from Java, which is often considered a highly object-oriented language but still has primitive types and static methods, learning Smalltalk was a refreshing experience. Unlike Java, where object-oriented principles are sometimes bent for performance or convenience, Smalltalk follows them in their purest form. Everything—numbers, classes, methods, even control structures—is an object.


The Core of Smalltalk: Message Passing

In Smalltalk, computation happens by sending messages to objects. Instead of calling functions, you tell objects what to do. For example:

5 + 3.

Here, 5 is an object, and + is a message sent to it with 3 as an argument. There’s no concept of built-in operators; everything is a method call.

Another example:

'Hello, Smalltalk' reverse.

This sends the reverse message to the string object, which returns ''klatSllamS ,olleH''.

A more complex example:

('Hello' , ' Smalltalk') asUppercase.

This concatenates two strings and converts the result to uppercase: HELLO SMALLTALK.

Method Lookup & Inheritance

When you send a message, Smalltalk looks up the method:

  1. Starts in the object’s class.

  2. Searches the superclass if not found.

  3. Raises an error (MessageNotUnderstood) if still not found.

This elegant lookup mechanism makes inheritance and polymorphism seamless.


Java vs. Smalltalk: Key Differences

Having worked with Java extensively, I was surprised by how different Smalltalk feels. While both languages embrace object-oriented programming, Smalltalk takes it to a whole new level.

FeatureJavaSmalltalk
Object OrientationNot purely OOP (has primitives like int, double)Everything is an object, even numbers and control structures
SyntaxC-style syntax with curly braces {} and semicolons ;Minimalist syntax—just message passing and periods .
Static MethodsUses static methods, breaking OOP principlesNo static methods—everything belongs to an object
Method CallsMethods are invoked explicitly with ()Methods (messages) don’t use (); instead, keywords are used
Control FlowUses if, for, while statementsUses message passing (ifTrue:, whileTrue:)

For example, in Java, an if statement looks like this:

if (x > 10) {
    System.out.println("Large number");
}

In Smalltalk, the same logic is written as:

x > 10 ifTrue: [ Transcript show: 'Large number' ].

Instead of keywords like if or while, Smalltalk treats them as messages sent to boolean objects.

This felt strange at first, but once I got used to it, I realized how consistent and elegant it was. There’s no need to memorize special syntax—just message passing everywhere.


Variables in Smalltalk

One of the key learnings in my Smalltalk journey was understanding variable scope and types. Unlike statically typed languages, Smalltalk variables are untyped but must be declared before use.

Types of Variables in Smalltalk

1️⃣ Global Variables

  • Defined in Smalltalk, a system-wide Dictionary.

  • Accessible from anywhere in the program.

Example:

Smalltalk at: #GlobalVar put: 10.  "Defines a global variable"
Transcript show: (Smalltalk at: #GlobalVar).  "Retrieves and prints the value"

2️⃣ Class Variables

  • Shared among all instances of a class.

  • Defined using classVariableNames:.

Example:

Object subclass: #BankAccount
    classVariableNames: 'BankName'.

BankAccount class >> initialize
    BankName := 'Global Bank'.

3️⃣ Instance Variables

  • Unique to each object (instance of a class).

  • Defined using instanceVariableNames:.

Example:

Object subclass: #Person
    instanceVariableNames: 'name age'.

Person >> initializeWith: aName age: anAge
    name := aName.
    age := anAge.

4️⃣ Temporary Variables

  • Exist only within a method or block.

  • Declared inside | |.

Example:

Person >> describe
    | tempMessage |
    tempMessage := 'Name: ', name, ', Age: ', age printString.
    Transcript show: tempMessage; cr.

5️⃣ Method & Block Parameters

  • Passed as arguments to methods or blocks.

  • Cannot be reassigned inside the method or block.

Example:

Person >> setName: newName
    name := newName.

Block Parameter Example:

#(1 2 3 4 5) do: [:num | Transcript show: num printString; cr].

Control Flow & Iteration in Smalltalk

Smalltalk avoids traditional for and while loops, replacing them with message-based iteration.

Counting Loops (to:do:)

1 to: 5 do: [:i | Transcript show: i printString; cr].

This prints numbers 1 to 5.

Custom Step Loops (to:by:do:)

2 to: 10 by: 2 do: [:i | Transcript show: i printString; cr].

Prints even numbers from 2 to 10.

Looping Over Collections (do:)

#('Apple' 'Banana' 'Cherry') do: [:fruit | Transcript show: fruit; cr].

Iterates over each element in an array.

Filtering Elements (select:)

#(1 2 3 4 5 6 7 8 9 10) select: [:num | num even].

Returns #(2 4 6 8 10), selecting only even numbers.


Final Thoughts

Learning Smalltalk has changed how I think about programming. The pure object-oriented nature of the language forces you to embrace message passing, dynamic exploration, and live coding. It has also given me a new perspective on Java—despite being OOP-heavy, Java still has procedural elements that Smalltalk completely avoids.

For anyone interested in understanding true object-oriented programming, Smalltalk is a must-learn. The experience has helped me navigate Pharo’s codebase with much more confidence, and I’m excited to build real-world projects with it.

10
Subscribe to my newsletter

Read articles from Sneha Raj directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Sneha Raj
Sneha Raj

Computer Science Student | Aspiring Entrepreneur | Orator & Writer I am a passionate computer science student with a deep curiosity for exploring the intersections of technology, creativity, and human potential. Proficient in Java, Python, C, Go (Golang), and MySQL, I am building expertise in areas like web development, machine learning, and open-source contributions. I aspire to use technology as a force for good, developing innovative solutions that help save the environment and foster a balance between progress and sustainability. Beyond coding, I am a lifelong learner and a lover of history, philosophy, and literature. These interests inspire me to reflect on the human experience, fueling my passion for writing poetry and immersing myself in English classics. I believe in the power of words and ideas to shape perspectives and find joy in crafting meaningful narratives, whether through writing or public speaking. As an orator and a natural teacher, I enjoy breaking down complex concepts, inspiring others, and engaging in thoughtful discussions that spark curiosity and growth. Balancing analytical problem-solving with creative expression, I strive to create a symphony where technology, humanity, and nature coexist harmoniously.