Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

Lazy Evaluation

Simple example: Infinite sequence

Lazy evaluation allows the creation of things like infinite data structures. One example is the definition of an endless sequence:

The feature ones creates an instance of list that starts with the head value 1 followed by a tail that is ones as well. The tail is constructed lazily through a function call to ones only when needed.

We can now take an arbitrary number of elements from this sequence, e.g., using a call to take as shown in the following example that creates sequences of 5 and 50 elements:

What happens here?

On a call to ones, a Cons-cell is created that contains a head value 1 and a function to create the tail when needed. This tail function calls ones when the tail of this list is requested.

Dangers

Infinite data structures like this may easily result in infinite loops or infinite recursion. It is, e.g., not possible to count the elements of the infinite list above:

Despite that, conversion into a string works because the output for infinite lists is cropped by default:

Lazy evaluation for performance

In addition to making infinite structure possible, another important aspect of lazy evaluation is that it avoids run-time overhead for the evaluation of values if these values are not needed. An example would be a logging mechanism as follows:

This code runs very slowly just because the logging messages are created.

A more efficient alternative uses lazy evaluation as follows:

In the lazy version, the msg parameter for log is no longer of type String but now has type () -> String, i.e., a function producing a string. This function is called implicitly when needed.

Additionally, the message parameter passed to log now is a Lazy String, which can be given as an ordinary string, or in the form of a lambda ()->... which runs code to create a string when called.