
Things I Learned Writing a Fibonacci Generator in JavaScript - ingve
https://medium.com/javascript-scene/7-surprising-things-i-learned-writing-a-fibonacci-generator-4886a5c87710
======
tzs
The memoized version does not even remotely work.

    
    
      a = fib(5);
      for (i = 0; i < 7; ++i) console.log(a.next());
    

gives the expected

    
    
      Object {value: 0, done: false}
      Object {value: 1, done: false}
      Object {value: 1, done: false}
      Object {value: 2, done: false}
      Object {value: 3, done: false}
      Object {value: undefined, done: true}
      Object {value: undefined, done: true}
    

But then

    
    
      b = fib(3)
      for (i = 0; i < 5; ++i) console.log(b.next());
    

gives the completely wrong:

    
    
      Object {value: 1, done: false}
      Object {value: 0, done: false}
      Object {value: 1, done: false}
      Object {value: 1, done: false}
      Object {value: undefined, done: true}

~~~
ericelliott
Fixed.

------
stepvhen
One of the exercises in chapter 1 of SICP is writing a Fibonacci function
using successive squaring[1]. It's fast, not recursive, and doesn't rely on
floating point arithmetic. It would be interesting to see the author's results
with a stronger algorithm.

[https://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-11.htm...](https://mitpress.mit.edu/sicp/full-text/book/book-
Z-H-11.html#%_thm_1.19)

~~~
bhrgunatha
> it's fast, not recursive, and doesn't rely on floating point arithmetic

I think using 'iter' in the name is misleading. Recursion _is_ a form of
iteration. In that exercise fib-iter _is_ recursive - it calls itself. That's
the very definition of recursion. I think they use the name 'iter' because the
overall process is linear in time the same way an iterative loop in other
languages is. In this case it's logarithmic in time. The additional arguments
and tail call optimisation (guaranteed by the Scheme standard) avoid a stack
of intermediate values so it's constant space as well.

If you delve further it's not _actually_ constant space OR logarithmic times
since the numbers get large so fast that storage, addition and multiplication
and evaluation are no longer atomic and will have an effect on the time and
space characteristics.

Still it's one of my favourite exercise from the book and they use it and
reference it in Racket's number theory module.[1]

[1]
[https://github.com/racket/math/blob/5cc1080d90d2603f790abd41...](https://github.com/racket/math/blob/5cc1080d90d2603f790abd41d5b33a6f9a8278c0/math-
lib/math/private/number-theory/fibonacci.rkt)

~~~
jeffwass
>"In that exercise fib-iter is recursive - it calls itself. That's the very
definition of recursion."

Yet SICP addresses exactly this point!

The authors still mandate it's not truly recursive in that the required state
is passed along to each iterative call.

From the parent's SICP link, but many paragraphs back :

"In contrasting iteration and recursion, we must be careful not to confuse the
notion of a recursive process with the notion of a recursive procedure. When
we describe a procedure as recursive, we are referring to the syntactic fact
that the procedure definition refers (either directly or indirectly) to the
procedure itself. But when we describe a process as following a pattern that
is, say, linearly recursive, we are speaking about how the process evolves,
not about the syntax of how a procedure is written. It may seem disturbing
that we refer to a recursive procedure such as fact-iter as generating an
iterative process. However, the process really is iterative: Its state is
captured completely by its three state variables, and an interpreter need keep
track of only three variables in order to execute the process."

~~~
bhrgunatha
It's been a long time since I read it and I'd forgotten about that
explanation. I understand the distinction they are making but it still it
seems a confusing use of terminology, especially when you read it out of
context - like the comment I replied to.

They were clearly aware of that too ... "It may seem disturbing that we refer
to a recursive procedure such as fact-iter as generating an iterative process.
"

------
gravypod
Sadly, a little known construct from javascript that I've fallen in love with
is the closure. I feel like it is an easier way of expressing the idea of a
generator.

    
    
      var fib = (function () {
              let current = 0;
              let next = 1;
              return function (increment) {
                      for (var i = 0; i < increment; i++) {
                              [current, next] = [next, current + next]
                      }
                      return current
              }; 
      })();
    

This is an example of an implementation of a Fibonacci sequence as shown in
this post. The same optimizations still apply, but I think this is nicer (in
my opinion) then using yield.

Edit: Altogether, good show. I enjoyed the post.

~~~
cyphar
Closures predate JavaScript by at least 30 years (it's a construct in Lambda
calculus which was being discovered in the 60s). Lisp had closures before many
of us were born.

~~~
gravypod
By from I mean easily represented within.

Most people don't think of a function with an inherited scope as a closure
since by the standard PLT people will tell you that Javascript does not
provide "real" closures.

I'm sure you know what I meant. It's the "Javascript Way" TM of doing this.

My "little known" I mean that most programmers do not think of doing this out
right. It took me seeing an amazing talk by the creator of JSON called
"Javascript the Good Parts" to realize how powerful this construct was, and
how Javascript made it so easy.

~~~
dionidium
I'm going to push back a little further on this. Closures are fundamental to
JS and widely known about and used. Crockford, too, is famous in JS circles,
as is the talk you mention.

