October 19, 2016
On Tuesday, 18 October 2016 at 20:22:58 UTC, Andrei Alexandrescu wrote:
> On 10/18/2016 04:15 PM, Atila Neves wrote:
>>
>> I think I get it; I'm just not sure given the comments that pop up in
>> the forum. Isn't one of the main reasons distinguishing between these two?
>>
>> void fun(ref const Foo);
>> void fun(Foo);
>>
>> If they can't be distinguished, you don't get move semantics "for free".
>
> That's right, thanks Atila. -- Andreu

Actually thinking it over some more, you would be able to distinguish it. You would simply treat func(Foo) to be the equivalent of func(Foo&&) in C++.

void func(ref const Foo);
void func(Foo);

enum ctfeFoo = Foo();

func(ctfeFoo); // calls func(ref const Foo);
               // zero reason to do a move as enum's can't house runtime values

const Foo foo;

func(foo); // calls func(ref const Foo);

func(Foo()); // calls func(Foo)
             // no ambiguity, same reason there isn't one for C++'s &&
             // Foo() is modifiable temporary

import std.algorithms.mutation : move;

Foo rfoo;
func(move(rfoo)); // calls func(Foo)


So now you would be able to define a single function to take both rvalues and lvalues.
October 19, 2016
Am Tue, 18 Oct 2016 22:43:01 +0200
schrieb Timon Gehr <timon.gehr@gmx.ch>:

> It wouldn't even be the same thing if it was allowed. D const is not C++ const. Enforcing transitive read-only on rvalue references does not make that much sense.

For me using const ref vs. const is typically entirely a matter of avoiding a costly copy. The function body shouldn't care whether the data came from an rvalue or lvalue. It is exemplified in the following lines where doSomething takes a const ref and worldTransform returns by value:

  const worldTransform = someObj.worldTransform();
  otherObj.doSomething(arg1, arg2, worldTransform);

I'd prefer to write:

  otherObj.doSomething(arg1, arg2, someObj.worldTransform());

as the temporaries add significant noise in some functions and make the equivalent C++ code look cleaner.

It may be noteworthy that the lack of rvalue references only really got annoying for me with matrix calculations, because there are so many medium sized temporaries. Some of them come directly from binary operators. Functions often need to perform a set of computations that bare a lot of similarity, where visual cues help the understanding. In a reduced form:

  calculate(  matrix);  // works
  calculate(2*matrix);  // doesn't work, requires temporary
  calculate(3*matrix);  //              "

Introducing temporaries makes the similarity of the calculation less evident. Making calculate take auto-ref would result in duplicate code and thrash the instruction cache (especially with 2 or 3 arguments). Dropping "ref" results in unnecessary matrix copies at this and other call sites.

-- 
Marco

October 19, 2016
On 18 October 2016 at 14:34, Walter Bright via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 10/17/2016 7:54 PM, Manu via Digitalmars-d wrote:
>
>> You mean like that time I spent at least 2 years fighting for
>> final-by-default, won over the entire community except for a single
>> person who said they were indifferent (who I forget who was).
>> Even you begrudgingly conceded (or at least appeared to), the change
>> was implemented, reviewed, merged, and then Andrei appeared back from
>> holiday or wherever, and got angry that it happened in his absence and
>> said he would *never* approve such a thing, and immediately reverted
>> the patch...?
>>
>> One of the most democratic experiences of my life ;)
>>
>> I would be involved in the 'scope' DIP, but I fear my contribution
>> would work against my interests. I'm currently unhappy with it, but I
>> don't really care anymore. I've lost sight of the dream ;)
>> I just want to be able to pass an rvalue to a function that receives a
>> const ref... that's why I came to this forum in the first place like,
>> 7 years ago. 7 years later... still can't.
>>
>>
> You've gotten user defined attributes in the language (and very undemocratically, I might add!), Win64 support, VC++ symbolic debug info, a number of improvements to C++ class support, SIMD support, SIMD intrinsics, pragma inline, yeah, we never listen to you :-)
>

