SlideShare a Scribd company logo
Fibonacci Func*on Gallery
@philip_schwarz
slides by https://fpilluminated.org/
Scheme
Part 2
• Infinite Stream with Explicit Genera4on
• Infinite Stream with Implicit Defini4on
• Infinite Stream with Unfolding
• Infinite Stream with Itera4on
• Infinite Stream with Scanning
In part one of this series we looked at six
implementa3ons of the Fibonacci func3on. If you are
interested in a quick recap of those func3ons, you can
find it on the next slide, otherwise feel free to skip it.
version #1 (naĆÆve)
• not tail-recursive (not stack-safe)
• exponen4al .me complexity
• linear stack frame depth
version #2 (tupling-based)
• not tail-recursive (not stack-safe)
• linear .me complexity
• linear stack frame depth
Implementa3ons explored so far
version #3 (accumulator-based)
• tail-recursive (stack-safe)
• linear .me complexity
def fib(i: Int): Eval[BigInt] = i match
case 0 => Eval.now(0)
case 1 => Eval.now(1)
case _ =>
for
a <- Eval.defer(fib(i - 1))
b <- fib(i - 2)
yield a + b
def fib(i: Int): IO[BigInt] = i match
case 0 => IO.pure(0)
case 1 => IO.pure(1)
case _ =>
for
a <- IO.defer(fib(i - 1))
b <- fib(i - 2)
yield a + b
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
(1 to i).foldLeft(BigInt(0), BigInt(1))
{ case ((a, b), _) => (b, a + b) }
def fib(i: Int): BigInt = i match
case 0 => 0
case 1 => 1
case _ => fib(i - 1) + fib(i - 2)
1
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) = i match
case 0 => (0, 1)
case _ => fibtwo(i - 1) match
{ case (a, b) => (b, a + b) }
2
def fib(i: Int): BigInt =
tailFib(0, 1, i)
def tailFib(a: BigInt, b: BigInt, i: Int): BigInt =
i match
case 0 => a
case _ => tailFib(b, a + b, i - 1)
3
4 5 6
1 2 3
version #5 (stack-safe naĆÆve - Eval-based)
• not tail-recursive but stack-safe
• exponen4al .me complexity
5
version #6 (stack-safe naĆÆve - IO-based)
• not tail-recursive but stack-safe
• exponen4al .me complexity
6
version #4 (le: fold-based)
• non-recursive (stack-safe)
• linear .me complexity
4
For the next two implementa3ons of the Fibonacci func3on, we are going to turn to
Structure and Interpreta4on of Computer Programs (SICP).
The following 10 slides are a lightning-fast, minimal refresher on (or intro to) the
building blocks used in two implementa3ons of the Fibonacci sequence.
The two implementa3ons, wriDen in the Scheme dialect of Lisp, don’t use plain
sequences, implemented with lists. Instead, they use sequences implemented with
streams, i.e. lazy and possibly infinite sequences.
While a full introduc3on to lists and streams is outside the scope of this deck, let’s
learn (or review) just enough about them to be able to understand the two Fibonacci
sequence implementa3ons that we are interested in.
SICP
3.5 Streams
...
From an abstract point of view, a stream is simply a sequence.
However, we will find that the straighJorward implementa4on of streams as lists (as in sec4on 2.2.1) doesn’t fully reveal the power
of stream processing.
As an alterna4ve, we introduce the technique of delayed evalua(on, which enables us to represent very large (even infinite)
sequences as streams. Stream processing lets us model systems that have state without ever using assignment or mutable data.
Structure and
Interpretation
of Computer Programs
2.2.1 Represen4ng Sequences
Figure 2.4: The sequence 1,2,3,4 represented as a chain of pairs.
One of the useful structures we can build with pairs is a sequence -- an ordered collec<on of data objects. There are, of course, many ways to
represent sequences in terms of pairs. One parDcularly straighEorward representaDon is illustrated in figure 2.4, where the sequence 1, 2, 3, 4 is
represented as a chain of pairs. The car of each pair is the corresponding item in the chain, and the cdr of the pair is the next pair in the chain.
The cdr of the final pair signals the end of the sequence by poinDng to a dis<nguished value that is not a pair, represented in box-and-pointer
diagrams as a diagonal line and in programs as the value of the variable nil. The en<re sequence is constructed by nested cons opera<ons:
(cons 1
(cons 2
(cons 3
(cons 4 nil))))
Construc)ng a plain sequence (list)
> (cons 1
(cons 2
(cons 3
(cons 4 nil))))
(1 2 3 4)
> `(1 2 3 4)
(1 2 3 4)
> 1 :: (2 :: (3 :: (4 :: Nil)))
List(1, 2, 3, 4)
> List(1, 2, 3, 4)
List(1, 2, 3, 4)
> 1 : (2 : (3 : (4 : [])))
[1, 2, 3, 4]
> [1, 2, 3, 4]
[1, 2, 3, 4]
> (cons 1
(cons 2
(cons 3
(cons 4 nil))))
(1 2 3 4)
> (list 1 2 3 4)
(1 2 3 4)
> (def one-through-four `(1 2 3 4))
> (first one-through-four)
1
> (rest one-through-four)
(2 3 4)
> (first (rest one-through-four))
2
> val one_through_four = List(1, 2, 3, 4)
> one_through_four.head
1
> one_through_four.tail
List(2, 3, 4)
> one_through_four.tail.head
2
> one_through_four = [1, 2, 3, 4]
> head one_through_four
1
> tail one_through_four
[2, 3, 4]
> head (tail one_through_four)
2
> (define one-through-four (list 1 2 3 4))
> (car one-through-four)
1
> (cdr one-through-four)
(2 3 4)
> (car (cdr one-through-four))
2
Selec)ng the head and tail of a plain sequence (list)
3.5.1 Streams Are Delayed Lists
As we saw in sec4on 2.2.3, sequences can serve as standard interfaces for combining program modules. We formulated powerful
abstrac4ons for manipula4ng sequences, such as map, filter, and accumulate, that capture a wide variety of opera4ons in a manner
that is both succinct and elegant.
Structure and
Interpretation
of Computer Programs
(define (map proc items)
(if (null? items)
nil
(cons (proc (car items))
(map proc (cdr items)))))
(define (filter predicate sequence)
(cond ((null? sequence) nil)
((predicate (car sequence))
(cons (car sequence)
(filter predicate (cdr sequence))))
(else (filter predicate (cdr sequence)))))
(define (accumulate op initial sequence)
(if (null? sequence)
initial
(op (car sequence)
(accumulate op initial (cdr sequence)))))
š’‡š’š’š’…š’“ ∷ š›¼ → š›½ → š›½ → š›½ → š›¼ → š›½
š’‡š’š’š’…š’“ š‘“ š‘’ = š‘’
š’‡š’š’š’…š’“ š‘“ š‘’ š‘„: š‘„š‘  = š‘“ š‘„ š’‡š’š’š’…š’“ š‘“ š‘’ š‘„š‘ 
map ∷ (α → š›½) → [α] → [š›½]
map f =
map f š‘„ ∶ š‘„š‘  = š‘“ š‘„ ∶ map š‘“ š‘„š‘ 
:ilter ∷ (α → šµš‘œš‘œš‘™) → [α] → [α]
:ilter p =
:ilter p š‘„ ∶ š‘„š‘  = š¢šŸ š‘ š‘„
š­š”šžš§ š‘„ ∶ :ilter p š‘„š‘ 
šžš„š¬šž :ilter p š‘„š‘ 
š‘“š‘œš‘™š‘‘š‘Ÿ ∷ š›¼ → š›½ → š›½ → š›½ → š›¼ → š›½
š‘“š‘œš‘™š‘‘š‘Ÿ š‘“ š‘’ = š‘’
š‘“š‘œš‘™š‘‘š‘Ÿ š‘“ š‘’ š‘„: š‘„š‘  = š‘“ š‘„ š‘“š‘œš‘™š‘‘š‘Ÿ š‘“ š‘’ š‘„š‘ 
map ∷ (α → š›½) → [α] → š›½
map f =
map f š‘„ ∶ š‘„š‘  = š‘“ š‘„ ∶ map š‘“ š‘„š‘ 
:ilter ∷ (α → šµš‘œš‘œš‘™) → [α] → [α]
:ilter p =
:ilter p š‘„ ∶ š‘„š‘  = š¢šŸ š‘ š‘„
š­š”šžš§ š‘„ ∶ :ilter p š‘„š‘ 
šžš„š¬šž :ilter p š‘„š‘ 
(define (sum-even-fibs n)
(fold-left +
0
(filter even?
(map fib
(iota (+ n 1) 0)))))
(define (fib n)
(cond ((= n 0) 0)
((= n 1) 1)
(else (+ (fib (- n 1))
(fib (- n 2))))))
(defn sum-even-fibs [n]
(reduce +
0
(filter even?
(map fib
(range 0 (inc n))))))
(defn fib [n]
(cond (= n 0) 0
(= n 1) 1
:else (+ (fib (- n 1))
(fib (- n 2)))))
def sum_even_fibs(n: Int): Int =
List.range(0, n+1)
.map(fib)
.filter(isEven)
.fold(0)(_+_)
def fib(n: Int): Int = n match def isEven(n: Int): Boolean =
case 0 => 0 n % 2 == 0
case 1 => 1
case n => fib(n - 1) + fib(n - 2)
sum_even_fibs :: Int -> Int
sum_even_fibs n =
foldl (+)
0
(filter is_even
(map fib
[0..n]))
fib :: Int -> Int is_even :: Int -> Bool
fib 0 = 0 is_even n = (mod n 2) == 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)
mapping, filtering, and folding a plain sequence (list)
☨ FWIW, instead of using the hand-rolled map, filter and accumulate func3ons seen on the previous slide, we are using built-in func3ons map, filter and fold-leU.
☨
Unfortunately, if we represent sequences as lists, this elegance is bought at the price of severe inefficiency with respect to both the
4me and space required by our computa4ons. When we represent manipula4ons on sequences as transforma4ons of lists, our
programs must construct and copy data structures (which may be huge) at every step of a process.
To see why this is true, let us compare two programs for compu4ng the sum of all the prime numbers in an interval. The first
program is wriXen in standard itera4ve style:53
(define (sum-primes a b)
(define (iter count accum)
(cond ((> count b) accum)
((prime? count) (iter (+ count 1) (+ count accum)))
(else (iter (+ count 1) accum))))
(iter a 0))
The second program performs the same computation using the sequence operations of section 2.2.3:
(define (sum-primes a b)
(accumulate +
0
(filter prime? (enumerate-interval a b))))
In carrying out the computa4on, the first program needs to store only the sum being accumulated. In contrast, the filter in the
second program cannot do any tes4ng un4l enumerate-interval has constructed a complete list of the numbers in the interval.
The filter generates another list, which in turn is passed to accumulate before being collapsed to form a sum.
Such large intermediate storage is not needed by the first program, which we can think of as enumera4ng the interval
incrementally, adding each prime to the sum as it is generated.
53 Assume that we have a predicate prime? (e.g., as in sec3on 1.2.6) that tests for primality.
Structure and
Interpretation
of Computer Programs
The inefficiency in using lists becomes painfully apparent if we use the sequence paradigm to compute the second prime in the
interval from 10,000 to 1,000,000 by evalua4ng the expression
(car (cdr (filter prime?
(enumerate-interval 10000 1000000))))
This expression does find the second prime, but the computa4onal overhead is outrageous. We construct a list of almost a million
integers, filter this list by tes4ng each element for primality, and then ignore almost all of the result.
In a more tradi4onal programming style, we would interleave the enumera4on and the filtering, and stop when we reached the
second prime.
Streams are a clever idea that allows one to use sequence manipula4ons without incurring the costs of manipula4ng sequences as
lists.
With streams we can achieve the best of both worlds: We can formulate programs elegantly as sequence manipula4ons, while
aXaining the efficiency of incremental computa4on.
The basic idea is to arrange to construct a stream only par4ally, and to pass the par4al construc4on to the program that consumes
the stream.
If the consumer aXempts to access a part of the stream that has not yet been constructed, the stream will automa4cally construct
just enough more of itself to produce the required part, thus preserving the illusion that the en4re stream exists.
In other words, although we will write programs as if we were processing complete sequences, we design our stream
implementa4on to automa4cally and transparently interleave the construc4on of the stream with its use.
Structure and
Interpretation
of Computer Programs
On the surface, streams are just lists with different names for the procedures that manipulate them.
There is a constructor, cons-stream, and two selectors, stream-car and stream-cdr, which sa4sfy the constraints
(stream-car (cons-stream x y)) = x
(stream-cdr (cons-stream x y)) = y
There is a dis4nguishable object, the-empty-stream, which cannot be the result of any cons-stream opera4on, and which can be
iden4fied with the predicate stream-null?.54
Thus we can make and use streams, in just the same way as we can make and use lists, to represent aggregate data arranged in a
sequence.
In par4cular, we can build stream analogs of the list opera4ons from chapter 2, such as list-ref, map, and for-each:
(define (stream-ref s n)
(if (= n 0)
(stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define (stream-map proc s)
(if (stream-null? s)
the-empty-stream
(cons-stream (proc (stream-car s))
(stream-map proc (stream-cdr s)))))
…
54 In the MIT implementa3on, the-empty-stream is the same as the empty list '(), and stream-null? is the same as null?.
Structure and
Interpretation
of Computer Programs
(define (list-ref items n)
(if (= n 0)
(car items)
(list-ref (cdr items) (- n 1))))
(define (map proc items)
(if (null? items)
nil
(cons (proc (car items))
(map proc (cdr items)))))
…
To make the stream implementa4on automa4cally and transparently interleave the construc4on of a stream with its use, we will
arrange for the cdr of a stream to be evaluated when it is accessed by the stream-cdr procedure rather than when the stream is
constructed by cons-stream.
…
As a data abstrac4on, streams are the same as lists. The difference is the 4me at which the elements are evaluated.
With ordinary lists, both the car and the cdr are evaluated at construc4on 4me. With streams, the cdr is evaluated at selec4on
4me.
Structure and
Interpretation
of Computer Programs
Next, we turn to infinite streams.
Structure and
Interpretation
of Computer Programs
3.5.2 Infinite Streams
We have seen how to support the illusion of manipula4ng streams as complete en44es even though, in actuality, we compute
only as much of the stream as we need to access. We can exploit this technique to represent sequences efficiently as streams,
even if the sequences are very long. What is more striking, we can use streams to represent sequences that are infinitely long.
For instance, consider the following defini4on of the stream of posi4ve integers:
(define (integers-starting-from n)
(cons-stream n (integers-starting-from (+ n 1))))
(define integers (integers-starting-from 1))
This makes sense because integers will be a pair whose car is 1 and whose cdr is a promise to produce the integers beginning
with 2. This is an infinitely long stream, but in any given 4me we can examine only a finite por4on of it. Thus, our programs will
never know that the en4re infinite stream is not there.
Using integers we can define other infinite streams, such as the stream of integers that are not divisible by 7:
(define (divisible? x y) (= (remainder x y) 0))
(define no-sevens
(stream-filter (lambda (x) (not (divisible? x 7)))
integers))
Then we can find integers not divisible by 7 simply by accessing elements of this stream:
(stream-ref no-sevens 100)
117
Structure and
Interpretation
of Computer Programs
In analogy with integers, we can define the infinite stream of Fibonacci numbers:
(define (fibgen a b)
(cons-stream a (fibgen b (+ a b))))
(define fibs (fibgen 0 1))
fibs is a pair whose car is 0 and whose cdr is a promise to evaluate (fibgen 1 1).
When we evaluate this delayed (fibgen 1 1), it will produce a pair whose car is 1 and whose cdr is a promise to
evaluate (fibgen 1 2), and so on.
Following that refresher on (or intro to) sequences
implemented as lists or streams, let’s turn to the use of
infinite streams to compute the Fibonacci sequence.
infinite stream
implementa)on
(explicit genera1on)
#7
> (stream-ref fibs 5)
5
> (stream-ref fibs 50)
12586269025
> (stream-ref fibs 100)
354224848179261915075
> (define (fib n)
(stream-ref fibs n))
> (fib 50)
12586269025
> (fib 100)
354224848179261915075
Let’s try fibs out
and then define fib.
def fibs: LazyList[BigInt] =
fibgen(0, 1)
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
a #:: fibgen(b, a + b)
(define fibs
(fibgen 0 1))
(define (fibgen a b)
(cons-stream a (fibgen b (+ a b))))
> (stream-ref fibs 5)
5
> (stream-ref fibs 50)
12586269025
> (stream-ref fibs 100)
354224848179261915075
> fibs(5)
val res0: BigInt = 5
> fibs(50)
val res1: BigInt = 12586269025
> fibs(100)
val res2: BigInt = 354224848179261915075
A stream being a ā€˜delayed list’, the Scala equivalent is a lazy list.
Here is the Scala version of the Scheme infinite stream implementa4on.
(define (fib n)
(stream-ref fibs n))
Since calling fibs(n) is just as convenient as calling fib(n),
let’s not bother defining a Scala version of fib.
infinite stream
implementa)on
(explicit genera1on)
#7
def fibs: LazyList[BigInt] =
fibgen(0, 1)
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
a #:: fibgen(b, a + b)
The fibgen helper func3on in the infinite stream implementa4on is
one that we also come across in Programming in Scala (see next slide).
infinite stream
implementa)on
#6
def fibFrom(a: Int, b: Int): LazyList[Int] =
a #:: fibFrom(b, a + b)
LazyList example in
Programming in Scala
LazyLists
A lazy list is a list whose elements are computed lazily. Only those elements requested will be computed. A lazy list can, therefore, be infinitely long. Otherwise,
lazy lists have the same performance characteris4cs as lists. Whereas lists are constructed with the :: operator, lazy lists are constructed with the similar-looking
#:: . Here is a simple example of a lazy list containing the integers 1, 2, and 3:
scala> val str = 1 #:: 2 #:: 3 #:: LazyList.empty
val str: scala.collection.immutable.LazyList[Int] = LazyList(<not computed>)
The head of this lazy list is 1, and the tail of it has 2 and 3. None of the elements are printed here, though,
because the list hasn’t been computed yet! Lazy lists are specified to compute lazily, and the toString
method of a lazy list is careful not to force any extra evalua4on.
Below is a more complex example. It computes a lazy list that contains a Fibonacci sequence star4ng with
the given two numbers. A Fibonacci sequence is one where each element is the sum of the previous two
elements in the series:
scala> def fibFrom(a: Int, b: Int): LazyList[Int] =
a #:: fibFrom(b, a + b)
def fibFrom: (a: Int, b: Int)LazyList[Int]
This func4on is decep4vely simple. The first element of the sequence is clearly a, and the rest of the sequence is the Fibonacci sequence star4ng with b followed
by a + b. The tricky part is compu4ng this sequence without causing an infinite recursion. If the func4on used :: instead of #::, then every call to the func4on
would result in another call, thus causing an infinite recursion. Since it uses #::, though, the right-hand side is not evaluated un4l it is requested.
Here are the first few elements of the Fibonacci sequence star4ng witht two ones:
scala> val fibs = fibFrom(1, 1).take(7)
val fibs: scala.collection.immutable.LazyList[Int] = LazyList(<not computed>)
scala> fibs.toList
val res23: List[Int] = List(1, 1, 2, 3, 5, 8, 13)
What do streams look like in Haskell?
They are just lists, because Haskell uses an evaluation strategy called lazy evaluation, in which expressions are only
evaluated as much as required by the context in which they are used.
In Haskell we can create an ordinary list that is potentially infinite: it is only evaluated as much as required by the context.
Here is the Haskell equivalent of the
Scala infinite stream implementa4on.
fibs :: Num t => [t]
fibs = fibgen 0 1
fibgen :: Num t => t -> t -> [t]
fibgen a b = a : fibgen b (a + b)
def fibs: LazyList[BigInt] =
fibgen(0, 1)
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
a #:: fibgen(b, a + b)
Othe next slide you can see a very
similar Clojure implementa4on.
infinite stream
implementa)on
(explicit genera1on)
#7
> fibs(100)
val res0: BigInt = 354224848179261915075
> fibs.take(10).toList
val res1: List[BigInt] = List(0,1,1,2,3,5,8,13,21,34)
> fibs !! 100
354224848179261915075
> (take 10 fibs)
[0,1,1,2,3,5,8,13,21,34]
Lazy Sequences
Lazy sequences are constructed using the macro lazy-seq: (lazy-seq & body)
A lazy-seq invokes its body only when needed, that is, when seq is called directly or indirectly. lazy-seq then caches the
result for subsequent calls. You can use lazy-seq to define a lazy Fibonacci series as follows:
1: (defnlazy-seq-fibo
2: ([]
3: (concat [0 1] (lazy-seq-fibo 0N 1N)))
4: ([a b]
5: (let [n (+ a b)]
6: (lazy-seq
7: (cons n (lazy-seq-fibo b n))))))
On line 3, the zero-argument body returns the concatenation of the basis values [0 1] and then calls the two-argument
body to calculate the rest of the values. On line 5, the two-argument body calculates the next value n in the series, and on
line 7 it conses n onto the rest of the values.
The key is line 6, which makes its body lazy. Without this, the recursive call to lazy-seq-fibo on line 7 would happen
immediately, and lazy-seq-fibo would recurse until it blew the stack. This illustrates the general pattern: wrap the
recursive part of a function body with lazy-seq to replace recursion with laziness.
lazy-seq-fibo works for small values:
(take 10 (lazy-seq-fibo))
-> (0 1 1N 2N 3N 5N 8N 13N 21N 34N)
lazy-seq-fibo also works for large values. Use (rem ... 1000) to print only the last 3 digits of the one millionth Fibonacci number:
(rem (nth (lazy-seq-fibo) 1000000) 1000)
-> 875N
Stuart Halloway
stuarthalloway
infinite stream
implementa)on
(explicit genera1on)
#7
Compu3ng the millionth Fibonacci number using
the Scala version runs out of heap space.
scala> def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
| a #:: fibgen(b, a + b)
|
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt]
scala> def fibs: LazyList[BigInt] =
| fibgen(0, 1)
|
def fibs: LazyList[BigInt]
scala> fibs(1_000_000)
java.lang.OutOfMemoryError: Java heap space
at java.base/java.math.BigInteger.add(BigInteger.java:1475)
at java.base/java.math.BigInteger.add(BigInteger.java:1381)
at scala.math.BigInt.$plus(BigInt.scala:311)
at rs$line$16$.fibgen$$anonfun$1(rs$line$16:2)
at rs$line$16$$$Lambda/0x0000000131684800.apply(Unknown Source)
at scala.collection.immutable.LazyList$Deferrer$.$anonfun$$hash$colon$colon$extension$2(LazyList.scala:1143)
at scala.collection.immutable.LazyList$Deferrer$$$Lambda/0x0000000131659cd8.apply(Unknown Source)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state$lzycompute(LazyList.scala:259)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state(LazyList.scala:252)
at scala.collection.immutable.LazyList.isEmpty(LazyList.scala:269)
at scala.collection.immutable.LazyList$.$anonfun$dropImpl$1(LazyList.scala:1073)
at scala.collection.immutable.LazyList$$$Lambda/0x0000000131659a20.apply(Unknown Source)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state$lzycompute(LazyList.scala:259)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state(LazyList.scala:252)
at scala.collection.immutable.LazyList.isEmpty(LazyList.scala:269)
at scala.collection.LinearSeqOps.apply(LinearSeq.scala:131)
at scala.collection.LinearSeqOps.apply$(LinearSeq.scala:128)
at scala.collection.immutable.LazyList.apply(LazyList.scala:240)
... 14 elided
scala>
infinite stream
implementation
(explicit generation)
#7
Compu3ng the millionth Fibonacci number using
the Haskell version does not exhaust heap space.
ghci> fibgen a b = a : fibgen b (a + b)
ghci> fibs = fibgen 0 1
ghci> (fibs !! 1000000) > 1
True
ghci>
infinite stream
implementa)on
(explicit genera1on)
#7
As a recap, here are the Scheme, Clojure,
Scala, and Haskell versions compared.
infinite stream
implementa)on
(explicit genera1on)
#7
(defn lazy-seq-fibo
([]
(concat [0 1] (lazy-seq-fibo 0N 1N)))
([a b]
(let [n (+ a b)]
(lazy-seq
(cons n (lazy-seq-fibo b n))))))
def fibs: LazyList[BigInt] =
fibgen(0, 1)
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
a #:: fibgen(b, a + b)
(define fibs
(fibgen 0 1))
(define (fibgen a b)
(cons-stream a (fibgen b (+ a b))))
fibs :: Num t => [t]
fibs = fibgen 0 1
fibgen :: Num t => t -> t -> [t]
fibgen a b = a : fibgen b (a + b)
In the next slide we are going to see:
1) Why I added ā€˜explicit genera4on’ to the name of the implementa3on we have just seen
2) An even simpler implementa3on that defines an infinite stream implicitly
infinite stream
implementa)on
(explicit genera1on)
#7
just seen
coming up next
infinite stream
implementa)on
(implicit defini1on)
#8
Defining streams implicitly
The integers and fibs streams above were defined by specifying ''generating'' procedures that explicitly compute the stream
elements one by one. An alternative way to specify streams is to take advantage of delayed evaluation to define streams
implicitly.
For example, the following expression defines the stream ones to be an infinite stream of ones:
(define ones (cons-stream 1 ones))
This works much like the definition of a recursive procedure: ones is a pair whose car is 1 and whose cdr is a promise to
evaluate ones. Evaluating the cdr gives us again a 1 and a promise to evaluate ones, and so on.
We can do more interesting things by manipulating streams with operations such as add-streams, which produces the
elementwise sum of two given streams
(define (add-streams s1 s2)
(stream-map + s1 s2))
Now we can define the integers as follows:
(define integers (cons-stream 1 (add-streams ones integers)))
This defines integers to be a stream whose first element is 1 and the rest of which is the sum of ones and integers.
Thus, the second element of integers is 1 plus the first element of integers, or 2; the third element of integers is 1 plus the second
element of integers, or 3; and so on.
This definition works because, at any point, enough of the integers stream has been generated so that we can feed it back into
the definition to produce the next integer.
Structure and
Interpretation
of Computer Programs
The stream-map funcDon used here is a generalisaDon of the one seen in slide
12, in that it allows the mapping of procedures that take mulDple arguments.
We can define the Fibonacci numbers in the same style:
(define fibs
(cons-stream 0
(cons-stream 1
(add-streams (stream-cdr fibs)
fibs))))
This definition says that fibs is a stream beginning with 0 and 1, such that the rest of the stream can be generated by
adding fibs to itself shifted by one place:
1 1 2 3 5 8 13 21 … = (stream-cdr fibs)
0 1 1 2 3 5 8 13 … = fibs
0 1 1 2 3 5 8 13 21 34 … = fibs
SICP
infinite stream
implementa)on
(implicit defini1on)
#8
val fibs: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: (fibs zip fibs.tail).map(_+_)
(define fibs
(cons-stream 0
(cons-stream 1
(add-streams (stream-cdr fibs)
fibs))))
Here is the Scala version of the Scheme infinite
stream implementa3on with implicit defini4on.
1 1 2 3 5 8 13 21 … = (stream-cdr fibs)
0 1 1 2 3 5 8 13 … = fibs
0 1 1 2 3 5 8 13 21 34 … = fibs
scala> fibs(10)
val res0: BigInt = 55
scala> fibs(100)
val res1: BigInt = 354224848179261915075
scala> fibs(1000)
val res2: BigInt = 434665576869374564356885276750406258025646605173717804024817290895365554179490518904038798400792
55169295922593080322634775209689623239873322471161642996440906533187938298969649928516003704476137795166849228875
infinite stream
implementation
(implicit definition)
#8
scala> fibs(100_000)
val res0: BigInt =
25974069347221724166155034021275915414880485386517696584724770703952534543511273686265556772836716744754637587223074432111638399473875091030965697382188304493052287638531334
92135302679278956701051276578271635608073050532200243233114383986516137827238124777453778337299916214634050054669860390862750996639366409211890125271960172105060300350586894
02855810367511765825136837743868493641345733883436515877542537191241050033219599133006220436303521375652542182399869084855637408017925176162939175496345855861630076281991608
11098365263529954406942842065710460449038056471363460330005208522777075544467947237090309790190148604328468198579610159510018506082649192345873133991501339199323631023018641
72536477136266475080133982431231703431452964181790051187957316766834979901682011849907756686456845066287392485603914047605199550066288826345877189410680370091879365001733011
71002831047394745625609144493282137485557386408057981302826664027035429441210491999580313187680589918651342517595991152056315533770399694103551827527491995980225750790203779
81030899229849963044962558140455170002502997643221934621653662108418767454282982613982344783665815880408190033073829395000821320093747154851310272208173054322648669496309879
14714362925554252624043999615326979876807510646819068792118299167964409178271868561702918102212679267401362650499784968843680975254700131004574186406448299485872551744746695
65187912691699324456481767332225714931496776334584662383033382023970243685947828764187578857291071013370030009422933359729277919140921280490154597626279105705524815888405177
94181929052167695766087488155678601288183543542923073978101547857013284386127286201766539534449930019800629538936985500723286651317181135886613537472684585432548981137176605
19461693791688442534259478126310388952047956594380715301911253964847112638900713362856910155145342332944128435722099628674611942095166100230974070996553190050815866991144544
26478828726428450172533204864831945789203998489382363674561822037509734856684743388724904933703163382657176072977889179891366732519062324711803728017392157239082276922807729
24566627505383375006926077210593619421268920302567443565378008318306375933345023502569729065152853271943677560156660399164048825639676930792905029514886934137991251748566670
74717514938979038653338139534684837808612673755438382110844897653836848318258836339917310455850905663846202501463131183108742907729262215943020429159474030610183981685506695
02619737615085717611994758757221298720531206079186498036159609233959410411863516885488391191851790615115627529361584900087215019222651178531508925102752804515123860379218469
21215338292871369243215273327141574788295902601571954853164447945467502858402360002383447905203451080332820138038807089807348326201227952633606773669875783326254859449060219
17368867786241120562109836985019729017715780112040458649153935115783499546100636635745448508241888279067531359950519206222976015376529797308588164873117308237059828489404487
40393205359293597645416556079547247786202996923295613897198946794221872736051233655952113310877875822887959758032045960847902450638519417431261637751045992110248687949634170
68620929088930685252348056925998333775103901013166178123051145719327066291671254465121517468025481903583516889717075706778656188008220346836321018130262329960275994035799977
74046244952114531588370357904483293150007246173417355805567832153454341170020258560809166294198637401514569572272836921963229511187762530753402594781448204657460288485500062
80693481139827601685558407954216205754355729151064153759293902288435612079264370556006236798654438246437394697247194599655579550583803482559783968277608473153025178895171863
07227611036305093600742622617173630586132915440246954329046162586917746305785076749374879923291817501634840688134655343709975893536074051729094126976575932951568186247471276
36468836551757018353417274662607306510451195762866349922848678780591085118985653555434958761664016447588028633629704046289097067736256584300235314749461233912068632146637087
84469921042754156941091224656857120471724113337848981676409692498163342117685715031167104006817530319211541561195804257065869312727621371069747222602965552461105371555453249
97508432752001992143019105053629960070429632978051030666506387862681576587726837451289768507963663710593809112254288358391941211547737599813019216509521401333060709873137329
26518169226845063443954056729812031546392324981793780469103793422169495229100793029949237507299325063050942813902793084134473061411643355614764093104425918481363930542369378
97652052645634764831827263337151211203062923388928648794920973784786188486826080464731953920084039830800880386904955741975621929392211082576639768136104449002472094834032679
67688376213967440757138872928630798218493143438797780887379588968409461434159271317578365114578289355818599029235343888888465874521308381377794436361197628390368945957601203
16502279857901545344747352706972851454599861422902737291131463782045516225447535356773622793648545035710208644541208984235038908770223039849380214734809687433336225449150117
41175157070456105089527400020638049796796040261781866448124854726963082347337724554339051984130876978127656591676422902294818176307571025579336500815228638363449313808997178
50870708636322058690189383777660630060667577324272729292474212952650007066467227300099561241914091389846752249557907293984956087504566942177715511073466304566039441362358884
43676215273928597072287937355966723924613827468703217858459948257514745406436460997059316120596841560473234396652457231650317792833860590388360417691428732735703986803342604
67007171736357309112298130690328613712259793709660577517296452826375743407579228218074435290866960685402171859789116633386385858973620911424843217864503947919542420819162608
85710691104339948014730131008698488664307212167624731196181907378207665829682807960794822595490363282665780069948568253005364366748225346037051345036031521542969439918662368
57638062351209884448741138600171173647632126029961408561925599707566827866778732377419444462275399909291044697716476151118672327238679208133367306181944849396607123345271856
52025364362196419878275297881306008031314181706931446822118927578497828109436775154071010635055379800384221904550848223938699329692665922111274269813306230007346562849809363
66930494468016285537126334126203784919194986000972008367278766507868863069334189952257683143908324848863403189401941610369798438333466086767094316436535384309121578155435128
52077720858098902099586449602479491970687230765687109234380719509824814473157813780080639358418756655098501321882852840184981407690738507369535377711880388528935347600930338
59869160828933542114772293656190727626460372602723932099118782040706741227225812076672904007192423793033097213236418409395610299597129179982829000953914738243780277905111203
09545825328887211461701334403859396540478061993332245473178034073409025121302172795957538631581488103929524754109438805550983826276331276067181261710220113561818007754002275
16734144169216424973175621363128588281978005788832454534581522434937268133433997710512532081478345067139835038332901313945986481820272322043341930929011907832896569222878337
49735430156172282911562732946881485328192210075237362682764315268573549322302801810144964900901552924863833888566489300225097434360120081436515362536919944670971112695196672
57800618912154402224875646015546328120919458246535574320476442126507906552082083379760714651275083204871652715774723258872757611283575921325539344462894332581050286335836692
91828566894736223508250294964065798630809614341696830467595174355313224362664207197608459024263017473392225291248366316428006552870975051997504913009859468071013602336440164
40017918861085323076499171437205446782359721176046515320016308533631935158964589068172237281231032027189791795127279965605369403211124284659099455638021546131610626752163380
56643943188812681994940055370686976218552318589211009634410129335357339184596681975398342846968228894600763520316889220020219313183697575569620611157743058263055358620156378
91246031220672933992617378379625150999935403648731423208873977968908908369996292995391977217796533421249291978383751460062054967341662833487341011097770535898066498136011395
57158432830871394058253527405608101150390794168807919721293314830307263867863141103844312821599493682434299818871976863760449634259752425688618868897898088831586507626260485
64650043228968561492550639688114044004295038942458723822335431010786915173283336047792627277656860761777056168740502577437499837758301438561354272738385897741335269491654839
29721519554793578923866762502745370104660909382449626626935321303744538892479216161188889702077910448563199514826630802879549546453583866307344423753319712279158861707289652
09014984830543598320077132665340729066201677570640969018377120130682324533347796666052532549087360196148037824156607127165038358225728921570820936951099589013285949072430618
33257552012080900071750220229497428018234454137119162984499147222541965946822214682606449618392542496709031040075814888579716722463228870164384039084638567311643081695373267
90303114583680575021119639905615169154708510459700542098571797318015564741406172334145847111268547929892443001391468289103679179216978616582489007322033591376706527676521307
14398530276098847805621699465965546137917498565973922737941672649537780199209835542786617912312669937473077773056932443016683933301155451554265686493749212868704912175424596
78311329692484924667442619990339728256748734602011504422287804661243201830161082321839086547710423982285313165596856880052265714744288233175394565438819286244326625033453881
99590085105211383124491861802624432195540433985722841341254409411771722156867086291742124053110620522842986199273629406208834754853645128123279609097213953775360023076765694
20821994303464878334854449271353945022459133437466493770165560576338469706291872574542650587941463017663976045747431108155674709165270874812526715991379324052730461369396116
98925898083119063225107779285620719994594877006118010022961323045882945584409524966111583428049086438608807964405577636918577437540258968559272525145634043852178258905995539
54627451385454452916761042969267970893580056234501918571489030418495767400819359973218711957496357095967825171096264752068890806407651445893132870767454169607107931692704285
16809341331104635350624220981036321677191042078616218421376393819462569728678141363638962012397691046541895680619732314841422455007161721585132130203068417608721589270209887
91089380810459033972765473264169168454456276007595613671035845756490944306924525320850030910687831575615198475675691912847846546925586651115579134612724253360836351313421839
05177154511228464455136016013513228948543271504760839307556100908786096663870612278690274831819331606701484957163004705262228238406266818448788374548131994380387613830128859
88526420199228618820849958864088852135250145761539648264745102590253074317295689963649961570755185583716593536712544851508936290456773663003556245737477910098799249914696722
40414816012895309440154889426137831400878043114317418580718261851490511387448313584390672289494082582860216502889272283874264327861686903819605301558944594518087351972460082
21529343980828254126128257157209350985382800738560472910941184006084485235377833503306861977724501886364070344973366473100602018128792886991861824418453968994777259482169137
13364747045317297980924584436112961899759569624097184556402051143258959184472492094293030165148871307980210237906553652515478029805940752944051314580755153779486163587990115
81920198088796949671874482241568364635343261602426329347616344581638901638051238941845239734218414968892623984896486420934098166814947711551770095626690298501015135375998012
72501241971119871526593747484778935488777815192931171431167444773882941064615028751327709474504763922874890662989841540259350834035142035136168819248238998027706666916342133
42431205450735938861668769118818577611813577133248396520988208598239129860638682280475436240895652292141085985203733054462595326134023486468927506052689375514840329854208699
12210525970056285767077025676953009789700464089200098521069802954196998021380532957981594782899344432454915653278452238405512404452082264354206563133107029407223715527705042
63482073984454889589248861397657079145414427653584572951329719091947694411910966797474262675590953832039169673494261360032263077428684105040061351052194413778158095005714526
84600981035210924904002795805073643696102124113773971716486952549311480504012656835126882959841398322267637780450062650724173175739521979689075482519932925964980162706866565
80301788774056151671597319273204793762473755058550528396602945669925221736008740812120142090710419375985717214313380174251415824918247109050847159772494170493202541652393232
33258851588893337097136310892571531417761978326033750109026284066415801371359356529278088456305951770081443994114674291850360748852366654744869928083230516815711602911836374
14795849210086052898146954775081233889694315286102120273674704990393041703517134212692348670056662750622905863691188222890317051030540688209697087554532936943406398129769647
80318254516421783473477164710584232385945801830527562139101869976043058440686657123468696794560441557421000391797583489799358827518815246759308789281592434921975453876683056
84668420775409821781247053354523194797398953320175988640281058825557698004397120538312459428957377696001857497335249965013509368925958021863811725906506436882127156815751021
71290076599275037022828396396291597325117341858672102349731776596945428362551937155600914368032931196284254662840314244437064843239037490641081130079284895576724348120009030
98884572709077508736388732996425550504738125289759629348228789176199207251383093882882925104168376227582040819189336036538752841167857037209897188329869219278166296758445801
74911809119663048187434155067790863948831489241504300476704527971283482211522202837062857314244107823792513645086677566622804977211397140621664116324756784216612961477109018
82609467737768640617672148429389497667138012278894130902655351109611834701256519754080709538406091686393690667378662720942943426426040290215831734500372746258899262204987712
11784055633484924903260035085690993823927772974984135656148307882623633223683807098223460122742413790364734517359252157547571609342709351929017239549214264906911152715233381
09124042812102893738488167358953934508930697715522989199698903885883275409044300321986834003470271220020159699371690650330547577095398748580670024491045504890061727189168031
39452803616563394157133463722255047754746075605502410876438212168884891694037125890194849068537972224456200948381949153272450227621858916950740579498375982100660448199651936
01102615769471762025717020486849146168940684041408335875621183192108380056321445620189415059457800253187474719116048406779977654148306221790693308538751292989830095802775541
45435058768984944179136535891620098725222049055183554603706533183176716110738009786625247488691476077664470147193074476302411660335671765564874440577990531996271632972009109
44924921645603061882777294775076477744645258632891915910744425232008291820951802108370035388133098321589460868012795422475207192413464833496391509481309754143324420929993075
14810779190023461281223301617994299306188005334145506339321393396468616164169552202164479954172431711657444713641977332048993650747678441499295480730258564429423817876415064
92878361767978677158510784235702640213388018875601989234056868423215585628508645525258377010620532224244987990625263484010774322488172558602233302076399933854152015343847725
44291789513063705032044491779775237087195827797679968611362653229111862963116468515993466069346055754595606315583003369763400027668515129384363888609082837614115773200352756
51587459065670254394379311048385713132944906049265823631089495350900826731544972263966480886180415739778884728921746189741897217007700098624496537590127270152276345108749069
48012210684952063002519011655963580552429180205586904259685261047412834518466736938580027700252965356366721619883672428226933950325930390994583168665542234654857020875504617
52052185372156728267990341813552060299989536647010655790053212954133692447249221243632452304289518846177912233806967423398069488727058750338922839509513520912310925815900696
03951563677360671090505662996035718764232479207528361608055976977787564767672105212223271848214844466312614875842260926088757643317310232637688648225946912110323677375581
22133470556805958008310127481673962019583598023967414489867276845869819376783757167936723213081586191045995058970991064686919463448038574143829629547131372173669836184558
14450574867612432245151994336218291619146802609112179300186478805006135160314435007618921344160248809174105123229035717920549792797092450247994084269615881844261616378004
47594782122408732041244211691998055726491182436619218357147628914258057718717436880003241130087048193739622950171430900984769272374988759386399425305953316078916188108635
05982444578942799346514915952884869757488025823353571677864826828051140885429732788197765736966005727700162592404301688659946862983717270595809808730901820120931003430058
79655269478804980920548430546761103465474806729067439976361259243463771999584386281239198547020241488007688081884808789239159136946329311327684932977720164664172758725912
23547844808134333280500877588552646861195769621722393086937957571658218524162043419723839899327348034292623407223381551022091012629492497424232716988420232973032601617905
75673111235465890298298313115123607606773968998153812286999642014609852579793691246016346088762321286205634215901479188632194659637483482564291616278532948239313229440231
04327728876813955021334826638868745325928158785450389099156194963247885503509028939097371898800399902613201587267863787309567810962531100805448941885798356590206368069964
31650339120299443277267708693052407184165920700961392864019667257500870122181497331336958096003697517649513500402859262492033981110149532275336218445007443315624345324842
17986108346261345897591234839970751854223281677187215956827243245910829019886390369784542622566912542747056097567984857136623679023878478161201477982939080513150258174523
77352951016529693456278612224115078358775537334837276443983808200066721474003446632277691893696761287898348894209468810230842703645285450496675969731883604449670285319063
73969163579809288657199353977234954867871804164014152814894437850362910715178052858575839877111454742401564164771941163913549354667555935926088492005463846854030280809364
17250583653368093407225310820844723570226809826951426162451204040711501448747856199922814664565893938488028643822313849852328452360667045805113679663751039248163336173274
54727577563681097734453927582756059742516070546868965779453052160231593986578097480151541498709777807870535705800847237689242218975031275852714017311762127989874495840619
98439133656802977212087519349885044997139142851580323248230213406303125860726245416377652345055220510863182853596585207081733927095664450114040551065790550374177803933516
58360904543047721422281816832539613634982525215232257690920254216409657452618066051777901592902884240599998882753691957540116954696152270401280857579766154722192925655963
99182094889464265751228876633030213374636744921744935163710472573298083281272646818775935658421838359470279201366390768974173896225257578266399080979264701140758036785059
93818871845600946958332707751261812820153910417739509182441375619999378192403624695582359241714787027794484431087519018074141102903707060520851629757983617542510416422448
67577350756338018895379263183389855955956527857227926155524494739363665533904528656215464288343162282921123290451842212532888101415884061619939195042230059898349966569463
58018681671707481882321584864773438678091156466075517538555222442852404946803369229998930078390002069012151774069642857393019691050098827852305379763794025796895329511243
61667789105855572133817890899454539479159273749586002682378444868720372434888346168562900978505324970369333619424398028823643235538082080038757417109692897254998785662530
48867033095150518452126944989251596392079421452606508516052325614861938282489838000815085351564642761700832096483117944401971780149213345335903336672376719229722069970766
05548245224741692777463752213520171623172213763244569915402239549415822741893058991174693177377651873585003231801443288391637424379585469569122177409894861151556404660956
50945381155209218637115186845625432750478705300069984231401801694211091059254935961167194576309623288312712683285017603217716804002496576741869271132155732700499357099423
24416387089242427584407651215572676037924765341808984312676941110313165951429479377670698881249643421933287404390485538222160837088907598277390184204138197811025854537088
58670145062357851396010998747605253545010043935306207243970997644514679099338144899464460978095773195360493873495002686056455569322422969181563029392248760647087343116638
42054424896287602136502469918930401125131038350856219080602708666048735858490017042009239297891939381251167984217881152092591304355723216356608956035143838839390189531662
74355609970015699780289236362349895374653428746875
scala>
Earlier I said that in Haskell, streams are just ordinary lists, because we can create an ordinary
list that is poten4ally infinite: it is only evaluated as much as required by the context.
Remember the first Scheme example of an implicitly defined infinite stream?
(define ones (cons-stream 1 ones))
Here is how it looks in Haskell.
> ones = 1 : ones
> head ones
1
> tail (head ones)
1
> ones !! 100
1
> take 10 ones
[1,1,1,1,1,1,1,1,1,1]
To understand the cause of this inefficiency, let’s begin the calcula3on of, say, š‘“š‘–š‘ 8 :
š‘“š‘–š‘ 8
⇒ š‘“š‘–š‘ 7 + š‘“š‘–š‘ 6
⇒ š‘“š‘–š‘ 6 + š‘“š‘–š‘ 5 + š‘“š‘–š‘ 5 + š‘“š‘–š‘ 4
⇒ š‘“š‘–š‘ 5 + š‘“š‘–š‘ 4 + š‘“š‘–š‘ 4 + š‘“š‘–š‘ 3 + š‘“š‘–š‘ 4 + š‘“š‘–š‘ 3 + š‘“š‘–š‘ 3 + š‘“š‘–š‘ 2
⇒
š‘“š‘–š‘ 4 + š‘“š‘–š‘ 3 + š‘“š‘–š‘ 3 + š‘“š‘–š‘ 2
+
š‘“š‘–š‘ 3 + š‘“š‘–š‘ 2 + š‘“š‘–š‘ 2 + š‘“š‘–š‘ 1
+
š‘“š‘–š‘ 3 + š‘“š‘–š‘ 2 + š‘“š‘–š‘ 2 + š‘“š‘–š‘ 1
+
š‘“š‘–š‘ 2 + š‘“š‘–š‘ 1 + š‘“š‘–š‘ 1 + š‘“š‘–š‘ 0
…
It is easy to see that this calcula4on is blowing up exponen4ally. That is, to compute the nth Fibonacci number will
require a number of steps propor4onal to 2n. Sadly, many of the computa4ons are being repeated, but in general we
cannot expect a Haskell implementa3on to realise this and take advantage of it. So what do we do?
Paul E. Hudak
Remember the passage (in slide 3 of part 1) in which Paul Hudak asked what should be done
to address the fact that the 4me complexity of the naĆÆve implementa3on is exponen4al?
His answer, in the next four slides, is the Haskell version of the infinite stream
implementa3on with implicit defini4on.
naĆÆve
implementa)on
#1
š‘“š‘–š‘ ∷ š¼š‘›š‘”š‘’š‘”š‘’š‘Ÿ → š¼š‘›š‘”š‘’š‘”š‘’š‘Ÿ
š‘“š‘–š‘ 0 = 1
š‘“š‘–š‘ 1 = 1
š‘“š‘–š‘ š‘› = š‘“š‘–š‘ š‘› āˆ’ 1 + š‘“š‘–š‘ š‘› āˆ’ 2
Paul E. Hudak
One solu4on is to construct the Fibonacci sequence directly as an infinite stream. The key to this construc4on is no4cing
that if we add pointwise the Fibonacci sequence to the tail of the Fibonacci sequence, we get the tail of the tail of the
Fibonacci sequence.
1 1 2 3 5 8 13 21 … = Fibonacci sequence
1 2 3 5 8 13 21 34 … = tail of Fibonacci sequence
2 3 5 8 13 21 34 55 … = tail of tail of Fibonacci sequence
This leads naturally to the following defini4on of the Fibonacci sequence:
š‘“š‘–š‘š‘  ∷ š¼š‘›š‘”š‘’š‘”š‘’š‘Ÿ
š‘“š‘–š‘š‘  = 1 ∶ 1 ∶ š‘§š‘–š‘š‘Šš‘–š‘”ā„Ž + š‘“š‘–š‘š‘  (š‘”š‘Žš‘–š‘™ š‘“š‘–š‘š‘ )
Note the concise and naturally recursive nature of this defini4on. Evalua4ng š‘”š‘Žš‘˜š‘’ 10 š‘“š‘–š‘š‘  yields:
[1,1,2,3,5,8,13,21,34,55]
as expected.
DETAILS
Try running take n fibs with successively larger values of n; you will find that it runs very fast, even though the Fibonacci
numbers start geng quite large. In fact, in Hugs the 3me is dominated by how long it takes to print the numbers; try
running fibs !! 1000 to see how quickly a single value can be computed and printed.
This program is very efficient. To see why, we can proceed by calcula4on.
infinite stream
implementa)on
(implicit defini1on)
#8
Paul E. Hudak
The first step is easy:
š‘“š‘–š‘š‘ 
⇒ 1 ∶ 1 ∶ š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  (š‘”š‘Žš‘–š‘™ š‘“š‘–š‘š‘ )
where, for succinctness, I have wriDen š’‚š’…š’… for š’›š’Šš’‘š‘¾š’Šš’•š’‰ + .
However, if we now simply subs3tute the defini3on of š‘“š‘–š‘š‘  for both of its occurrences, we find ourselves heading toward the
same exponen4al blow-up that we saw earlier:
⇒ 1 ∶ 1 ∶ š‘Žš‘‘š‘‘ 1 ∶ 1 ∶ š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  š‘”š‘Žš‘–š‘™ š‘“š‘–š‘š‘ 
(š‘”š‘Žš‘–š‘™ (1 ∶ 1 ∶ š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  (š‘”š‘Žš‘–š‘™ š‘“š‘–š‘š‘ )))
Fortunately, a Haskell implementa4on will be cleverer than this by sharing š‘“š‘–š‘š‘  as well as its tail. Star4ng from the
beginning again, this sharing is no4ceable immediately aUer the first step:
š‘“š‘–š‘š‘ 
⇒ 1 ∶ 1 ∶ š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  (š‘”š‘Žš‘–š‘™ š‘“š‘–š‘š‘ )
At which point, we can express the sharing of the tail using a š’˜š’‰š’†š’“š’† clause:
⇒ 1 ∶ š‘”š‘“
š’˜š’‰š’†š’“š’† š‘”š‘“ = 1 ∶ š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  (š‘”š‘Žš‘–š‘™ š‘“š‘–š‘š‘ )
⇒ 1 ∶ š‘”š‘“
š’˜š’‰š’†š’“š’† š‘”š‘“ = 1 ∶ š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  š‘”š‘“
Paul E. Hudak
We can also express the sharing of the tail of the tail in prepara4on for unfolding š’‚š’…š’… (I will use š’•š’‡šŸ, š’•š’‡šŸ‘, and so on, for the
names of the successive tails):
⇒ 1 ∶ š‘”š‘“
š’˜š’‰š’†š’“š’† š‘”š‘“ = 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = š‘Žš‘‘š‘‘ š‘“š‘–š‘š‘  š‘”š‘“
Finally, we can unfold š’‚š’…š’… to yield:
⇒ 1 ∶ š‘”š‘“
š’˜š’‰š’†š’“š’† š‘”š‘“ = 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = 2 ∶ š‘Žš‘‘š‘‘ š‘”š‘“ š‘”š‘“2
Repea4ng this process, we introduce even more sharing, and unfold š’‚š’…š’… again:
⇒ 1 ∶ š‘”š‘“
š’˜š’‰š’†š’“š’† š‘”š‘“ = 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = 2 ∶ š‘”š‘“3
š’˜š’‰š’†š’“š’† š‘”š‘“3 = š‘Žš‘‘š‘‘ š‘”š‘“ š‘”š‘“2
⇒ 1 ∶ š‘”š‘“
š’˜š’‰š’†š’“š’† š‘”š‘“ = 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = 2 ∶ š‘”š‘“3
š’˜š’‰š’†š’“š’† š‘”š‘“3 = 3 ∶ š‘Žš‘‘š‘‘ š‘”š‘“2 š‘”š‘“3
But now note that š’•š’‡ is only used in one place, and thus might as well be eliminated, yielding:
⇒ 1 ∶ 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = 2 ∶ š‘”š‘“3
š’˜š’‰š’†š’“š’† š‘”š‘“3 = 3 ∶ š‘Žš‘‘š‘‘ š‘”š‘“2 š‘”š‘“3
Paul E. Hudak
At this point, we can begin to repeat the sequence of introducing a new š’˜š’‰š’†š’“š’† clause to capture sharing, unfolding š’‚š’…š’…,
and then elimina4ng the outermost š’˜š’‰š’†š’“š’† binding. This will yield successively longer versions of the result. Here is one
more applica4on of that sequence:
⇒ 1 ∶ 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = 2 ∶ š‘”š‘“3
š’˜š’‰š’†š’“š’† š‘”š‘“3 = 3 ∶ š‘”š‘“4
š’˜š’‰š’†š’“š’† š‘”š‘“4 = š‘Žš‘‘š‘‘ š‘”š‘“2 š‘”š‘“3
⇒ 1 ∶ 1 ∶ š‘”š‘“2
š’˜š’‰š’†š’“š’† š‘”š‘“2 = 2 ∶ š‘”š‘“3
š’˜š’‰š’†š’“š’† š‘”š‘“3 = 3 ∶ š‘”š‘“4
š’˜š’‰š’†š’“š’† š‘”š‘“4 = 5 ∶ š‘Žš‘‘š‘‘ š‘”š‘“3 š‘”š‘“4
⇒ 1 ∶ 1 ∶ 2 ∶ š‘”š‘“3
š’˜š’‰š’†š’“š’† š‘”š‘“3 = 3 ∶ š‘”š‘“4
š’˜š’‰š’†š’“š’† š‘”š‘“4 = 5 ∶ š‘Žš‘‘š‘‘ š‘”š‘“3 š‘”š‘“4
The reason why there are always at least two š’˜š’‰š’†š’“š’† clauses is that Ribs recurses on itself as well as its tail. The elimina4on
of the š’˜š’‰š’†š’“š’† clause corresponds to the garbage collec4on of unused memory by an implementa4on.
Although this process may seem a bit tedious, it is important only when wan4ng to reason about the efficiency (in 4me and
space) of the calcula4on. If you are just interested in the resul4ng values, you can, of course, use the exponen4ally
expanding calcula4on, with no fear that you might get a different answer.
ghci> fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
ghci> fibs !! 100000
2597406934722172416615503402127591541488048538651769658472477070395253454351127368626555677283671674475463758722307443211163839947387509103096569738218830449305228763853133
4921353026792789567010512765782716356080730505322002432331143839865161378272381247774537783372999162146340500546698603908627509966393664092118901252719601721050603003505868
9402855810367511765825136837743868493641345733883436515877542537191241050033219599133006220436303521375652542182399869084855637408017925176162939175496345855861630076281991
6081109836526352995440694284206571046044903805647136346033000520852277707554446794723709030979019014860432846819857961015951001850608264919234587313399150133919932363102301
8641725364771362664750801339824312317034314529641817900511879573167668349799016820118499077566864568450662873924856039140476051995500662888263458771894106803700918793650017
3301171002831047394745625609144493282137485557386408057981302826664027035429441210491999580313187680589918651342517595991152056315533770399694103551827527491995980225750790
2037798103089922984996304496255814045517000250299764322193462165366210841876745428298261398234478366581588040819003307382939500082132009374715485131027220817305432264866949
6309879147143629255542526240439996153269798768075106468190687921182991679644091782718685617029181022126792674013626504997849688436809752547001310045741864064482994858725517
4474669565187912691699324456481767332225714931496776334584662383033382023970243685947828764187578857291071013370030009422933359729277919140921280490154597626279105705524815
8884051779418192905216769576608748815567860128818354354292307397810154785701328438612728620176653953444993001980062953893698550072328665131718113588661353747268458543254898
1137176605194616937916884425342594781263103889520479565943807153019112539648471126389007133628569101551453423329441284357220996286746119420951661002309740709965531900508158
6699114454426478828726428450172533204864831945789203998489382363674561822037509734856684743388724904933703163382657176072977889179891366732519062324711803728017392157239082
2769228077292456662750538337500692607721059361942126892030256744356537800831830637593334502350256972906515285327194367756015666039916404882563967693079290502951488693413799
1251748566670747175149389790386533381395346848378086126737554383821108448976538368483182588363399173104558509056638462025014631311831087429077292622159430204291594740306101
8398168550669502619737615085717611994758757221298720531206079186498036159609233959410411863516885488391191851790615115627529361584900087215019222651178531508925102752804515
1238603792184692121533829287136924321527332714157478829590260157195485316444794546750285840236000238344790520345108033282013803880708980734832620122795263360677366987578332
6254859449060219173688677862411205621098369850197290177157801120404586491539351157834995461006366357454485082418882790675313599505192062229760153765297973085881648731173082
3705982848940448740393205359293597645416556079547247786202996923295613897198946794221872736051233655952113310877875822887959758032045960847902450638519417431261637751045992
1102486879496341706862092908893068525234805692599833377510390101316617812305114571932706629167125446512151746802548190358351688971707570677865618800822034683632101813026232
9960275994035799977740462449521145315883703579044832931500072461734173558055678321534543411700202585608091662941986374015145695722728369219632295111877625307534025947814482
0465746028848550006280693481139827601685558407954216205754355729151064153759293902288435612079264370556006236798654438246437394697247194599655579550583803482559783968277608
4731530251788951718630722761103630509360074262261717363058613291544024695432904616258691774630578507674937487992329181750163484068813465534370997589353607405172909412697657
5932951568186247471276364688365517570183534172746626073065104511957628663499228486787805910851189856535554349587616640164475880286336297040462890970677362565843002353147494
6123391206863214663708784469921042754156941091224656857120471724113337848981676409692498163342117685715031167104006817530319211541561195804257065869312727621371069747222602
9655524611053715554532499750843275200199214301910505362996007042963297805103066650638786268157658772683745128976850796366371059380911225428835839194121154773759981301921650
9521401333060709873137329265181692268450634439540567298120315463923249817937804691037934221694952291007930299492375072993250630509428139027930841344730614116433556147640931
0442591848136393054236937897652052645634764831827263337151211203062923388928648794920973784786188486826080464731953920084039830800880386904955741975621929392211082576639768
1361044490024720948340326796768837621396744075713887292863079821849314343879778088737958896840946143415927131757836511457828935581859902923534388888846587452130838137779443
6361197628390368945957601203165022798579015453447473527069728514545998614229027372911314637820455162254475353567736227936485450357102086445412089842350389087702230398493802
1473480968743333622544915011741175157070456105089527400020638049796796040261781866448124854726963082347337724554339051984130876978127656591676422902294818176307571025579336
5008152286383634493138089971785087070863632205869018938377766063006066757732427272929247421295265000706646722730009956124191409138984675224955790729398495608750456694217771
5511073466304566039441362358884436762152739285970722879373559667239246138274687032178584599482575147454064364609970593161205968415604732343966524572316503177928338605903883
6041769142873273570398680334260467007171736357309112298130690328613712259793709660577517296452826375743407579228218074435290866960685402171859789116633386385858973620911424
8432178645039479195424208191626088571069110433994801473013100869848866430721216762473119618190737820766582968280796079482259549036328266578006994856825300536436674822534603
7051345036031521542969439918662368576380623512098844487411386001711736476321260299614085619255997075668278667787323774194444622753999092910446977164761511186723272386792081
3336730618194484939660712334527185652025364362196419878275297881306008031314181706931446822118927578497828109436775154071010635055379800384221904550848223938699329692665922
1112742698133062300073465628498093636693049446801628553712633412620378491919498600097200836727876650786886306933418995225768314390832484886340318940194161036979843833346608
6767094316436535384309121578155435128520777208580989020995864496024794919706872307656871092343807195098248144731578137800806393584187566550985013218828528401849814076907385
0736953537771188038852893534760093033859869160828933542114772293656190727626460372602723932099118782040706741227225812076672904007192423793033097213236418409395610299597129
1799828290009539147382437802779051112030954582532888721146170133440385939654047806199333224547317803407340902512130217279595753863158148810392952475410943880555098382627633
1276067181261710220113561818007754002275167341441692164249731756213631285882819780057888324545345815224349372681334339977105125320814783450671398350383329013139459864818202
7232204334193092901190783289656922287833749735430156172282911562732946881485328192210075237362682764315268573549322302801810144964900901552924863833888566489300225097434360
1200814365153625369199446709711126951966725780061891215440222487564601554632812091945824653557432047644212650790655208208337976071465127508320487165271577472325887275761128
3575921325539344462894332581050286335836692918285668947362235082502949640657986308096143416968304675951743553132243626642071976084590242630174733922252912483663164280065528
7097505199750491300985946807101360233644016440017918861085323076499171437205446782359721176046515320016308533631935158964589068172237281231032027189791795127279965605369403
2111242846590994556380215461316106267521633805664394318881268199494005537068697621855231858921100963441012933535733918459668197539834284696822889460076352031688922002021931318
3697575569620611157743058263055358620156378912460312206729339926173783796251509999354036487314232088739779689089083699962929953919772177965334212492919783837514600620549673416
6283348734101109777053589806649813601139557158432830871394058253527405608101150390794168807919721293314830307263867863141103844312821599493682434299818871976863760449634259752
4256886188688978980888315865076262604856465004322896856149255063968811404400429503894245872382233543101078691517328333604779262727765686076177705616874050257743749983775830143
8561354272738385897741335269491654839297215195547935789238667625027453701046609093824496266269353213037445388924792161611888897020779104485631995148266308028795495464535838663
0734442375331971227915886170728965209014984830543598320077132665340729066201677570640969018377120130682324533347796666052532549087360196148037824156607127165038358225728921570
8209369510995890132859490724306183325755201208090007175022022949742801823445413711916298449914722254196594682221468260644961839254249670903104007581488857971672246322887016438
4039084638567311643081695373267903031145836805750211196399056151691547085104597005420985717973180155647414061723341458471112685479298924430013914682891036791792169786165824890
0732203359137670652767652130714398530276098847805621699465965546137917498565973922737941672649537780199209835542786617912312669937473077773056932443016683933301155451554265686
4937492128687049121754245967831132969248492466744261999033972825674873460201150442228780466124320183016108232183908654771042398228531316559685688005226571474428823317539456543
8819286244326625033453881995900851052113831244918618026244321955404339857228413412544094117717221568670862917421240531106205228429861992736294062088347548536451281232796090972
1395377536002307676569420821994303464878334854449271353945022459133437466493770165560576338469706291872574542650587941463017663976045747431108155674709165270874812526715991379
3240527304613693961169892589808311906322510777928562071999459487700611801002296132304588294558440952496611158342804908643860880796440557763691857743754025896855927252514563404
3852178258905995539546274513854544529167610429692679708935800562345019185714890304184957674008193599732187119574963570959678251710962647520688908064076514458931328707674541696
0710793169270428516809341331104635350624220981036321677191042078616218421376393819462569728678141363638962012397691046541895680619732314841422455007161721585132130203068417608
7215892702098879108938081045903397276547326416916845445627600759561367103584575649094430692452532085003091068783157561519847567569191284784654692558665111557913461272425336083
6351313421839051771545112284644551360160135132289485432715047608393075561009087860966638706122786902748318193316067014849571630047052622282384062668184487883745481319943803876
1383012885988526420199228618820849958864088852135250145761539648264745102590253074317295689963649961570755185583716593536712544851508936290456773663003556245737477910098799249
9146967224041481601289530944015488942613783140087804311431741858071826185149051138744831358439067228949408258286021650288927228387426432786168690381960530155894459451808735197
2460082215293439808282541261282571572093509853828007385604729109411840060844852353778335033068619777245018863640703449733664731006020181287928869918618244184539689947772594821
6913713364747045317297980924584436112961899759569624097184556402051143258959184472492094293030165148871307980210237906553652515478029805940752944051314580755153779486163587990
1158192019808879694967187448224156836463534326160242632934761634458163890163805123894184523973421841496889262398489648642093409816681494771155177009562669029850101513537599801
2725012419711198715265937474847789354887778151929311714311674447738829410646150287513277094745047639228748906629898415402593508340351420351361688192482389980277066669163421334
2431205450735938861668769118818577611813577133248396520988208598239129860638682280475436240895652292141085985203733054462595326134023486468927506052689375514840329854208699122
1052597005628576707702567695300978970046408920009852106980295419699802138053295798159478289934443245491565327845223840551240445208226435420656313310702940722371552770504263482
0739844548895892488613976570791454144276535845729513297190919476944119109667974742626755909538320391696734942613600322630774286841050400613510521944137781580950057145268460098
1035210924904002795805073643696102124113773971716486952549311480504012656835126882959841398322267637780450062650724173175739521979689075482519932925964980162706866565803017887
7405615167159731927320479376247375505855052839660294566992522173600874081212014209071041937598571721431338017425141582491824710905084715977249417049320254165239323233258851588
8933370971363108925715314177619783260337501090262840664158013713593565292780884563059517700814439941146742918503607488523666547448699280832305168157116029118363741479584921008
6052898146954775081233889694315286102120273674704990393041703517134212692348670056662750622905863691188222890317051030540688209697087554532936943406398129769647803182545164217
8347347716471058423238594580183052756213910186997604305844068665712346869679456044155742100039179758348979935882751881524675930878928159243492197545387668305684668420775409821
7812470533545231947973989533201759886402810588255576980043971205383124594289573776960018574973352499650135093689259580218638117259065064368821271568157510217129007659927503702
2828396396291597325117341858672102349731776596945428362551937155600914368032931196284254662840314244437064843239037490641081130079284895576724348120009030988845727090775087363
8873299642555050473812528975962934822878917619920725138309388288292510416837622758204081918933603653875284116785703720989718832986921927816629675844580174911809119663048187434
1550677908639488314892415043004767045279712834822115222028370628573142441078237925136450866775666228049772113971406216641163247567842166129614771090188260946773776864061767214
8429389497667138012278894130902655351109611834701256519754080709538406091686393690667378662720942943426426040290215831734500372746258899262204987712117840556334849249032600350
8569099382392777297498413565614830788262363322368380709822346012274241379036473451735925215754757160934270935192901723954921426490691115271523338109124042812102893738488167358
9539345089306977155229891996989038858832754090443003219868340034702712200201596993716906503305475770953987485806700244910455048900617271891680313945280361656339415713346372225
5047754746075605502410876438212168884891694037125890194849068537972224456200948381949153272450227621858916950740579498375982100660448199651936011026157694717620257170204868491
4616894068404140833587562118319210838005632144562018941505945780025318747471911604840677997765414830622179069330853875129298983009580277554145435058768984944179136535891620098
7252220490551835546037065331831767161107380097866252474886914760776644701471930744763024116603356717655648744405779905319962716329720091094492492164560306188277729477507647774
4645258632891915910744425232008291820951802108370035388133098321589460868012795422475207192413464833496391509481309754143324420929993075148107791900234612812233016179942993061
8800533414550633932139339646861616416955220216447995417243171165744471364197733204899365074767844149929548073025856442942381787641506492878361767978677158510784235702640213388
0188756019892340568684232155856285086455252583770106205322242449879906252634840107743224881725586022333020763999338541520153438477254429178951306370503204449177977523708719582
7797679968611362653229111862963116468515993466069346055754595606315583003369763400027668515129384363888609082837614115773200352756515874590656702543943793110483857131329449060
4926582363108949535090082673154497226396648088618041573977888472892174618974189721700770009862449653759012727015227634510874906948012210684952063002519011655963580552429180205
5869042596852610474128345184667369385800277002529653563667216198836724282269339503259303909945831686655422346548570208755046175205218537215672826799034181355206029998953664701
0655790053212954133692447249221243632452304289518846177912233806967423398069488727058750338922839509513520912310925815900696039515636773606710905056629960357187642324792075283
6160805597697778756476767210521222327184821484446631261487584226092608875764331731023263768864822594691211032367737558122133470556805958008310127481673962019583598023967414489
86727684586981937678375716793672321308158619104599505897099106468691946344803857414382962954713137217366983618455814450574867612432245151994336218291619146802609112179300186
47880500613516031443500761892134416024880917410512322903571792054979279709245024799408426961588184426161637800447594782122408732041244211691998055726491182436619218357147628
91425805771871743688000324113008704819373962295017143090098476927237498875938639942530595331607891618810863505982444578942799346514915952884869757488025823353571677864826828
05114088542973278819776573696600572770016259240430168865994686298371727059580980873090182012093100343005879655269478804980920548430546761103465474806729067439976361259243463
77199958438628123919854702024148800768808188480878923915913694632931132768493297772016466417275872591223547844808134333280500877588552646861195769621722393086937957571658218
52416204341972383989932734803429262340722338155102209101262949249742423271698842023297303260161790575673111235465890298298313115123607606773968998153812286999642014609852579
79369124601634608876232128620563421590147918863219465963748348256429161627853294823931322944023104327728876813955021334826638868745325928158785450389099156194963247885503509
02893909737189880039990261320158726786378730956781096253110080544894188579835659020636806996431650339120299443277267708693052407184165920700961392864019667257500870122181497
33133695809600369751764951350040285926249203398111014953227533621844500744331562434532484217986108346261345897591234839970751854223281677187215956827243245910829019886390369
78454262256691254274705609756798485713662367902387847816120147798293908051315025817452377352951016529693456278612224115078358775537334837276443983808200066721474003446632277
69189369676128789834889420946881023084270364528545049667596973188360444967028531906373969163579809288657199353977234954867871804164014152814894437850362910715178052858575839
87711145474240156416477194116391354935466755593592608849200546384685403028080936417250583653368093407225310820844723570226809826951426162451204040711501448747856199922814664
56589393848802864382231384985232845236066704580511367966375103924816333617327454727577563681097734453927582756059742516070546868965779453052160231593986578097480151541498709
77780787053570580084723768924221897503127585271401731176212798987449584061998439133656802977212087519349885044997139142851580323248230213406303125860726245416377652345055220
51086318285359658520708173392709566445011404055106579055037417780393351658360904543047721422281816832539613634982525215232257690920254216409657452618066051777901592902884240
59999888275369195754011695469615227040128085757976615472219292565596399182094889464265751228876633030213374636744921744935163710472573298083281272646818775935658421838359470
27920136639076897417389622525757826639908097926470114075803678505993818871845600946958332707751261812820153910417739509182441375619999378192403624695582359241714787027794484
43108751901807414110290370706052085162975798361754251041642244867577350756338018895379263183389855955956527857227926155524494739363665533904528656215464288343162282921123290
45184221253288810141588406161993919504223005989834996656946358018681671707481882321584864773438678091156466075517538555222442852404946803369229998930078390002069012151774069
64285739301969105009882785230537976379402579689532951124361667789105855572133817890899454539479159273749586002682378444868720372434888346168562900978505324970369333619424398
02882364323553808208003875741710969289725499878566253048867033095150518452126944989251596392079421452606508516052325614861938282489838000815085351564642761700832096483117944
40197178014921334533590333667237671922972206997076605548245224741692777463752213520171623172213763244569915402239549415822741893058991174693177377651873585003231801443288391
63742437958546956912217740989486115155640466095650945381155209218637115186845625432750478705300069984231401801694211091059254935961167194576309623288312712683285017603217716
80400249657674186927113215573270049935709942324416387089242427584407651215572676037924765341808984312676941110313165951429479377670698881249643421933287404390485538222160837
08890759827739018420413819781102585453708858670145062357851396010998747605253545010043935306207243970997644514679099338144899464460978095773195360493873495002686056455569322
42296918156302939224876064708734311663842054424896287602136502469918930401125131038350856219080602708666048735858490017042009239297891939381251167984217881152092591304355723
21635660895603514383883939018953166274355609970015699780289236362349895374653428746875
ghci>
In the next two slides, Stuart Halloway shows us a
Clojure version of the current infinite stream
implementa3on, and in doing so, explains why we should
be careful not to hold on to the head of a lazy sequence.
Losing your head
There’s one last thing to consider when working with lazy sequences. Lazy sequences let you define a large
(possibly infinite) sequence and then work with a small part of that sequence in memory at a given moment. This
clever ploy will fail if you (or some API) unintentionally hold a reference to the part of the sequence you no longer
care about.
The most common way this can happen is if you accidentally hold the head (first item) of a sequence. In the
examples in previous sections, each variant of the Fibonacci numbers was defined as a function returning a
sequence, not the sequence itself.
You could define the sequence directly as a top-level var:
; holds the head (avoid!)
(defhead-fibo (lazy-cat [0N 1N] (map + head-fibo (rest head-fibo))))
This definition uses lazy-cat, which is like concat except that the arguments are evaluated only when needed. This
is a very pretty definition, in that it defines the recursion by mapping a sum over (each element of the Fibonaccis)
and (each element of the rest of the Fibonaccis).
Stuart Halloway
stuarthalloway
infinite stream
implementa)on
(implicit defini1on)
#8
head-fibo works great for small Fibonacci numbers:
(take 10 head-fibo)
-> [0N 1N 1N 2N 3N 5N 8N 13N 21N 34N]
but not so well for huge ones:
(nth head-fibo 1000000)
-> java.lang.OutOfMemoryError : GC overhead limit exceeded
The problem is that the top-level var head-fibo holds the head of the collection. This prevents the garbage collector
from reclaiming elements of the sequence after you’ve moved past those elements. So, any part of the Fibonacci
sequence that you actually use gets cached for the life of the value referenced by head-fibo, which is likely to be the
life of the program.
Unless you want to cache a sequence as you traverse it, you must be careful not to keep a reference to the head of
the sequence. As the head-fibo example demonstrates, you should normally expose lazy sequences as a function
that returns the sequence, not as a var that contains the sequence. If a caller of your function wants an explicit
cache, the caller can always create its own var. With lazy sequences, losing your head is often a good idea.
Stuart Halloway
stuarthalloway
infinite stream
implementa)on
(implicit defini1on)
#8
Compu3ng the millionth Fibonacci number using
the Scala version also runs out of heap space.
This is true of all the Scala implementa3ons in this
deck, so I am going to stop repea3ng it.
scala> val fibs: LazyList[BigInt] =
| BigInt(0) #:: BigInt(1) #:: (fibs zip fibs.tail).map(_+_)
|
val fibs: LazyList[BigInt] = LazyList(<not computed>)
scala> fibs(1_000_000)
java.lang.OutOfMemoryError: Java heap space
at java.base/java.math.BigInteger.add(BigInteger.java:1425)
at java.base/java.math.BigInteger.add(BigInteger.java:1331)
at scala.math.BigInt.$plus(BigInt.scala:311)
at rs$line$1$.$init$$$anonfun$1$$anonfun$1$$anonfun$1(rs$line$1:1)
at rs$line$1$$$Lambda$1668/0x00000008015cc580.apply(Unknown Source)
at scala.collection.immutable.LazyList.$anonfun$mapImpl$1(LazyList.scala:517)
at scala.collection.immutable.LazyList$$Lambda$1671/0x00000008015cab18.apply(Unknown Source)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state$lzycompute(LazyList.scala:259)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state(LazyList.scala:252)
at scala.collection.immutable.LazyList.isEmpty(LazyList.scala:269)
at scala.collection.immutable.LazyList$.$anonfun$dropImpl$1(LazyList.scala:1073)
at scala.collection.immutable.LazyList$$$Lambda$1663/0x000000080159f248.apply(Unknown Source)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state$lzycompute(LazyList.scala:259)
at scala.collection.immutable.LazyList.scala$collection$immutable$LazyList$$state(LazyList.scala:252)
at scala.collection.immutable.LazyList.isEmpty(LazyList.scala:269)
at scala.collection.LinearSeqOps.apply(LinearSeq.scala:131)
at scala.collection.LinearSeqOps.apply$(LinearSeq.scala:128)
at scala.collection.immutable.LazyList.apply(LazyList.scala:240)
... 14 elided
scala>
infinite stream
implementa)on
(implicit defini1on)
#8
I didn’t know that these days, compu3ng the
Fibonacci sequence is actually an example in the
Scala API documenta4on for LazyList (see next slide).
This class implements an immutable linked list. We call it "lazy" because it computes its elements only when they are needed.
Elements are memoized; that is, the value of each element is computed at most once.
Elements are computed in-order and are never skipped. In other words, accessing the tail causes the head to be computed first.
How lazy is a LazyList? When you have a value of type LazyList, you don't know yet whether the list is empty or not. If you learn that it is non-empty, then you also know that the head
has been computed. But the tail is itself a LazyList, whose empDness-or-not might remain undetermined.
A LazyList may be infinite. For example, LazyList.from(0) contains all of the natural numbers 0, 1, 2, and so on. For infinite sequences, some methods (such as count, sum, max or min)
will not terminate.
Here is an example:
import scala.math.BigInt
object Main extends App {
val fibs: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: fibs.zip(fibs.tail).map { n => n._1 + n._2 }
fibs.take(5).foreach(println)
}
Note that the definiDon of fibs uses val not def. The memoization of the LazyList requires us to have somewhere to store the informaDon and a val allows us to do that.
Further remarks about the seman<cs of LazyList:
• Though the LazyList changes as it is accessed, this does not contradict its immutability. Once the values are memoized they do not change. Values that have yet to be memoized sDll
"exist", they simply haven't been computed yet.
• One must be cauDous of memoiza<on; it can eat up memory if you're not careful. That's because memoiza<on of the LazyList creates a structure much
like scala.collecDon.immutable.List. As long as something is holding on to the head, the head holds on to the tail, and so on recursively. If, on the other hand, there is nothing holding on to
the head (e.g. if we used def to define the LazyList) then once it is no longer being used directly, it disappears.
Compu3ng the millionth Fibonacci number using
the Haskell version does not exhaust heap space.
ghci> fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
ghci> (fibs !! (1000000)) > 1
True
ghci>
infinite stream
implementa)on
(implicit defini1on)
#8
val fibs: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: (fibs zip fibs.tail).map(_+_)
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
As a recap, here are the Scheme, Clojure,
Scala, and Haskell versions compared.
(define fibs
(cons-stream 0
(cons-stream 1
(add-streams (stream-cdr fibs)
fibs))))
infinite stream
implementa)on
(implicit defini1on)
#8
(def fibs (lazy-cat [0N 1N] (map + fibs (rest fibs))))
Next, consider the leU-fold based implementa3on from part 1. Note how range (1 to i)
is only used to control the number of steps in the folding process. It is only the length of
the range that maDers, not its values. e.g. the range may just as well be (-1 to -i).
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
(1 to i).foldLeft(BigInt(0), BigInt(1))
{ case ((a, b), _) => (b, a + b) }
One way to eliminate the need for the range is
to use the unfold function provided by LazyList.
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
LazyList.unfold((BigInt(0), BigInt(1)))
{ case (a, b) => Some((a, b), (b, a + b)) }(i)
infinite stream
implementa)on
(unfolding)
#9
Next, we can simplify the unfolding implementa3on
by using the iterate func3on provided by LazyList.
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
LazyList.unfold((BigInt(0), BigInt(1)))
{ case (a, b) => Some((a, b), (b, a + b)) }(i)
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
LazyList.iterate((BigInt(0), BigInt(1)))
{ case (a, b) => (b, a + b) }(i)
infinite stream
implementa)on
(itera1on)
#10
Remember the first implementa3on of the Fibonacci sequence
in this deck, which was based on an implicit defini4on?
val fibs: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: (fibs zip fibs.tail).map(_+_)
infinite stream
implementa)on
(implicit defini1on)
#8
To conclude the deck, in the next four slides we look at another
implementa3on that is also based on an implicit defini4on.
infinite stream
implementa)on
(scanning)
#11
fibs :: Num a => [a]
fibs = 0 : scanl (+) 1 fibs
LeU scan func3on scanl is similar to leU fold func3on foldl,
but returns a list of successive reduced values from the le].
š‘ š‘š‘Žš‘›š‘™ āŠ• š‘’ š‘„0, š‘„1, š‘„2
⬇
[š‘’, š‘’ āŠ• š‘„0, (š‘’ āŠ• š‘„0) āŠ• š‘„1, ((š‘’ āŠ• š‘„0) āŠ• š‘„1) āŠ• š‘„2]
š‘“š‘œš‘™š‘‘š‘™ ∷ š›½ → š›¼ → š›½ → š›½ → š›¼ → š›½
š‘“š‘œš‘™š‘‘š‘™ š‘“ š‘’ = š‘’
š‘“š‘œš‘™š‘‘š‘™ š‘“ š‘’ š‘„: š‘„š‘  = š‘“š‘œš‘™š‘‘š‘™ š‘“ š‘“ š‘’ š‘„ š‘„š‘ 
š‘ š‘š‘Žš‘›š‘™ ∷ š›½ → š›¼ → š›½ → š›½ → š›¼ → [š›½]
š‘ š‘š‘Žš‘›š‘™ š‘“ š‘’ = [š‘’]
š‘ š‘š‘Žš‘›š‘™ š‘“ š‘’ š‘„: š‘„š‘  = š‘’ ∶ š‘ š‘š‘Žš‘›š‘™ š‘“ š‘“ š‘’ š‘„ š‘„š‘ 
š‘“š‘œš‘™š‘‘š‘™ āŠ• š‘’ š‘„0, š‘„1, š‘„2
⬇
((š‘’ āŠ• š‘„0) āŠ• š‘„1) āŠ• š‘„2
Here we define the Fibonacci sequence simply as the result of consing
0 (the first Fibonacci number) onto the result of doing a leU scan of
the sequence itself with addi3on and an ini3al accumulator of 1.
Here is a less efficient, but easier to understand defini3on of a leU scan. Given a func3on š‘“, an ini3al accumulator š‘’, and a
list of items š‘„š‘ , scanl first uses the inits func3on to compute the ini4al segments of the given list, and then maps each
resul3ng segment to the result of folding the segment using the given func3on š‘“ and the given ini3al accumulator š‘’.
š‘ š‘š‘Žš‘›š‘™ ∷ š›½ → š›¼ → š›½ → š›½ → š›¼ → [š›½]
š‘ š‘š‘Žš‘›š‘™ š‘“ š‘’ š‘„š‘  = š‘šš‘Žš‘ š‘“š‘œš‘™š‘‘š‘™ š‘“ š‘’ š‘–š‘›š‘–š‘”š‘  š‘„š‘ 
š‘–š‘›š‘–š‘”š‘  š‘„0, š‘„1, š‘„2 = [[ ], š‘„0 , š‘„0, š‘„1 ,
š‘„0, š‘„1, š‘„2 ]
Here is an example of inits being used to
compute the ini4al segments of a small list.
To understand how fibs works, on the next slide we go through the steps involved in the evalua3on of
scanl (+) 0 [1,2,3]
and on the subsequent slide we go through a similar exercise for the evalua3on of
fibs = 0 : scanl (+) 1 fibs
numbers scanl (+) 0 … accumulator
[1,2,3] ? N/A
[1,2,3] 0 : ? 0
[1,2,3] 0 : 1 : ? 0 + 1 = 1
[1,2,3] 0 : 1 : 3 : ? 1 + 2 = 3
[1,2,3] 0 : 1 : 3 : 6 : [] 3 + 3 = 6
[0,1,3,6]
numbers scanl (+) 0 … accumulator
[1,2,3] ? N/A
[1,2,3] 0 : ? 0
[1,2,3] 0 : 1 : ? 0 + 1 = 1
[1,2,3] 0 : 1 : 3 : ? 1 + 2 = 3
[1,2,3] 0 : 1 : 3 : 6 : [] 3 + 3 = 6
[0,1,3,6]
fibs scanl (+) F1 … accumulator
F0 : … ? N/A
F0 : … F1 : ? F1
F0 : … F1 : F2 : ? F1 + F0 = F2
F0 : … F1 : F2 : F3 : ? F2 + F1 = F3
F0 : … F1 : F2 : F3 : F4 : ? F3 + F2 = F4
[F1,F2,F3,F4,…?…]
F0 = 0
F1 = 1
F2 = 1
F3 = 2
F4 = 3
…
val fibs: LazyList[BigInt] =
BigInt(0) #:: fibs.scan(BigInt(1))(_+_)
infinite stream
implementa)on
(scanning)
#11
fibs :: Num a => [a]
fibs = 0 : scanl (+) 1 fibs
Here is the Scala version of the Haskell implementa3on.
Scala func3on scan just delegates to func3on scanLeU.
delegates to
To conclude this deck, the next slide contains the Scala version
of the five implementa3ons that we have seen in the deck.
def fibs: LazyList[BigInt] =
fibgen(0, 1)
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
a #:: fibgen(b, a + b)
infinite stream
implementation
(explicit generation)
#7
val fibs: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: (fibs zip fibs.tail).map(_+_)
infinite stream
implementa)on
(implicit defini1on)
#8
val fibs: LazyList[BigInt] =
BigInt(0) #:: fibs.scan(BigInt(1))(_+_)
infinite stream
implementa)on
(scanning)
#11
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
LazyList.iterate((BigInt(0), BigInt(1)))
{ case (a, b) => (b, a + b) }(i)
infinite stream
implementa)on
(itera1on)
#10
def fib(i: Int): BigInt =
fibtwo(i).first
def fibtwo(i: Int): (BigInt, BigInt) =
LazyList.unfold((BigInt(0), BigInt(1)))
{ case (a, b) => Some((a, b), (b, a + b)) }(i)
infinite stream
implementa)on
(unfolding)
#9
The next slide is the same as the previous one, except
that implementa3ons #9 and #10 have been simplified
so that they consist of a single fibs func3on with the
same signature as the other implementa3ons.
def fibs: LazyList[BigInt] =
fibgen(0, 1)
def fibgen(a: BigInt, b: BigInt): LazyList[BigInt] =
a #:: fibgen(b, a + b)
infinite stream
implementation
(explicit generation)
#7
val fibs: LazyList[BigInt] =
BigInt(0) #:: BigInt(1) #:: (fibs zip fibs.tail).map(_+_)
infinite stream
implementa)on
(implicit defini1on)
#8
val fibs: LazyList[BigInt] =
BigInt(0) #:: fibs.scan(BigInt(1))(_+_)
infinite stream
implementa)on
(scanning)
#11
val fibs: LazyList[BigInt] =
LazyList.iterate((BigInt(0), BigInt(1))){
case (a, b) => (b, a + b)
}.map(_.first)
infinite stream
implementa)on
(itera1on)
#10
val fibs: LazyList[BigInt] =
LazyList.unfold((BigInt(0), BigInt(1))){
case (a, b) => Some((a, b), (b, a + b))
}.map(_.first)
infinite stream
implementa)on
(unfolding)
#9
That’s all for part 2.
I hope you found it useful.

