DIP 1016--ref T accepts r-values--Community Review Round 1

Manu turkeyman at gmail.com
Fri Jul 20 21:16:20 UTC 2018


On Fri, 20 Jul 2018 at 12:36, Jonathan M Davis via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> On Friday, July 20, 2018 11:50:41 Manu via Digitalmars-d wrote:
> > > I am completely against allowing ref to accept rvalues without some sort
> > > of attribute indicating that it should be allowed to (e.g. @rvalue
> > > ref).
> > I sincerely hope you're in the minority :(
> >
> > > Allowing ref to accept rvalues goes completely against the idea that ref
> > > is for passing an object so that it can be mutated and have its result
> > > affect the caller.
> >
> > That is *one use* for ref. I produced text to the effect of changing
> > your mental model and such assertions.
>
> It's the primary use for ref as it stands given that ref does not currently
> accept rvalues,

I'm not sure this is true.
I encounter ref constantly. It's just awkward and uncomfortable to use
rvalues => it's awkward and uncomfortable to use ref.
And I find it's comparatively rarely used for the thing you say.

I think 'primary' use is not what you say, and it's just that we all
suffer under the current rules.
Those that don't understand my pain probably just don't interact with
ref much at all. You can't have a strong opinion on this matter if you
rarely interact with ref.

I occasionally use it for the thing you say, but that's definitely a
minority case, and even in that case, I this rule has no affect on the
problem.
I have *never ever, in my life* 'accidentally' discarded an output
that I needed to use by passing an rvalue to an output-ing ref.

Think about it, that doesn't even structurally make sense.
If the function returns results via a ref, then the only way to refer
to the results it to refer to the lvalue that I passed in.
If I passed an rvalue, then it would be impossible to refer to the
results, and I would be unable to write the next line of code.

The compiler doesn't need to 'help' me here, because I literally can't
progress if I accidentally passed an rvalue.
If I successfully did pass an rvalue and dismiss the results, then
it's implied by the fact my code compiles and runs that I didn't need
the result; in that case, is no different than ignoring a return value
(which is perfectly valid and acceptable practise).

I'm sure it's *possible* to construct a case where you exhibit an
undesirable effect, but we're getting into such unlikely and obviously
contrived territory, that I don't see how any reasonable person could
find that the hindrance caused in all other cases by the current
design is in balance.

> and personally, when I use ref on a function, it's a very
> specific API decision where it really does not make sense to accept lvalues.
> It's also how plenty of other folks use ref (e.g. it's generally how Phobo
> uses ref). This DIP doesn't change any of that. It just makes it harder in
> favor of providing a way to pass rvalues by ref.

Sorry... what is this DIP making harder?

> IMHO, those two use cases
> are distinct and should be distinct in the API. Using @disable as the DIP
> suggests is ridiculously verbose in comparison to how ref currently works,
> and it would require updating many existing uses of ref just to avoid the
> bugs caused by accepting rvalues.

I think the 'bug' is implicitly resolved by the fact that you can't
make use of the results if you pass an rvalue anyway.
Like, there's no conceivable situation where a user thought they
authored their code correctly, but passing an rvalue by accident
allowed their code to compile.

Consider:
  void getOutput(ref T x);
  void doStuff(T x);

  T output;
  getOutput(output); // returns output
  doStuff(output); // consumes output

This is the 'bug' scenario:
  getOutput(makeT()); // returns output to rvalue
  doStuff( ...? ); // what do you even type here? the 'bug' resolves
itself implicitly by the programmer having to type something in this
gap

> IMHO, it makes far more sense to require
> an explicit attribute to indicate that a parameter accepts rvalues. It's
> less error-prone, less verbose, and doesn't cause problems for existing
> code.

Adding yet-another-attribute is another form of swapping one kind of
metacrobatics (to lift Schveighoffer's term) with a different kind,
and then this DIP is self-defeating.
If you want to synth a forwarding function, or something in that
domain, you now need to detect and mirror another `@rvalue` attribute
(guaranteed text mixin)... maybe this leads to `auto @rvalue`?

It's chaos.


More information about the Digitalmars-d mailing list