Laziness#

Due to the call-by-need reduction order of bruijn, several operations are lazily evaluated (automagically!).

Infinite lists#

You can use infinite list generators like repeat or iterate to lazily interact with list elements.

:import std/List .

:test (length (take (+3) (repeat (+4)))) ((+3))
:test (take (+5) (iterate ++‣ (+0))) (((+0) : ((+1) : ((+2) : ((+3) : {}(+4))))))

Math#

# power function
:test ((iterate (…⋅… (+2)) (+1)) !! (+3)) ((+8))

# prime numbers
primes nub ((…≠?… (+1)) ∘∘ gcd) (iterate ++‣ (+2)) ⧗ (List Number)

:test (take (+4) primes) ((+2) : ((+3) : ((+5) : {}(+7))))

# fibonacci
fibs head <$> (iterate [~0 : (^0 + ~0)] ((+0) : (+1))) ⧗ (List Number)

:test (take (+4) primes) ((+0) : ((+1) : ((+1) : {}(+2))))

Optimization#

Laziness can (in some cases) produce huge performance boosts. For example:

# 10 seconds
:time (+10) ** (+1000)

# 0.02 seconds
:time ((+10) ** (+1000)) =? (+42)

This works because a ternary number is just a concatenation of trits which (in this case) gets recursively generated by the pow function. The eq? function just throws away the first argument if it's already clear that the numbers can't be equal (in this case after the first argument got bigger than (+400)).