rvalues -> ref (yup... again!)

Manu turkeyman at gmail.com
Fri Mar 30 18:17:17 UTC 2018


On 30 March 2018 at 02:06, Atila Neves via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On Tuesday, 27 March 2018 at 18:14:18 UTC, Manu wrote:
>>
>> On 27 March 2018 at 00:14, Atila Neves via Digitalmars-d
>> <digitalmars-d at puremagic.com> wrote:
>>>
>>> On Monday, 26 March 2018 at 19:24:13 UTC, Manu wrote:
>>>>
>>>>
>>>> On 26 March 2018 at 07:40, Atila Neves via Digitalmars-d
>>>> <digitalmars-d at puremagic.com> wrote:
>>>>>
>>>>>
>>>>> On Friday, 23 March 2018 at 22:01:44 UTC, Manu wrote:
>>>>>>
>>>>>>
>
>>> That's _if_ T is big and _if_ it even gets copied,
>>
>>
>> You've just described the exact anatomy of a ref function!
>> You wouldn't write a function to receive T by ref UNLESS T was both
>> big, and the function probably won't inline (therefore definitely
>> copy), and that condition will be triggered by any of the list of
>> reasons I've said a bunch of times (extern, dll, lib, virtual, etc).
>> People don't just love writing ref (well, some people might), but they
>> use it deliberately, typically in user-facing boundary API's for these
>> exact reasons.
>
>
> I know. I was arguing that those cases are uncommon and the API pain is
> therefore not too big of an issue. I'm pretty sure that you feel it more
> because of what you write in D.

Totally.
But I think it's uncommon at least in-part because of this
inconvenience. It's at least a little bit circular. Even you're saying
above "yeah, just do by-val, it's *probably* insignificant"... you
only say that because you've allowed this inconvenience to change your
behaviour. And I think that's to be expected.
Other reasons that it's not common:
extern(C++) is not common.
OOP (virtuals) in D are fairly uncommon. We don't OOP much in D.
Closed-source (binary lib) distribution is uncommon... possibly
unheard of? (yet!)
DLL's are still problematic onvarious fronts, and I don't think they
enjoy anywhere near as much use as they deserve.

Most of these aren't desirable... we'd like to see more commercial
(closed source?) users, DLL's should be more popular than they are...
and more extern(C++) means more people using a key development
investment in D.
So yeah, I agree it's relatively uncommon if you don't interact with
one of the niches where it tends to be common! :P


>> Right. I'm talking about deliberate use of ref... Or *existing*
>> (deliberate) use of ref, as is the case in almost all my my cases. The
>> code already exists.
>
>
> Right, and I was assuming (perhaps incorrectly) that this existing code was
> C++, hence me being on board with binding rvalues to const ref there.

Right. But I'm not a fan is just rearranging the edge cases by
limiting it to a different set of cases and not applying it generally.
This also interacts with meta constructions, and while there are ANY
cases where calling doesn't just work as usual and it needs special
case handling, meta will still need static-if's to handle those cases.
We're just changing the criteria for the 'if'.
By allowing fully symmetric function calling rules, only then does the
noisy case-handling logic disappear from meta.


>> Only if you ARE moving, and not copying. D must deep copy too if you
>> actually copy.
>> Your example assumes C++ doesn't have a move constructor. D has
>> implicit move semantics, so you can only make an equivalent comparison
>> where C++ also defines the move constructor so the move case doesn't
>> pollute the ref comparison.
>
> I wasn't assuming the lack of a move constructor. What I was saying is that
> passing by value in C++ will usually mean a copy, whereas in D it usually
> means a move.

Right. But we're not talking about move's, we're talking about
NOT-move's (ie, preventing copies by passing by ref) ;)
Despite the appearance that we might be talking about rvalues, we're
actually talking about passing lvalues by ref... that's WHY you write
a function to accept its args by ref; to prevent deep copies when
passing lvalues.
The issue is, it's super-common to call functions with rvalues, and
the edge cases created by using ref are annoying and asymmetric, hence
such functions should receive rvalues too.


>>>> In C++'s case, it's not that references were deficient at being
>>>> references that C++ needed rval-references, it's that references were
>>>> deficient at being move-able.
>>>
>>> There were deficient at being moveable because temporaries can bind to
>>> const T&.
>>
>> ... what? That's just not true at all.
>> If temporaries couldn't bind to C++ ref, then you *definitely*
>> wouldn't be able to move it, because you can guarantee that someone
>> else owns the reference.
>
> Precisely. That's how D works.

Sorry, I'm lost now. I don't understand your initial point. You
created a relationship between ref's accepting rvalues, and the reason
that C++ introduced rvalue-references.
No such relationship exists... and I was trying to show that your
reasoning was inverted.


>> rvalue references were introduced in C++ to capture the calls with
>> rvalues into a separate function call, exactly the same way as the
>> by-value overload will catch the rvalues in D (and perform an implicit
>> move).
>
> Yes.
>
>> References have no interaction with move semantics.
>
> Even given interior pointers, I disagree.

Please explain how there's any relationship between ref functions and
move semantics?

C++/D's mechanism for catching the move case is different, but that
still doesn't affect or interact with the ref case.
ref accepting rvalues has absolutely no effect on move semantics,
either theoretically in D, or practically in C++. It's a totally
separate problem space.


>> But again, we're not talking about move semantics here, we're just talking
>> about references ;)
>
> See comment above ;)

Likewise :P


>>> I'd love to know what that would look like.
>>
>>
>> That's exactly what I've been saying. For like, 9 years..
>> It looks like this:
>>
>> https://github.com/TurkeyMan/DIPs/blob/ref_args/DIPs/DIP1xxx-rval_to_ref.md
>>  (contribution appreciated)
>
> I was unaware of this (or I forgot). After reading it I'm not sure of what
> corner cases might arise, but if I'm getting it right I think it could work.

Right. So does that admission dismiss your points above where you
suggest there's some reason that C++ ref functions accepting rvalues
lead to T&&?
As far as I can tell from your prior posts, your only resistance is
the idea of a 'slippery slope' that leads to T&& appearing in D? I
promise, I'm just as concerned that never happens as you :)
If you can find a connection, I want to know about it. But I'm
confident that no such thing exists..


>> And as far as I
>> can tell, it basically only affects me, because I do so much work
>> against established C++ code! >_<
>
>
> That's entirely possible. I can use my fingers to count the number of times
> I've written `extern(C++)`.

Exactly.
I'd like to think that my set of use cases are not cases that we want
to discourage however. I'd like to see more users like myself in the
future...


More information about the Digitalmars-d mailing list