On Saturday, 14 March 2015 at 20:15:30 UTC, Walter Bright wrote:
> I've often thought, as do many others here, that immutability
> should be the default for variables.
>> Case (1) is what I'm talking about here. If it is made const,
> then there are a couple ways forward in declaring a mutable
> variable:
The following is just my point of view, so take it with a grain
of salt and correct me if I state/understand something wrong:
I usually abstain from participating in discussions here, because
more often than not someone else will already more or less write
what I would, so there is little point in my writing what has
already been posted. This issue, however, I consider fairly
important, as what you propose would make me classify D as "don't
touch", which I really don't want considering that I've been
following and using D for the better part of ten years; let me
explain why:
There exists an abstract amount of data that I want to store
somewhere and access within my program. I shall call one instance
of something I put my data into "storage entity" (SE for short).
Now depending on what properties my data inherently has (or I
may additionally attribute to it) I may want or need a SE to
- allow any data within it to be changed ([wholly] mutable)
- prohibit any data within it to be changed ([wholly] immutable)
- allow some of the data within it to be changed (partially
mutable)
[Here and unless otherwise stated I do not use immutable in the
transitive meaning that D currently applies to it, instead it is
only applied to one SE]
The first of the three is what is generally in computer science
(CS) called a variable, the second a constant. SEs of the third
type are also mostly referred to as variables, as they are
usually implemented as an extension to the first. I know that
from a mathematical standpoint, a variable is only a symbol with
an attributed value without any associated notion about
(im)mutability, so even a contant would be a variable, but this
is not how the terminology is used in CS. In CS a variable must
allow some kind of mutability; not necessarily wholly, but
without mutability it would be a constant, not a variable. As
such, should D's SEs default to being wholly immutable (which you
seem to propose), it should not call them variables anymore
(since they aren't), but instead clearly state that "D's SE
default to being constants and if you want a variable, do [...]".
With only primitives (no pointers), there can be no partial
mutability, you are either allowed to assign a new (primitive)
value or you are not. Partial mutability becomes a serious
concern, however, once pointers/references are involved, e.g. if
you want to reference an SE that is wholly immutable. Does your
reference automatically also become immutable (as I understand if
- and please correct me if I am wrong here - this is what D's
transitive "immutable" means)? I understand that with this
extremely complex issue, it may seem desirably to instead default
to whole non-transtitive immutability and make people explicitly
state when they want their SEs to be mutable. One might argue
that it would make a lot of things simpler for everyone involved.
However, D is a systems programming language and I would
counter-argue that I believe the amount of partially mutable SEs
to far outweight the amount of wholly immutable ones and having
something like
int foo = 5;
[...]
foo = 6;
produce a compile-error because "foo" is by default
non-transitive immutable [D terminology would be "const" I think]
is something I can only call absurd for the following reason:
It breaks with the convention systems programming languages have
been using for a very long time. While I'm not generally against
cutting off traditions no longer needed, I believe this would
have a serious negative impact on people coming form C/C++ who
are expecting new cool stuff (which D definitely has) without
ground-breaking changes. The longer the list of core differences
to the way you code you have to remind yourself about when
switching to D, the less likely you will switch to D, I think.
What I would propose is the following: Have the compiler-frontend
track for all SE whether they are assigned to more than once
(counting the initial assignment). Any SE that isn't can safely
be marked "const" (or non-transitive immutable) the way to
described in your opening post. However, is an SE assigned to at
least twice is must not be marked as const. This should - in my
opinion - give about the same level of safety as marking
everything as "const" by default while not breaking with any
long-standing conventions.