On Saturday, 24 March 2018 at 11:57:25 UTC, John Colvin wrote:
I understand what you want, but I'm struggling to understand why it's such a huge deal.

The reason you want to pass by reference is for performance, to avoid copying the data at the call boundary.

It's pretty simple:

float foo() { ... }
ref float bar() { ... }

void someFunc(ref float);

someFunc(bar()); // ok

float temp = foo();
someFunc(temp); // Have to create a temporary anyways for the function to work someFunc(foo()); // Compile error, need to use the hideous code above


So there really isn't any performance penalty cause if you want to call that function you are going to have to create a temporary variable anyways, but now you can't just call the function in one line. It requires multiple lines and a temporary variable name.

This becomes especially horrible for math libraries:

void someFunc(ref Vector3) { ... }

someFunc(a + b); // Can't do this

Vector3 temp = a + b;
someFunc(temp); // Have to do this

So there's no performance penalty for what he is requesting, but allows for a cleaner syntax to do the exact same thing.

So there are 2 cases: an lvalue needs to be passed, or an rvalue needs to be passed.

1. The address of the lvalue is passed.

2. The rvalue is copied to a local, then the address of that local is passed.

So in the rvalue case, you're not getting the performance benefit of passing by reference, because you have to copy to a local anyway.

What I would do in D currently to get the same performance and API:

void foo(float[32] v) { foo(v); }
void foo(ref float[32] v) { ... }

or

void foo()(auto ref float[32] v) { ... }

What is so totally unacceptable about those solutions? I personally like the second because it scales better to multiple parameters. I know you have said it's not relevant and annoying that people bring up auto ref, but I dont' get how or why. It's exactly D's solution to the problem.

It doesn't scale better, that's part of the problem:

void foo()(auto ref MyType1, auto ref MyType2, auto ref MyType3, auto ref MyType4) { ... }

The above has the possibility of generating 16 different functions that basically all do the exact same thing. It creates excessive bloat, and now what if you want to take the address of the function? You can't cause you have to choose between one of the 16 variants.

This is template bloat at it's finest, except it isn't even doing anything useful. I can only imagine telling someone they have to code gen 16 identical functions just to be able to call a function without having to create useless temporary variables in the scope a function is being called in.

Reply via email to