October 27, 2020
On Tuesday, 27 October 2020 at 16:56:40 UTC, Ola Fosheim Grøstad wrote:
> Yes, what I meant is that it is a value on the stack. But there is a disconnect with classes. "oddball" passes as a class, even though it would not pass as a struct:
>
> class A { int x; }
> class B { A a; }
>
> A oddball() {
>     scope B b = new B;
>     b.a = new A;
>     return b.a;
> }

`oddball` is neither a class nor a struct; it's a function.

If you change both `A` and `B` to structs and update the code to `A*` and `B*` where needed, then it works the same as with classes. If you change them to structs but don't use pointers, then it works differently because you're removing indirections.

> But WHY does this pass?
>
> class A { int x; }
> struct B { A a; }
>
> A misbehave() @safe {
>     scope A tmp = new A;
>     scope B b;
>     b.a = tmp;
>     return b.a;
> }

It doesn't? The last line gives "Error: scope variable `b` may not be returned". Remember to compile with `-preview=dip1000`.

[...]
> I understand. So for structs it works the same way as scope-parameters?

I'm not sure if I understand the question, but as far as I understand `scope` locals and `scope` parameters work the same for all types. (Maybe there are subtle differences in life time. Maybe there are bugs. But basically they're the same thing.)
October 27, 2020
On Tuesday, 27 October 2020 at 18:24:47 UTC, ag0aep6g wrote:
> On Tuesday, 27 October 2020 at 16:56:40 UTC, Ola Fosheim Grøstad wrote:
>> Yes, what I meant is that it is a value on the stack. But there is a disconnect with classes. "oddball" passes as a class, even though it would not pass as a struct:
>>
>> class A { int x; }
>> class B { A a; }
>>
>> A oddball() {
>>     scope B b = new B;
>>     b.a = new A;
>>     return b.a;
>> }
>
> `oddball` is neither a class nor a struct; it's a function.

Yes, obviously, but it it passes as a class.

> If you change both `A` and `B` to structs and update the code to `A*` and `B*` where needed, then it works the same as with classes.

Well, but "scope B b = new B;" will stack allocate, right? So it is allocated on the stack like a struct. I suspect a user would expect b.a to be restricted as it would have been as a struct.

But yes, I get the "one indirection" thing you mentioned. The question is, is that useful enough? Is that something users will understand?


> It doesn't? The last line gives "Error: scope variable `b` may not be returned". Remember to compile with `-preview=dip1000`.

You are right, the compile switch was missing.

> I'm not sure if I understand the question, but as far as I understand `scope` locals and `scope` parameters work the same for all types. (Maybe there are subtle differences in life

Except that "scope B b = new B" stack allocates? Or does that happen for parameters too? Does this cause stack allocation of B?

  f(scope B b){…}

  f(new B);




October 27, 2020
On Tuesday, 27 October 2020 at 18:35:40 UTC, Ola Fosheim Grøstad wrote:
> On Tuesday, 27 October 2020 at 18:24:47 UTC, ag0aep6g wrote:
>> On Tuesday, 27 October 2020 at 16:56:40 UTC, Ola Fosheim Grøstad wrote:
[...]
>>> class A { int x; }
>>> class B { A a; }
>>>
>>> A oddball() {
>>>     scope B b = new B;
>>>     b.a = new A;
>>>     return b.a;
>>> }
>>
>> `oddball` is neither a class nor a struct; it's a function.
>
> Yes, obviously, but it it passes as a class.

I didn't understand what you mean by "passing as a class". I guess you mean that it returns a class.

[...]
> Well, but "scope B b = new B;" will stack allocate, right? So it is allocated on the stack like a struct. I suspect a user would expect b.a to be restricted as it would have been as a struct.

Ok, I see your point now. I wasn't thinking about `scope` as an indicator for stack allocation at all. As far as I'm aware that's just a possible optimization, not a guarantee. And it's somewhat independent from DIP 1000's `scope`.

If it becomes more than an optimization, then yeah it might make sense to not view `scope` class variables as indirections in that case. Or maybe it wouldn't be sound. I really have no idea.

> But yes, I get the "one indirection" thing you mentioned. The question is, is that useful enough? Is that something users will understand?

It's fairly obvious to me that `scope` is not easy to understand. The buggy implementation and insufficient documentation don't help. At the same time, I am myself not interested in finding a better solution to the problem.

[...]
>> I'm not sure if I understand the question, but as far as I understand `scope` locals and `scope` parameters work the same for all types. (Maybe there are subtle differences in life
>
> Except that "scope B b = new B" stack allocates? Or does that happen for parameters too? Does this cause stack allocation of B?
>
>   f(scope B b){…}
>
>   f(new B);

I don't think so. You're right that stack allocation is a significant difference, but only if it is (or becomes) more than an optimization.
October 27, 2020
On Tuesday, 27 October 2020 at 19:13:28 UTC, ag0aep6g wrote:
> I didn't understand what you mean by "passing as a class". I guess you mean that it returns a class.

Oh, bad wording on my part. I meant "dressed up as a class".

> Ok, I see your point now. I wasn't thinking about `scope` as an indicator for stack allocation at all. As far as I'm aware that's just a possible optimization, not a guarantee.

Ah! I thought it was a feature. :-)

> It's fairly obvious to me that `scope` is not easy to understand. The buggy implementation and insufficient documentation don't help. At the same time, I am myself not interested in finding a better solution to the problem.

I think it is interesting to think about what the consequences would be if it was transitive. Basically: anything reached through this variable is scoped.

1 2
Next ›   Last »