Reassignment and Mutability
Constants are variables that do not vary. This seems like a simple statement. Yet many programming languages present a confusing view of constancy that surprises unsuspecting programmers. Consider the following equivalent JavaScript and Java programs.
There is no error in either of these programs, and they both produce the output [1, 4, 9]
. But how can this be if they are modifying an array variable marked as constant? It's because const
and final
apply to the name, but not to the value to which the name is bound. A const
or final
name cannot be bound to some other value, but the value itself remains mutable.
In Java, you can prevent reassignment with final
, but there is no way to make an arbitrary array or object immutable. Only the class designer can lock down an object. In JavaScript, Object.freeze
locks down an object.
Maybe Ruby constants are true constants that lock down the name from being reassigned and the value from being mutated?
What happens when you try to reassign a constant in Ruby?
Maybe we need some tougher languages. C has more of a backbone, doesn't it?
C does indeed lock down the value. Does it lock down the name?
Oh, dear. The name is not locked down. The semantics of const
in C are exactly opposite of what const
means in JavaScript.
However, the designers of C recognize that name reassignment and value mutability are independent features. They therefore allow you to add a second const
modifier. The leftmost const
modifier, which appears before the type, locks down the value. The rightmost const
modifier, which appears before the name, locks down the name.