October 01, 2020
On Thursday, 1 October 2020 at 09:49:36 UTC, Mathias LANG wrote:
> Author here. The most complete way to know would be to read the changelog: https://dlang.org/changelog/2.094.0.html#preview-in
> The TL;DR is that, in addition to `const scope`, `in` now automatically behaves as `ref` when "it makes sense" such as large value types or presence of destructors / postblit (more details in the changelog!) and will accept rvalues, unlike other ref parameters.

Why was this added when we already have `auto ref`? Yes, it makes the function a template, but if `in` can automatically choose whether the variable is ref or not, then auto ref could easily do the same.
October 01, 2020
On 10/1/20 10:36 AM, Meta wrote:
> On Thursday, 1 October 2020 at 09:49:36 UTC, Mathias LANG wrote:
>> Author here. The most complete way to know would be to read the changelog: https://dlang.org/changelog/2.094.0.html#preview-in
>> The TL;DR is that, in addition to `const scope`, `in` now automatically behaves as `ref` when "it makes sense" such as large value types or presence of destructors / postblit (more details in the changelog!) and will accept rvalues, unlike other ref parameters.
> 
> Why was this added when we already have `auto ref`? Yes, it makes the function a template, but if `in` can automatically choose whether the variable is ref or not, then auto ref could easily do the same.

There is a difference. `in` is choosing it based on the type, not whether it's an rvalue or lvalue. auto ref doesn't care whether it's an int or a 1k-sized struct, if it's an lvalue, it's ref, and if it's an rvalue, it's non-ref.

Not only that, but every auto-ref parameter is another template parameter varying on the usage. So calling on an lvalue and rvalue will generate 2 separate mostly-identical functions.

With -preview=in, only one function is generated per type.

-Steve
October 01, 2020
On Thursday, 1 October 2020 at 09:49:36 UTC, Mathias LANG wrote:
> [snip]
>
> Author here. The most complete way to know would be to read the changelog: https://dlang.org/changelog/2.094.0.html#preview-in
> The TL;DR is that, in addition to `const scope`, `in` now automatically behaves as `ref` when "it makes sense" such as large value types or presence of destructors / postblit (more details in the changelog!) and will accept rvalues, unlike other ref parameters.

Typo from the link

"However, this didn't really capture the intended meaning of in: the be applied on input parameters. "


October 01, 2020
On Thursday, 1 October 2020 at 16:44:09 UTC, jmh530 wrote:
>[snip]
>
> Typo from the link
>
> "However, this didn't really capture the intended meaning of in: the be applied on input parameters. "

It looks like that whole paragraph has a bunch of typos...
October 01, 2020
On Thursday, 1 October 2020 at 16:19:48 UTC, Steven Schveighoffer wrote:
> On 10/1/20 10:36 AM, Meta wrote:
>> On Thursday, 1 October 2020 at 09:49:36 UTC, Mathias LANG wrote:
>>> Author here. The most complete way to know would be to read the changelog: https://dlang.org/changelog/2.094.0.html#preview-in
>>> The TL;DR is that, in addition to `const scope`, `in` now automatically behaves as `ref` when "it makes sense" such as large value types or presence of destructors / postblit (more details in the changelog!) and will accept rvalues, unlike other ref parameters.
>> 
>> Why was this added when we already have `auto ref`? Yes, it makes the function a template, but if `in` can automatically choose whether the variable is ref or not, then auto ref could easily do the same.
>
> There is a difference. `in` is choosing it based on the type, not whether it's an rvalue or lvalue. auto ref doesn't care whether it's an int or a 1k-sized struct, if it's an lvalue, it's ref, and if it's an rvalue, it's non-ref.

