February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert | On 02/07/2013 10:28 PM, Robert wrote: > On Thu, 2013-02-07 at 16:08 -0500, Steven Schveighoffer wrote: >> int delegate()[] arr; >> >> arr.front(); > > That's part of the mess we are trying to clean up here? Of course. > As of DIP 23, you would have to do arr.front()() in order to actually call the > delegate. > I prefer DIP24. > The current behaviour is also that you have to do arr.front()() in order > to actually call the function. So with DIP23 in effect you would > actually have to remove @property in order to be backwards compatible. > Nobody wants to be backwards compatible in this regard. |
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert | On Thu, 07 Feb 2013 16:28:42 -0500, Robert <jfanatiker@gmx.at> wrote: > On Thu, 2013-02-07 at 16:08 -0500, Steven Schveighoffer wrote: >> int delegate()[] arr; >> >> arr.front(); > > That's part of the mess we are trying to clean up here? As of DIP 23, > you would have to do arr.front()() in order to actually call the > delegate. Not with @property > The current behaviour is also that you have to do arr.front()() in order > to actually call the function. So with DIP23 in effect you would > actually have to remove @property in order to be backwards compatible. I don't understand the point here. Why would we want to be backwards compatible with a buggy compiler? In a bug-free implementation of arrays-as-ranges, arr[0] and arr.front should be perfectly interchangeable (with the well-known exception of strings). -Steve |
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Ok, forget backwards compatibility for a moment, it was just an
additional goody.
On Thu, 2013-02-07 at 19:38 -0500, Steven Schveighoffer wrote:
> Not with @property
>
>
That's the point, it would no longer be a property but a simple function returning ref.
front for arrays would not be a property for two reasons:
1. front is a UFCS function, I think supporting UFCS with properties is
just getting it wrong, have a look at DIP 23 if you don't believe me.
2. My current version, would not allow properties to return ref, but instead a property is a property if it defines a getter or a setter or both with the following exact definition:
@property void a(T val);
@property T a();
Everything that does not match these requirements can no longer be a property.
With this restrictions in place, properties cause no problems, everything works as expected, no weird corner cases. These restrictions happen to establish property semantics that match the field hiding pattern and this is what properties are all about, if you ask me.
The moment we stop trying making properties something they aren't, everything works out.
With optional parentheses in place, accessors to fields via a ref are still possible, they just no longer conform to the property specification and thus can not be marked with @property. (And don't need to be, because: arr.front=something; and something=arr.front; both still would work)
The gain of this? Clear semantics. If I have a property and I can write access it, I know that there is a set function. If I have a property I can read, there has to be a getter. If it is no property, I don't have any guarantees, which might be fine, depending on the API. (E.g. for your arr.front example).
|
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to eskimo | On Fri, 08 Feb 2013 10:28:14 -0500, eskimo <jfanatiker@gmx.at> wrote: > Ok, forget backwards compatibility for a moment, it was just an > additional goody. > On Thu, 2013-02-07 at 19:38 -0500, Steven Schveighoffer wrote: >> Not with @property >> >> > > That's the point, it would no longer be a property but a simple function > returning ref. Then it doesn't conform to the range API, where front is a property. > front for arrays would not be a property for two reasons: > 1. front is a UFCS function, I think supporting UFCS with properties is > just getting it wrong, have a look at DIP 23 if you don't believe me. I don't believe you. DIP23 has flaws. Care to explain? "just wrong" isn't an explanation. > 2. My current version, would not allow properties to return ref, but > instead a property is a property if it defines a getter or a setter or > both with the following exact definition: > > @property void a(T val); > @property T a(); This is a severe reduction in expression, we should not be looking for extra ways to invalidate existing code unless there is an extremely good reason. "Just wrong" is not it. -Steve |
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Fri, 2013-02-08 at 12:52 -0500, Steven Schveighoffer wrote: > > Then it doesn't conform to the range API, where front is a property. I can't find anything about that front has to be a property here: http://dlang.org/phobos/std_range.html#isInputRange all it states that you can get the current element by issuing: r.front which would still be possible with the optional parentheses of DIP23. > > > front for arrays would not be a property for two reasons: > > 1. front is a UFCS function, I think supporting UFCS with properties > is > > just getting it wrong, have a look at DIP 23 if you don't believe > me. > > I don't believe you. DIP23 has flaws. Care to explain? "just > wrong" > isn't an explanation. Look at the section "No module-level properties". Why not?! That's a perfectly valid use of properties. The proposal disallows module-level properties, but instead allows: 42.fun = 43; which reads like: assign 43 to the fun property of 42. We get this really obscure feature but disallowing module-level properties? If that is not wrong, than I don't know what is. > > > 2. My current version, would not allow properties to return ref, but instead a property is a property if it defines a getter or a setter > or > > both with the following exact definition: > > > > @property void a(T val); > > @property T a(); > > This is a severe reduction in expression, we should not be looking > for > extra ways to invalidate existing code unless there is an extremely > good > reason. "Just wrong" is not it. I have really good reasons and I hope I'll explain them well enough in the DIP I am currently writing. You already suggested that keeping compatibility to a broken implementation is not worth it, simply removing the @property in cases where there are no longer allowed, seems not too hard a change to me, especially if we agree that we have to break compatibility in one way or the other. |
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert | On Fri, 08 Feb 2013 14:05:40 -0500, Robert <jfanatiker@gmx.at> wrote: > On Fri, 2013-02-08 at 12:52 -0500, Steven Schveighoffer wrote: >> >> Then it doesn't conform to the range API, where front is a property. > I can't find anything about that front has to be a property here: > http://dlang.org/phobos/std_range.html#isInputRange > > all it states that you can get the current element by issuing: > r.front > which would still be possible with the optional parentheses of DIP23. Technically this is true. But the expectation is that r.front is a property/field, not a function. That aspect is difficult to capture in a template, especially in the current implementation where @property on a getter is essentially redundant info. In fact, the only case where a properly-implemented @property would be required on a getter is for delegate properties. I would argue that if @property worked correctly, it would be possible and correct to require r.front to be a property in that template. >> >> > front for arrays would not be a property for two reasons: >> > 1. front is a UFCS function, I think supporting UFCS with properties >> is >> > just getting it wrong, have a look at DIP 23 if you don't believe >> me. >> >> I don't believe you. DIP23 has flaws. Care to explain? "just >> wrong" >> isn't an explanation. > > Look at the section "No module-level properties". Why not?! That's a > perfectly valid use of properties. The proposal disallows module-level > properties, but instead allows: > 42.fun = 43; > which reads like: assign 43 to the fun property of 42. We get this > really obscure feature but disallowing module-level properties? If that > is not wrong, than I don't know what is. Module level properties pose an issue, because @property does not designate whether a property is a getter or a setter. In particular, a single-arg property function could be considered both a module property setter, or a UFCS property getter. So your issue is not really that UFCS properties are wrong, it's that disabling module-level properties is wrong. I agree with you, but at the same time, module level properties are not as common or useful as UFCS. In fact, one could argue they are more confusing since module scope is one of the only scopes that can be obscured. There are other possible solutions, such as designating something as a getter specifically, or adding more syntax (i.e. decorating the first parameter as 'this' for a module-level UFCS getter). But for now, the easiest thing is to disallow one or the other, and since UFCS properties are pretty much essential in Phobos, he's disabling the module level properties. The 42.fun = 43 example, just about everything is wrong with that. Look here is another function that D "allows": void increment(int x); What is that exactly supposed to do? 42.increment(); // what? increment(42); // what? Design and naming of functions is never going to be a problem that the compiler can solve. >> >> > 2. My current version, would not allow properties to return ref, but >> > instead a property is a property if it defines a getter or a setter >> or >> > both with the following exact definition: >> > >> > @property void a(T val); >> > @property T a(); >> >> This is a severe reduction in expression, we should not be looking >> for >> extra ways to invalidate existing code unless there is an extremely >> good >> reason. "Just wrong" is not it. > > I have really good reasons and I hope I'll explain them well enough in > the DIP I am currently writing. You already suggested that keeping > compatibility to a broken implementation is not worth it, simply > removing the @property in cases where there are no longer allowed, seems > not too hard a change to me, especially if we agree that we have to > break compatibility in one way or the other. My point on that was, if something works but is not supposed to, we shouldn't have to worry about keeping that code working. @property in its current form is NOT implemented as it was designed. There is no requirement to keep existing behavior that doesn't correctly work. In the example given, @property is supposed to ban the use of parentheses according to the spec, but it doesn't. In fact, in the case of a @property that returns a delegate, it REQUIRES the extra parentheses. This is a bug, and not something to try and keep working. On the other hand, ref @properties is NOT a bug, it functions as designed. Whether to remove it or not is certainly a discussion we can have, but it's not buggy behavior. See the difference? -Steve |
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Robert | On 2/8/13 2:05 PM, Robert wrote:
> Look at the section "No module-level properties". Why not?! That's a
> perfectly valid use of properties. The proposal disallows module-level
> properties, but instead allows:
> 42.fun = 43;
> which reads like: assign 43 to the fun property of 42. We get this
> really obscure feature but disallowing module-level properties? If that
> is not wrong, than I don't know what is.
There would be ambiguities with module level properties. A property with one argument may be either a setter for a module-level property or a getter for the property of a module-level object.
Andrei
|
February 08, 2013 Re: Taking address of properties | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 2013-02-08 21:13, Steven Schveighoffer wrote:
>> I can't find anything about that front has to be a property here:
>> http://dlang.org/phobos/std_range.html#isInputRange
>>
>> all it states that you can get the current element by issuing:
>> r.front
>> which would still be possible with the optional parentheses of DIP23.
>
> Technically this is true. But the expectation is that r.front is a
> property/field, not a function. That aspect is difficult to capture in a
> template, especially in the current implementation where @property on a getter
> is essentially redundant info.
There may be nothing saying that r.front has to be a @property, but don't forget setters. There are many examples of the following statement:
r.front = val;
Just look at the sources: grep -R "\.front = " ./src/phobos/
General agreement is that plain functions shouldn't be allowed to be called
like setters, with assignment operator. So what now? Should all that code be
changed to use r.front(val) instead? Or should void front(T val) remain a
@property, while ref T front() becomes a plain function?
|
February 08, 2013 Re: On DIP 23 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | On Thursday, 7 February 2013 at 18:55:23 UTC, Dicebot wrote:
> On Thursday, 7 February 2013 at 16:35:17 UTC, Andrei Alexandrescu wrote:
>> I felt we were getting somewhere.
>>
>> Andrei
>
> Both yes and no at the same time.
>
> Last proposals did a great job addressing different issues regarding property syntax and I somewhat like them in that sense. But they miss an important paragraph about what properties are supposed to be in D semantically, when they should be used and what problems they try to solve. So far design feels like it is syntax based as opposed to use case based.
In writing my article about nested structs, I stumbled upon a general definition of a property which may be of value here.
"A property is a named set of overloaded operations on a piece of
data which replaces the appearance of that data in code(™)."
|
February 08, 2013 Re: On DIP 23 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Zach the Mystic | On Friday, 8 February 2013 at 21:31:17 UTC, Zach the Mystic wrote:
> On Thursday, 7 February 2013 at 18:55:23 UTC, Dicebot wrote:
>> On Thursday, 7 February 2013 at 16:35:17 UTC, Andrei Alexandrescu wrote:
>>> I felt we were getting somewhere.
>>>
>>> Andrei
>>
>> Both yes and no at the same time.
>>
>> Last proposals did a great job addressing different issues regarding property syntax and I somewhat like them in that sense. But they miss an important paragraph about what properties are supposed to be in D semantically, when they should be used and what problems they try to solve. So far design feels like it is syntax based as opposed to use case based.
>
> In writing my article about nested structs, I stumbled upon a general definition of a property which may be of value here.
>
> "A property is a named set of overloaded operations on a piece of
> data which replaces the appearance of that data in code(™)."
By stumbled I mean I accidentally wrote it without knowing what I
was doing.
|
Copyright © 1999-2021 by the D Language Foundation