A pure function is a function whose result depends only on its arguments. There must be no dependency on state, io, time, etc. for a function to be pure. Pure function have very nice features such as being always thread-safe and very easy for optimizing compilers. Nevertheless, pure functions are useless as computer programs since any non-trivial program must interact with some input to produce some output, maybe even interactively.
Effects are a means to model non-functional aspects of an otherwise pure function. In Fuzion, effects additionally provide a means to change the implementation of an effect used by a function. For example, a function might perform logging using an effect. Then, the caller of this function itself requires this effect unless it provides a handler for the logging effect.
As an introduction, let us implement a simple HelloWorld! using
greeter effect that provides an operation
Note that the effects listed when the Fuzion compiler analyses this program
(click Effects!) is
greeter is installed explicitly, but the installation
If we run
main directly without setting a
effect, we will get an error:
In this case, the analysis for required effects (click Effects!)
greeter since this effect is required to run this code.
To give a glimpse of the power of effects, we now run a slightly more
main feature on a list different implementations of
greeter effect. First, the same as before. Next, one that print
to the standard error stream instead. Then, one that is just silent and does not
greet at all. And finally, one that performs only the first greeting and then
returns, i.e., it stops any further calculation within
directly returns from the call to
Coroutines using Effects
Here is a small example defining a generator effect
with an operation
yield. The effect is then used in a feature that
traverses a list to yield all the elements of that list.
Using State Effect to Count
The next example also traverses a list, but this time to count the number of
elements. For this, a
state effect is used that is incremented for
each element of the list that is traversed.