Binding rvalues to ref [WAS: I close BIP27. I won't be pursuing BIPs anymore]

Namespace via Digitalmars-d digitalmars-d at puremagic.com
Wed Oct 19 13:19:57 PDT 2016


On Wednesday, 19 October 2016 at 19:19:35 UTC, Jonathan M Davis 
wrote:
> That's an orthogonal issue. My point is that normally, a 
> parameter is a ref parameter, because the function is going to 
> use that value and potentially mutate it in the process, and 
> you want the original variable that was passed in to be mutated 
> rather than for the function to be operating on a copy. 
> However, once you can pass rvalues to ref parameters, there 
> will likely be a sharp increase in the number of ref parameters 
> whose entire purpose in being ref is to avoid a copy rather 
> than because the original variable is supposed to be mutated. 
> That increases the risk of accidentally mutating function 
> arguments as well as making it far less obvious when a function 
> is supposed to be mutating its argument. C++ solved that 
> problem by making it so that only const ref parameters could 
> take rvalues, whereas we would be totally open to it if 
> non-const ref parameters accepted rvalues.
>
> Whether the argument escapes the function doesn't matter for 
> any of that. There may be good reasons why you don't want it 
> to, in which case, if scope is implemented to prevent ref 
> parameters from escaping, scope will give you that. But just 
> because you want to mutate the ref argument doesn't necessarily 
> mean that you care about it escaping. You _do_ care if the 
> purpose is simply to avoid a copy, because you don't want the 
> rvalue to escape, since that would be an @safety issue, and so 
> it would make sense to require scope in that case, but at best, 
> that means that the lack of scope indicates that the ref 
> argument is supposed to be mutated as opposed to simply avoid a 
> copy, whereas scope ref says nothing about whether the ref 
> argument is supposed to be mutated or simply avoid a copy - 
> just that whatever the argument is, it should no escape.

Ok, I understand what you mean, but as long as the argument 
cannot escape I have a different opinion.

> So, arguably, it makes more sense to have a new attribute that 
> makes it specifically so that a ref accepts rvalues (e.g. 
> @rvalue ref) rather than making ref in general accept rvalues 
> (the new attribute could even imply scope, since it would be 
> required), but that would mean adding yet another attribute, 
> and we arguably have too many of those already.
>
> - Jonathan M Davis

Yes, we have way to many. So it would make more sense if we add 
helper/wrappers into phobos (at least for the time being) and 
refer to them.
My byRef "hack" or even my last experiment below could lower the 
dissatisfaction.

----
struct Vector2f
{
     float x, y;
}

void one(ref const Vector2f v)
{
     writeln(v.x, '|', v.y);
}

void two(ref const Vector2f source, ref const Vector2f target)
{
     writefln("From (%.2f|%.2f) to (%.2f|%.2f)", source.x, 
source.y, target.x, target.y);
}

void invoke(alias f, V...)(V vs)
{
	f(vs);
}

void invoke(F, V...)(F f, V vs)
{
	f(vs);
}

invoke!one(Vector2f(10, 20));
invoke!two(Vector2f(1, 2), Vector2f(3, 4));
	
invoke(&one, Vector2f(10, 20));
invoke(&two, Vector2f(1, 2), Vector2f(3, 4));
----



More information about the Digitalmars-d mailing list