digitalmars.D - ref and out parameters on call site
- WebFreak001 (31/31) Mar 18 2020 I would like to bring it up yet again! (I think this is my 3rd
- Paul Backus (2/4) Mar 18 2020 How would `auto ref` and core.lifetime.forward work with this?
- WebFreak001 (31/35) Mar 30 2020 forward kind of seems like magic with alias right now, so it will
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
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
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: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);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 30 2020