August 15, 2016
On Monday, 15 August 2016 at 07:19:00 UTC, lobo wrote:
> On Monday, 15 August 2016 at 07:10:00 UTC, ZombineDev wrote:
>> On Monday, 15 August 2016 at 04:56:07 UTC, Joseph Rushton Wakeling wrote:
>>> On Sunday, 14 August 2016 at 10:11:25 UTC, Guillaume Chatelet wrote:
>>>> Isn't it what a scoped class is supposed to provide?
>>>>
>>>> class Rnd {}
>>>>
>>>> void foo() {
>>>>   scope rnd  = new Rnd; // reference semantic and stack allocated
>>>> }
>>>
>>> Does that actually work in D2? I thought it was a D1-only thing.
>>
>> Yes, but for some unknown to me reason it was deprecated (or it will be in the future) in favour of std.typecons.scoped. Actually, it is used in many places throughout DDMD, so I don't think its going away soon.
>
> When was it deprecated? I use it a lot and DMD 2.071.1 gives no warning.
>
> bye,
> lobo

It's not deprecated, but it will be, at least according to this page: http://dlang.org/deprecate. (Search for "scope for allocating classes on the stack".)
August 15, 2016
On Monday, 15 August 2016 at 07:19:00 UTC, lobo wrote:
> When was it deprecated? I use it a lot and DMD 2.071.1 gives no warning.

It was planned for removal because it was very un-@safe (no escaping checks whatsoever) and as such was not better than library implementation. Quite likely with DIP1000 implemented there will be no point in deprecating it anymore.
August 15, 2016
On Monday, 15 August 2016 at 10:27:00 UTC, Dicebot wrote:
> On Monday, 15 August 2016 at 07:19:00 UTC, lobo wrote:
>> When was it deprecated? I use it a lot and DMD 2.071.1 gives no warning.
>
> It was planned for removal because it was very un-@safe (no escaping checks whatsoever) and as such was not better than library implementation.

I suspected as much.

> Quite likely with DIP1000 implemented there will be no point in deprecating it anymore.

+1 I think that would be great!


August 15, 2016
On Mon, Aug 15, 2016 at 1:57 PM, ZombineDev via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote:

> On Monday, 15 August 2016 at 10:27:00 UTC, Dicebot wrote:
>
>> On Monday, 15 August 2016 at 07:19:00 UTC, lobo wrote:
>>
>>> When was it deprecated? I use it a lot and DMD 2.071.1 gives no warning.
>>>
>>
>> It was planned for removal because it was very un-@safe (no escaping checks whatsoever) and as such was not better than library implementation.
>>
>
import std.stdio;

class Rnd {
this() {
writeln("created");
}
~this() {
writeln("destroyed");
}

int i;
}

auto test() {
scope rnd  = new Rnd; // reference semantic and stack allocated
auto rnd2 = rnd;

rnd.i = 2;
assert(rnd2.i == 2);
return rnd2;
}

void main() {
writeln("start test");
auto v = test();
writeln("test exited", v);
}

Output:
start test
created
destroyed
segmentation fault (core dumped)  rdmd scoped_ref_class_semantics.d



> I suspected as much.
>
> Quite likely with DIP1000 implemented there will be no point in
>> deprecating it anymore.
>>
>
> +1 I think that would be great!
>
>
>
The above example should not compile after DIP1000? If so that will be great!


August 15, 2016
On 08/15/2016 03:41 PM, Rory McGuire via Digitalmars-d-announce wrote:
> scope rnd  = new Rnd; // reference semantic and stack allocated auto rnd2 = rnd;
> 
> rnd.i = 2;
> assert(rnd2.i == 2);
> return rnd2;

Point is that that would become illegal if DIP1000 is implemented thus giving scope class concept more justification. It would still have @safe holes though because proposed `scope` does not work through many indirection levels - but better than existing situation when nothing is checked.



August 15, 2016
On Mon, Aug 15, 2016 at 2:49 PM, Dicebot via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote:

> On 08/15/2016 03:41 PM, Rory McGuire via Digitalmars-d-announce wrote:
> > scope rnd  = new Rnd; // reference semantic and stack allocated auto rnd2 = rnd;
> >
> > rnd.i = 2;
> > assert(rnd2.i == 2);
> > return rnd2;
>
> Point is that that would become illegal if DIP1000 is implemented thus giving scope class concept more justification. It would still have @safe holes though because proposed `scope` does not work through many indirection levels - but better than existing situation when nothing is checked.
>
>
okay nice, so that code would not compile but code such as:
void test() {
scope rnd  = new Rnd; // reference semantic and stack allocated
auto rnd2 = rnd;
        some_sneaky_function_that_saves_global_state(rnd);
}
would still not be checked. And would crash inexplicably at the point the
global was accessed?


