DIP69 - Implement scope for escape proof references

via Digitalmars-d digitalmars-d at puremagic.com
Fri Dec 12 04:18:49 PST 2014


On Friday, 12 December 2014 at 08:42:22 UTC, Manu via 
Digitalmars-d wrote:
> On 11 December 2014 at 23:55, via Digitalmars-d
> <digitalmars-d at puremagic.com> wrote:
>> This is a point that most people don't seem to understand yet, 
>> and which
>> wasn't obvious for me either, at the beginning:
>>
>> * A `ref` parameter means that it cannot escape the function, 
>> _except_ by
>> return.
>> * A `scope ref` parameter means that it cannot escape the 
>> function  _ever_,
>> not even by return.
>> * A `scope ref` return means that it cannot leave the current 
>> statement.
>>
>> Therefore, a `scope ref` return value can be passed on to the 
>> next function
>> as a `ref` argument. If that function again returns a 
>> reference (even if not
>> explicitly designated as `scope`), the compiler will treat it 
>> as if it were
>> `scope ref`.
>
> Ummm. I reckon there's a good reason that people don't seem to
> understand this... because it would have difficulty being any 
> more
> unintuitive!
> It's contrary to the behaviour of basically everything else in 
> D!
> const, pure, nothrow, etc... they all work a reliable and 
> consistent way.

Unfortunately I have to agree.

>
> Also, I still don't think I get it... a scope-ref return, which 
> has a
> restriction as you say, can be subverted by being piped through 
> a
> function that receives and returns it as ref?
> What is the point?

It cannot be subverted. As soon as you pass something into a 
function G() as `ref` that's been returned from a function F() 
via `scope ref`, the compiler needs to treat what is returned 
from G() as `scope ref`, even if it's only declared as `ref`.

As you say, it's unintuitive and non-obvious.

>
>>> I'm also quite uneasy with the fact that scope would not be 
>>> transitive
>>> as a storage class. What happens when it's applied to a value 
>>> type,
>>> like a struct, that contains some pointers? An adaptation 
>>> wrapper for
>>> a single pointer is super common; ie, a tiny struct passed by 
>>> value
>>> with scope needs to have it's contained pointer receive the 
>>> scope-ness
>>> of the argument.
>>
>>
>> I agree, this is important. In my proposal, this works without 
>> transitivity.
>> The wrapper stores the pointer as a `scope` member, then by 
>> copying the
>> wrapper, the pointer gets copied implicitly, to which the 
>> normal scope
>> restrictions apply (`scope` on members means "will not outlive 
>> the
>> aggregate"). If it stored it as normal non-scope pointer, it 
>> couldn't get
>> assigned in the first place. (Additionally, some higher level 
>> tricks are
>> possible if we allow scope for value types and overloading on 
>> scope.)
>
> How can a member be marked scope? Apparently it's a storage 
> class, not
> a type constructor... we can only attribute storage classes to
> function args/results(?).

I was talking about my proposal here, where it's a type modifier, 
not a storage class.

deadalnix also brought up the problem of transitivity. This, too, 
would simply go away if it's a type modifier.


More information about the Digitalmars-d mailing list