<div dir="ltr">2013/2/3 Andrei Alexandrescu <span dir="ltr"><<a href="mailto:SeeWebsiteForEmail@erdani.org" target="_blank">SeeWebsiteForEmail@erdani.org</a>></span><br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Walter and I have had a discussion on how to finalize properties.<br>
<br>
<a href="http://wiki.dlang.org/DIP23" target="_blank">http://wiki.dlang.org/DIP23</a></blockquote><div><br></div><div style>Awesome!!</div><div style><br></div><div style>After reading it, I thought that there is some consistent rules.</div>
<div style><br></div><div style><div>1. When a function is annotated with @property, it cannot be called with parenthesis syntax.</div><div>2. 0-arg functions which not annotated with @property can be called without parentheses.</div>
<div>3. Ref return getter can make "auxiliary setter", if formal getter is missing.</div><div>4. `typeof(exp)` never returns "function type". In other words, the actual type of `exp` and `typeof(exp)` should be same.</div>
<div>5. Both `&prop` and `&func` should return function pointer / delegate object</div><div>6. UFCS CAN NOT call global setter by getter syntax.</div><div><br></div><div style>I think that 4 to 6 are important points of this DIP. Based on the rules, I could write an exhaustive test case.</div>
<div style><br></div><div style><div>alias Type = int;</div><div><br></div><div>unittest</div><div>{</div><div> struct S</div><div> {</div><div> @property Type foo(); // formal getter</div><div> @property void bar(Type); // formal setter</div>
<div> @property ref Type baz(); // ref return getter == auxiliary setter</div><div> }</div><div> S s;</div><div> static assert( __traits(compiles, { s.foo; }));</div><div> static assert(!__traits(compiles, { s.foo(); }));</div>
<div> static assert(is(typeof(s.foo) == Type));</div><div> static assert(is(typeof(&s.foo) == Type delegate()));</div><div><br></div><div> static assert( __traits(compiles, { s.bar = 1; }));</div><div> static assert(!__traits(compiles, { s.bar(1); }));</div>
<div> static assert(is(typeof(s.bar)) == false);</div><div> static assert(is(typeof(&s.bar) == void delegate(Type)));</div><div><br></div><div> static assert( __traits(compiles, { s.baz; }));</div><div> static assert(!__traits(compiles, { s.baz(); }));</div>
<div> static assert( __traits(compiles, { s.baz = 1; }));</div><div> static assert(is(typeof(s.baz) == Type));</div><div> static assert(is(typeof(&s.foo) == ref Type delegate()));</div><div>}</div><div>unittest</div>
<div>{</div><div> struct S</div><div> {</div><div> Type foo(); // 0-arg function</div><div> void bar(Type n); // 1-arg function</div><div> ref Type baz(); // 0-arg ref return function</div>
<div> }</div><div> S s;</div><div> static assert( __traits(compiles, { s.foo; }));</div><div> static assert( __traits(compiles, { s.foo(); }));</div><div> static assert(is(typeof(s.foo) == Type));</div>
<div> static assert(is(typeof(&s.foo) == Type delegate()));</div><div><br></div><div> static assert(!__traits(compiles, { s.bar = 1; }));</div><div> static assert( __traits(compiles, { s.bar(1); }));</div><div>
static assert(is(typeof(s.bar)) == false);</div><div> static assert(is(typeof(&s.bar) == void delegate(Type)));</div><div><br></div><div> static assert( __traits(compiles, { s.baz; }));</div><div> static assert( __traits(compiles, { s.baz = 1; }));</div>
<div> static assert( __traits(compiles, { s.baz(); }));</div><div> static assert(is(typeof(s.baz) == Type));</div><div> static assert(is(typeof(&s.baz) == ref Type delegate()));</div><div>}</div><div><br></div>
<div>@property Type foo();</div><div>@property void bar(Type);</div><div>@property ref Type baz();</div><div><br></div><div>unittest</div><div>{</div><div> static assert( __traits(compiles, { foo; }));</div><div> static assert(!__traits(compiles, { foo(); }));</div>
<div> static assert(is(typeof(foo) == Type));</div><div> static assert(is(typeof(&foo) == Type function()));</div><div><br></div><div> static assert( __traits(compiles, { bar = 1; }));</div><div> static assert(!__traits(compiles, { bar(1); }));</div>
<div> static assert(is(typeof(bar)) == false);</div><div> static assert(is(typeof(&bar) == Type function()));</div><div><br></div><div> static assert( __traits(compiles, { baz; }));</div><div> static assert(!__traits(compiles, { baz(); }));</div>
<div> static assert( __traits(compiles, { baz = 1; }));</div><div> static assert(!__traits(compiles, { baz() = 1; }));</div><div> static assert(is(typeof(baz) == Type));</div><div> static assert(is(typeof(&baz) == ref Type function()));</div>
<div>}</div><div><br></div><div>@property Type foh(Type);</div><div>@property void bah(Type n, Type m);</div><div>@property ref Type bas(Type);</div><div><br></div><div>Type hoo(Type);</div><div>void var(Type, Type);</div>
<div>ref Type vaz(Type);</div><div><br></div><div>unittest</div><div>{</div><div> static assert( __traits(compiles, { foh = 1; }) && !__traits(compiles, { hoo = 1; }));</div><div> static assert(!__traits(compiles, { foh(1); }) && __traits(compiles, { hoo(1); }));</div>
<div> static assert(!__traits(compiles, { 1.foh; }) && __traits(compiles, { 1.hoo; }));</div><div> static assert(!__traits(compiles, { 1.foh(); }) && __traits(compiles, { 1.hoo(); }));</div>
<div><br></div><div> static assert(!__traits(compiles, { bah(1, 2); }) && __traits(compiles, { var(1, 2); }));</div><div> static assert( __traits(compiles, { 1.bah = 2; }) && !__traits(compiles, { 1.var = 2; }));</div>
<div> static assert(!__traits(compiles, { 1.bah(2); }) && __traits(compiles, { 1.var(2); }));</div><div><br></div><div> static assert( __traits(compiles, { bas = 1; }) && !__traits(compiles, { vaz = 1; }));</div>
<div> static assert(!__traits(compiles, { bas(1); }) && __traits(compiles, { vaz(1); }));</div><div> static assert(!__traits(compiles, { bas(1) = 2; }) && __traits(compiles, { vaz(1) = 2; }));</div>
<div> static assert(!__traits(compiles, { 1.bas; }) && __traits(compiles, { 1.vaz; }));</div><div> static assert(!__traits(compiles, { 1.bas = 2; }) && __traits(compiles, { 1.vaz = 2; }));</div>
<div> static assert(!__traits(compiles, { 1.bas(); }) && __traits(compiles, { 1.vaz(); }));</div><div> static assert(!__traits(compiles, { 1.bas() = 2; }) && __traits(compiles, { 1.vaz() = 2; }));</div>
<div>}</div><div><br></div><div style>Is this correct?</div><div style><br></div><div style>Kenji Hara</div></div></div></div></div></div>