On Sun, 05 May 2013 01:49:42 -0400, Andrei Alexandrescu <seewebsiteforem...@erdani.org> wrote:

2. Code evolution.

Jonathan mentioned this too. The problem here is that as code evolves, meaningful code doing real work becomes silently useless code that patently does nothing. Consider:

class Collection(T) {
   ref T opIndex(size_t i) { ... }
   ...
}

void fix(ref double x) { if (isnan(x)) x = 0; }

void fixAll(Collection!double c) {
   foreach (i; 0 .. c.length) {
     fix(c[i]);
   }
}

As design evolves, Collection's opIndex may change to return a T instead of ref T (e.g. certain implementations of sparse vectors). When that happens, the caller code will continue to compile and run. However, it won't do anything interesting: fix will be always called against a temporary plucked from the collection.

What about specifying ref at the call site when you know you want the data modified?

fix(ref c[i]);

Then if c decides to start returning by value, this is a compiler error.

IMO, fix really should take a pointer. But we want to avoid pointers due to the danger of them.

so this is like applying & but keeps it safe.

-Steve

Reply via email to