Skip to content
This repository has been archived by the owner on Aug 26, 2022. It is now read-only.

Latest commit

 

History

History
38 lines (25 loc) · 2.12 KB

Delay and Force.md

File metadata and controls

38 lines (25 loc) · 2.12 KB

Strictness and Laziness; Delayed Terms and Forcing

Plutarch, like UPLC, is strict by default; this is in contrast to Haskell, which is nonstrict. In practice, this means that calling a function in Plutarch evaluates all arguments to the Plutarch lambda Term beforehand.

Note: the below example does not correspond precisely to the implementation of pif or pif'; it is for didactic purposes only

This behavior may be undesirable, for example, when one of two Terms are branched upon within an if statement. The Plutarch level function pif' is naturally strict in its arguments - and therefore evaluate both branches before even entering the function body.

pif' :: Term s (PBool :--> b :--> b :--> b)
pif' = plam hif

A strict if is undesirable for the obvious reason: we only follow one branch at runtime, so it doesn't make sense to evaluate both before examining the PBool value to which we apply pif.

To avoid this, we use pdelay to create a "delayed Term." pdelay wraps the PType tag of a term, overriding the default strict behavior and indicating that the term should not be evaluated immediately. pdelay has the following type:

pdelay :: Term s a -> Term s (PDelayed a)

A delayed term evaluates when it is forced using the pforce function. Forcing a term strips the PDelayed wrapper:

pforce :: Term s (PDelayed a) -> Term s a

Thus, if we wanted a lazy pif, we could do the following:

-- | Utilizing Haskell level functions with `pdelay` and `pforce` to have lazy wrapper around `pif`.
hif :: Term s PBool -> Term s a -> Term s a -> Term s a
hif cond whenTrue whenFalse = pforce $ pif' # cond # pdelay whenTrue # pdelay whenFalse

A note of caution: calling pforce on the same delayed term twice will execute the computation each time. Users familiar with Haskell's handling of laziness -- where forcing a thunk twice never duplicates computation -- should note that UPLC behaves differently.

Finally, readers should note that pdelay and pforce are extremely powerful tools when writing Plutarch scripts and are encouraged to familiarize themselves accordingly.