16

In the "Programming Erlang" book it's said that the language uses "single assignment" variables. In other articles about functional programming languages I always read of "immutable values" instead.

Does the wording "single assignment" mean something different from "immutable values"?

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
acorello
  • 4,473
  • 4
  • 31
  • 46
  • 1
    Ok, I understand that technically "single assignment" is different from "immutable values". I.e. in Java we can have final variables that point to mutable objects and non-final (re-assignable) variables that point to immutable objects. But... being able to use the two together seems to me a dangerous mix. That's basically why I'm asking if there a point focusing on single-assignment in Erlang rather than immutability. As far as I know Erlang data structures are immutable, and bound "variables" will always point to only one. And that's like Haskell, isn't it? – acorello Mar 18 '12 at 15:34

5 Answers5

17

In erlang, a variable can be either bound or unbound. You can only assign a value to an unbound variable. And that's where the single assignment comes from, because once the variable is bound, you can no longer assign a new value to it. So in erlang, you can't do the following, even if 0 and 1 are immutable values.

X = 1.
X = 2. // This is not a valid operation

The term immutable is relative to the value of the variable, and not the variable itself. So in some languages, you can assign to the same variable different values that are immutable:

X = immutableValue;
X = anotherImutableValue; // This is a valid operation

Edit: From wikipedia

Immutable Object:

In object-oriented and functional programming, an immutable object is an object whose state cannot be modified after it is created.

Single Assignment:

Single assignment is an example of name binding and differs from assignment as described in this article in that it can only be done once, usually when the variable is created; no subsequent re-assignment is allowed. [...] Once created by single assignment, named values are not variables but immutable objects.

Warren Young
  • 40,875
  • 8
  • 85
  • 101
sch
  • 27,436
  • 3
  • 68
  • 83
  • If I'm not mistaken, Erlang also uses a single `=` for equality testing, which has something to do with this as well. In Haskell, a single `=` is used *only* for assignment, while `==` is used for equality testing. – Dan Burton Mar 18 '12 at 00:09
  • 9
    In Erlang, `=` is a pattern matching operator. It behaves like assignment when the variable is unbound. `=:=` and `==` are used for equality testing. – sch Mar 18 '12 at 00:14
7

The difference is related to the difference between (re-)binding a variable and mutating a value.

"Single assignment" means, that you cannot re-bind a variable with different values, e.g.:

1> A = 1.
2> A = 2.
** exception error: no match of right hand side value 2

"Immutable values" on the other hand mean that you cannot change the values themselves (for example, from a parallel thread), so if you want to want to modify a list, you have to make a copy or something semantically equivalent instead of changing in-place.

bereal
  • 32,519
  • 6
  • 58
  • 104
4

Haskell programmer reporting in. Yes, "single assignment" and "immutable values" are both the exact same thing. Haskell takes this concept a bit deeper: everything's value is defined at compile time. Yes, everything.

You might then ask how that is possible, since Haskell can clearly do I/O. The answer is that you when you define an operation that extracts an input from the outside world, you are not defining the value, but merely the operation that extracts it. You never explicitly define the value that is bound. In Haskell, when you do things like:

echo = forever $ do
    x <- getLine
    putStrLn x

You are not "defining" x but rather just just telling getLine and putStrLn how to interact. The only thing you are actually defining is echo, which is nothing more than an action waiting to be run. Clearly, echo's behavior is defined at compile time, whereas the value of x is not.

Maybe you already knew that, but I'm writing this also for the benefit of other people who have a similar question about Haskell vs. Erlang.

Gabriella Gonzalez
  • 34,863
  • 3
  • 77
  • 135
4

Well, Haskell is referentially transparent. That means a "variable" is a variable in the mathematical sense. The sole notion of "assigning to a variable" makes no sense in Haskell, because there is no semantic difference between a name and the value it stands for. In other words, the equals sign (=) indeed introduces an equation.

In this concept naturally every value is immutable and when you define x = 3, then there is no difference between x and 3. As the equation says, they are the exact same thing.

ertes
  • 57
  • 1
4

I don't know Erlang at all, so I may not be able to give the best answer.

In Haskell, you don't write a program as a sequence of steps to be evaluated. Instead you define a collection of equations. Consequently the concept of "assignment" doesn't come up. When I write x = 1 in Haskell, this is not a directive to bind the name x to the value 1, it is a declaration that x is 1.

In Erlang, can you do anything at all with an unbound variable other than assign it? Even a construct that tests whether a variable is bound or not would make Erlang's single assignment quite different from Haskell's notion of variables. For that matter, if you can even try to read an unbound variable and have it throw an exception which you can then catch, that would make Erlang's single assignment quite different.

Again, this is due to Haskell not having a concept of assignment at all. An assignment is a step that happens at some point. There is the world before the assignment, in which the variable had its old value or was unbound, and the world after the assignment in which the variable has its new value. Each world is valid, and executing more steps in each world may have different results.

In Haskell, when I refer to x either x is in scope and defined, in which case it has a value, or its not in scope, in which case I haven't even written a Haskell program and the compiler will reject it. There is no before and after.

Given that a brief bit of googling indicates to me that variables can be unbound again in Erlang, I would say they are quite different concepts.

Ben
  • 68,572
  • 20
  • 126
  • 174
  • Thanks, it gives some light about the possible difference between the two languages. – acorello Mar 19 '12 at 23:53
  • 1
    [good news](http://stackoverflow.com/a/2518372/849891): «when you "unbind" the value you can re-bind it again. *Needless to say it only works in Erlang shell.*» (emphasis mine). So it's part of the [shell](http://erlang.org/doc/man/shell.html) operation, not of the language itself. (I don't know Erlang, only Haskell and Prolog). – Will Ness Oct 09 '16 at 14:27
  • in Prolog we do in fact have "a construct that tests whether a variable is bound or not": `var(A)` succeeds if `A` is unbound, fails otherwise. – Will Ness Jul 01 '20 at 13:42