← Back to context

Comment by ramchip

2 days ago

> There, the reference to `i` is being mutated.

That's rebinding. Mutation is when you change the state of an object. Variables are not objects. You can't have a reference (aka pointer) pointing to a variable.

I don't know if you're referring to a particular language's peculiarities, but it doesn't really matter. It's mutation.

tombert's point (I think) is that in a functional setting, factorial(n) is always factorial(n). In an imperative setting, first it's 1, then 2, then 6, then 24, etc.

Here's factorial calculated imperatively in C#.

  public async Task Factorial() {
      long primitiveResult = 1L;
      Wrapped<long> objectResult = new Wrapped<long>(1L);

      var observer = new Task(ObserveVariable);
      observer.Start();

      for (var i = 2; i <= 15; i++) {
        primitiveResult *= i;
        objectResult = new Wrapped<long>(objectResult.Value * i);
        await Task.Delay(100);
      }

      observer.Wait();
      return;

      void ObserveVariable() {
        while (primitiveResult != 1307674368000 || objectResult.Value != 1307674368000) {
          Thread.Sleep(100);
        }
      }
  }

There are two results (one primitive and one object) to show that it doesn't matter. Maybe there's no such thing as a Reference-to-a-Variable in whatever language you have in mind, but in the above code ObserveVariable refers to a variable (while it mutates).

I mean this is getting into splitting-hairs territory, but I would argue that rebinding is a form of mutation; the variable i is changing as far as the programmer is concerned.

If I were to write

    var i = new Obj(2)

    // do stuff 1
    
    i = new Obj(3)

    // do stuff 2

Then yes, that’s technically rebinding and not directly mutating the value in memory, but from “do stuff 2’s” perspective the value has changed. It still acts more or less the same as if it had directly changed.

> You can't have a reference (aka pointer) pointing to a variable.

What?

    int a;
    int * p = &a;

?