First Draft: Static Single Assignment
Peter C
peterc at gmail.com
Sat Dec 6 04:16:59 UTC 2025
On Saturday, 6 December 2025 at 00:48:19 UTC, Walter Bright wrote:
> It's true that there's not much point to using `final` to
> replace `const` for a non-pointer type.
>
> It's more useful in the role of head-const.
ok. now we can move to the more interesting stuff, beyond
primitive types, since:
final int x = 42;
is semantically *identical* to:
const int x = 42;
That's because primitive values are inherently immutable - i.e a
mutation on a primitive type is actually a re-assignment. That
is, you are overwriting the storage bound to a variable with a
new value.
Now allowing two different keywords to express the same thing on
these types could be seen as redundancy or even syntactic noise.
Therefore final seems to provide no additional expressiveness on
primitive types. One could argue therefore, that 'final' should
not be allowed on primitive types, for the reason that it is
essentially the exact same as const.
A counter argument would be, that 'final' is not saying anything
about 'object immutability', and that primitive immutability is
already inherent, because there is no indirection. So even though
'final' exactly duplicates 'const' for primitive types,
consistency and uniformity matter more.
That is, when someone writes:
final T x = ...;
they expect it to work for every T.
So for those who will use 'final' on primitive types, you're
doing it because you are want to explicately state that the
binding is immutable. If you want instead wanted to state that
the value is immutable, just use const. The semantics are the
same, but the intention is different.
On non-primitive types, final stops being a trivial redundancy
and becomes a meaningful design and safety tool!
final can protect a reference to an object, with forcing
immutablilty on the object itself.
final Foo f = new Foo();
f = new Foo(); // oops, lost the original object.
vs:
final Foo f = new Foo();
f = new Foo(); // Error: cannot modify `final f`
Anyone who argues that 'final' is a useless or unnecessary safety
guarantee does not understand programming. Accidental rebinding
is a common source of subtle, hard-to-find bugs in
object-oriented programming.
In large systems, protecting the reference can prevent far more
serious bugs than controlling object mutability alone.
More information about the dip.development
mailing list