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.

Reply via email to