April 21, 2013
On 04/21/2013 06:27 AM, Zach the Mystic wrote:
> ...
> Yeah, that's kind of what I meant when I said it's a two-for-one deal.
> You get to pass temps, and you get safety checking too.

I prefer to buy separate products separately.
April 21, 2013
On 22 April 2013 03:39, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 04/21/2013 02:51 AM, Manu wrote:
>
>> On 21 April 2013 06:51, Timon Gehr <timon.gehr@gmx.ch <mailto:timon.gehr@gmx.ch>> wrote:
>>
>>     On 04/20/2013 05:56 PM, Dicebot wrote:
>>
>>         You miss quite an important point - DIP36 does not add new
>>         feature. It
>>         partially defines existing feature (scope) to replace an
>>         existing but
>>         broken solution (auto ref). Nothing new is really added to the
>>         language,
>>         only existing stuff better defined.
>>
>>
>>     _New meaning_ is assigned to existing grammar whose original purpose
>>     is at most loosely related to the _new_ features.
>>
>>     I do not think that making 'scope' indicate an rvalue reference is
>>     particularly future proof.
>>
>>
>> That's not what scope does. Scope promises that the variables will not escape the scope.
>>
>
> That is the intention, but this formulation is awfully imprecise. Hence nothing has been implemented.
>
> void foo(scope ref int x){ ... }
> void foo(scope int* x){ ... }
> void foo(scope ref int* x){ ... }
>

What's the problem here?


// ???
>
> struct S{
>     scope S* x; // ???
> }
>

I don't think scope on a struct member makes a lot of sense.
scope on a local variable declaration makes sense though, it would be able
to be assigned from another scope variable.
Although I would say the same about ref on a local variable declaration,
which is disallowed for completely unknown reasons.


 And as such, just happens to make passing a temporary
>> by ref safe.
>> ...
>>
>
> But this is not about safety! Passing an rvalue by ref is disallowed even in @system code. Hence 'scope' is assigned a meaning different from its intention. The DIP also aims to add more special behaviour to built-in literals.
>

Passing an r-value by ref is disallowed for arbitrary reasons. It can
easily create a temporary on the spot, but it doesn't, because it's not
considered good form to pass a temp to a function by ref.
This offers the possibility to pass a temp safely, and consequently, the
compiler may generate the temp for you.

Explain to me what meaning 'scope' has been assigned that is different from it's intention? And what 'special behaviour'?

I honestly can't understand the objections, by you or deadalnix. Can someone actually explain the problem clearly?


April 21, 2013
On 22 April 2013 04:23, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 04/21/2013 06:27 AM, Zach the Mystic wrote:
>
>> ...
>>
>> Yeah, that's kind of what I meant when I said it's a two-for-one deal. You get to pass temps, and you get safety checking too.
>>
>
> I prefer to buy separate products separately.
>

I'm confused, what 2 products are you getting? Which of said products do you actually object to?


April 21, 2013
On 04/21/2013 10:38 PM, Manu wrote:
> ...
>
>         That's not what scope does. Scope promises that the variables
>         will not
>         escape the scope.
>
>
>     That is the intention, but this formulation is awfully imprecise.
>     Hence nothing has been implemented.
>
>     void foo(scope ref int x){ ... }
>     void foo(scope int* x){ ... }
>     void foo(scope ref int* x){ ... }
>
>
> What's the problem here?
>

What does 'scope' bind to? How to make it bind to something else (if at all)?

Does the proposal lock down 'scope' to always refer to every single pointer in the argument?

>
>     // ???
>
>     struct S{
>          scope S* x; // ???
>     }
>
>
> I don't think scope on a struct member makes a lot of sense.

void main()@safe{
    S s;
    auto t = S(&t);
}

> scope on a local variable declaration makes sense though, it would be
> able to be assigned from another scope variable.

'scope' shouldn't restrict the abstraction capability of structs.

> Although I would say the same about ref on a local variable declaration,
> which is disallowed for completely unknown reasons.
>
>
>         And as such, just happens to make passing a temporary
>         by ref safe.
>         ...
>
>
>     But this is not about safety! Passing an rvalue by ref is disallowed
>     even in @system code. Hence 'scope' is assigned a meaning different
>     from its intention. The DIP also aims to add more special behaviour
>     to built-in literals.
>
>
> Passing an r-value by ref is disallowed for arbitrary reasons.

Reasons not closely related to lack of 'scope'. So why bind the new rule to scope?

> It can easily create a temporary on the spot, but it doesn't, because it's not
> considered good form to pass a temp to a function by ref.  ...

Yet this is what everyone appears to want to do.

> Explain to me what meaning 'scope' has been assigned that is different
> from it's intention?

Implicit binding of (some) rvalues to ref.

> And what 'special behaviour'?
>