More Related Content

Similar to Fibonacci Function Gallery - Part 2 - One in a series (20)

PDF
Faster Python, FOSDEM
Victor Stinner
Ā 
PDF
computer notes - Memory organization
ecomputernotes
Ā 
PPTX
iPython
Aman Lalpuria
Ā 
PDF
Full Stack Clojure
Michiel Borkent
Ā 
PDF
Pune Clojure Course Outline
Baishampayan Ghose
Ā 
PPTX
Lecture 2 coal sping12
Rabia Khalid
Ā 
ODP
Functional Programming With Scala
Knoldus Inc.
Ā 
PDF
How to start functional programming (in Scala): Day1
Taisuke Oe
Ā 
PDF
Please I want a detailed complete answers for each part.Then make.pdf
siennatimbok52331
Ā 
PDF
Pythran: Static compiler for high performance by Mehdi Amini PyData SV 2014
PyData
Ā 
PPTX
Time and Space Complexity Analysis.pptx
dudelover
Ā 
PPTX
VCE Unit 01 (2).pptx
skilljiolms
Ā 
PDF
Tutorial2
ashumairitar
Ā 
PPT
sonam Kumari python.ppt
ssuserd64918
Ā 
PPTX
matlab presentation fro engninering students
SyedSadiq73
Ā 
PDF
openMP loop parallelization
Albert DeFusco
Ā 
PDF
Functional Programming inside OOP? It’s possible with Python
Carlos V.
Ā 
PPTX
Lecture 5 – Computing with Numbers (Math Lib).pptx
jovannyflex
Ā 
PPTX
Lecture 5 – Computing with Numbers (Math Lib).pptx
jovannyflex
Ā 
PDF
Fibonacci Function Gallery - Part 1 (of a series) - with minor corrections
Philip Schwarz
Ā 
Faster Python, FOSDEM
Victor Stinner
Ā 
computer notes - Memory organization
ecomputernotes
Ā 
iPython
Aman Lalpuria
Ā 
Full Stack Clojure
Michiel Borkent
Ā 
Pune Clojure Course Outline
Baishampayan Ghose
Ā 
Lecture 2 coal sping12
Rabia Khalid
Ā 
Functional Programming With Scala
Knoldus Inc.
Ā 
How to start functional programming (in Scala): Day1
Taisuke Oe
Ā 
Please I want a detailed complete answers for each part.Then make.pdf
siennatimbok52331
Ā 
Pythran: Static compiler for high performance by Mehdi Amini PyData SV 2014
PyData
Ā 
Time and Space Complexity Analysis.pptx
dudelover
Ā 
VCE Unit 01 (2).pptx
skilljiolms
Ā 
Tutorial2
ashumairitar
Ā 
sonam Kumari python.ppt
ssuserd64918
Ā 
matlab presentation fro engninering students
SyedSadiq73
Ā 
openMP loop parallelization
Albert DeFusco
Ā 
Functional Programming inside OOP? It’s possible with Python
Carlos V.
Ā 
Lecture 5 – Computing with Numbers (Math Lib).pptx
jovannyflex
Ā 
Lecture 5 – Computing with Numbers (Math Lib).pptx
jovannyflex
Ā 
Fibonacci Function Gallery - Part 1 (of a series) - with minor corrections
Philip Schwarz
Ā 

