11.9.1Transforming a Call to a Show
Why is show:
useful at all?
- First of all
show:
allows one to replace multiple components in one request. This is not possible withcall:
as it blocks the flow of execution and the developer has no possibility to display another component at the same time. - Another reason to use
show:
is that it is more lightweight and that it uses fewer resources thancall:
. This means that if the blocking behavior is not needed, thenshow:
is more memory friendly. - Finally some Smalltalk dialects cannot implement
call:
due to limitations in their VM.
If you want or must get rid of the call:
statements in a sequence of calls things are relatively simple. Transform code using call:
Task>>go
| a b c |
a := self call: A.
b := self call: B.
c := self call: C.
...
to the following using show:onAnswer:
Task>>go
self show: A onAnswer: [ :a |
self show: B onAnswer: [ :b |
self show: C onAnswer: [ :c |
... ] ] ]
If you have a loop like the following one, things are slightly more complicated:
Task>>go
[ self call: A ]
whileTrue: [ self call: B ]
The example below shows an equivalent piece of code that uses recursion to implement the loop:
Task>>go
self show: A onAnswer: [ :a |
a ifTrue: [
self show: B onAnswer: [ :b |
self go ] ] ]
The transformation technique applied here is called continuation-passing style or short CPS. The onAnswer:
block implements the continuation of the flow after the shown component answered. Unfortunately for more complicated flows CPS lead to messy code pretty quickly.