www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - ref and out parameters on call site

reply WebFreak001 <d.forum webfreak.org> writes:
I would like to bring it up yet again! (I think this is my 3rd 
time talking about it lol)

Can we get make the call site of a ref/out function repeat the 


Example:
void foo(double a, ref string s, out int[] x);

called with:
foo(doubleValue, ref stringValue, out intArray);

My basic idea was this:
* Force usage of ref/out on call site, otherwise cause 
deprecation for now.
* If function is called with UFCS, ref is not needed on first 
argument (before the .)


Reason:
It's currently impossible to know if a function argument mutates 
a variable or not without jumping into the definition or 
documentation. Code reviews get orders of magnitude more 
difficult to get right when calling new functions you aren't 
familiar with.

I think this would massively help readability and simplify static 
analysis and code reviews. This also has the added benefit that 
you can easily unambiguously call both ref and non-ref overloads 
using an lvalue. It also makes it possible to _require_ functions 
like template callbacks to have a ref/out parameter.

If we were to go this way, we could go all the way and even allow 
const/immutable construction out of "out" arguments:

if (generateSomething(out const something)) {
     writeln("yay, something: ", something);
}

Any ideas? Counter arguments why this shouldn't be implemented 
other than old code breakage?
Mar 18 2020
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 18 March 2020 at 17:23:26 UTC, WebFreak001 wrote:
 Any ideas? Counter arguments why this shouldn't be implemented 
 other than old code breakage?
How would `auto ref` and core.lifetime.forward work with this?
Mar 18 2020
parent WebFreak001 <d.forum webfreak.org> writes:
On Wednesday, 18 March 2020 at 17:46:22 UTC, Paul Backus wrote:
 On Wednesday, 18 March 2020 at 17:23:26 UTC, WebFreak001 wrote:
 Any ideas? Counter arguments why this shouldn't be implemented 
 other than old code breakage?
How would `auto ref` and core.lifetime.forward work with this?
forward kind of seems like magic with alias right now, so it will probably either break permanently or need to be reimplemented. However I think having more control would be worth a lot. Current behavior: class C { static int foo(int n) { return 1; } static int foo(ref int n) { return 2; } } // with forward int bar()(auto ref int x) { return C.foo(forward!x); } // without forward int baz()(auto ref int x) { return C.foo(x); } int i; assert(bar(1) == 1); assert(bar(i) == 2); assert(baz(1) == 2); assert(baz(i) == 2); New behavior: assert(bar(1) == 1); assert(bar(i) == 1); assert(bar(ref i) == 2); // <- needs implementation somehow though assert(baz(1) == 1); assert(baz(i) == 1); assert(baz(ref i) == 1); however you can now define int foo()(auto ref int x) { return C.foo(ref x); } assert(foo(1) == 2); assert(foo(i) == 2); assert(foo(ref i) == 2);
Mar 30 2020