The Smalltalk is an extraordinary language. Firstly, this is a mother of all OOP family languages. Secondly, Java was invented as alternative for payed (sic!) programming language Smalltalk, and if IBM won the race with Microsoft a that time, things might end up very differently and Smalltalk could still be a hype.
Initially I’ve been exposed to Ruby, but only with Smalltalk I finally grasp lot’s of ideas in Ruby, so as the roots of the syntax.
Smalltalk doesn’t have public properties at all. Though it does have getters and setters with quite the same name as the field itself. So you don’t write anything like setName, getName.
Thus you don’t have any of issues with decisions like: should I declare this variable as private, or more fancy, protected? Everything is just private, that’s it. Other objects can’t have any access to the internals apart from what is available with methods .Smalltalk even doesn’t have a syntax to access the property variable. That’s simple.
Assume you have a class Human
.
call getter name value of Human
Human name.
call setter name with value
Human name: "The one".
There is no such thing as positional arguments for the methods. Either one argument or named many. Nothing else. Super easy.
Function 1
Human take: "The second".
Function 2
Human take: "The second" flag: True.
This can’t be implemented clearly with Java. You will have to have a single function that takes flag with default value. So then you forced to check it later in the code.
Lisp has this property by having different bodies for different sets of arguments for the same function.
history
^ history ifNil: [ history := OrderedCollection new ]
See this ifNil: method? It accepts the block, which is namely anonymous function and executes it when the target object is nil.
^ is just a return
.
Every object contains ifNil
method, so this getter pattern allows concise object initialization.
Well, this is true. What you should use instead is the ifTrue: ifFalse: method with arguments one for positive, second for negative predicate and they accept anonymous functions. Everything is an object, right? so boolean operation produces Boolean object that has ifTrue: ifFalse: method that accept code blocks.
predicate ifTrue: [do this] ifFalse: [do that]
Smalltalk has a very concise syntax, but for returning the object it provides ;
operator.
This enables to chain calls to the same object in a very straightforward manner.
Example for Java
new Apple()
.method1()
.method2()
Why is there a separate syntax in Java for constructor? I don’t know. Smalltalk just calls constructor method with the same syntax as normal function call.
The same example for Smalltalk
Apple new method1; method2;
Since main thing in the language is calling methods from objects, you don’t need to have much syntax. Same concept applies to Forth language.
[ block ] - this is syntax for a piece of code
[ :anArgument | block ]
so now you can use anArgument
value right in the block. Do you recognise vertical pipes argument from Ruby? This is it.
Indeed, mostly functions in Smalltalk are really small and concise. The good reason for that is the IDE is a part of language image, this changes programmer experience dramatically. IDE is full of functionality like generate scaffold getters, setters, best in breed refactoring capabilities.
Along with outstanding IDE support the concise function bodies is a consequense of small language footprint. No verbosity required, no types needed to be specified, funcition calls don’t ever require brackets.
I think unit testing that is done in Smalltalk still delivers the best experience possible.
Pressing on the green dot you can re-run test.
What a brilliant idea to have only assert
as the test method!
Example:
testClassifyIncident
|anIncident aState|
aState:= ticket status.
anIncident := ticket classifyAs: Incident service: service.
self assert: anIncident class equals: Incident.
self assert: anIncident status class equals: ClassifiedTicketState.
self assert: (ticket history includes: aState).
self assert: anIncident service equals: service.
self assert: anIncident agreement equals: agreement
Look at this example above! An expression is almost in plain English, almost AppleScript ;)
I have chosen the Pharo as a tool for thought, because it doesn’t require any boilerplate to start thinking on domain and experiment with entities. The REPL is awesome and allows to dig and to feel the data.
Smalltalk pioneered system layer abstraction before Java. You always run your program in form of image using thin virtual machine layer.
I think it is really interesting how Seaside web framework works using pure objects with NO templates. This is quite interesting idea to build web interfaces.
Smalltalk is a language from the past that is still worth learning.