If I read the ambiguous wording of the proposal correctly, the following code will be disallowed:

void foo1(scope ref int x) { }

void main(){
    foo1(1); // error
}

But this will be fine:

void foo1(scope ref int x) { }
int bar(){ return 1; }

void main(){
    foo1(bar());
}

> I honestly can't understand the objections, by you or deadalnix. Can
> someone actually explain the problem clearly?

Having a lot of ad-hoc programming language rules leads to a clumsy design. Eg. see the evolution of C++.
April 21, 2013
On Sunday, 21 April 2013 at 22:16:14 UTC, Timon Gehr wrote:
> What does 'scope' bind to? How to make it bind to something else (if at all)?

I agree this is an issue. We need to enumerate the use cases. Is 'scope' transitive or does it only apply to the first thing it hits?

>> Passing an r-value by ref is disallowed for arbitrary reasons.
>
> Reasons not closely related to lack of 'scope'. So why bind the new rule to scope?

I think that it's possible to consider binding it as a convenient benefit of what 'scope' is generally meant to do anyway. I think the crossover of the two features is quite high. But it is a judgment call. Sometimes you may want to allow rvalue refs without prohibiting escaping them, or prohibit escaping them without allowing rvalues refs. But the point of 'scope' is that it safely takes stack references, which is exactly what rvalue temps are.

Maybe getting the two features separate is good, but since it will require another parameter attribute, it suggests a need for increased reliance on attribute inference to spare the programmer the trouble. The main reason to consider combining is that it saves on syntax.

> If I read the ambiguous wording of the proposal correctly, the following code will be disallowed:
>
> void foo1(scope ref int x) { }
>
> void main(){
>     foo1(1); // error
> }

My impression is that this would be allowed, not disallowed.

> But this will be fine:
>
> void foo1(scope ref int x) { }
> int bar(){ return 1; }
>
> void main(){
>     foo1(bar());
> }

I think this would also be allowed.
April 22, 2013
>> If I read the ambiguous wording of the proposal correctly, the following code will be disallowed:
>>
>> void foo1(scope ref int x) { }
>>
>> void main(){
>>    foo1(1); // error
>> }
>
> My impression is that this would be allowed, not disallowed.
>
>> But this will be fine:
>>
>> void foo1(scope ref int x) { }
>> int bar(){ return 1; }
>>
>> void main(){
>>    foo1(bar());
>> }
>
> I think this would also be allowed.

Yes, both cases are allowed. Dicebot initially wanted that scope ref does not accept literals (only in ref should this do), but Kenji has convinced him that this is unnecessary.
In the current pull of Kenji both cases works fine.
I also have taken the time and added the overload rules to the DIP.
April 22, 2013
I realise I'm new here but this seems to be suggesting a whole load of changes and special cases for something that can be done in (IMHO) a much simpler way:

Why not simply make escaping a "ref" pointer an unsafe operation. The compiler should be able to detect this and report it without any changes to the syntax.

This should cover 99% of cases with no extra attributes required and no limitations on what you can do with a "ref" within the function. In the 1% of cases that a pointer needs to be escaped safely you can add an attribute (maybe "heap ref" or something, although perhaps some existing syntax could be used) that requires the input to have been allocated on the heap.

In the case that a stack variable is passed as a "heap ref" parameter the compiler can automatically promote it where possible, or if that's not possible, such as the variable being marked "scope" (existing meaning) then it should complain.

All values (including literals and temporaries) should then be able to be passed to a "ref const" parameter.

As far as I'm aware the only real purpose for R-value references is to implement move semantics. This could already be done using "ref in" syntax, as that makes no guarantees that the value is not going to be destroyed, only says that the value should be initialised prior to it being passed in. The only change would be to allow passing temporaries as "ref in".

To promise that the variable is not going to be modified "ref const" or "ref const in" can be used.

April 22, 2013
On Monday, 22 April 2013 at 12:22:14 UTC, Diggory wrote:
> I realise I'm new here but this seems to be suggesting a whole load of changes and special cases for something that can be done in (IMHO) a much simpler way:
>
> Why not simply make escaping a "ref" pointer an unsafe operation. The compiler should be able to detect this and report it without any changes to the syntax.
>
> This should cover 99% of cases with no extra attributes required and no limitations on what you can do with a "ref" within the function. In the 1% of cases that a pointer needs to be escaped safely you can add an attribute (maybe "heap ref" or something, although perhaps some existing syntax could be used) that requires the input to have been allocated on the heap.
>
> In the case that a stack variable is passed as a "heap ref" parameter the compiler can automatically promote it where possible, or if that's not possible, such as the variable being marked "scope" (existing meaning) then it should complain.
>
> All values (including literals and temporaries) should then be able to be passed to a "ref const" parameter.
>
> As far as I'm aware the only real purpose for R-value references is to implement move semantics. This could already be done using "ref in" syntax, as that makes no guarantees that the value is not going to be destroyed, only says that the value should be initialised prior to it being passed in. The only change would be to allow passing temporaries as "ref in".
>
> To promise that the variable is not going to be modified "ref const" or "ref const in" can be used.

