blob: 20d120514277f244059780e3ee110f4569a5b1c5 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
# 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`{.bruijn} or
`iterate`{.bruijn} to lazily interact with list elements.
``` bruijn
:import std/List .
:test (length (take (+3) (repeat (+4)))) ((+3))
:test (take (+5) (iterate ++‣ (+0))) (((+0) : ((+1) : ((+2) : ((+3) : {}(+4))))))
```
## Math
``` bruijn
# 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:
``` bruijn
# 11 seconds
:time (+10) ** (+500)
# 0.1 seconds
:time ((+10) ** (+500)) =? (+400)
```
This works because a ternary number is just a concatenation of trits
which (in this case) gets recursively generated by the `pow`{.bruijn}
function. The `eq?`{.bruijn} 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)`{.bruijn}).
|