May 29, 2017
On Monday, 29 May 2017 at 07:51:13 UTC, Jonathan M Davis wrote:
> I expect that we're going to see a DIP related to rvalue references at some point here, because some of the folks (particularly the game folks) think that it's critical to be able to have a function that doesn't care whether it's taking a value by value or by ref - just that it takes it efficiently, and they don't want to be forced to use auto ref to do it (since that requires templates).

So it would use ref or value depending on the target platform? I guess that could make sense since some platforms allow vector registers as parameters, but it sounds more like an implementation detail?

Or did you mean something else?
May 29, 2017
Ola Fosheim Grostad wrote:

> This is information that a good IDE could be designed to provide.

when people start talking about how IDE can help to solve particular language problem, it is a clear sign of bad language design.
May 29, 2017
Nicholas Wilson wrote:

> On Sunday, 28 May 2017 at 17:54:30 UTC, WebFreak001 wrote:
>> Imagine you wrote a function
>>
>> void foo(ref int a) {
>>   if (std.random.uniform(0, 10) == 0)
>>     a = 0;
>>   // Actual code doing something
>> }
>>
>> [...]
>
> It seems nice in theory but how will it interact with generic code?
> Perhaps it should be optional and purely documentative.

exactly like "&" does.
May 29, 2017
Nick Sabalausky (Abscissa) wrote:

> In response to any claim that this isn't a real problem in practice, I submit the possibility that, if it indeed isn't a real problem, maybe that's *because* of people (like Stefan and ketmar) simply avoiding the feature entirely so that it *doesn't* become a problem.

exactly! you can include Adam here too, btw. we all prefer to use pointer args exactly to avoid *the* *problem*. so it is not a problem for us anymore... but we aren't solved it, we simply cheated. basically, my only `ref` usage is `in auto ref` (which is not a "real" ref anyway, as argument cannot be changed).

side note: also, with pointers i can do `void foo (int a, bool* res=null) {...}`. not a big deal: one can always create set of overloads to get the same effect with ref, but -- less typing! ;-)

