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/[email protected]

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

Reply via email to