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

Manu turkeyman at gmail.com
Sat Jul 21 01:02:27 UTC 2018


On Fri, 20 Jul 2018 at 17:33, Jonathan M Davis via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
>
> On Saturday, July 21, 2018 00:10:09 Nicholas Wilson via Digitalmars-d wrote:
> > So this problem is restricted output range @properties that
> > somehow don't return by ref, aren't intended to be used after
> > having data written to them _and_ aren't singleton like?
>
> It's a problem for any function that accepts by ref with the intention of
> mutating the argument rather than to avoid copying, and something other than
> an lvalue is passed. Output ranges are just a particularly common use case.

They are. But it's particularly hard to imagine a non-contrived
situation where the compile error would alert the user to a bug that
they wouldn't naturally discover in some other way (likely, the very
next line).
Such cases are so few, that I can't find that they balance the broad
value in this DIP.
Further, if you are writing code where this is at unusually high-risk
for some reason, use the @disable technique.

> And property functions are just an easy way to think that you're passing an
> lvalue when you're not. For that matter, it's an easy mistake to make with
> lots of functions in D, because parens are unnecessary when there are no
> function arguments or when the only function argument is passed via UFCS.
> And of course, if someone doesn't read the docs carefully enough (which
> happens far too often), there are plenty of problems that someone could run
> into where they pass an rvalue to a function designed to operate on an
> lvalue.

This is just saying stuff.

I think you're describing now a bug where a function returns an
lvalue, but it was meant to return an rvalue.
The user then uses that buggy function in conjunction with ref, and
the output is lost (I still can't quite imagine the scenario, given
the restrictive criteria that Nicholas highlighted earlier).

1. The function that's buggy is not the function that involves ref.
2. You're expecting the function that involves ref to catch a bug in
an unrelated function via the existing ref semantics. I think you're
exceeding reason.
3. While it _might_ catch your issue, the buggy function is still
buggy, and may manifest the bug in any number of other far more likely
ways:
   - it may not be involved in a call to ref (and therefore bug not
caught that way)
   - the accidentally-by-val return value may be accessed directly, or
via a method

You're describing an unrelated bug, and it's not ref's job to catch it.
At best, it's just a matter of luck that ref's existing semantic was
able to prevent a bug like you describe, but I think such a
responsibility it well outside of the design's charter.

> Right now, ref catches any and all mistakes where someone tries to
> pass an rvalue by ref, but if ref accepts rvalues, it won't catch any of
> them.

I'm still yet to identify a single realistic scenario where such a
mistake is likely.
I'm sure it's possible that some situations exist, but they're
evidently rare, and if you do identify such a particularly high risk
situation, use the @disable technique. It makes the at-risk construct
beautifully explicit in its intended design.

Adding an @rvalue attribute eliminates the primary value of this DIP.
Situation with meta would become substantially worse.
Meta case-handling which falls back to text-mixins (necessary when
attributes outside the type system appear) is the very worst kind of
'metacrobatics'.


More information about the Digitalmars-d mailing list