On Sunday, 14 December 2014 at 00:45:06 UTC, Manu via
Digitalmars-d wrote:
Perhaps scope and RC are different things?
Solve scope purely for RC, and you've broken scope for other
purposes
that it's useful; that is, inhibiting escaping of data.
Exactly. It shouldn't matter which type this data has - both
references and value types are valid. I would define `scope` like
this:
"A value designated with `scope` may not be assigned to a
variable (or parameter, ...) with a lifetime longer than its
owner's lifetime."
Maybe there's a compromise. If we say scope isn't
'transitive', but it
is transitive when it comes to aggregates?
One thing I've tried very hard to make work in D is have basic
types /
aggregages / arrays be interchangeable.
It should only be applicable to whatever is explicitly marked as
`scope`. For references, that's the reference itself, but not
what it points to. For aggregates, it's the entire aggregate with
all it's members. That way, all types will be treated uniformly.
Of course, this can only work with a type modifier, not with a
storage class.
I'm looking for ways to make scope fit your proposed mould and
be useful to me.
If I can't do this then my most common use case is unsatisfied:
struct Wrap
{
OpaqueThing *ptr;
this() {}
~this() {} // <- constructors that twiddle RC effectively.
this(this) {}
this() scope {}
~this() scope {} // <- Overloadable for 'scope', in which
case,
don't twiddle the RC!
this(this) scope {}
// lots of operations on OpaqueThing wrapped up here...
}
void f(scope Wrap x) <-- RC twiddling is effectively elided
here due
to constructor overloads
{
}
If you can propose an alternative solution?
This is representative of my 99% case. Sometimes the struct is
more
than a single pointer though.
Unfortunately Walter rejected this when I had proposed it.
In the current proposal, we cannot overload on scope. The
proposed solution is to not "borrow" the wrapper, but only its
payload.
But this is restrictive; even in the case of RC, there are
use-cases that cannot be served with this technique, namely when
the callee can only decide at runtime whether it wants to make a
copy of an RC value it received. The correct solution would be to
pass the RC wrapper itself as scope, as you show in your example,
thereby delegating the decision of whether to adjust the refcount
from the caller to the callee.