yet i must say that using pointers in a code where they should be references makes me... nervous. it just doesn't feel right. but meh, i'll trade that (and safety, 'cause `&` is unsafe) for "call site ref indicator".

that's why i don't bother writing @safe code, btw: in one or another way i will be forced to hack aroung @safe restrictions, so no reason to start that dance at all. (or just mark the whole thing as @trusted and hope for the best)
May 29, 2017
On Monday, May 29, 2017 08:22:23 Ola Fosheim Grøstad via Digitalmars-d wrote:
> On Monday, 29 May 2017 at 07:51:13 UTC, Jonathan M Davis wrote:
> > I expect that we're going to see a DIP related to rvalue references at some point here, because some of the folks (particularly the game folks) think that it's critical to be able to have a function that doesn't care whether it's taking a value by value or by ref - just that it takes it efficiently, and they don't want to be forced to use auto ref to do it (since that requires templates).
>
> So it would use ref or value depending on the target platform? I guess that could make sense since some platforms allow vector registers as parameters, but it sounds more like an implementation detail?
>
> Or did you mean something else?

I probably didn't say it very well.

With C++, if you have const T&, it will accept both lvalues and rvalues. A number of folks (particularly those writing games) want an equivalent to that in D where they can then pass both lvalues and rvalues without incurring a copy. Historically, Andrei has been against it because of issues with rvalue references, but based on some of the more recent discussions, it sounds like it _might_ be possible to come up with a solution that he'd be okay with (particularly with some of the improvements that come with DIPs 25 and 1000). Ethan Watson has expressed interest in writing a DIP on the matter, so I expect that we'll see one at some point here.

- Jonathan M Davis


May 29, 2017
On Monday, 29 May 2017 at 08:41:05 UTC, Jonathan M Davis wrote:
> With C++, if you have const T&, it will accept both lvalues and rvalues. A number of folks (particularly those writing games) want an equivalent to that in D where they can then pass both lvalues and rvalues without incurring a copy.

Mmm. But it sounds more like a compiler hint on const value types could work? Except when the making of a copy creates side-effects... so you would have to guard against that.

The whole thing with temporaries in C++ in part lead to && move semantics. So this is a slippery slope, perhaps.

> solution that he'd be okay with (particularly with some of the improvements that come with DIPs 25 and 1000). Ethan Watson has expressed interest in writing a DIP on the matter, so I expect that we'll see one at some point here.

I think D is going the wrong way with all this special casing. Memory management is hard enough as it is. At some point Rust's type system will look easier...

Much better if you can get away with using a compiler hint and give the compiler a flag that turns that hint into an absolute for the game-programmers.

It could also be an annotation on a type, that isn't part of the type. (This type should aways be passed as const-ref)

May 29, 2017
On Monday, May 29, 2017 09:17:31 Ola Fosheim Grøstad via Digitalmars-d wrote:
> On Monday, 29 May 2017 at 08:41:05 UTC, Jonathan M Davis wrote:
> > With C++, if you have const T&, it will accept both lvalues and rvalues. A number of folks (particularly those writing games) want an equivalent to that in D where they can then pass both lvalues and rvalues without incurring a copy.
>
> Mmm. But it sounds more like a compiler hint on const value types could work? Except when the making of a copy creates side-effects... so you would have to guard against that.
>
> The whole thing with temporaries in C++ in part lead to && move semantics. So this is a slippery slope, perhaps.

I don't know what's going to be proposed, so I can't really say much about it. I just know what the problem is that they want to solve. However, I can say that whatever they do, having const as a requirement would not fly, because D's const is so restrictive. I think that in a previous discussion, it was suggested that we do something like have an attribute like @rvalue that would go on a ref parameter which would then make it so that the ref parameter would accept rvalues. So, we may get something like that, or it could be that something completely different will be proposed. My main concern is that we not simply make it so that ref accepts rvalues, because then it makes it harder to know when ref is used because a value is going to be returned via the ref parameter and when it's used simply to avoid copying. But I don't know what it will take to alleviate Andrei's concerns about rvalue references, and I expect that that's ultimately the hurdle that any DIP would have to get over. However, DIPs 25 and 1000 should solve the related @safety concerns which were always what Walter was worried about.

- Jonathan M Davis


May 29, 2017
On Monday, 29 May 2017 at 08:40:27 UTC, ketmar wrote:
> yet i must say that using pointers in a code where they should be references makes me... nervous. it just doesn't feel right. but meh, i'll trade that (and safety, 'cause `&` is unsafe) for "call site ref indicator".

So one win with dip1000 is it allows it:

---
@safe void foo(scope int* a) {}
@safe void bar() {
        int a;
        foo(&a);
}
---

$ dmd ppp -c
ppp.d(4): Error: cannot take address of local a in @safe function bar


But with dip 1000:

$ dmd ppp -dip1000 -c
# success!


Of course, dip1000 breaks the living crap out of just about everything else (though all the errors are in phobos....) but it is semi-sane in this case.
May 29, 2017
On Monday, 29 May 2017 at 07:46:07 UTC, Stanislav Blinov wrote:
> On Monday, 29 May 2017 at 07:39:40 UTC, Dukc wrote:
>
>> [snip]
>
> Explicitly? It is:
>
> import std.stdio;
>
> struct S
> {
>     int v;
> }
>
> void foo(ref S s)
> {
>     writeln("took S by ref: ", s.v);
> }
>
> void foo(S s)
> {
>     writeln("took rvalue S...");
>     foo(s);      // calls ref overload
> }
>
> void main()
> {
>     S s;
>     foo(s);      // calls ref overload
>     foo(S.init); // calls rvalue overload
> }
>
> And for templates we have auto ref.

Of course, I should have noticed one can already do it that way. No need for change, then (imo).

May 29, 2017
On Monday, 29 May 2017 at 07:39:40 UTC, Dukc wrote:
> I think it's mostly about good taste on what you define functions to take as ref input. I have a feeling the present way is not a big problem in practice because it is intuitive somehow. Besides, member functions mutate their class/struct anyway, and we don't want to lose our ability to call extension funcions with same syntax as member ones.

well for the extension functions I wrote that if the ref parameter is the first argument and it's called with ufcs syntax, it could implicitly add the ref probably. I don't think there are any big issues with that, it does look like a member function and the programmer could easily read it as "this modifies it"