<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>