Unexpected behaviour in notebook

I’ve written a small notebook and I’m not sure if it behaves like it should or not (to me it seems as if I’ve accidentally created some kind of generator function…)

I’ve got a cell with an array “digitArray” and another one with a function “countUp” that takes an array as input and returns an array. A third cell “result” calls “countUp” with “digitArray” as parameter. When the cell with the function is evaluated, “result” counts up, although the input array isn’t mutable and keeps its initial value.

Could anyone take a look at it and explain what’s going on?

Thanks in advance, Torben

Hi Torben,

Sure, what’s going on here is:

  • JavaScript objects and arrays are always mutable: assigning to properties of objects and indexes or arrays will mutate those objects or arrays in-place. Observable doesn’t change this behavior, in order to keep compatibility with existing JavaScript code and paradigms. We did introduce a mutable keyword that adds a concept of mutable cells to notebooks, but the inverse idea, that all non-mutable-keyworded-values, are immutable, isn’t the case.
  • This notebook is a bit of a illusion: the digitArray is mutated and is not keeping its original value: if you create a new cell that is simply digitArray (a reference to the variable) and re-evaluate it, you’ll see that the value changes. But because it’s being mutated in-place, the notebook can’t ‘know’ when it’s being changed, so references to the variable don’t automatically/magically update.
  • Check out the mutation section of this notebook for more information on how mutation happens in JavaScript and how to avoid it.

In this case, the cleanest way to avoid mutating that array in place would be to pass a copy of digitArray to it, like

result = countUp(digitArray.slice())

or to copy the array when it’s passed, like:

countUp = digits => {
  digits = digits.slice();
  let index = digits.length - 1;

Hopefully that clarifies things. If I could time-travel back to 1995, I’d certainly encourage the creators of JavaScript to make these basic datatypes at least optionally immutable, but alas, for now immutability is a best-practice and a pattern, rather than something enforced by the language.

  • Tom