On this page:
Delay
Delay.expect_  of
Delay
delay
Delay.force
Delay.evt
Delay.is_  forced
Delay.is_  running
Delay.handle
Delay.from_  handle
0.45+9.1.0.3

10.5 Delayed Evaluation🔗ℹ

 import: rhombus/delay package: rhombus-lib

The rhombus/delay module implements delayed evaluation. A delay value contains an expression whose evaluation waits until the delay is forced with the Delay.force method. After the delay’s value is forced, further calls to Delay.force produce the same result.

annotation

Delay

 

annotation

Delay.expect_of(ann, ...)

 

function

fun Delay(thunk :: () -> ~any) :: Delay

 

expression

delay:

  maybe_kind

  body

  ...

 

maybe_kind

 = 

~sync

 | 

ϵ

The Delay annotation is satisfired by delay values, which are normally created using the delay form. The Delay.expect_of annotation causes the Delay.force result of an annotated expression to have the static information values(ann, ...) (where multiple anns correspond to multiple values produced by the delay’s expression). The forced values are not checked or converted, however, and each ann is used only for its static information.

The Delay function creates a delay given a function of zero arguments to be called on demand to produce the value.

The delay form creates a delay that evaluates the body sequence on demand to obtain the delay’s value.

A delay is not thread-safe by default: concurrent attempts to force a delay can trigger an exception. Specify ~sync before the body of a delay form to create a delay that is thread-safe, in which case concurrent attempts to force the delay’s value causes all but one thread to wait until the result is ready.

> def d:

    delay:

      println("working")

      1 + 2

> d.force()

working

3

> d.force()

3

method

method (dly :: Delay).force()

Return the value(s) of a delay, which is the result of the body sequence in a delay form, for example.

Calling the Delay.force method on a delay that is currently being forced throws a “reentrant promise” exception. Use the ~sync kind in delay to create a delay that can be forced concurrently by multiple threads.

> def d:

    delay:

      "ok"

> d.force()

"ok"

> def d2:

    delay:

      d2.force()

> d2.force()

force: reentrant promise ‘...eference/delay.scrbl:93:4’

method

method (dly :: Delay).evt(

  ~pool: pool :: maybe(thread.Thread.Pool || Any.of(#'own))

           = #false

) :~ Evt

Forces dly in a fresh thread and returns a synchronizable event whose value, when the force is complete, is the result of dly.

The pool argument is passed along to a use of thread, so it can be #'own or a ThreadPool to force the delay in parallel, instead of merely concurrently.

> def d1:

    delay:

      1

> def d2:

    delay:

      Evt.system_idle.sync()

      2

> Evt.sync(d1.evt(), d2.evt())

1

method

method (dly :: Delay).is_forced() :: Boolean

 

method

method (dly :: Delay).is_running() :: Boolean

The Delay.is_forced method reports whether dly has been forced already, in which case dly.force() will immediately return the delay’s value(s).

The Delay.is_running method reports whether dly is currently being forced, in which case dly.force() will throw an exception.

property

property (dly :: Delay).handle :: Any

 

function

fun Delay.from_handle(handle) :: Delay

The Delay.handle property returns a Racket promise that corresponds to the delay. The Delay.from_handle function creates a delay from a Racket promise.