17 Implementing a Counter

Let's implement a counter that returns a bigger number every time we call it. We couldn't do this before, as we could only write deterministic functions, functions that return a value solely based on their input.

Every time we invoke the function next, we'll get the value we got last time, but plus 1.

We'll start with a counter ref, to keep track of the value we're currently at.

Now let's use this ref in our next function.

Now let's test our function!

Our counter is counting! Now that we've seen that it's working, lets simplify it. The standard library includes two functions, incr and decr that increment and decrement a function respectfully.

What if we were to define counter in our function? Let's do it.

Uh oh... seems like we broke something. That's because when our let expression ends, the counter ref goes out of scope; however, there's one other thing we can try.

To understand this, let's think back to our evaluation rules for let-expressions.

First, we evaluate the value of the let expression, then we replace that value with the evaluated value. This works, because we're replacing counter with the value that ref 0 evaluates to, the location in memory, so when we pass counter to incr or ( ! ), we're actually passing the value that ref 0 evaluates to, the location in memory.

The call to ref 0 only gets evaluated once, never again.