February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Monday, 4 February 2013 at 04:45:27 UTC, Jonathan M Davis wrote:
> On Sunday, February 03, 2013 03:16:08 Andrei Alexandrescu wrote:
>> Destroy.
>
> Another thing to consider would be to allow putting @property on a variable
> with the idea that variables marked as such would not be usable in any
> situation where a property function wouldn't be - such as taking their address
> or passing them by ref. [..]
If we consider a variable marked as @property as a variable whose access is restricted, then the following should be also illegal uses of it:
1) calling its non-const method
2) mutating its data field
If we consider a variable marked as @property as lowered to getter and setter properties, then it doesn't have those restrictions. This is what I would advocate.
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On 2/3/13 11:00 PM, David Nadlinger wrote: > The problem I see is that usually, one can insert grouping pairs of > parentheses into an expression according to the operator > precedence/associativity rules at will without changing the result. This > isn't merely a theoretical exercise, but the way (well, in the form of > trees) I tend to reason about source code intuitively. Well this is going to sound bad, but you either use reason or intuition. I don't see how one can reason intuitively. > Now, grouping the expression »&a.b« according to the precedence rules > yields »&(a.b)« – but in your proposal, they mean completely different > things. I agree they mean different things. I'm unclear that's a problem. All your examples stop here, there's no propagation of the issue. To take the address of a property, one writes &obj.prop. To take the address of a property's result, one writes &(obj.prop). And that's that. It all works with typeof. > You could argue that &<expression>.<identifier> is a special construct > different from the normal address-of operator. But where do you mentally > draw the line? What about &a.b.c <-> &(a.b).c <-> &((a.b).c)? &(a + b).c > <-> &((a + b).c)? That argument is easily destroyed. In a.b.c, a.b is the expression and c is the property name. > Again, from an user's perspective the change in behavior seems to be > completely at odds with the usual rule in C-family languages that > grouping parens can be added without changing the meaning of an > expression. I think we avoid much more bizarre things that way, such that expr and &expr meaning sometimes the same exact thing. Or that we have expressions without a type. And nobody blinks an eye. I just think we're better off. > Thus, this part of the proposed syntax strikes me as being > extremely misleading, which is especially bad because the situation with > the two possible meanings is confusing enough to start out with already. > And how often do you think you'll find yourself in the situation of > needing to get a delegate from a property anyway? Can't we just make > »@property getter expressions are always equivalent to their return > value« a hard (simple!) rule and add something like > __traits(propertyGetter, ...) for the rare cases where you really need > to get hold of the underlying function? I don't see where the trouble is. If I thought the trait is necessary, I'd make it part of the proposal. Currently I don't see it as necessary, but I definitely can be convinced. Andrei |
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to BLM768 | On 2/3/13 11:17 PM, BLM768 wrote:
> On Monday, 4 February 2013 at 04:00:28 UTC, David Nadlinger wrote:
>> On Monday, 4 February 2013 at 03:15:51 UTC, David Nadlinger wrote:
>>
>> And how often do you think you'll find yourself in the situation of
>> needing to get a delegate from a property anyway? Can't we just make
>> »@property getter expressions are always equivalent to their return
>> value« a hard (simple!) rule and add something like
>> __traits(propertyGetter, ...) for the rare cases where you really need
>> to get hold of the underlying function?
>>
>> David
>
> I like this solution; it follows the Principle of Least Surprise
> quite well. The syntax may be a bit longer, but it's immediately
> obvious even to a beginning/intermediate D user what's going on
> without having to worry about too many nuances.
This is a good point, and __traits make all possible syntactic confusion go away.
Andrei
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On 2/3/13 11:31 PM, Jonathan M Davis wrote:
> I tend to agree that making the parens change the nature of the expression is
> a bad idea.
I think there's some misunderstanding here. Parens change the nature of expressions ALL the time.
There is a weird rule in C++11 that makes sometimes typeof(expr) and typeof((expr)) mean different things. That is arguably an example to avoid. But introducing parens among parts of an expression is expected to affect meaning.
Andrei
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu Attachments:
| 2013/2/4 Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> > On 2/3/13 11:00 PM, David Nadlinger wrote: > >> >> Now, grouping the expression »&a.b« according to the precedence rules >> yields »&(a.b)« – but in your proposal, they mean completely different >> things. >> > > I agree they mean different things. I'm unclear that's a problem. All your examples stop here, there's no propagation of the issue. To take the address of a property, one writes &obj.prop. To take the address of a property's result, one writes &(obj.prop). And that's that. It all works with typeof. If the expression is generated from string mixin, might have a problem. // This is much simple case. Real example might be more complicated. template AddressOf(string exp) { enum AddressOf = "&" ~ exp; } struct S { @property int prop() { return 1; } } void main() { S s; assert(s.prop == 1); int* p = mixin(AddressOf!("s.prop")); // &s.prop returns delegate } I think that parenthesis-dependent syntax is not good. Kenji Hara |
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 4 February 2013 at 05:36:10 UTC, Andrei Alexandrescu wrote:
> On 2/3/13 11:31 PM, Jonathan M Davis wrote:
>> I tend to agree that making the parens change the nature of the expression is
>> a bad idea.
>
> I think there's some misunderstanding here. Parens change the nature of expressions ALL the time.
>
> There is a weird rule in C++11 that makes sometimes typeof(expr) and typeof((expr)) mean different things. That is arguably an example to avoid. But introducing parens among parts of an expression is expected to affect meaning.
>
Weird behaviors of C++ are a very good reason to have D in the first place.
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 4 February 2013 at 05:32:39 UTC, Andrei Alexandrescu
wrote:
> On 2/3/13 11:00 PM, David Nadlinger wrote:
>> The problem I see is that usually, one can insert grouping pairs of
>> parentheses into an expression according to the operator
>> precedence/associativity rules at will without changing the result. This
>> isn't merely a theoretical exercise, but the way (well, in the form of
>> trees) I tend to reason about source code intuitively.
>
> Well this is going to sound bad, but you either use reason or intuition. I don't see how one can reason intuitively.
>
Yes, that is why, ideally, you want to close the gap as much as
possible.
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Monday, 4 February 2013 at 05:32:39 UTC, Andrei Alexandrescu wrote:
> On 2/3/13 11:00 PM, David Nadlinger wrote:
>> The problem I see is that usually, one can insert grouping pairs of
>> parentheses into an expression according to the operator
>> precedence/associativity rules at will without changing the result. This
>> isn't merely a theoretical exercise, but the way (well, in the form of
>> trees) I tend to reason about source code intuitively.
>
> Well this is going to sound bad, but you either use reason or intuition. I don't see how one can reason intuitively.
>
>> Now, grouping the expression »&a.b« according to the precedence rules
>> yields »&(a.b)« – but in your proposal, they mean completely different
>> things.
>
> I agree they mean different things. I'm unclear that's a problem. All your examples stop here, there's no propagation of the issue. To take the address of a property, one writes &obj.prop. To take the address of a property's result, one writes &(obj.prop). And that's that. It all works with typeof.
>
> [SNIP]
>
> Andrei
It was my understanding that once a function is declared a property, it is meant to emulate a field. In such circumstance, there were talks about plain and simply not allowing taking the address of an @property function.
2 questions:
1. Was this proposal rejected, or have we just forgotten about it?
2. What are the actual use cases for taking the address of a property function?
Unless I'm mistaken, the "entire mess" of &a.b would be solved if we simply recognized it as "but you aren't allowed to take the address of the function b, so why have a syntax to support it anyways"? In such circumstance, "&a.b" == "&(a.b)" == "the address of the thing obtaining by running a.b"
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to TommiT | Am Mon, 04 Feb 2013 04:24:46 +0100
schrieb "TommiT" <tommitissari@hotmail.com>:
> On Monday, 4 February 2013 at 02:36:41 UTC, Timon Gehr wrote:
> > On 02/04/2013 03:23 AM, kenji hara wrote:
> >> Unfortunately, I can present a counterexample.
> >>
> >> struct S {
> >> static int value;
> >> static @property int foo() { return value; }
> >> static @property void foo(int n) { value = n; }
> >>
> >> }
> >> void main() {
> >> int n = S.foo;
> >> S.foo = 1;
> >> }
> >>
> >> Should they be disallowed, as like module level properties?
> >>
> >> Kenji Hara
> >
> > Probably. (static essentially means module-level, but in a potentially nested name space.)
>
> I disagree. Static properties can be allowed because they're not
> ambiguous. The problem with module-level:
> @property void foo(int n) {}
> ...are the two interpretations of foo as either a setter taking
> an int or a getter property of int type. So, one of those
> interpretations must be disallowed. But, with static member
> properties, there aren't multiple interpretations.
"getter property of int type"
But a getter shouldn't return void, right? So it's actually not ambiguous?
|
February 04, 2013 Re: DIP23 draft: Fixing properties redux | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On 2013-02-03 17:11, Andrei Alexandrescu wrote: > It's dangerous to get too clever about that. Anyhow, such rewrites are > possible: > > ++a.p ----> { auto v = a.p; ++v; a.p = v; return v; }() > a.p++ ----> { auto v = a.p; ++a.p; return v; }() > > and so on. Is that part of the proposal or not? -- /Jacob Carlborg |
Copyright © 1999-2021 by the D Language Foundation