Buckets of Marbles
This exercise asks you to write a program—any program!—that contains nested functions and block scopes, which satisfies these constraints: Try the exercise for yourself, then check out the suggested solution at the end of this appendix.Closure (PART 1)
Let’s practice closure with some common computer-math operations: determining if a value is prime, and generating a list of prime factors. For example:isPrime(..):
factorize(..):
isPrime(4327) multiple times in a program, it goes through all its computation steps every time. That’s a lot of wasted work!
Part 1
Use closure to implement a cache to remember the results of
isPrime(..), so that the primality of a given number is only ever computed once.Part 2
Use the same closure cache technique for
factorize(..).isPrime(..) and factorize(..).
A Word About Memory
We can see that saving repeated calls improves computation speed. But this usage of closure is making an explicit trade-off: memory. This can definitely be worth the expense, but only if we think it’s likely we see repetition of common inputs. Try the exercise for yourself, then check out the suggested solution at the end of this appendix.Closure (PART 2)
In this exercise, we’re going to practice closure by defining atoggle(..) utility that gives us a value toggler.
You will pass one or more values (as arguments) into toggle(..), and get back a function. That returned function will alternate/rotate between all the passed-in values in order, one at a time, as it’s called repeatedly.
The corner case of passing in no values to
toggle(..) is not very important; such a toggler instance could just always return undefined.Closure (PART 3)
In this third and final exercise on closure, we’re going to implement a basic calculator. Thecalculator() function will produce an instance of a calculator that maintains its own state:
calc(..) is called, you’ll pass in a single character that represents a keypress of a calculator button. We’ll restrict our calculator to:
- Digits (0-9)
- Arithmetic operations (+, -, *, /)
- ”=” to compute the operation
useCalc(..) helper that runs the calculator with characters from a string:
formatTotal(..) function your calculator should use:
Modules
This exercise is to convert the calculator from Closure (PART 3) into a module. We’re not adding any additional functionality, only changing its interface. Instead of calling a single functioncalc(..), we’ll be calling specific methods on the public API for each “keypress.”
This module should be expressed as a classic module factory function called calculator(), so that multiple calculators can be created if desired.
The public API should include:
number()
Input: the character/number “pressed”
Operators
plus(), minus(), mult(), div()eq()
Compute the result
useCalc(..) helper:
Suggested Solutions
Remember, each suggested solution is just one way to approach the problems. They’re not “the right answer,” but they do illustrate a reasonable approach.Suggested: Buckets of Marbles
Suggested: Closure (PART 1)
- Wrap an IIFE to define the scope for the cache variable
- In the underlying call, first check the cache
- At each
return, assign to the cache and return that result
Suggested: Closure (PART 2)
Suggested: Closure (PART 3)
Suggested: Modules
That’s it for this book! Congratulations on your achievement. When you’re ready, move on to the next book in the series.

