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).
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.
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#)?
I think the user should be enforced to use foo(ref input)
instead of foo(input) as it greatly increases understanding of
the code on the caller side and another advantage is that
programs analyzing the AST can better understand if the
argument is unused (DScanner could use this for example).
On the other hand a lot of code has been written without this
already and especially a lot of UFCS code would break with this
like for example functions acting like member functions of the
ref argument. A fix for this might be just implying the ref you
would add on an argument if you use UFCS but I'm not sure if
that is really a good idea.
This post is just an idea because I think it can result in
really confused users and that the usage both by library
developer and user of out/ref in general is kind of bad by
design because it will just imply it and it won't be visible in
the code. Especially when changing the API this will result in
many runtime errors that need to be discovered if the user
doesn't read the changelog.
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?
If a parameter is marked as ref then you have to assume it will
be modified by the function (unless it's const/inout/immutable).
If it's marked as out then you know it will be. If you didn't
know that the function takes its parameters by ref or out...
You're should've RTFM.