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