Assignments - Spicery/Nutmeg GitHub Wiki

[Taken from direct messages with ZA]

So I had a bit of an idea for explaining declarative (aka side-effect free) programming after last night's discussion. The plan is to distinguish different kinds of assignment and give each of them a 'side-effect score'.

So the first type of assignment looks like this:

foo := 99

And it does two things - it introduces a new variable foo and tells us its initial value. This has a side-effect scope of 0.

The second type of assignment looks like this:

foo <- 88

This does one thing, which is to update the value of the variable foo. The variable must already be declared and must be in scope. It can only be used with a variable on the left-hand side, so foo[0] <- 77 would be a syntax error. It has a side-effect score of 1. We will avoid = for assignment by the way because using the equals sign for a side-effecting operator is perverse.

The third type of assignment looks like this:

foo[0] <-- value

This does one thing, which is to alter the 0th element of foo. It can also look like this:

foo.age <-- 21

In other words, it doesn't alter the variable but the value that the variable points to. It has a side-effect score of 2.

The fourth type of assignment looks like either of these:

bar[0] <== value
foo.age <== -1

This is the copy-and-set assignment. It is equivalent to copying the value of the variable before the update. So the first assignment to bar[0] could be written as:

bar <- copy(bar)
bar[0] <-- value

This has a side-effect score of 1.

To calculate the side-effect score of a function/method, all you need to do is to find the biggest side-effect score from its assignments AND the side-effect scores of the functions it calls. This will give you 0, 1 or 2. (There's a little tweak you have to do to this for mutually recursive functions but I am going to brush over that as a technical detail only of interest to compiler writers)

  • Functions that have a side-effect score of 0 are declarative.
  • Functions that have a side-effect score of 2 are imperative.
  • Functions that have a side-effect score of 1 are a hybrid, as you might expect. Their internals look imperative but from the outside they are side-effect free.

Now all assignments in normal programming fall can be mapped to :=, <- and <--. (The copying assignment <== is super interesting and you do sometimes see code that is written in that style but it's unusual.)