August 15, 2016
On 08/15/2016 04:54 PM, Rory McGuire via Digitalmars-d-announce wrote:
> okay nice, so that code would not compile but code such as:
> void test() {
> scope rnd  = new Rnd; // reference semantic and stack allocated
> auto rnd2 = rnd;
>         some_sneaky_function_that_saves_global_state(rnd);
> }
> would still not be checked. And would crash inexplicably at the point
> the global was accessed?

some_sneaky_function_that_saves_global_state would have to be declared as `some_sneaky_function_that_saves_global_state(scope Rnd rnd)` to be allowed to use rnd as argument which prevents escaping to globals.

What would still be the problem is if `Rnd` contains reference to another class internally (which gets manually destroyed when Rnd is destroyed) and `some_sneaky_function_that_saves_global_state` saves it instead - because by current design `scope` is a storage class and not transitive.



August 15, 2016
On Mon, Aug 15, 2016 at 4:05 PM, Dicebot via Digitalmars-d-announce < digitalmars-d-announce@puremagic.com> wrote:

> On 08/15/2016 04:54 PM, Rory McGuire via Digitalmars-d-announce wrote:
> > okay nice, so that code would not compile but code such as:
> > void test() {
> > scope rnd  = new Rnd; // reference semantic and stack allocated
> > auto rnd2 = rnd;
> >         some_sneaky_function_that_saves_global_state(rnd);
> > }
> > would still not be checked. And would crash inexplicably at the point
> > the global was accessed?
>
> some_sneaky_function_that_saves_global_state would have to be declared as `some_sneaky_function_that_saves_global_state(scope Rnd rnd)` to be allowed to use rnd as argument which prevents escaping to globals.
>
> What would still be the problem is if `Rnd` contains reference to another class internally (which gets manually destroyed when Rnd is destroyed) and `some_sneaky_function_that_saves_global_state` saves it instead - because by current design `scope` is a storage class and not transitive.
>
>
Thanks! That is an excellent explanation. Is the below a test case for that?

import std.stdio;

class Rnd {
NormalRefSemantics inner; // protecting this is irrelevant in more complex
objects?
this() {
inner = new NormalRefSemantics();
writeln("created");
}
~this() {
delete inner;// this is what causes the segfault
writeln("destroyed");
}

int i;
}

void test() {
scope rnd  = new Rnd; // reference semantic and stack allocated
auto rnd2 = rnd;

rnd.i = 2;
assert(rnd2.i == 2);
sneaky_escape(rnd);
}

void main() {
writeln("start test");
test();
writeln("test exited", oops);
}

class NormalRefSemantics {
this() {
writeln("I'm alive");
}
~this() {
writeln("inner destruction");
}
}
NormalRefSemantics oops;
void sneaky_escape(Rnd r) {
oops = r.inner; // how can we protect this inner part of the class from
escaping?
// would we need to mark classes and functions as "scope safe"? (similar to
"thread safe")
}

==
This DIP is really interesting, reminds me of back when we were playing
around with "emplace".

R


August 15, 2016
On 8/15/2016 6:54 AM, Rory McGuire via Digitalmars-d-announce wrote:
> okay nice, so that code would not compile but code such as:
> void test() {
> scope rnd  = new Rnd; // reference semantic and stack allocated
> auto rnd2 = rnd;
>         some_sneaky_function_that_saves_global_state(rnd);
> }
> would still not be checked. And would crash inexplicably at the point the global
> was accessed?

A local variable initialized with a scoped value will have 'scope' inferred for it.
August 16, 2016
On Monday, 15 August 2016 at 21:25:22 UTC, Walter Bright wrote:
> On 8/15/2016 6:54 AM, Rory McGuire via Digitalmars-d-announce wrote:
>> okay nice, so that code would not compile but code such as:
>> void test() {
>> scope rnd  = new Rnd; // reference semantic and stack allocated
>> auto rnd2 = rnd;
>>         some_sneaky_function_that_saves_global_state(rnd);
>> }
>> would still not be checked. And would crash inexplicably at the point the global
>> was accessed?
>
> A local variable initialized with a scoped value will have 'scope' inferred for it.

What happens in that case ?

void test() {
scope rnd  = new Rnd; // reference semantic and stack allocated
Rnd rnd2;
 rnd2 = rnd;
         some_sneaky_function_that_saves_global_state(rnd);
}

or is that not even possible ? (sorry I'm still a noob in D).