February 04, 2013
On Monday, February 04, 2013 09:22:56 Jacob Carlborg wrote:
> 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?

It is now, though I don't think that it was intially. It's in the "Applying operators" section.

- Jonathan M Davis
February 04, 2013
On 2013-02-04 02:56, Jonathan M Davis wrote:

> Technically, the bit about having exactly one or exactly two parameters is
> wrong, unless you're counting the invisible this pointer/reference in that.
> Member property functions end up with exactly zero or exactly one parameters.

I don't know if the text has been update since you read it but it says:

"counting the implicit this parameter if at all".

-- 
/Jacob Carlborg
February 04, 2013
On 2/4/13 2:10 AM, monarch_dodra wrote:
> 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?

Well I at least haven't forgotten. Generally in D we don't want to 100% disallow doing something sensible.

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

Yes, if we disallowed address taking things would get a bit simpler.


Andrei
February 04, 2013
From DIP:
If prop is a property, &prop or a.prop obey the normal rules...

I think there missing '&' before a.prop:

If prop is a property, &prop or &a.prop obey the normal rules...



February 04, 2013
On 02/04/2013 05:21 AM, deadalnix wrote:
> On Monday, 4 February 2013 at 03:13:07 UTC, Andrei Alexandrescu wrote:
>> On 2/3/13 9:58 PM, David Nadlinger wrote:
>>> My point is precisely that. I think there are much simpler solutions
>>> than adding some magic properties to a pair of parentheses in the right
>>> position, even if it might look like a convenient hack.
>>
>> I don't think it's a hack at all. Think it over, and compare it with
>> the language semantics even today.
>>
>
> Going from complete crap to bearable don't make bearable good.

In what way is this bearable?
February 04, 2013
On 02/04/2013 04:24 AM, TommiT wrote:
> 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.

Well, it is what the proposal says.

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

You are right.
February 04, 2013
On Monday, 4 February 2013 at 13:12:54 UTC, Timon Gehr wrote:
> On 02/04/2013 05:21 AM, deadalnix wrote:
>> On Monday, 4 February 2013 at 03:13:07 UTC, Andrei Alexandrescu wrote:
>>> On 2/3/13 9:58 PM, David Nadlinger wrote:
>>>> My point is precisely that. I think there are much simpler solutions
>>>> than adding some magic properties to a pair of parentheses in the right
>>>> position, even if it might look like a convenient hack.
>>>
>>> I don't think it's a hack at all. Think it over, and compare it with
>>> the language semantics even today.
>>>
>>
>> Going from complete crap to bearable don't make bearable good.
>
> In what way is this bearable?

The proposal is a big improvement over current behavior. Still it has major flaws, like the way & and property interact.
February 04, 2013
On 02/03/2013 11:11 AM, Andrei Alexandrescu wrote:
> On 2/3/13 5:14 AM, Johannes Pfau wrote:
>> ...
>
>> 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?
>
> We need to add this to the proposal. There are two schools of thought here:
>
> 1. Make properties emulate regular variables as much as possible. In
> that case &a.p is the same as &(a.p), i.e. it applies to the returned
> value. (One counter-argument here is that properties should seldom
> return a reference because that breaks encapsulation.)
>
> 2. Allow people to do whatever they need to do without much aggravation.
> In that case &a.p obeys the normal rules of taking a method's address,
> and &(a.p) applies to the returned value.
>
> I favor (2) and put it in http://wiki.dlang.org/DIP23. Will talk to Walter.
>

I disagree with this.  I think that allowing address-of on getters is potentially a big source of trouble.  I've felt that getters should be forbidden from returning lvalues.  So returning ref from a getter is not OK, but const ref should be fine.

Anyone who wants to make the property behave like a reference should define an appropriate setter for it.

There are a couple reasons for this:
- It would be nice to allow variables/fields to have @property as an annotation.  This would forbid address-of to allow seamless transition into fully-implemented property functions later.  To make the roundtrip possible, the property functions should also disallow address-of.
- Allowing mutation of a getter's expression can create unwanted ambiguities when attempting to apply property rewrites.  Without an lvalue getter it becomes unambiguous: any side-effectful operation on a property (that isn't direct assignment, or something requiring a read) will call both its getter and setter.

>> ...
>
>
> Andrei

February 04, 2013
On 2/4/13 12:53 AM, kenji hara wrote:
> 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

Couldn't AddressOf use "&(" + exp + ")"?

I thought more about this. The problem remains even without @property, due to optional parens in function invocation. Consider:

ref int fun() { ... }
auto p1 = &fun;
auto p2 = &(fun);
auto p3 = &(fun());

What are the types of the three? The optional parens in invocation require some disambiguation. I think the sensible disambiguation is to have &fun take the address of fun and the other two take the address of fun's result.

I would agree restricting the properties, but requiring a __trait to take the address of a regular function or method seems overkill.


Andrei
February 04, 2013
On 02/04/2013 06:36 AM, 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.

Agreed.

> Parens change the nature of expressions ALL the time.
>

In D? No way.

Precedence rules are introduced in order to make parens _implicit_.

In a language with unary & and binary ., There are two possible interpretations for &a.b:

(&a).b
&(a.b)

In the case of D, &a.b is just a shortcut for &(a.b). How can they denote different things?

> There is a weird rule in C++11 that makes sometimes typeof(expr) and
> typeof((expr)) mean different things.

There is also the argument-dependent name lookup thing

namespace bar{
    struct S{} baz;
    S foo(S x){ return x; }
}

int main(){
    foo(bar::baz); // Koenig lookup finds bar::foo
    (foo)(bar::baz); // no Koenig lookup, foo undefined
}

Not examples to follow.

> That is arguably an example to
> avoid. But introducing parens among parts of an expression is expected
> to affect meaning.
>

Sure, but that is not what happens here at all. The parens are introduced around ONE part of the expression.