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.