These are practically uncontroversial though. Things like final and scope,
I had to work very hard for for many years. The amount of energy I spent on
that final case was like, more than I'll ever contribute again to anything.
The reason I was so insulted, and generally disengaged from this community
over that matter, was that I spent *years* arguing and slowly winning this
community over, to a point of unanimous agreement among the interested
parties involved in the discussions, and then it was done; implemented,
reviewed, merged, etc... and Andrei appeared and clicked the revert button
without any hesitation. He didn't need to argue his case, he just put his
foot down and said "this will not happen".
I think that's the point Amaury was making, and that I was generally
supporting.
Perhaps he's entitled to do that... that's not for me to say. But it pissed
me off enough to stop contributing my energy in any substantial manner.

You've been a large influence over D, and a very positive one.
>

Thanks. I wish that event never happened and I still felt as enthusiastic as I have in the past.

I'd really like to get this color lib through, but it feels kinda stunted... I understand the feeling that I've seen many others expressing or complaining about. I think some process could be improved to keep a sense of motion associated with peoples efforts, and it might come up less often.


October 19, 2016
On 19 October 2016 at 03:51, Jonathan M Davis via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Tuesday, October 18, 2016 13:36:42 Namespace via Digitalmars-d wrote:
> > On Tuesday, 18 October 2016 at 09:50:35 UTC, ketmar wrote:
> > > On Tuesday, 18 October 2016 at 06:30:15 UTC, Namespace wrote:
> > >> On Tuesday, 18 October 2016 at 02:54:08 UTC, Manu wrote:
> > >>> I just want to be able to pass an rvalue to a function that
> > >>> receives a
> > >>> const ref... that's why I came to this forum in the first
> > >>> place like,
> > >>> 7 years ago. 7 years later... still can't.
> > >>
> > >> I recently wrote a PR for p0nce D idioms, which shows how you
> > >> can do that
> > >> https://github.com/p0nce/d-idioms/pull/119
> > >
> > > there is a huge difference between "i can hack around it" and "i can do it".
> >
> > True. ;) It's like the static-array-without-length-and-gc hack. You can do it with language constructs but it's inconvenient. So it's up to Walter and Andrei to decide if this inconvenience is bearable or not.
>
> Andrei decided ages ago that he didn't think that having const ref take
> rvalues was a good idea and that he doesn't think that it's a big deal. I
> don't recall whether Walter has said much on the issue, but AFAIK, he
> hasn't
> said anything to contradict that, and Andrei has been very vocal about how
> rvalue references were a horrible mistake in C++ and that he doesn't want
> to
> see anything of the sort in D.


Don't misunderstand, at no point I'm aware has anyone ever talked about
rval references.
This is all about passing rvalues as normal references.

People just want to be able to do this:

  void f(ref const(Vector) v);

  f(v1 + v2);

or:

  f(Vector(10,20,30));

That is all. The rval produces a temporary, and the temporary is passed to the function.


October 19, 2016
On 19 October 2016 at 04:07, Andrei Alexandrescu via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 10/18/2016 01:51 PM, Jonathan M Davis via Digitalmars-d wrote:
>
>> Andrei has been very vocal about how
>> rvalue references were a horrible mistake in C++
>>
>
> Please misquote appropriately :o). I said binding rvalues to const ref is the mistake that led to the rvalue references complication. That's the truth and nothing but the truth, but not the whole truth; one thing is that the rvalue references features covers additional things not caused by the const ref mistake. -- Andrei
>

Really? Can you show how allowing passing rvalues as const T& lead to T&&? I honestly have never heard anything about this connection, and I can't imagine how they're connected. They seem like orthogonal issues to me...? Implementing move semantics has nothing to do with passing a temporary?


October 19, 2016
On 19 October 2016 at 06:22, Andrei Alexandrescu via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 10/18/2016 04:15 PM, Atila Neves wrote:
>
>>
>> I think I get it; I'm just not sure given the comments that pop up in
>> the forum. Isn't one of the main reasons distinguishing between these two?
>>
>> void fun(ref const Foo);
>> void fun(Foo);
>>
>> If they can't be distinguished, you don't get move semantics "for free".
>>
>
> That's right, thanks Atila. -- Andreu
>

This is obvious though, lval calls the first, rval calls the second. Surely most programmers would intuitively expect that behaviour? Is there some issue there?


October 19, 2016
On Wednesday, 19 October 2016 at 05:41:17 UTC, Manu wrote:
> People just want to be able to do this:
>
>   void f(ref const(Vector) v);
>
>   f(v1 + v2);
>
> or:
>
>   f(Vector(10,20,30));
>
> That is all. The rval produces a temporary, and the temporary is passed to the function.

