On Monday, 22 December 2014 at 20:51:46 UTC, Walter Bright wrote:
On 12/22/2014 12:04 AM, Dicebot wrote:
Point of transitive scope is to make easy to expose complex
custom data
structures without breaking memory safety.
I do understand that. Making it work with the type system is
another matter entirely - it's far more complex than just
adding a qualifier. 'inout' looks simple but still has ongoing
issues.
And the thing is, wrappers can be used instead of qualifiers,
in the same places in the same way. It's much simpler.
Ok, lets consider some examples of code I'd want to work with
wrapper approach.
Basic tree structure:
struct Node
{
Node* left, right;
Payload payload;
}
struct Tree
{
Node* root;
}
Restricting public access to nodes to prevent storing persistent
node pointers.
Your proposed approach:
struct Wrapper(T)
{
scope T wrapped;
alias wrapped this;
}
struct Node
{
private:
Node* _left, _right;
public:
auto left() @property { return Wrapper!(Node*)(_left); }
auto right() @property { return Wrapper!(Node*)(_right); }
Payload payload;
}
struct Tree
{
private:
Node* _root;
public:
auto root() @property { return Wrapper!(Node*)(_root); }
}
Am I correct?
If yes, this is exactly the breakage issue I was speaking about :
any code that looked like `is(typeof(Tree.root) == Node*)` will
stop working.
With my latest proposal (pseudo-transitive storage class which is
not part of a type) getters would look simply like `scope Node*
root() @property { return _root; }` and `is(typeof(Tree.root) ==
Node*)` still remained true. Only impact on existing would be
restriction of operations to take address or assign a pointer.
I am pretty sure I am missing many complicated parts here but
this seems like a big deal in retro-fitting existing libraries to
use scope after it was added.