www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Partial modification of DIP23 to allow module level property

reply "Kenji Hara" <k.hara.pg gmail.com> writes:
 http://wiki.dlang.org/DIP23

I had thought about DIP23 for a while, to allow module-level property function. As the conclusion, we can have that without breaking the essence in DIP23. ==========
 In a nutshell
 2. A  property may have EXACTLY ONE or EXACTLY TWO parameters, 
 counting the implicit this parameter if at all.
 The ONE-parameter version is ALWAYS a getter, and the 
 TWO-parameter version is ALWAYS a setter.
 There's no variadics, defaulted parameters, and such.

We should change this sentence to: ---- 2. A property may have EXACTLY ZERO or EXACTLY ONE parameter, without counting the implicit this parameter if at all. The ZERO-parameter version is ALWAYS a getter, and the ONE-parameter version is ALWAYS a setter. There's no variadics, defaulted parameters, and such. ----
 Optional parens stay in

No modification is necessary.
 No module-level properties

It should be replaced to completely: ---- * Module level properties stay in There is still module-level property emulating a global variable. That means a property defined at module level must take either ZERO parameter (meaning its a getter) or ONE parameter (meaning it's a setter). // at module level private long _distance; property long distance() { return _distance; } property void distance(double d) { assert(d >= 0); _distance = cast(long)std.math.trunc(d); } unittest { distance = 3.1; assert(_distance == 3) auto d = distance; assert(d == 3); } To avoid syntactic ambiguity, it's forbidden to define property getter callable by using UFCS. property ref int front(int[] a) { return a[0]; } unittest { int[] arr = [1,2,3]; assert(front(arr) == 1); // OK assert(arr.front == 1); // compile-time error, "setter property function cannot call with UFCS" } Instead, such 'front' function would work if remove the property annotation. ref int front(int[] a) { return a[0]; } unittest { int[] arr = [1,2,3]; assert(front(arr) == 1); // OK assert(arr.front() == 1); // OK, UFCS assert(arr.front == 1); // Even OK, UFCS + optional paranthesis feature arr.front() = 2; // assign to returned ref assert(arr[0] == 2); arr.front = 3; // Even OK, optional parenthesis assert(arr[0] == 2); int* p = &arr.front; // Even OK, arr.front is rewritten to // front(arr), so '&' operator will be applied to the ref value returned from 'front'. } For the combination of UFCS and setter syntax, a function which takes TWO parameters and defined at module level can SPECIALLY be annotated with property. property void all(double[] x, int y) { x[] = cast(double) y; } unittest { auto d = [ 1.2, 3.4 ]; d.all = 42; // UFCS + setter syntax // rewritten to: all(d, 42) assert(d == [ 42.0, 42.0 ]); } ---- Regards. Kenji Hara
Feb 08 2013
next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 09, 2013 06:15:34 Kenji Hara wrote:
 To avoid syntactic ambiguity, it's forbidden to define property
 getter callable by using UFCS.

And why is it that the global function gets to be a setter property and the UFCS function doesn't? What's the advantage in choosing the UFCS function as the one that has to be a normal function which just happens to be called without parens (but could be called with them) over choosing the global getter property to be the one that's a function that can be called without parens? I'd much rather see the global getter have to be declared without property (and rely an the ability to be called without parens but be unable to enforce it). And I _definitely_ wouldn't want to set a precedence for front to be declared as a non-property function. It needs to be consistently called without parens to work in generic code, and if arrays are able to use front with parens, then we definitely risk a lot of range-based functions being written incorrectly due to the fact that far too often, range-based functions only end up being tested with arrays, and in that case, the parens wouldn't cause an error like they should. It wouldn't be caught until someone actually tried it with another type of range (possibly much later). Granted, the writer of the range-based function should have tested it better, but given that arrays are by far the most common type of range, I think that it's just asking for trouble to allow their front or back to be used with parens. - Jonathan M Davis
Feb 08 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
--f46d04428792cbf66304d544b026
Content-Type: text/plain; charset=UTF-8

2013/2/9 Jonathan M Davis <jmdavisProg gmx.com>

 And why is it that the global function gets to be a setter property and the
 UFCS function doesn't? What's the advantage in choosing the UFCS function
 as
 the one that has to be a normal function which just happens to be called
 without parens (but could be called with them) over choosing the global
 getter
 property to be the one that's a function that can be called without parens?

To get a balance between rule simplicity and actually possible use cases. In my long thought, I have found that property annotation is not really necessary for UFCS getters (e.g. std.array.front). After the implementation of "optional paranthesis" feature which described in DIP23, a use of UFCS getter will work as same as now - using left hand side of assignment (e.g. arr.front = value) and even getting address of returned ref (auto ptr = &arr.front) . Then, we can use a property function defined in module level and has exactly one parameter as a module level setter without ambiguity. This is much reasonable benefit compared to the cost.
 I'd much rather see the global getter have to be declared without  property
 (and rely an the ability to be called without parens but be unable to
 enforce
 it).

I think it will introduce an inconsistency against method property functions, as follows: - Method property should have zero parameter for getter, or one parameter for setter. Both should be annotated with property. - Module level property should have zero parameter for getter, but MUST not be annotated with property. Module level property should have one parameter for setter and should be annotated with property. This is much complicated than my proposed sentence: 2. A property may have EXACTLY ZERO or EXACTLY ONE parameter, without counting the implicit this parameter if at all. The ZERO-parameter version is ALWAYS a getter, and the ONE-parameter version is ALWAYS a setter. There's no variadics, defaulted parameters, and such. And I _definitely_ wouldn't want to set a precedence for front to be
 declared as a non-property function. It needs to be consistently called
 without parens to work in generic code, and if arrays are able to use front
 with parens, then we definitely risk a lot of range-based functions being
 written incorrectly due to the fact that far too often, range-based
 functions
 only end up being tested with arrays, and in that case, the parens wouldn't
 cause an error like they should. It wouldn't be caught until someone
 actually
 tried it with another type of range (possibly much later). Granted, the
 writer
 of the range-based function should have tested it better, but given that
 arrays are by far the most common type of range, I think that it's just
 asking
 for trouble to allow their front or back to be used with parens.

Sorry I cannot imagine an actual use case you are considering. Kenji Hara --f46d04428792cbf66304d544b026 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">2013/2/9 Jonathan M Davis <span dir=3D"ltr">&lt;<a href=3D= "mailto:jmdavisProg gmx.com" target=3D"_blank">jmdavisProg gmx.com</a>&gt;<= /span><br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote= class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:= 1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left= :1ex"> <div class=3D"im"><span style=3D"color:rgb(34,34,34)">And why is it that th= e global function gets to be a setter property and the</span><br></div> UFCS function doesn&#39;t? What&#39;s the advantage in choosing the UFCS fu= nction as<br> the one that has to be a normal function which just happens to be called<br=

ter<br> property to be the one that&#39;s a function that can be called without par= ens?<br></blockquote><div><br></div><div>To get a balance between rule simp= licity and actually possible use cases.<br></div><div><br></div><div style> <div>In my long thought, I have found that property annotation is not real= ly necessary for UFCS getters (e.g. std.array.front).=C2=A0</div><div>After= the implementation of &quot;optional paranthesis&quot; feature which descr= ibed in DIP23, a use of UFCS getter will work as same as now - using left h= and side of assignment (e.g. arr.front =3D value) and even getting address = of returned ref (auto ptr =3D &amp;arr.front) . Then, we can use a propert= y function defined in module level and has exactly one parameter as a modul= e level setter without ambiguity. This is much reasonable benefit compared = to the cost.</div> <div>=C2=A0<br></div></div><blockquote class=3D"gmail_quote" style=3D"margi= n:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204= );border-left-style:solid;padding-left:1ex"> I&#39;d much rather see the global getter have to be declared without prop= erty<br> (and rely an the ability to be called without parens but be unable to enfor= ce<br> it).</blockquote><div><br></div><div style>I think it will introduce an inc= onsistency against method property functions, as follows:</div><div style>= <br></div><div style>- Method property should have zero parameter for gette= r, or one parameter for setter.</div> <div style>=C2=A0 Both should be annotated with property.</div><div style>= - Module level property should have zero parameter for getter, but MUST not= be annotated with property.</div><div style>=C2=A0 Module level property = should have one parameter for setter and should be annotated with property= .<br> </div><div style><br></div><div style>This is much complicated than my prop= osed sentence:</div><div>=C2=A0</div><div><span style=3D"font-family:arial,= sans-serif;font-size:14px">2. A property may have EXACTLY ZERO or EXACTLY = ONE parameter, without counting the implicit this parameter if at all.</spa= n><br style=3D"font-family:arial,sans-serif;font-size:14px"> <span style=3D"font-family:arial,sans-serif;font-size:14px">The ZERO-parame= ter version is ALWAYS a getter, and the ONE-parameter version is ALWAYS a s= etter.</span><br style=3D"font-family:arial,sans-serif;font-size:14px"><spa= n style=3D"font-family:arial,sans-serif;font-size:14px">There&#39;s no vari= adics, defaulted parameters, and such.</span><br style=3D"font-family:arial= ,sans-serif;font-size:14px"> </div><div><br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px = 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);bord= er-left-style:solid;padding-left:1ex">And I _definitely_ wouldn&#39;t want = to set a precedence for front to be<br> declared as a non-property function. It needs to be consistently called<br> without parens to work in generic code, and if arrays are able to use front= <br> with parens, then we definitely risk a lot of range-based functions being<b= r> written incorrectly due to the fact that far too often, range-based functio= ns<br> only end up being tested with arrays, and in that case, the parens wouldn&#= 39;t<br> cause an error like they should. It wouldn&#39;t be caught until someone ac= tually<br> tried it with another type of range (possibly much later). Granted, the wri= ter<br> of the range-based function should have tested it better, but given that<br=

asking<br> for trouble to allow their front or back to be used with parens.<br></block= quote><div><br></div><div style>Sorry I cannot imagine an actual use case y= ou are considering.</div><div style><br></div><div style>Kenji Hara</div> </div></div></div> --f46d04428792cbf66304d544b026--
Feb 08 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
--089e013d12c0813f7704d544c068
Content-Type: text/plain; charset=UTF-8

2013/2/9 kenji hara <k.hara.pg gmail.com>

 2013/2/9 Jonathan M Davis <jmdavisProg gmx.com>

 And I _definitely_ wouldn't want to set a precedence for front to be

 without parens to work in generic code, and if arrays are able to use
 front
 with parens, then we definitely risk a lot of range-based functions being
 written incorrectly due to the fact that far too often, range-based
 functions
 only end up being tested with arrays, and in that case, the parens
 wouldn't
 cause an error like they should. It wouldn't be caught until someone
 actually
 tried it with another type of range (possibly much later). Granted, the
 writer
 of the range-based function should have tested it better, but given that
 arrays are by far the most common type of range, I think that it's just
 asking
 for trouble to allow their front or back to be used with parens.

Sorry I cannot imagine an actual use case you are considering.

Ah... do you consider this case? import std.array : front; int delegate()[] eventHandlers; auto result = eventHandlers.front(); // want to _call_ eventHandlers[0] Indeed, under the my proposal, typeof(result) becomes `int delegate()`, not `int`. Hmmmm..... Kenji Hara --089e013d12c0813f7704d544c068 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">2013/2/9 kenji hara <span dir=3D"ltr">&lt;<a href=3D"mailt= o:k.hara.pg gmail.com" target=3D"_blank">k.hara.pg gmail.com</a>&gt;</span>= <br><div class=3D"gmail_extra"><div class=3D"gmail_quote"><blockquote class= =3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;bo= rder-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> <div dir=3D"ltr"><div class=3D"im">2013/2/9 Jonathan M Davis <span dir=3D"l= tr">&lt;<a href=3D"mailto:jmdavisProg gmx.com" target=3D"_blank">jmdavisPro= g gmx.com</a>&gt;</span><br></div><div class=3D"gmail_extra"><div class=3D"= gmail_quote"> <div class=3D"im"><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px= 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-= left-style:solid;padding-left:1ex"> <div>And I _definitely_ wouldn&#39;t want to set a precedence for front to = be<br></div></blockquote></div><div class=3D"im"><blockquote class=3D"gmail= _quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left= -color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"> declared as a non-property function. It needs to be consistently called<br> without parens to work in generic code, and if arrays are able to use front= <br> with parens, then we definitely risk a lot of range-based functions being<b= r> written incorrectly due to the fact that far too often, range-based functio= ns<br> only end up being tested with arrays, and in that case, the parens wouldn&#= 39;t<br> cause an error like they should. It wouldn&#39;t be caught until someone ac= tually<br> tried it with another type of range (possibly much later). Granted, the wri= ter<br> of the range-based function should have tested it better, but given that<br=

asking<br> for trouble to allow their front or back to be used with parens.<br></block= quote><div><br></div></div><div>Sorry I cannot imagine an actual use case y= ou are considering.</div></div></div></div></blockquote><div><br></div> <div style>Ah... do you consider this case?</div><div style><br></div><div>= import std.array : front;</div><div>int delegate()[] eventHandlers;</div><d= iv>auto result =3D eventHandlers.front(); // want to _call_ eventHandlers[0= ]<br> </div><div style><br></div><div style>Indeed, under the my proposal, typeof= (result) becomes `int delegate()`, not `int`.</div><div style><br></div><di= v style>Hmmmm.....</div><div style><br></div><div style>Kenji Hara</div> </div></div></div> --089e013d12c0813f7704d544c068--
Feb 08 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 09, 2013 15:26:10 kenji hara wrote:
 2013/2/9 kenji hara <k.hara.pg gmail.com>
 
 2013/2/9 Jonathan M Davis <jmdavisProg gmx.com>
 
 And I _definitely_ wouldn't want to set a precedence for front to be

declared as a non-property function. It needs to be consistently called
 without parens to work in generic code, and if arrays are able to use
 front
 with parens, then we definitely risk a lot of range-based functions being
 written incorrectly due to the fact that far too often, range-based
 functions
 only end up being tested with arrays, and in that case, the parens
 wouldn't
 cause an error like they should. It wouldn't be caught until someone
 actually
 tried it with another type of range (possibly much later). Granted, the
 writer
 of the range-based function should have tested it better, but given that
 arrays are by far the most common type of range, I think that it's just
 asking
 for trouble to allow their front or back to be used with parens.

Sorry I cannot imagine an actual use case you are considering.

Ah... do you consider this case? import std.array : front; int delegate()[] eventHandlers; auto result = eventHandlers.front(); // want to _call_ eventHandlers[0] Indeed, under the my proposal, typeof(result) becomes `int delegate()`, not `int`. Hmmmm.....

That and the fact that if front isn't actually a property, then you can do stuff like this: auto func(R)(R range) if(isForwardRange!R) { auto f = range.front(); //... return blah; } That code would then happily compile with arrays but fail with every other type of range. But since arrays are the most common type of range, it seems fairly common for people to test range-based functions with just arrays, and so it becomes very easy for people write code which is supposed to be range- based but only works with arrays. But the delegate example does make it much worse, because then range-based functions wouldn't be able to rely on front() calling the callable returned by front in the cases where front returns a callable, since that would only work with ranges which weren't arrays. Optional parens in generic code using a generic API is just begging for trouble. Any property in such an API needs to actually be property so that it can't be called with parens and so that if it _is_ called with parens, it's attempted to use the parens on the return value. - Jonathan M Davis
Feb 08 2013
prev sibling next sibling parent kenji hara <k.hara.pg gmail.com> writes:
--047d7bf10a8681cafc04d5452f1f
Content-Type: text/plain; charset=UTF-8

2013/2/9 Jonathan M Davis <jmdavisProg gmx.com>

 On Saturday, February 09, 2013 15:26:10 kenji hara wrote:
 2013/2/9 kenji hara <k.hara.pg gmail.com>

 2013/2/9 Jonathan M Davis <jmdavisProg gmx.com>

 And I _definitely_ wouldn't want to set a precedence for front to be

declared as a non-property function. It needs to be consistently called
 without parens to work in generic code, and if arrays are able to use
 front
 with parens, then we definitely risk a lot of range-based functions



 written incorrectly due to the fact that far too often, range-based
 functions
 only end up being tested with arrays, and in that case, the parens
 wouldn't
 cause an error like they should. It wouldn't be caught until someone
 actually
 tried it with another type of range (possibly much later). Granted,



 writer
 of the range-based function should have tested it better, but given



 arrays are by far the most common type of range, I think that it's



 asking
 for trouble to allow their front or back to be used with parens.

Sorry I cannot imagine an actual use case you are considering.

Ah... do you consider this case? import std.array : front; int delegate()[] eventHandlers; auto result = eventHandlers.front(); // want to _call_ eventHandlers[0] Indeed, under the my proposal, typeof(result) becomes `int delegate()`,

 `int`.

 Hmmmm.....

That and the fact that if front isn't actually a property, then you can do stuff like this: auto func(R)(R range) if(isForwardRange!R) { auto f = range.front(); //... return blah; } That code would then happily compile with arrays but fail with every other type of range. But since arrays are the most common type of range, it seems fairly common for people to test range-based functions with just arrays, and so it becomes very easy for people write code which is supposed to be range- based but only works with arrays. But the delegate example does make it much worse, because then range-based functions wouldn't be able to rely on front() calling the callable returned by front in the cases where front returns a callable, since that would only work with ranges which weren't arrays. Optional parens in generic code using a generic API is just begging for trouble. Any property in such an API needs to actually be property so that it can't be called with parens and so that if it _is_ called with parens, it's attempted to use the parens on the return value.

It makes sense... Thanks. Kenji Hara --047d7bf10a8681cafc04d5452f1f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div>2013/2/9 Jonathan M Davis <span dir=3D"ltr">&lt;<a hr= ef=3D"mailto:jmdavisProg gmx.com" target=3D"_blank">jmdavisProg gmx.com</a>= &gt;</span><br></div><div class=3D"gmail_extra"><div class=3D"gmail_quote">= <blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-= left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;p= adding-left:1ex"> <div class=3D""><div class=3D"h5">On Saturday, February 09, 2013 15:26:10 k= enji hara wrote:<br> &gt; 2013/2/9 kenji hara &lt;<a href=3D"mailto:k.hara.pg gmail.com">k.hara.= pg gmail.com</a>&gt;<br> &gt;<br> &gt; &gt; 2013/2/9 Jonathan M Davis &lt;<a href=3D"mailto:jmdavisProg gmx.c= om">jmdavisProg gmx.com</a>&gt;<br> &gt; &gt;<br> &gt; &gt;&gt; And I _definitely_ wouldn&#39;t want to set a precedence for = front to be<br> &gt; &gt;<br> &gt; &gt; declared as a non-property function. It needs to be consistently = called<br> &gt; &gt;<br> &gt; &gt;&gt; without parens to work in generic code, and if arrays are abl= e to use<br> &gt; &gt;&gt; front<br> &gt; &gt;&gt; with parens, then we definitely risk a lot of range-based fun= ctions being<br> &gt; &gt;&gt; written incorrectly due to the fact that far too often, range= -based<br> &gt; &gt;&gt; functions<br> &gt; &gt;&gt; only end up being tested with arrays, and in that case, the p= arens<br> &gt; &gt;&gt; wouldn&#39;t<br> &gt; &gt;&gt; cause an error like they should. It wouldn&#39;t be caught un= til someone<br> &gt; &gt;&gt; actually<br> &gt; &gt;&gt; tried it with another type of range (possibly much later). Gr= anted, the<br> &gt; &gt;&gt; writer<br> &gt; &gt;&gt; of the range-based function should have tested it better, but= given that<br> &gt; &gt;&gt; arrays are by far the most common type of range, I think that= it&#39;s just<br> &gt; &gt;&gt; asking<br> &gt; &gt;&gt; for trouble to allow their front or back to be used with pare= ns.<br> &gt; &gt;<br> &gt; &gt; Sorry I cannot imagine an actual use case you are considering.<br=

&gt; Ah... do you consider this case?<br> &gt;<br> &gt; import std.array : front;<br> &gt; int delegate()[] eventHandlers;<br> &gt; auto result =3D eventHandlers.front(); // want to _call_ eventHandlers= [0]<br> &gt;<br> &gt; Indeed, under the my proposal, typeof(result) becomes `int delegate()`= , not<br> &gt; `int`.<br> &gt;<br> &gt; Hmmmm.....<br> <br> </div></div>That and the fact that if front isn&#39;t actually a property, = then you can do<br> stuff like this:<br> <br> auto func(R)(R range)<br> =C2=A0 =C2=A0 if(isForwardRange!R)<br> {<br> =C2=A0 =C2=A0 auto f =3D range.front();<br> =C2=A0 =C2=A0 //...<br> =C2=A0 =C2=A0 return blah;<br> }<br> <br> That code would then happily compile with arrays but fail with every other<= br> type of range. But since arrays are the most common type of range, it seems= <br> fairly common for people to test range-based functions with just arrays, an= d<br> so it becomes very easy for people write code which is supposed to be range= -<br> based but only works with arrays.<br> <br> But the delegate example does make it much worse, because then range-based<= br> functions wouldn&#39;t be able to rely on front() calling the callable retu= rned by<br> front in the cases where front returns a callable, since that would only wo= rk<br> with ranges which weren&#39;t arrays. Optional parens in generic code using= a<br> generic API is just begging for trouble. Any property in such an API needs = to<br> actually be property so that it can&#39;t be called with parens and so tha= t if it<br> _is_ called with parens, it&#39;s attempted to use the parens on the return= value.</blockquote><div>=C2=A0</div></div></div><div class=3D"gmail_extra"=
<div>It makes sense... Thanks.<br></div><div><br></div><div style>Kenji Ha=

</div></div> --047d7bf10a8681cafc04d5452f1f--
Feb 08 2013
prev sibling next sibling parent Robert <jfanatiker gmx.at> writes:
 arrays are by far the most common type of range, I think that it's
 just asking 
 for trouble to allow their front or back to be used with parens.

Except you ebrace the idea that front is a function (property or not) and make parens work in all cases. Why not do it the other way round, front has to be a function property or not. Seems to work far better, it is a simple rule. No performance penalty as trivial set/get can easily be lined in, ...
Feb 09 2013
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Saturday, February 09, 2013 13:01:58 Robert wrote:
 arrays are by far the most common type of range, I think that it's
 just asking
 for trouble to allow their front or back to be used with parens.

Except you ebrace the idea that front is a function (property or not) and make parens work in all cases. Why not do it the other way round, front has to be a function property or not. Seems to work far better, it is a simple rule. No performance penalty as trivial set/get can easily be lined in, ...

It fails miserably when the element type of a range is callable. That's the main reason that property was introduced in the first place. - Jonathan M Davis
Feb 09 2013
prev sibling parent Robert <jfanatiker gmx.at> writes:
On Sat, 2013-02-09 at 04:12 -0800, Jonathan M Davis wrote:
 It fails miserably when the element type of a range is callable.
 That's the 
 main reason that  property was introduced in the first place.

front()(); Always! front is guaranteed to be a function, (I tried to explain why in the DIP), so this is consistent behaviour, meaning it will work with templates.
Feb 09 2013