This DIP already suggest 'in ref' besides 'scope ref'. 'in' is a shortcut for const scope.
And Andrei already reject variants which _only_ consist of non-mutable rvalue ref's (like const ref), because the const system in D is physical.
But this could be read on the wiki. You should read the DIP before you write here. ;)

April 22, 2013
On Monday, 22 April 2013 at 13:17:36 UTC, Namespace wrote:
> On Monday, 22 April 2013 at 12:22:14 UTC, Diggory wrote:
>> I realise I'm new here but this seems to be suggesting a whole load of changes and special cases for something that can be done in (IMHO) a much simpler way:
>>
>> Why not simply make escaping a "ref" pointer an unsafe operation. The compiler should be able to detect this and report it without any changes to the syntax.
>>
>> This should cover 99% of cases with no extra attributes required and no limitations on what you can do with a "ref" within the function. In the 1% of cases that a pointer needs to be escaped safely you can add an attribute (maybe "heap ref" or something, although perhaps some existing syntax could be used) that requires the input to have been allocated on the heap.
>>
>> In the case that a stack variable is passed as a "heap ref" parameter the compiler can automatically promote it where possible, or if that's not possible, such as the variable being marked "scope" (existing meaning) then it should complain.
>>
>> All values (including literals and temporaries) should then be able to be passed to a "ref const" parameter.
>>
>> As far as I'm aware the only real purpose for R-value references is to implement move semantics. This could already be done using "ref in" syntax, as that makes no guarantees that the value is not going to be destroyed, only says that the value should be initialised prior to it being passed in. The only change would be to allow passing temporaries as "ref in".
>>
>> To promise that the variable is not going to be modified "ref const" or "ref const in" can be used.
>
> This DIP already suggest 'in ref' besides 'scope ref'. 'in' is a shortcut for const scope.
> And Andrei already reject variants which _only_ consist of non-mutable rvalue ref's (like const ref), because the const system in D is physical.

The definition was somewhat hidden in the language reference and the first reference I found on the forum said that "in" simply meant that the value should be initialised by the caller (in the same way that "out" means that the callee initialises the value).

> But this could be read on the wiki. You should read the DIP before you write here. ;)

I have but the DIP isn't consistent, for example in test1 it says R-value temporaries are allowed:
> void test1(scope ref A a)

And in test32 it says they are not "Only adressable parameters are valid, not temporaries, no extra template instances.":
> void test32(T)(scope ref T id)

And then:
> test32(1337); // Fine, temporary mutable int variable is created with value 1337

Some other problems:
- Taking the address of a "scope ref" variable is prohibited even if the compiler can prove that it's safe.
- Implementing "forward" in the following is impossible:
doSomething(forward(<temporary/literal>))
Obviously a function that simply returns what is passed in seems pointless but it may be very useful if sometimes that function should do something else.

All the restrictions on "scope ref" are exactly the same as the restrictions on "ref" if DIP25 is implemented, except that "scope ref" variables can't be returned (why is this the case when by following the same rules as DIP25 it can be safe?)

In which case why not allow passing R-value references as normal "ref" parameters? Why the need for "scope" when the only new restriction it introduces can (and should) be avoided.

DIP25 says that the return value of a ref function must not be assumed to have a lifetime longer than the shortest lifetime of any of its ref parameters. This formulation works just as well for an R-value reference as it does for a reference to a local variable, just that the first is slightly shorter.
April 22, 2013
> I have but the DIP isn't consistent
I must have overlooked this all the time. I will clean up this inconsistency.
The statement that only adressable elements are taken by scope ref is not true anymore. Both, scope ref and in ref can take any values. If it is an rvalue, a temporary is created and this is passed to the function.
Thanks for the hint.

> In which case why not allow passing R-value references as normal "ref" parameters? Why the need for "scope" when the only new restriction it introduces can (and should) be avoided.

> DIP25 says that the return value of a ref function must not be assumed to have a lifetime longer than the shortest lifetime of any of its ref parameters. This formulation works just as well for an R-value reference as it does for a reference to a local variable, just that the first is slightly shorter.

You should search for "rvalue references". 'ref' that takes both, lvalues and revalues was suggested and AFAIK rejected.
Otherwise you could open a new DIP or first a thread and ask for this. I'm curious of the answers.
This issue is very old (Exactly one year ago it was officially discussed for the first time). But the core problem exist since 2.038. There was 'auto ref' introduced. This was the first attempt to solve this problem. Long long time ago and it annoys us still today.