Added copy constructors to "Programming in D"

Ali Çehreli acehreli at yahoo.com
Wed Feb 9 18:28:15 UTC 2022


On 2/9/22 02:15, Anonymouse wrote:
> On Saturday, 8 January 2022 at 02:07:10 UTC, Ali Çehreli wrote:
>> 2) The other noteworthy change in the book is my now-different stance 
>> on variables: Now I recommend 'const' over 'immutable' for variables.
> 
> I'm curious, could you elaborate a bit on this? I skimmed through the 
> page on Immutability but I didn't find anything explaining it.

To make sure we are looking at the same version, the new content has the 
following section:

<quote>
in parameters

As we will see in the next chapter, in implies const and is more useful 
with the ‑preview=in command line switch. For that reason, I recommend 
in parameters over const parameters.
</quote>

   http://ddili.org/ders/d.en/const_and_immutable.html

In short, in the past, under the influence of "stronger guarantee" 
clearly sounding better, I was recommending immutable for variables:

   immutable i = 42;

Realizing that I don't do that in my own code, now I recommend const:

   const i = 42;

Further, now that we have -preview=in (thanks to Mathias Lang), I 
recommend 'in' over const for parameters. (Actually, I had always 
recommended 'in' and did use it in some of the examples in the book 
(inconsistently) but I wasn't using it in my own code.)

But the whole thing is complicated. :) So, I asked for and received 
opinions on this thread:

   https://forum.dlang.org/thread/sig2d4$657$1@digitalmars.com

I don't find the common description helpful:  "immutable provides 
stronger guarantee." That's true and sounds better than mere "strong" 
but it does not help a programmer with deciding on which one to use. 
Rather, I like the following distinction:

- const is a promise

- immutable is a requirement

Now, that helps me decide which one to use when. Let's start with a 
function:

void foo(in A a, immutable B b) {
   // ...
}

There, foo "promises" to not mutate 'a' ('in' implies 'const') and 
"requires" that 'b' is not mutated by any other code.

With that understanding, it is silly to "require" that no other code 
mutates a local variable:

void x() {
   immutable b = B();  // Really? Who can mutate it?
   // ...
}

So, the following is logical (and shorter :) ):

void x() {
   const b = B();
   // ...
}

Now, if I need to pass it to a function that "requires" immutable, of 
course I will have to define it as immutable to satisfy that requirement:

void x() {
   immutable b = B();
   foo(A(), b);
   // ...
}

Aside: One of the confusions is that 'const' would work there as well 
*if* B did not have any indirection. But if it's defined as e.g.

struct B {
   int[] arr;
}

then, x() will not compile with 'const b'.

In summary:

Variables: 'const' by default, 'immutable' as needed (because somebody 
requires it)

Parameters: 'in' by default, 'immutable' if required

That's my view. I think there are others who disagree with parts of it 
and that's why this issue is surprisingly complicated.

Ali


More information about the Digitalmars-d-announce mailing list