## Lazy evaluation

Lazy evaluation (or call-by-need) delays evaluating an expression until it is actually needed; when it is evaluated, the result is saved so repeated evaluation is not needed. Lazy evaluation is a technique that can make some algorithms easier to express compactly or much more efficiently, or both. It is the normal evaluation mechanism for strict functional (side-effect-free) languages such as Haskell. However, automatic lazy evaluation is awkward to combine with side-effects such as input-output. It can also be difficult to implement lazy evaluation efficiently, as it requires more book-keeping.

Kawa, like other Schemes, uses “eager evaluation” - an expression is normally evaluated immediately, unless it is wrapped in a special form. Standard Scheme has some basic building blocks for “manual” lazy evaluation, using an explicit `delay` operator to indicate that an expression is to be evaluated lazily, yielding a promise, and a `force` function to force evaluation of a promise. This functionality is enhanced in SRFI 45, in R7RS-draft (based on SRFI 45), and SRFI 41 (lazy lists aka streams).

Kawa makes lazy evaluation easier to use, by implicit forcing: The promise is automatically evaluated (forced) when used in a context that requires a normal value, such as arithmetic needing a number. Kawa enhances lazy evaluation in other ways, including support for safe multi-threaded programming.

### Delayed evaluation

Syntax: `delay` ``expression``

> The `delay` construct is used together with the procedure `force` to implement lazy evaluation or call by need.

> The result of `(delay `expression`)` is a promise which at some point in the future may be asked (by the `force` procedure) to evaluate `expression`, and deliver the resulting value. The effect of `expression` returning multiple values is unspecified.

Syntax: `delay-force` ``expression``

Syntax: `lazy` ``expression``

> The `delay-force` construct is similar to `delay`, but it is expected that its argument evaluates to a promise. (Kawa treats a non-promise value as if it were a forced promise.) The returned promise, when forced, will evaluate to whatever the original promise would have evaluated to if it had been forced.

> The expression `(delay-force `expression`)` is conceptually similar to `(delay (force `expression`))`, with the difference that forcing the result of `delay-force` will in effect result in a tail call to `(force `expression`)`, while forcing the result of `(delay (force `expression`))` might not. Thus iterative lazy algorithms that might result in a long series of chains of `delay` and `force` can be rewritten using delay-force to prevent consuming unbounded space during evaluation.

> Using `delay-force` or `lazy` is equivalent. The name `delay-force` is from R7RS; the name `lazy` is from the older SRFI-45.

Procedure: `eager` `obj`

> Returns a promise that when forced will return `obj`. It is similar to `delay`, but does not delay its argument; it is a procedure rather than syntax.

> The Kawa implementation just returns `obj` as-is. This is because Kawa treats as equivalent a value and forced promise evaluating to the value.

Procedure: `force` `promise`

> The `force` procedure forces the value of `promise`. As a Kawa extension, if the `promise` is not a promise (a value that does not implement `gnu.mapping.Lazy`) then the argument is returned unchanged. If no value has been computed for the promise, then a value is computed and returned. The value of the promise is cached (or “memoized”) so that if it is forced a second time, the previously computed value is returned.

>     (force (delay (+ 1 2)))                ⇒  3

>     (let ((p (delay (+ 1 2))))
>       (list (force p) (force p)))          ⇒  (3 3)

>     (define integers
>       (letrec ((next
>                 (lambda (n)
>                   (cons n (delay (next (+ n 1)))))))
>         (next 0)))
>     (define head
>       (lambda (stream) (car (force stream))))
>     (define tail
>       (lambda (stream) (cdr (force stream))))

>     (head (tail (tail integers)))          ⇒  2

> The following example is a mechanical transformation of a lazy stream-filtering algorithm into Scheme. Each call to a constructor is wrapped in `delay`, and each argument passed to a deconstructor is wrapped in `force`. The use of `(lazy ...)` instead of `(delay (force ...))` around the body of the procedure ensures that an ever-growing sequence of pending promises does not exhaust the heap.

>     (define (stream-filter p? s)
>       (lazy
>        (if (null? (force s))
>            (delay ’())
>            (let ((h (car (force s)))
>                  (t (cdr (force s))))
>              (if (p? h)
>                  (delay (cons h (stream-filter p? t)))
>                  (stream-filter p? t))))))

>     (head (tail (tail (stream-filter odd? integers))))
>         ⇒ 5

Procedure: `force*` `promise`

> Does `force` as many times as necessary to produce a non-promise. (A non-promise is a value that does not implement `gnu.mapping.Lazy`, or if it does implement `gnu.mapping.Lazy` then forcing the value using the `getValue` method yields the receiver.)

> The `force*` function is a Kawa extension. Kawa will add implicit calls to `force*` in most contexts that need it, but you can also call it explicitly.

The following examples are not intended to illustrate good programming style, as `delay`, `lazy`, and `force` are mainly intended for programs written in the functional style. However, they do illustrate the property that only one value is computed for a promise, no matter how many times it is forced.

    (define count 0)
    (define p
      (delay (begin (set! count (+ count 1))
                    (if (> count x)
                        count
                        (force p)))))
    (define x 5)
    p                  ⇒ a promise
    (force p)          ⇒ 6
    p                  ⇒ a promise, still
    (begin (set! x 10)
           (force p))  ⇒ 6

