Paul Jurczak:

int test(alias F)(in int nLoops) /*pure nothrow*/ {
   int[10] a;
   typeof(return) n = 0;

   foreach (immutable _; 0 .. nLoops) {
       a[4] = !a[4];
       n += F(a);
   }

   return n;
}

What is the purpose of "immutable _;" above? Why not "i;"?

I have used _ as variable iteration name to remind the person that is reading the code that loop variable name is not used inside the loop itself. When you have more of those variables you can number them as _1, _2, or use no more than two underscores __.

And there the usage of immutable is to disallow the mutation the iteration variable inside the loop. In my opinion, to keep code clean and less bug-prone D should on make foreach indexes immutable on default. This saves you from bugs when you iterate on struct items:

struct Foo { int x; }
auto foos = [Foo(10), Foo(20)];
foreach (f; foos)
    f.x++;

It's not uncommon in those cases to forget a "ref" and think foos are changed. If iteration items are immutable as in C# this saves you from this class of bugs.

I have asked this in past, but D lacks a "mutable" keyword for the situations when you want to actually mutate the foreach variable, and generally Walter didn't sound very interested on this.

So as workaround for this language design problem, it's a good habit to always put a const/immutable on foreach variables, unless you don't wait it, and unless something forces you to not use a const.


void main() {
   enum size_t nLoops = 60_000_000;
   StopWatch sw;

   foreach (alg; TypeTuple!(isPalindrome0, isPalindrome1,
                            isPalindrome2, isPalindrome3,
                            isPalindrome4)) {
       sw.reset;
       sw.start;
       immutable n = test!alg(nLoops);
       sw.stop;
       writeln(n, " ", sw.peek.msecs);
   }
}

Same question here: why immutable?

It's explained here:
http://blog.knatten.org/2011/11/11/disempower-every-variable/

In short all your variables/function arguments should be tagged as const/immutable unless the semantics of your algorithm needs them to mutate, or unless some limit in D/Phobos forbids you to (like when you have created a lazy range, currently you can't assign it to const and then use it).

Bye,
bearophile

Reply via email to