KtTalk
A kotlin library of extension functions that add smalltalk style methods to objects.
Motivation
Smalltalk is a pure OO language in which everything is an object, and everything happens by sending messages(aka method calls). For this reason, it does not have built-in control structures, and you will achieve conditional branches and iterations/loops by calling methods.
For example, if statements in smalltalk are implemented as sending message ifTrue: trueClosure ifFalse: falseClosure to a Boolean object:
220)
ifTrue: [ Transcript show: ’17 x 13 is greater than 220’ ]
// The true block will execute, prints "17 x 13 is greater than 220" on the transcript.
“>
(17 * 13 > 220)
ifTrue: [ Transcript show: ’17 x 13 is greater than 220’ ]
// The true block will execute, prints "17 x 13 is greater than 220" on the transcript.
Similarly, sending message whileTrue: block to a closure object achieves something similar to a while loop:
<div class="highlight highlight-source-smalltalk position-relative" data-snippet-clipboard-copy-content="n := 1.
[ n
n := 1.
[ n < 1000 ] whileTrue: [ n := n*2 ].
// n is now 1024.
This is an elegant OO approach to handle the procedural control structures, combining the strength of OOP and FP. Unfortunately modern OO languages have abandoned this approach, and due to the language limitations its usually impossible to build such a userland library in the mainstream languages. The good new is that, it is actually possible to achieve such behaviors in Kotlin, thanks to its powerful language support for extension methods, trailing closures, infix function syntax and nonlocal return. With the KtTalk library, the above two smalltalk code can be written in Kotlin:
200) ifTrue { println("17 x 13 is greater than 220") }
var n = 1
{ n
(17 * 13 > 200) ifTrue { println("17 x 13 is greater than 220") }
var n = 1
{ n < 1000 } whileTrue { n = n * 2 }
As you see, Kotlin is a beautiful language that we can hope to write elegant code as we could in smalltalk. This library also provides other extension methods on Any, Boolean, Number and Closure types.
More Examples
The last section already provides two simple examples of achieving smalltalk-style if and while statement, but there are much more than that. You can use the method ifNull(block) on Any? and it will evaluates the supplied block if the receiver is null:
val p = Person()
p.name ifNull { throw Exception("An error occurred, the person does not have a name yet!") }
Smalltalk actively uses such methods to handle error conditions at the absence of a value/property. To me, this is a rather elegant way to throw an exception based on certain conditions, compared to writing lots of if checks.
On the other hand, you can use call the method timesRepeat(block) on an integer object i to evaluate the provided block of code i times:
val i = 5
i timesRepeat { println("Iteration: ${it}") }
It will print the line 5 times with the value of it ranging from 1 to 5. Similarly, there are methods upTo(to, block), downTo(to, block) and step(to, stepsize, block) that you can use for number objects. They are more elegant than writing traditional for loops(well Kotlin does not have C style for loops anyway), and thanks to Kotlin’s support for trailing closures the code looks nice even for methods accepting multiple arguments.
If you wonder how smalltalk handles exceptions, well, this is not rocket science either. There are such methods you can call on a block/closure object, as the below code snipper demonstrates:
<div class="highlight highlight-source-kotlin position-relative" data-snippet-clipboard-copy-content="val i = 5
{ i / 0 }.on { println("Cannot divide a number by 0") }
“>
val i = 5
{ i / 0 }.on<ArithmeticException> { println("Cannot divide a number by 0") }
This will attempt to evaluate the receiver block/closure object, which may throw an ArithmeticException. If this exception is thrown, catches it and evaluates another block. This look stunningly similar to a traditional try…catch statement, doesnt it?
Now we can see clearly that we may not need any control structures at all in a highly expressive/elegant programming language, as it is possible to implement all of them as methods on receiver objects. I quite like the notion of ‘receiver’ in Kotlin language, which reminds me of Smalltalk’s idea of ‘sending messages to receiver objects’.
This library is open source, and you may simply download it and build it with gradle. On the other hand, I’ve uploaded the pre-built .jar files in the directory /build/lib. Just add them to the class library of your Kotlin project and you are good to go. These .jar files are for different platforms, and you may use any of them for the specific platform you are targeting.
Unfortunately, kttalk is not currently on maven repository as I do not have an account with sonatype.org. This may change in future.
The documentation of this library is generated with the help of kdoc and dokka, visit the below link for the online version of the document: http://kttalk.mysidiahost.com/
Feel free to submit an issue or a PR if you have any suggestions about the library, whether it is an unidentified bug or a suggestion for improvement.