More from Philip Schwarz (20)

PDF
Folding Cheat Sheet Series Titles - a series of 9 decks
Philip Schwarz
Ā 
PDF
Folding Cheat Sheet # 9 - List Unfolding š‘¢š‘›š‘“š‘œš‘™š‘‘ as the Computational Dual of ...
Philip Schwarz
Ā 
PDF
List Unfolding - 'unfold' as the Computational Dual of 'fold', and how 'unfol...
Philip Schwarz
Ā 
PDF
Drawing Heighway’s Dragon - Part 4 - Interactive and Animated Dragon Creation
Philip Schwarz
Ā 
PDF
The Nature of Complexity in John Ousterhout’s Philosophy of Software Design
Philip Schwarz
Ā 
PDF
Drawing Heighway’s Dragon - Part 3 - Simplification Through Separation of Con...
Philip Schwarz
Ā 
PDF
The Open-Closed Principle - Part 2 - The Contemporary Version - An Introduction
Philip Schwarz
Ā 
PDF
The Open-Closed Principle - Part 1 - The Original Version
Philip Schwarz
Ā 
PDF
Drawing Heighway’s Dragon - Part II - Recursive Function Simplification - Fro...
Philip Schwarz
Ā 
PDF
Drawing Heighway’s Dragon - Recursive Function Rewrite - From Imperative Styl...
Philip Schwarz
Ā 
PDF
The Debt Metaphor - Ward Cunningham in his 2009 YouTube video
Philip Schwarz
Ā 
PDF
Folding Cheat Sheet Series Titles (so far)
Philip Schwarz
Ā 
PDF
From Subtype Polymorphism To Typeclass-based Ad hoc Polymorphism - An Example
Philip Schwarz
Ā 
PDF
Folding Cheat Sheet #8 - eighth in a series
Philip Schwarz
Ā 
PDF
Function Applicative for Great Good of Leap Year Function
Philip Schwarz
Ā 
PDF
Folding Cheat Sheet #7 - seventh in a series
Philip Schwarz
Ā 
PDF
Folding Cheat Sheet #6 - sixth in a series
Philip Schwarz
Ā 
PDF
Folding Cheat Sheet #5 - fifth in a series
Philip Schwarz
Ā 
PDF
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
Ā 
PDF
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
Ā 
Folding Cheat Sheet Series Titles - a series of 9 decks
Philip Schwarz
Ā 
Folding Cheat Sheet # 9 - List Unfolding š‘¢š‘›š‘“š‘œš‘™š‘‘ as the Computational Dual of ...
Philip Schwarz
Ā 
List Unfolding - 'unfold' as the Computational Dual of 'fold', and how 'unfol...
Philip Schwarz
Ā 
Drawing Heighway’s Dragon - Part 4 - Interactive and Animated Dragon Creation
Philip Schwarz
Ā 
The Nature of Complexity in John Ousterhout’s Philosophy of Software Design
Philip Schwarz
Ā 
Drawing Heighway’s Dragon - Part 3 - Simplification Through Separation of Con...
Philip Schwarz
Ā 
The Open-Closed Principle - Part 2 - The Contemporary Version - An Introduction
Philip Schwarz
Ā 
The Open-Closed Principle - Part 1 - The Original Version
Philip Schwarz
Ā 
Drawing Heighway’s Dragon - Part II - Recursive Function Simplification - Fro...
Philip Schwarz
Ā 
Drawing Heighway’s Dragon - Recursive Function Rewrite - From Imperative Styl...
Philip Schwarz
Ā 
The Debt Metaphor - Ward Cunningham in his 2009 YouTube video
Philip Schwarz
Ā 
Folding Cheat Sheet Series Titles (so far)
Philip Schwarz
Ā 
From Subtype Polymorphism To Typeclass-based Ad hoc Polymorphism - An Example
Philip Schwarz
Ā 
Folding Cheat Sheet #8 - eighth in a series
Philip Schwarz
Ā 
Function Applicative for Great Good of Leap Year Function
Philip Schwarz
Ā 
Folding Cheat Sheet #7 - seventh in a series
Philip Schwarz
Ā 
Folding Cheat Sheet #6 - sixth in a series
Philip Schwarz
Ā 
Folding Cheat Sheet #5 - fifth in a series
Philip Schwarz
Ā 
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
Ā 
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
Ā 
Ad

