DIP23 draft: Fixing properties redux

kenji hara k.hara.pg at gmail.com
Sun Feb 3 04:37:25 PST 2013


2013/2/3 Andrei Alexandrescu <SeeWebsiteForEmail at erdani.org>

> Walter and I have had a discussion on how to finalize properties.
>
> http://wiki.dlang.org/DIP23


Awesome!!

After reading it, I thought that there is some consistent rules.

1. When a function is annotated with @property, it cannot be called with
parenthesis syntax.
2. 0-arg functions which not annotated with @property can be called without
parentheses.
3. Ref return getter can make "auxiliary setter", if formal getter is
missing.
4. `typeof(exp)` never returns "function type". In other words, the actual
type of `exp` and `typeof(exp)` should be same.
5. Both `&prop` and `&func` should return function pointer / delegate object
6. UFCS CAN NOT call global setter by getter syntax.

I think that 4 to 6 are important points of this DIP. Based on the rules, I
could write an exhaustive test case.

alias Type = int;

unittest
{
    struct S
    {
        @property Type foo();       // formal getter
        @property void bar(Type);   // formal setter
        @property ref Type baz();   // ref return getter == auxiliary setter
    }
    S s;
    static assert( __traits(compiles, { s.foo;     }));
    static assert(!__traits(compiles, { s.foo();   }));
    static assert(is(typeof(s.foo) == Type));
    static assert(is(typeof(&s.foo) == Type delegate()));

    static assert( __traits(compiles, { s.bar = 1; }));
    static assert(!__traits(compiles, { s.bar(1);  }));
    static assert(is(typeof(s.bar)) == false);
    static assert(is(typeof(&s.bar) == void delegate(Type)));

    static assert( __traits(compiles, { s.baz;     }));
    static assert(!__traits(compiles, { s.baz();   }));
    static assert( __traits(compiles, { s.baz = 1; }));
    static assert(is(typeof(s.baz) == Type));
    static assert(is(typeof(&s.foo) == ref Type delegate()));
}
unittest
{
    struct S
    {
        Type foo();         // 0-arg function
        void bar(Type n);   // 1-arg function
        ref Type baz();     // 0-arg ref return function
    }
    S s;
    static assert( __traits(compiles, { s.foo;     }));
    static assert( __traits(compiles, { s.foo();   }));
    static assert(is(typeof(s.foo) == Type));
    static assert(is(typeof(&s.foo) == Type delegate()));

    static assert(!__traits(compiles, { s.bar = 1; }));
    static assert( __traits(compiles, { s.bar(1);  }));
    static assert(is(typeof(s.bar)) == false);
    static assert(is(typeof(&s.bar) == void delegate(Type)));

    static assert( __traits(compiles, { s.baz;     }));
    static assert( __traits(compiles, { s.baz = 1; }));
    static assert( __traits(compiles, { s.baz();   }));
    static assert(is(typeof(s.baz) == Type));
    static assert(is(typeof(&s.baz) == ref Type delegate()));
}

@property Type foo();
@property void bar(Type);
@property ref Type baz();

unittest
{
    static assert( __traits(compiles, { foo;     }));
    static assert(!__traits(compiles, { foo();   }));
    static assert(is(typeof(foo) == Type));
    static assert(is(typeof(&foo) == Type function()));

    static assert( __traits(compiles, { bar = 1; }));
    static assert(!__traits(compiles, { bar(1);  }));
    static assert(is(typeof(bar)) == false);
    static assert(is(typeof(&bar) == Type function()));

    static assert( __traits(compiles, { baz;       }));
    static assert(!__traits(compiles, { baz();     }));
    static assert( __traits(compiles, { baz = 1;   }));
    static assert(!__traits(compiles, { baz() = 1; }));
    static assert(is(typeof(baz) == Type));
    static assert(is(typeof(&baz) == ref Type function()));
}

@property Type foh(Type);
@property void bah(Type n, Type m);
@property ref Type bas(Type);

Type hoo(Type);
void var(Type, Type);
ref Type vaz(Type);

unittest
{
    static assert( __traits(compiles, { foh = 1; })     &&
!__traits(compiles, { hoo = 1; }));
    static assert(!__traits(compiles, { foh(1);  })     &&
 __traits(compiles, { hoo(1);  }));
    static assert(!__traits(compiles, { 1.foh;   })     &&
 __traits(compiles, { 1.hoo;   }));
    static assert(!__traits(compiles, { 1.foh(); })     &&
 __traits(compiles, { 1.hoo(); }));

    static assert(!__traits(compiles, { bah(1, 2); })   &&
 __traits(compiles, { var(1, 2); }));
    static assert( __traits(compiles, { 1.bah = 2; })   &&
!__traits(compiles, { 1.var = 2; }));
    static assert(!__traits(compiles, { 1.bah(2);  })   &&
 __traits(compiles, { 1.var(2);  }));

    static assert( __traits(compiles, { bas = 1;     }) &&
!__traits(compiles, { vaz = 1;     }));
    static assert(!__traits(compiles, { bas(1);      }) &&
 __traits(compiles, { vaz(1);      }));
    static assert(!__traits(compiles, { bas(1) = 2;  }) &&
 __traits(compiles, { vaz(1) = 2;  }));
    static assert(!__traits(compiles, { 1.bas;       }) &&
 __traits(compiles, { 1.vaz;       }));
    static assert(!__traits(compiles, { 1.bas = 2;   }) &&
 __traits(compiles, { 1.vaz = 2;   }));
    static assert(!__traits(compiles, { 1.bas();     }) &&
 __traits(compiles, { 1.vaz();     }));
    static assert(!__traits(compiles, { 1.bas() = 2; }) &&
 __traits(compiles, { 1.vaz() = 2; }));
}

Is this correct?

Kenji Hara
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20130203/9133bbba/attachment-0001.html>


More information about the Digitalmars-d mailing list