February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | Am Sun, 03 Feb 2013 03:16:08 -0500 schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>: > It is understood that the current proposal is just a draft and there must be quite a few corner cases it doesn't discuss. We also understand it's impossible to reconcile all viewpoints and please all tastes. Our hope is to get to a point where the rules are self-consistent, meaningful, and complete. > > > Destroy. > > Andrei "If a function returns a reference, then assignment through the paren-less call should work: " This is the only part where I would disagree. Why is this special rule necessary if we have full @property support? I think this would still allow too many false positives. One important aspect that this proposal doesn't cover yet is whether we want to allow "semantic rewriting" for properties: ---- Struct a; a.property++; //would this be legal? ---- for other corner cases this list is a good start: http://wiki.dlang.org/Property_Discussion_Wrap-up#Implementation_concerns * Can we get a reference to the property? What does &x.property mean? * How can we get the getter / setter functions? Do we need to get those? * What is the type of the property? Return type, setter function type or getter function type? How to get the other types? * What does x.property++ do? ([http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/Property#Semanticrewritingofproperties Semantic rewriting]) * Is returning ref values from the getter OK? * Is taking ref values in the setter OK? * Should all properties be nothrow? pure? getter const? ** Probably better as a rule for style guide. * Are UFCS properties possible? How do they work exactly? * How do you disambiguate property functions when they're free functions which conflict? ** Normal UFCS functions can be force called by using their fully qualified name. That's not possible for properties if function call syntax is disallowed? * How many parameters are allowed for property functions? ** Are default parameters allowed? ** Especially consider the example about __FILE__ and __LINE__ * Are templated properties allowed? ** The access syntax for properties doesn't allow providing types |
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Sun, 03 Feb 2013 03:16:08 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote: > Walter and I have had a discussion on how to finalize properties. > > http://wiki.dlang.org/DIP23 I agree with everything in this. This looks exactly like what I wanted a few days ago. Thank you! One aspect not addressed is free-function properties: @property int foo(int x) {return x * 5;} could be interpreted as: foo = 2; // not correct (for this example) int x = 2.foo; // correct Note that: @property int foo(); @property void foo(int x, int y); are both unambiguous. ================== I have a possible suggestion to fix this within your proposal: @property on single-arg free functions ONLY enables a setter mode, it does not work as a UFCS getter. Therefore, if you wish to write a UFCS getter, omit the @property designation. int foo(int x) {return x * 5;} foo = 2; // illegal int x = 2.foo; // OK, sets x to 10 int x = foo(2); // same as above @property int foo(int x) {_foo = x;} foo = 2; // OK, sets _foo to 2 int x = 2.foo; // illegal int x = foo(2); // illegal I know this is not a complete solution, and can be confusing, but we have little options at this point, given existing code. Also note that we already have a way to specify a getter property on a user-defined type, UFCS isn't entirely necessary for that. This will break SOME declarations, but removing @property should result in compiling code I think. -Steve |
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2013-02-03 09:16, Andrei Alexandrescu wrote: > Walter and I have had a discussion on how to finalize properties. > > http://wiki.dlang.org/DIP23 What about: writeln = "asd"; Allowed or not? -- /Jacob Carlborg |
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu Attachments:
| 2013/2/3 Andrei Alexandrescu <SeeWebsiteForEmail@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 |
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| 2013/2/3 Steven Schveighoffer <schveiguy@yahoo.com> > I have a possible suggestion to fix this within your proposal: > > @property on single-arg free functions ONLY enables a setter mode, it does not work as a UFCS getter. [snip] > I was thinking the exact same thing. Kenji Hara |
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | On Sunday, February 03, 2013 13:34:14 Jacob Carlborg wrote:
> On 2013-02-03 09:16, Andrei Alexandrescu wrote:
> > Walter and I have had a discussion on how to finalize properties.
> >
> > http://wiki.dlang.org/DIP23
>
> What about:
>
> writeln = "asd";
>
> Allowed or not?
I take it that you didn't read the DIP. At the very beginning of its section on "Write properties:"
-----------
In order to use the assignment operator "=" property-style, the @property annotation MUST be used.
-----------
- Jonathan M Davis
|
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Sun, 03 Feb 2013 07:16:17 -0500, Steven Schveighoffer <schveiguy@yahoo.com> wrote:
> On Sun, 03 Feb 2013 03:16:08 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
>
>> Walter and I have had a discussion on how to finalize properties.
>>
>> http://wiki.dlang.org/DIP23
>
> I agree with everything in this. This looks exactly like what I wanted a few days ago. Thank you!
>
> One aspect not addressed is free-function properties:
I thought of one other problem with this proposal. You can no longer get a delegate of a property. Like it or not, there will be existing code that does get a delegate to properties (it is allowed now).
I think we should provide a __traits accessor for this. Otherwise, there is no way to port said code to the new style.
-Steve
|
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 02/03/2013 09:16 AM, Andrei Alexandrescu wrote:
> Walter and I have had a discussion on how to finalize properties.
>
> http://wiki.dlang.org/DIP23
> ...
Looks good. Two things:
What about eg:
@property T front(T)(T[] arr){ return arr[0]; }
And:
"Avoid embarrassing situations such as expressions with unexpressible types or no-op address-of operator (as is the case with C functions)."
The DIP does not fix the first issue.
pragma(msg, typeof(*(int x)=>x)); // pure nothrow @safe int(int x)
|
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer Attachments:
| 2013/2/3 Steven Schveighoffer <schveiguy@yahoo.com>
> On Sun, 03 Feb 2013 07:16:17 -0500, Steven Schveighoffer < schveiguy@yahoo.com> wrote:
>
> On Sun, 03 Feb 2013 03:16:08 -0500, Andrei Alexandrescu <
>> SeeWebsiteForEmail@erdani.org**> wrote:
>>
>> Walter and I have had a discussion on how to finalize properties.
>>>
>>> http://wiki.dlang.org/DIP23
>>>
>>
>> I agree with everything in this. This looks exactly like what I wanted a few days ago. Thank you!
>>
>> One aspect not addressed is free-function properties:
>>
>
> I thought of one other problem with this proposal. You can no longer get a delegate of a property. Like it or not, there will be existing code that does get a delegate to properties (it is allowed now).
>
> I think we should provide a __traits accessor for this. Otherwise, there is no way to port said code to the new style.
>
On the contrary with you, I was read that we no longer get an address of ref returned value by address-op.
@property ref int foo();
static assert(is(typeof(&foo) == ref int function())); // typeof does not
return int*
If I am correct, there is no need for special enhancement like __traits.
Kenji Hara
|
February 03, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 02/03/2013 01:49 PM, Steven Schveighoffer wrote:
> On Sun, 03 Feb 2013 07:16:17 -0500, Steven Schveighoffer
> <schveiguy@yahoo.com> wrote:
>
>> On Sun, 03 Feb 2013 03:16:08 -0500, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> wrote:
>>
>>> Walter and I have had a discussion on how to finalize properties.
>>>
>>> http://wiki.dlang.org/DIP23
>>
>> I agree with everything in this. This looks exactly like what I
>> wanted a few days ago. Thank you!
>>
>> One aspect not addressed is free-function properties:
>
> I thought of one other problem with this proposal. You can no longer
> get a delegate of a property. Like it or not, there will be existing
> code that does get a delegate to properties (it is allowed now).
>
> I think we should provide a __traits accessor for this. Otherwise,
> there is no way to port said code to the new style.
>
> -Steve
T delegate() f = &a.prop -> auto f = ()=>a.prop;
T delegate(T) f = &a.prop -> auto f = (T x)=>a.prop=x;
|
Copyright © 1999-2021 by the D Language Foundation