On Sunday, 28 May 2017 at 17:54:30 UTC, WebFreak001 wrote:
Imagine you wrote a function

void foo(ref int a) {
  if (std.random.uniform(0, 10) == 0)
    a = 0;
  // Actual code doing something
}

in your API you didn't document that this will change `a` (or we will assume the user simply didn't read because you would never do something like this).

Taking the parameter as `ref int` *is* documenting that you will mutate it. Otherwise, you would have taken it as `ref const int` instead. Additionally, someone who does not read documentation is likely to have his/her program so riddled with bugs, that I don't think considering him/her is worth the effort.


The user now calls the code in his program, probably doesn't know that foo takes a as ref and because it's his first time using the function he doesn't expect it to either.

void main(string[] args) {
  int input = args[1].to!int + 1;
  writeln("Processing for ", input);
  foo(input);
writeln(100 / input); // idk, it will crash if input == 0 though
}

Now his code will occasionally crash but the user can't figure out why and can't always reproduce it. Imagine the code is somewhere deep inside event handlers from some GUI library or recursive calls too.

Then you'll have to debug, yes. An argument to always consider `ref T` as "I will mutate this" and `ref const T` as "I just want to read from this" and to (almost) never cast away const.


Should the language spec say that those functions should get called with `foo(ref input);` so that surprises like this where the user doesn't check the docs/implementation can't happen (like in C#)?

While I personally might like this syntax, what about const / immutable, does this then require `foo(ref const input)` and `foo(ref immutable input)`? Or `foo(ref cast(const int) input)`?

[...]

I can see both points of your argument, but here is one more argument against it: It introduces a language inconsistency by special casing references in function calls. We would have to allow `ref` everywhere we already allow `&` for pointers to get rid of the inconsistency (regardless of whether it makes sense to allow `ref` elsewhere).


Especially because this would break a lot of code I don't really expect anything to happen but maybe this could be taken into account when D3 will be designed or be added in some optional DIP that can be used using a compiler flag?

AFAIK D3 is hypothetical at this point.

Reply via email to