June 22, 2015
On Monday, 22 June 2015 at 16:10:10 UTC, Namespace wrote:
> Rather than raising the matter of scope again and again, we should be thankful that a solution for this nasty problem is accepted and could be merged.

I disagree strongly with this. A bad solution is worse than no solution.

> How scope and escape analysis could do a better job is unclear and if you want to solve the problem this way you will wait a very long time.

Not at all. `auto ref` without a working `scope` implementation is unsafe. If that is acceptable for now, then it should be just as acceptable to already use `scope ref` as a syntax for the same semantics, even if the required escape-proofing of `scope` is not yet implemented.

If/when we will finally get a working `scope`, using those functions will then be actually verified by the compiler. In the meantime, the `scope` keyword will at least express the intention to the caller and will serve as a reminder to the callee's author.

In contrast, with `auto ref` accepting rvalues, we will have the same keywords `auto ref` mean two very different things for templates and non-templates, we still won't have a way to write rvalue-ref-accepting template functions, and when we will finally get `scope`, `auto ref` will be a pointless alternative syntax for `scope ref` that will have to be kept around forever.

> So please let us concentrate and discuss how we could solve this problem with auto ref. :)

Use `scope ref` instead of `auto ref` now, and just ignore that it's unsafe for the moment. Your PR will become even shorter with it, because you no longer need `STCrvref`. Conceptually, just do "#define STCrvref (STCref | STCscope)".

>
> To repeat my statement from the PR:
> I would also prefer to avoid the generation of further functions, because I want to avoid the code bloat.

That's what my suggestion does, too.

> I like the way of the current implementation, because it is following the way C++ does and will be understandable for every person which comes from C++.

With the difference that C++ requires const-ness.
June 22, 2015
We had this discussion already with DIP 36. A PR still exists AFAIK, but because it was rejected I don't think that's going to happen. :) So auto ref is obviously the choice. If you insist on scope/in ref, please make your own thread and ask why it was rejected or read the corresponding thread.
June 22, 2015
I see no reasons why « ref in » is bad. Maybe someone explain ?
It's also natural for those who came from C++.
In C++ there's no problem with const&, so why they will be in D?
June 22, 2015
On 6/22/15 9:54 AM, "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net>" wrote:
> `auto ref` without a working `scope` implementation is unsafe.

I'm unclear on this. With the existence of the return attribute, what's unsafe about auto ref? -- Andrei
June 22, 2015
On Monday, 22 June 2015 at 18:03:43 UTC, Temtaime wrote:
> I see no reasons why « ref in » is bad. Maybe someone explain ?
> It's also natural for those who came from C++.
> In C++ there's no problem with const&, so why they will be in D?

Because const is transitive in D and therefore more restrictive.
June 22, 2015
On Monday, 22 June 2015 at 16:54:50 UTC, Marc Schütz wrote:
> On Monday, 22 June 2015 at 16:10:10 UTC, Namespace wrote:
>> Rather than raising the matter of scope again and again, we should be thankful that a solution for this nasty problem is accepted and could be merged.
>
> I disagree strongly with this. A bad solution is worse than no solution.
>
>> How scope and escape analysis could do a better job is unclear and if you want to solve the problem this way you will wait a very long time.
>
> Not at all. `auto ref` without a working `scope` implementation is unsafe. If that is acceptable for now, then it should be just as acceptable to already use `scope ref` as a syntax for the same semantics, even if the required escape-proofing of `scope` is not yet implemented.
>
> If/when we will finally get a working `scope`, using those functions will then be actually verified by the compiler. In the meantime, the `scope` keyword will at least express the intention to the caller and will serve as a reminder to the callee's author.
>
> In contrast, with `auto ref` accepting rvalues, we will have the same keywords `auto ref` mean two very different things for templates and non-templates, we still won't have a way to write rvalue-ref-accepting template functions, and when we will finally get `scope`, `auto ref` will be a pointless alternative syntax for `scope ref` that will have to be kept around forever.
>
>> So please let us concentrate and discuss how we could solve this problem with auto ref. :)
>
> Use `scope ref` instead of `auto ref` now, and just ignore that it's unsafe for the moment. Your PR will become even shorter with it, because you no longer need `STCrvref`. Conceptually, just do "#define STCrvref (STCref | STCscope)".

I definitely see your point and very much agree!

