Should out/ref parameters require the caller to specify out/ref like in C#?

Moritz Maxeiner via Digitalmars-d digitalmars-d at puremagic.com
Sun May 28 12:06:06 PDT 2017


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.


More information about the Digitalmars-d mailing list