… doesn’t that make SC like semi-lazy? Since it’s not evaluating g yet …

Yes, that’s exactly the connection!

In SuperCollider conditional evaluation is written something like:

```
+ True { ifThenElse { arg q, r; q.value } }
+ False { ifThenElse { arg q, r; r.value } }
```

and then *p.ifThenElse({ q }, { r })*.

The receiver (*p*) and the message arguments (*{ q }* and *{ r }*) are evaluated before performing the message send (c.f. *applicative-order* evaluation).

Hence the lovely and concise notation for writing procedures of no arguments!

In Haskell conditional evaluation is written something like:

ifThenElse True q r = q

ifThenElse False q r = r

and then *ifThenElse p q r*.

Haskell won’t evaluate any part of any expression unless and until it’s required (c.f. *normal-order* evaluation).

Haskell does something quite like rewriting each expression *e* as *{ e }* and implicitly sending *value* messages.

In addition it replaces *{ e }* with it’s answer when it’s first evaluated, so the work only happens once, something like:

```
var memoize = { arg f; var r; { r.isNil.if({ r = f.value }); r } };
var f = { arg c; "f!".postln; 42 };
var g = memoize.value({ "g!".postln; 84 });
[f.value, f.value, g.value, g.value] // prints f! twice and g! once
```

There are very nice aspects to both normal-order and applicative-order evaluators!

Ps. About:

…in imperative languages with side effects…

Haskell has a very simple mechanism for attaching an effect to an expression (c.f. *unsafePerformIO*) but in general it’s very hard to know if, or when, or how many times such effects will be evaluated, hence all the libraries (*Control.Applicative*, *Control.Monad* &etc.).

Applicative-order evaluation is a very nice sequencing construct!