>> I like the way of the current implementation, because it is following the way C++ does and will be understandable for every person which comes from C++.
>
> With the difference that C++ requires const-ness.

Yep, so `in ref T` translating to `scope const ref T` would be D's convenient and safe counterpart to C++' `const T&` parameters, for their main use case: passing pure-input arguments of types which are or may be costly to copy (post-blit ctor, dtor, or simply big). I explicitly mention 'may be' here because in templates one often doesn't know (containers...).

As I have already pointed out in another thread, I'd go one step further and propose an extremely convenient `in T` for this very common use case:

* The argument is passed by value (`const T`) if the compiler assumes moving/copying is more efficient than passing a reference (with its indirection on the callee side) for the particular target environment (hardware, ABI), e.g., for plain-old-datatypes T fitting into 1-2 registers, and Object references obviously.
* Otherwise, the argument is passed by-ref (`in ref T`). As `in T` doesn't mention any ref at all, it's clear that the hidden reference cannot escape.

Let me give you an example. The Win64 ABI only allows passing POD types <= 64 bit by value (exception: vector/SSE types). All other types need to be passed by ref, which means that D's otherwise cool in-place construction of arguments on the callee's function parameters stack isn't possible. The current `auto ref` implementation for templates is in vain on Win64 for these byref-types, as the ABI forces both versions to take the argument byref anyway.

I'm pretty sure I could live without an `auto ref` for templates once I can use `in T` for all my pure-input parameters. If the function may change the argument, I'd go with `scope ref T`, accepting rvalues too. If the function may even let the argument escape, it'll have to be `ref T` or `const/immutable ref T`. And if I just want to mutate the parameter inside my function, but not touch the argument, it'd be `T`. I can't think of any other use cases for function parameters atm.
June 22, 2015
On Monday, 22 June 2015 at 05:25:57 UTC, Walter Bright wrote:
> The idea is that fun(5) would be lowered to:
>
>    auto tmp = 5;
>    fun(tmp);
>
> But when talking to Andrei I didn't realize that it would be subtly different behavior than 'auto ref' for template functions, which makes me concerned that this is not a good idea.

Considering we already have working 'Sealed references', why not simply allow rvalues for plain ref?

Bonus: No risk of mixup with template auto ref after refactoring etc.
Save auto for other potential future use.
June 22, 2015
On Monday, 22 June 2015 at 20:42:58 UTC, Daniel N wrote:
> On Monday, 22 June 2015 at 05:25:57 UTC, Walter Bright wrote:
>> The idea is that fun(5) would be lowered to:
>>
>>    auto tmp = 5;
>>    fun(tmp);
>>
>> But when talking to Andrei I didn't realize that it would be subtly different behavior than 'auto ref' for template functions, which makes me concerned that this is not a good idea.
>
> Considering we already have working 'Sealed references', why not simply allow rvalues for plain ref?
>
> Bonus: No risk of mixup with template auto ref after refactoring etc.
> Save auto for other potential future use.

That would be horrible. How would you distinguish between lvalues and rvalues? What if you want to store a pointer to an lvalue? If ref accept both you cannot do that.
June 22, 2015
On Monday, 22 June 2015 at 20:42:58 UTC, Daniel N wrote:
> Considering we already have working 'Sealed references', why not simply allow rvalues for plain ref?

Please, please, no. That would be horrible. ref indicates an intention to mutate the argument, which makes no sense with rvalues. And if ref is used simply so that you can accept both rvalues and lvalues without copying lvalues, then there's zero indication in the function signature when the point of the ref is to actually set what's being passed in.

It works in C++ with const&, because you know that the function won't mutate the argument, but if you allow it with ref in general, then you stand no chance of being able to look at a function signature and deduce whether the function intends to mutate an argument or not. And even if Andrei wasn't so set against const ref that we could go that route in D as well, it wouldn't solve the problem either, because const in D is just too restrictive to use in many cases. We need a way to indicate that a parameter accepts both lvalues and rvalues without intending to mutate the argument but without actually guaranteeing it via const. And that does _not_ work with naked ref.

- Jonathan M Davis
June 22, 2015
On Monday, 22 June 2015 at 20:50:23 UTC, Namespace wrote:
> That would be horrible. How would you distinguish between lvalues and rvalues? What if you want to store a pointer to an lvalue? If ref accept both you cannot do that.

storing requires 'return ref'