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