On Wed, 29 Apr 2009 11:49:11 -0400, Jason House <[email protected]> wrote:
Robert Jacques Wrote:
Indeed I intend to handle more than that. The simple answer is that you
can not assign to a scope variable except at declaration. This is scope
rule 2. But this basically prevents output parameters (for exactly the
reasons you mentioned). However, I think you are referencing to the
section on the relaxation of rule two, which allows limited use of output
parameters. This relaxation works by recognizing that the head of scope
variables _must_ exist on the stack. Thus it is safe (with a few
exceptions, see scope rule 6) to swap them. However, assigning to anywhere
off the stack could result in the escape you mentioned and hence is
illegal:
scope Node ln = myLocalNode;
scope Node sn = mySharedNode;
swap(sn,ln);       // Okay, were are only swapping the local scope
references that exist on the stack
swap(sn, ln.next); // Error: Cannot take the reference of a scope tail

My gut reaction is that this is too restrictive of a limitation. If someone can't call swap(n.a, n.b) for an arbitrary non-const type n, they will complain.

I understand where you're coming from, but the whole point of having a scope type is to be a 'const' for ownership types. Just like const represents n may be immutable or mutable, scope represents n may be stack, local, shared or mobile. So I was trying to swap two objects of an arbitrary non-const type, I was trying to swap two objects of unknown and possibly different types (in this case a local and shared object, which is logically invalid). Swap is the canonical function that causes an object to escape its scope and supporting it at all is an achievement.

By the way, you can call swap(n.a, n.b) for scope n, if n.a and n.b are defined as having the same non-scope ownership type in the scope interface. for example:

class Node(T) {
    T value;
    Node(T) next;
}

has a scope interface of
{
    T value;
    Node(T) next;
}

and

shared class SL_Node(T) {
    T value;
    Node(T) next;
}

has a scope interface of
{
    T value;
    scope Node(T) next;
}

so

scope a = new Node!int();
scope b = new Node!int();
swap(a.next,b.next); // Okay, a.next and b.next are both of type local Node(int)
swap(a,b.next);      // Error, a is of type scope Node(int)

auto c = new shared Node!int(); // error, writter of Node didn't declare it multi-thread aware
scope c = new shared SL_Node!int(); // Okay
scope d = new shared SL_Node!int(); // Okay
swap(c.next,d.next); // Error, c.next and d.next are scope tails.

Hmm, need to clarify this on the wiki.

Another example

shared class E_Node(T) {
    atatic if(is(this==shared)) {
        T* value;
    } else {
        T value;
    }
    Node(T) next;
}

has a scope interface of
{
    // notice that value is missing
    scope Node(T) next;
}


Reply via email to