Probably worth pointing out that we laid it out exactly like this to Walter and Andrei at DConf, and how not having it made the Quantum Break animation code (all of which is 3D math) a pain to write thanks to having to define the temporary variables yourself. Especially when you're calling bound C++ functions and the programmers involved could compare it to C++ directly saying "Why can't we do this?"

This was actually a use case that had not been considered before, as it turns out.


October 19, 2016
On 19.10.2016 04:58, Marco Leise wrote:
> Am Tue, 18 Oct 2016 22:43:01 +0200
> schrieb Timon Gehr <timon.gehr@gmx.ch>:
>
>> It wouldn't even be the same thing if it was allowed. D const is not C++
>> const. Enforcing transitive read-only on rvalue references does not make
>> that much sense.
>
> For me using const ref vs. const is typically entirely a
> matter of avoiding a costly copy. The function body shouldn't
> care whether the data came from an rvalue or lvalue. It is
> exemplified in the following lines where doSomething takes a
> const ref and worldTransform returns by value:
>
>   const worldTransform = someObj.worldTransform();
>   otherObj.doSomething(arg1, arg2, worldTransform);
>
> I'd prefer to write:
>
>   otherObj.doSomething(arg1, arg2, someObj.worldTransform());
>
> as the temporaries add significant noise in some functions and
> make the equivalent C++ code look cleaner.
>
> It may be noteworthy that the lack of rvalue references only
> really got annoying for me with matrix calculations, because
> there are so many medium sized temporaries. Some of them come
> directly from binary operators. Functions often need to
> perform a set of computations that bare a lot of similarity,
> where visual cues help the understanding. In a reduced form:
>
>   calculate(  matrix);  // works
>   calculate(2*matrix);  // doesn't work, requires temporary
>   calculate(3*matrix);  //              "
>
> Introducing temporaries makes the similarity of the
> calculation less evident. Making calculate take auto-ref would
> result in duplicate code and thrash the instruction cache
> (especially with 2 or 3 arguments). Dropping "ref" results in
> unnecessary matrix copies at this and other call sites.
>

Yes, the lack of rvalue references can be annoying but 'const' should be orthogonal to any implemented solution.

There should be a way to pass rvalues by reference that are not prevented from being mutated, and it should be the same way as for const references. (For example, one possible approach is to just allow rvalues to bind to all 'ref' parameters (as is done for the implicit 'this' reference), alternatively there could be some additional "allow rvalues here" annotation that does not influence mutability.)
October 19, 2016
On 19 October 2016 at 19:11, Ethan Watson via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On Wednesday, 19 October 2016 at 05:41:17 UTC, Manu wrote:
>
>> People just want to be able to do this:
>>
>>   void f(ref const(Vector) v);
>>
>>   f(v1 + v2);
>>
>> or:
>>
>>   f(Vector(10,20,30));
>>
>> That is all. The rval produces a temporary, and the temporary is passed to the function.
>>
>
> Probably worth pointing out that we laid it out exactly like this to Walter and Andrei at DConf, and how not having it made the Quantum Break animation code (all of which is 3D math) a pain to write thanks to having to define the temporary variables yourself. Especially when you're calling bound C++ functions and the programmers involved could compare it to C++ directly saying "Why can't we do this?"
>
> This was actually a use case that had not been considered before, as it turns out.
>

Huh? Not even.
I dunno how it could have not been considered, since it was the exact
example I've given every time, and the exact case that motivated my first
(and many subsequent) posts on this forum back when we still worked at
Krome.. all this time later I *still* just wanna call functions in games
engines that receive a vector or matrix ;)


October 19, 2016
On Wednesday, 19 October 2016 at 09:34:39 UTC, Manu wrote:
> I dunno how it could have not been considered, since it was the exact
> example I've given every time, and the exact case that motivated my first
> (and many subsequent) posts on this forum back when we still worked at
> Krome.. all this time later I *still* just wanna call functions in games
> engines that receive a vector or matrix ;)

Well, it could very well have been the specifics as we laid it out that weren't considered, ie avoiding temporary variables that we never use again; and taking by const reference to avoid copying the struct to the stack (whether just created or already previously stored on the stack etc).

Win64 also has the __vectorcall calling convention, but that doesn't help in cases where you pass in several matrices as inputs for example. And it's not portable to other viable gaming platforms.

https://msdn.microsoft.com/en-us/library/dn375768.aspx