### Implicit forcing

If you pass a promise as an argument to a function like `sqrt` if must first be forced to a number. In general, Kawa does this automatically (implicitly) as needed, depending on the context. For example:

    (+ (delay (* 3 7)) 13)   ⇒ 34

Other functions, like `cons` have no problems with promises, and automatic forcing would be undesirable.

Generally, implicit forcing happens for arguments that require a specific type, and does not happen for arguments that work on any type (or `Object`).

Implicit forcing happens for:

- arguments to arithmetic functions;

- the sequence and the index in indexing operations, like `string-ref`;

- the operands to `eqv?` and `equal?` are forced, though the operands to `eq?` are not;

- port operands to port functions;

- the value to be emitted by a `display` but not the value to be emitted by a `write`;

- the function in an application.

Type membership tests, such as the `instance?` operation, generally do not force their values.

The exact behavior for when implicit forcing happens is a work-in-progress: There are certainly places where implicit forcing doesn’t happen while it should; there are also likely to be places where implicit forcing happens while it is undesirable.

Most Scheme implementations are such that a forced promise behaves differently from its forced value, but some Scheme implementions are such that there is no means by which a promise can be operationally distinguished from its forced value. Kawa is a hybrid: Kawa tries to minimize the difference between a forced promise and its forced value, and may freely optimize and replace a forced promise with its value.

### Blank promises

A blank promise is a promise that doesn’t (yet) have a value or a rule for calculating the value. Forcing a blank promise will wait forever, until some other thread makes the promise non-blank.

Blank promises are useful as a synchronization mechanism - you can use it to safely pass data from one thread (the producer) to another thread (the consumer). Note that you can only pass one value for a given promise: To pass multiple values, you need multiple promises.

    (define p (promise))
    (future ;; Consumer thread
      (begin
        (do-stuff)
        (define v (force promise)) ; waits until promise-set-value!
        (do-stuff-with v)))
    ;; Producer thread
    ... do stuff ...
    (promise-set-value! p (calculate-value))

Constructor: `promise`

> Calling `promise` as a zero-argument constructor creates a new blank promise.

> This calls the constructor for `gnu.mapping.Promise`. You can also create a non-blank promise, by setting one of the `value`, `alias`, `thunk`, or `exception` properties. Doing so is equivalent to calling `promise-set-value!`, `promise-set-alias!`, `promise-set-thunk!`, or `promise-set-exception!` on the resulting promise. For example: `(delay exp)` is equivalent to:

>     (promise thunk: (lambda() exp))

The following four procedures require that their first arguments be blank promises. When the procedure returns, the promise is no longer blank, and cannot be changed. This is because a promise is conceptually a placeholder for a single “not-yet-known” value; it is not a location that can be assigned multiple times. The former enables clean and safe (“declarative") use of multiple threads; the latter is much trickier.

Procedure: `promise-set-value!` `promise` `value`

> Sets the value of the `promise` to `value`, which makes the `promise` forced.

Procedure: `promise-set-exception!` `promise` `exception`

> Associate `exception` with the `promise`. When the `promise` is forced the `exception` gets thrown.

Procedure: `promise-set-alias!` `promise` `other`

> Bind the `promise` to be an alias of `other`. Forcing `promise` will cause `other` to be forced.

Procedure: `promise-set-thunk!` `promise` `thunk`

> Associate `thunk` (a zero-argument procedure) with the `promise`. The first time the `promise` is forced will causes the `thunk` to be called, with the result (a value or an exception) saved for future calls.

Procedure: `make-promise` `obj`

> The `make-promise` procedure returns a promise which, when forced, will return `obj`. It is similar to `delay`, but does not delay its argument: it is a procedure rather than syntax. If `obj` is already a promise, it is returned.

> Because of Kawa’s implicit forcing, there is seldom a need to use `make-promise`, except for portability.

### Lazy and eager types

Type: `promise[T]`

> This parameterized type is the type of promises that evaluate to an value of type `T`. It is equivalent to the Java interface `gnu.mapping.Lazy<T>`. The implementation class for promises is usually `gnu.mapping.Promise`, though there are other classes that implement `Lazy`, most notably `gnu.mapping.Future`, used for futures, which are promises evaluated in a separate thread.

Note the distinction between the types `integer` (the type of actual (eager) integer values), and `promise[integer]` (the type of (lazy) promises that evaluate to integer). The two are compatible: if a `promise[integer]` value is provided in a context requiring an `integer` then it is automatically evaluated (forced). If an `integer` value is provided in context requiring a `promise[integer]`, that conversion is basically a no-op (though the compiler may wrap the `integer` in a pre-forced promise).

In a fully-lazy language there would be no distinction, or at least the promise type would be the default. However, Kawa is a mostly-eager language, so the eager type is the default. This makes efficient code-generation easier: If an expression has an eager type, then the compiler can generate code that works on its values directly, without having to check for laziness.