Recently uploaded (20)

PPTX
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
Ā 
PPTX
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
Ā 
PDF
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
Ā 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
Ā 
PDF
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
Ā 
PDF
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
Ā 
PDF
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
Ā 
PPTX
Feb 2021 Cohesity first pitch presentation.pptx
enginsayin1
Ā 
PDF
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
Ā 
PDF
Salesforce CRM Services.VALiNTRY360
VALiNTRY360
Ā 
PPTX
Human Resources Information System (HRIS)
Amity University, Patna
Ā 
PDF
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
Ā 
PDF
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
Ā 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
Ā 
PPTX
An Introduction to ZAP by Checkmarx - Official Version
Simon Bennetts
Ā 
PDF
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
Ā 
PPT
MergeSortfbsjbjsfk sdfik k
RafishaikIT02044
Ā 
PDF
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
Ā 
PPTX
Tally software_Introduction_Presentation
AditiBansal54083
Ā 
PDF
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
Ā 
Fundamentals_of_Microservices_Architecture.pptx
MuhammadUzair504018
Ā 
MiniTool Power Data Recovery Full Crack Latest 2025
muhammadgurbazkhan
Ā 
Alexander Marshalov - How to use AI Assistants with your Monitoring system Q2...
VictoriaMetrics
Ā 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
Ā 
Alarm in Android-Scheduling Timed Tasks Using AlarmManager in Android.pdf
Nabin Dhakal
Ā 
vMix Pro 28.0.0.42 Download vMix Registration key Bundle
kulindacore
Ā 
Revenue streams of the Wazirx clone script.pdf
aaronjeffray
Ā 
Feb 2021 Cohesity first pitch presentation.pptx
enginsayin1
Ā 
Why Businesses Are Switching to Open Source Alternatives to Crystal Reports.pdf
Varsha Nayak
Ā 
Salesforce CRM Services.VALiNTRY360
VALiNTRY360
Ā 
Human Resources Information System (HRIS)
Amity University, Patna
Ā 
Mobile CMMS Solutions Empowering the Frontline Workforce
CryotosCMMSSoftware
Ā 
Linux Certificate of Completion - LabEx Certificate
VICTOR MAESTRE RAMIREZ
Ā 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
Ā 
An Introduction to ZAP by Checkmarx - Official Version
Simon Bennetts
Ā 
Unlock Efficiency with Insurance Policy Administration Systems
Insurance Tech Services
Ā 
MergeSortfbsjbjsfk sdfik k
RafishaikIT02044
Ā 
HiHelloHR – Simplify HR Operations for Modern Workplaces
HiHelloHR
Ā 
Tally software_Introduction_Presentation
AditiBansal54083
Ā 
Powering GIS with FME and VertiGIS - Peak of Data & AI 2025
Safe Software
Ā 
Ad

Fibonacci Function Gallery - Part 2 - One in a series