Algebraic Effects in Pharo using Exception Handling – Englished
author:: chicoary
source:: Algebraic Effects in Pharo using Exception Handling – Englished
clipped:: 2023-10-02
published::
Published in https://chicoary.wordpress.com/2023/09/13/algebraic-effects-in-pharo-using-exception-handling-englished/.
Versão em português: Algebraic Effects em Pharo usando Exception Handling.
Algebraic Effects
When I came across Ability from Unison, an implementation of the concept of algebraic effects, I decided to try something similar, as a prototype. Since I read that algebraic effects look like exception handling, I decided to use it to implement my naïve version below.
I’ll give you a brief explanation before you try it out.
The two lines
represent “pure functions” as in Purely functional programming. They have no side effects (if we consider that throwing exceptions is not a side effect). They are implemented using Pharo’s Block Closures.
The protected block
only contains calls to “pure functions”.
The above block contains the handles for the effects #ask
and #inform:
.
The
handles the effect #ask
. If the user does not give a non-empty response when UIManager default request: 'Value:'
displays the interface below the snippet self inform: 'Enter a value.'. error retry
displays a message stating the problem and causes the protected block to be executed again.
If a non-empty answer was entered by the user, the message error resume: anAnswer
is executed and the program counter, so to speak, returns to just after the expression that threw (raise) the error. As the expression that threw the error is ask := [ MyResumableError signal: #ask ]
the program resumes execution at the end of the block and with the value that was passed in the expression error resume: anAnswer
. The reader can easily deduce which code will be executed next.
You’ve probably figured out that
inform value: answer.
will be the next expression to be executed. And it throws an exception that represents the effect#inform:
.
The other snippet that represents the handle for the effect #inform:
shows what the user typed (since an Association was passed when the error representing the effect #inform
was thrown, we use the getters key
and value
to get the identifier of the effect and what should be shown, respectively).
Conclusion
Just like exception handling that uses a try catch
structure to separate the piece of code that handles errors, the effect handle
structure does the same by separating the “impurities” represented by the side effects in Purely functional programming from the rest.
One advantage that could soon be noticed is that my function ask
could have its implementation easily changed by changing the corresponding handle to get the user’s response over the network. The same could be done with the function inform
so that it writes to a database or sends a message over the network.