This seems ridiculous to me. We now have ANOTHER way of asking the compiler to choose for us whether to pass by ref or by value, completely mutually exclusive of auto ref. Where was the DIP (apologies if I just didn't see it)? Did Walter approve this? How do we explain the difference between in and auto ref with (as Andrei would say) a straight face?

> Not only that, but every auto-ref parameter is another template parameter varying on the usage. So calling on an lvalue and rvalue will generate 2 separate mostly-identical functions.
>
> With -preview=in, only one function is generated per type.

That's a QOI problem IMO.

> -Steve


October 01, 2020
On 10/1/20 12:47 PM, Meta wrote:
> On Thursday, 1 October 2020 at 16:19:48 UTC, Steven Schveighoffer wrote:
>>
>> There is a difference. `in` is choosing it based on the type, not whether it's an rvalue or lvalue. auto ref doesn't care whether it's an int or a 1k-sized struct, if it's an lvalue, it's ref, and if it's an rvalue, it's non-ref.
> 
> This seems ridiculous to me. We now have ANOTHER way of asking the compiler to choose for us whether to pass by ref or by value, completely mutually exclusive of auto ref. Where was the DIP (apologies if I just didn't see it)? Did Walter approve this? How do we explain the difference between in and auto ref with (as Andrei would say) a straight face?

Whether a *const* piece of data is passed by reference or value is an implementation detail -- you can't change it anyway. I don't want the compiler to pass const integers by reference -- that's wasteful.

auto ref is a different problem -- the data might be mutable, which makes an actual difference in semantics.

But this brings up a problem which I don't know if it was discussed -- aliasing.

What if you pass in the same value in 2 parameters, one ref and one in. And you change the value via the ref. What happens to the in parameter?

-Steve
October 01, 2020
On Thursday, 1 October 2020 at 16:47:37 UTC, Meta wrote:
> On Thursday, 1 October 2020 at 16:19:48 UTC, Steven Schveighoffer wrote:
>> On 10/1/20 10:36 AM, Meta wrote:
>>> On Thursday, 1 October 2020 at 09:49:36 UTC, Mathias LANG wrote:
>>>> Author here. The most complete way to know would be to read the changelog: https://dlang.org/changelog/2.094.0.html#preview-in
>>>> The TL;DR is that, in addition to `const scope`, `in` now automatically behaves as `ref` when "it makes sense" such as large value types or presence of destructors / postblit (more details in the changelog!) and will accept rvalues, unlike other ref parameters.
>>> 
>>> Why was this added when we already have `auto ref`? Yes, it makes the function a template, but if `in` can automatically choose whether the variable is ref or not, then auto ref could easily do the same.
>>
>> There is a difference. `in` is choosing it based on the type, not whether it's an rvalue or lvalue. auto ref doesn't care whether it's an int or a 1k-sized struct, if it's an lvalue, it's ref, and if it's an rvalue, it's non-ref.
>
> This seems ridiculous to me. We now have ANOTHER way of asking the compiler to choose for us whether to pass by ref or by value, completely mutually exclusive of auto ref. Where was the DIP (apologies if I just didn't see it)? Did Walter approve this? How do we explain the difference between in and auto ref with (as Andrei would say) a straight face?

`auto ref` is a mistake and shouldn't have existed. Thanks to Mathias, `in` parameters are finally working the way most sane people expect them to work.
I can't quite explain `auto ref` with straight face, while to explain `in` I just need to say "unless you're mutating or aliasing the parameter always mark it as `in`".

>> Not only that, but every auto-ref parameter is another template parameter varying on the usage. So calling on an lvalue and rvalue will generate 2 separate mostly-identical functions.
>>
>> With -preview=in, only one function is generated per type.
>
> That's a QOI problem IMO.
>

No, it's not. According the spec, `auto ref` parameters can only be used for templates (making them useless for virtual functions and delegates) and the compiler is required to generate a different functions depending on whether the parameter is an lvalue or an rvalue, which completely misses the point. There's code out there that expect two instances to be generated and distinguishes which one it's in using `static if (__traits(isRef, param))`. You can't change this behavior without breaking code, so it's not a QoI problem.

On the other hand, now the `in` parameter storage class finally has the opposite meaning of `out`. Makes code more elegant to write, easier to explain and teach.




October 01, 2020
On Thursday, 1 October 2020 at 16:47:37 UTC, Meta wrote:
>
> This seems ridiculous to me. We now have ANOTHER way of asking the compiler to choose for us whether to pass by ref or by value, completely mutually exclusive of auto ref. Where was the DIP (apologies if I just didn't see it)? Did Walter approve this? How do we explain the difference between in and auto ref with (as Andrei would say) a straight face?

Yes we have a 3rd way. Because `auto ref` just doesn't cut it for most usages, and `-preview=rvaluerefparam` never worked.

You can have a look at the full discussion in the PR that introduced it (dmd#11000).
I try to summarize a few arguments in favor of it here: https://github.com/dlang/dmd/pull/11000#issuecomment-674498704

As you can see from the discussion, it's not really something that was quickly merged, but the results of months of work. So while it might seems "ridiculous" to you, I'd appreciate if you could take the time to read through the discussion, as well as taking a look at Herb Sutter's presentation which was linked.

The key takeaway from that presentation is that instead of having the users specify *how* to pass the parameter, they should specify what is the parameter's semantic. In our case, input (in), output (out), or input/output (ref).

I'm not aware of a situation where you want to use `auto ref` on a parameter without `const` (or `const` semantic), because if you intend to modify the parameter, you need to be sure whether it's `ref` or not. I'm aware some people use it for forwarding but this has its own set of problem.
October 01, 2020
On Thursday, 1 October 2020 at 17:29:56 UTC, Mathias LANG wrote:
> On Thursday, 1 October 2020 at 16:47:37 UTC, Meta wrote:
>>
>> This seems ridiculous to me. We now have ANOTHER way of asking the compiler to choose for us whether to pass by ref or by value, completely mutually exclusive of auto ref. Where was the DIP (apologies if I just didn't see it)? Did Walter approve this? How do we explain the difference between in and auto ref with (as Andrei would say) a straight face?
>
> Yes we have a 3rd way. Because `auto ref` just doesn't cut it for most usages, and `-preview=rvaluerefparam` never worked.
>
> You can have a look at the full discussion in the PR that introduced it (dmd#11000).
> I try to summarize a few arguments in favor of it here: https://github.com/dlang/dmd/pull/11000#issuecomment-674498704
>
> As you can see from the discussion, it's not really something that was quickly merged, but the results of months of work. So while it might seems "ridiculous" to you, I'd appreciate if you could take the time to read through the discussion, as well as taking a look at Herb Sutter's presentation which was linked.
>
> The key takeaway from that presentation is that instead of having the users specify *how* to pass the parameter, they should specify what is the parameter's semantic. In our case, input (in), output (out), or input/output (ref).
>
> I'm not aware of a situation where you want to use `auto ref` on a parameter without `const` (or `const` semantic), because if you intend to modify the parameter, you need to be sure whether it's `ref` or not. I'm aware some people use it for forwarding but this has its own set of problem.

I've read the discussion but skipped the presentation. All I see is Atila expressing distaste for the compiler choosing how to pass values, and no explicit sign-off from either Walter or Atila before it was merged.

My objection is not to `in`'s new behaviour (although having something that functions similarly to auto ref but in subtly different ways is not good language design, IMO). My objection is that we have a major change to a language feature, that was merged without the apparent blessing of either of the two people who are supposed to be the gatekeepers for these decisions, and without a DIP (yes, it is behind -preview, but that implies that this will eventually make it into the language proper). That is what I am calling "ridiculous". If W or A did approve it and I just wasn't aware, then I apologize and retract my objection.
October 01, 2020
On Thursday, 1 October 2020 at 18:29:14 UTC, Meta wrote:
> If W or A did approve it and I just wasn't aware, then I apologize and retract my objection.

https://github.com/dlang/dmd/pull/11000#issuecomment-675605193