# Delayed computations

Values in Unison are not, by default, lazily evaluated. But it's common to want to express that a value or calculation should be delayed until it's absolutely needed.

For example the termlongTextin the following snippet is evaluated strictly:

longText : Text
longText = "🐵 Imagine infinite monkeys on infinite typewriters 🙊…"
coinflip : Boolean -> Text
coinflip bool = if bool then longText else "Hi"

But you might not actually need to evaluatelongText--thereare circumstances where the calculation of a value might be very expensive or could introduce surprising behavior if runeagerly.

One way you might solve for this is to create a "thunk": a function with no arguments which returns the desired value or computation when it's called.

longText : () -> Text
longText _ = "🐵 Imagine infinite monkeys on infinite typewriters 🙊…"

Because this is a common pattern, Unison provides the single quote,',as syntactic sugar for representing a function with the form() -> a.

We can rewrite the type() -> Textas just'Text.

longText : 'Text
longText : 'Text
longText = '"🐵 Imagine infinite monkeys on infinite typewriters 🙊…"

Just as Unison provides syntax for representing delayed computations in a type signature, there are a few ways to delay an expression in Unison.

🧠

These are all valid ways to implement a function for the type'Text:

• myFunction = '"delayed with single quote"
• myFunction _ = "delayed with underscore argument"
• myFunction = do "delayed with do keyword"

All three are equivalent in meaning.

When we want to run the thunk, we could call the value with()to represent "I'm calling this with zero arguments", but Unison also provides syntactic sugar for "forcing" or calling a thunk with the!symbol.

Calling our functionlongTextlooks like:

coinflip : Boolean -> Text
coinflip : Boolean -> Text
coinflip bool = if bool then !longText else "Hi"

To review: single quote,',an underscore_,or thedokeyword introduce athunkand the bang symbol,!,executes it, but what if we want to callcoinflipwith an argumenttrueand then return the result of that function application in a thunk? Our final desired return type is'Text.To do that, we have to surround the function application forcoinflip truein parentheses before prepending the single quote symbol.

delayedText : 'Text
delayedText = '(coinflip true)
!delayedText⧨"🐵 Imagine infinite monkeys on infinite typewriters 🙊…"
🧠
It might be tempting to write'coinflip truewith no parentheses in an attempt to get a return type of'Textor() -> Text,but the single quote ordosyntax delays thefunctionin that circumstance, not the result of evaluating the function.'coinflip truehas the signature(() -> Boolean) -> Text)and we're trying to pass it an argument oftrue.🙅🏻‍♀️ That may not be what we're looking for. When we want to delay the result ofexecuting a function,we must surround the entire expression in parentheses.