February 04, 2013
2013/2/5 Andrej Mitrovic <andrej.mitrovich@gmail.com>

> On 2/4/13, kenji hara <k.hara.pg@gmail.com> wrote:
> > This is not correct."m.s & m.s" is always parsed as binary bitwise AND
> expression.
> > So there is no address expression.
>
> Fantastic, more special casing. I don't think you guys realize what a mess you would introduce. Basically:
>
> s & s;  // fine, they're binary operators
> &s;  // oops, doesn't work even if property returns a type with a unary
> operator


Address operator cannot be overloaded. http://dlang.org/operatoroverloading

On 2/4/13, kenji hara <k.hara.pg@gmail.com> wrote:
> > Address expression is _only_one_ built-in feature to make a callable
> object
> > from function symbol. So
> > this "special feature" is enough reasonable to me.
>
> Yes "only one". And then later we'll add another "one", and another one, until we end up with the mess that is C++. This feature does not pull its own weight regardless of how easy it is to implement in the compiler. From a user's perspective, it is completely pointless and unintuitive.
>

We can think like this.
"To resolve ambiguity, we should introduce new operator: &( exp )".

Or, we can think like that we introduce one new restriction.
"If you want to get function address, you MUST not add redundant
parenthesis."
&func;   // OK
&(func);  // Bad.

It should be written in the article "Migration for Property Enforcement".

Kenji Hara


February 04, 2013
On 02/04/2013 04:02 PM, deadalnix wrote:
> On Monday, 4 February 2013 at 14:25:10 UTC, Timon Gehr wrote:
>> On 02/04/2013 03:05 PM, Andrei Alexandrescu wrote:
>>> ...
>>> 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.
>>
>> The obvious rule is not to give significance to redundant parentheses.
>>
>>> 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.
>>>
>>
>> No! &fun and &(fun) are the same thing. Functions that get their
>> address taken are not implicitly invoked. (Again, Scala agrees.)
>>
>
> Scala don't really agree. fun is the function pointer. It is evaluated
> if the function pointer is a NOOP, but that's it.

Of course Scala agrees.

scala> def foo() = 2
foo: ()Int

scala> foo
res0: Int = 2

scala> foo _
res1: () => Int = <function0>

scala> (foo) _
res2: () => Int = <function0>

scala> def bar[A](arg : A) = arg
bar: [A](arg: A)A

scala> bar(foo)
res3: Int = 2

> Here is scala semantic
> with D syntax :
>
> void bar() {}
> bar; // execute bar. Is an exception because taking the function pointer
> is a NOOP.
>

No, it is the rule.

> void foo(void function() bar) {}
> foo(bar); // OK, bar is not evaluated.

This is the exception. (That nobody has argued in favour of so far.)
February 04, 2013
04-Feb-2013 19:15, Andrej Mitrovic пишет:
> On 2/4/13, kenji hara <k.hara.pg@gmail.com> wrote:
>> This is not correct."m.s & m.s" is always parsed as binary bitwise AND expression.
>> So there is no address expression.
>
> Fantastic, more special casing. I don't think you guys realize what a
> mess you would introduce. Basically:
>
> s & s;  // fine, they're binary operators
> &s;  // oops, doesn't work even if property returns a type with a unary operator

Unary & is not overloadable, precisely due to confusing mess it can create (see C++).


-- 
Dmitry Olshansky
February 04, 2013
On 02/04/2013 04:08 PM, kenji hara wrote:
> 2013/2/4 Timon Gehr <timon.gehr@gmx.ch <mailto:timon.gehr@gmx.ch>>
>
>     On 02/04/2013 03:38 PM, kenji hara wrote:
>
>         I think this is necessary feature for the D's function and property
>         semantics.
>
>
>     Why?
>
>
> Because, "property" is one of D-specific feature.
>
> In D, "property" is directly translated to function call. So, we should
> get balance between two requirements:
> 1. property should be treated as its returned type.
> 2. property should be distinguished from raw field. (For example,
> serialization library should recognize it)
>

This is what __traits are for.

> Address expression is _only_one_ built-in feature to make a callable
> object from function symbol.

Property symbols are not to be treated like function symbols syntactically. That is the point. Otherwise we may as well get rid of properties.

> So this "special feature" is enough reasonable to me.
>
> ...

"special features" are usually not reasonable.
February 04, 2013
On 2/4/13, Dmitry Olshansky <dmitry.olsh@gmail.com> wrote:
> Unary & is not overloadable, precisely due to confusing mess it can
> create (see C++).

Right I overlooked that, but this new rule will introduce a confusing mess as well. Anyway my vote is firmly against it. If anything we should have a vote on it before someone starts hacking on master without us knowing about it (UDA's, anyone?).
February 04, 2013
I have thought in long term that, in D, "proerty" is just a syntactic rerwiting rule of  function call. It is much reasonable abstraction to me.

So, using __trait is overkill.

Kenji Hara
2013/02/05 0:45 "Timon Gehr" <timon.gehr@gmx.ch>:

> On 02/04/2013 04:08 PM, kenji hara wrote:
>
>> 2013/2/4 Timon Gehr <timon.gehr@gmx.ch <mailto:timon.gehr@gmx.ch>>
>>
>>     On 02/04/2013 03:38 PM, kenji hara wrote:
>>
>>         I think this is necessary feature for the D's function and
>> property
>>         semantics.
>>
>>
>>     Why?
>>
>>
>> Because, "property" is one of D-specific feature.
>>
>> In D, "property" is directly translated to function call. So, we should
>> get balance between two requirements:
>> 1. property should be treated as its returned type.
>> 2. property should be distinguished from raw field. (For example,
>> serialization library should recognize it)
>>
>>
> This is what __traits are for.
>
>  Address expression is _only_one_ built-in feature to make a callable
>> object from function symbol.
>>
>
> Property symbols are not to be treated like function symbols syntactically. That is the point. Otherwise we may as well get rid of properties.
>
>  So this "special feature" is enough reasonable to me.
>>
>> ...
>>
>
> "special features" are usually not reasonable.
>


February 04, 2013
On Mon, 04 Feb 2013 06:47:26 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

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

Basically any time you have a use case for creating a delegate that returns a field or a property value.  Instead of creating a wrapping delegate to call a function, it would make more sense to access the delegate directly.  In other words, the use case isn't important, what we are doing here is creating an optimization.

If the compiler could do that automatically, I think that would be fine too.

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

Elsewhere you shot down my idea of __traits(getDelegate) generically because we already have this possibility:

void foo(int) {}
void foo(string) {}

void delegate(string) dg = &foo; // select string overload

What if we use the same exception for properties?

@property int foo();

auto x = &foo; // error
int delegate() x = &foo; // ok

-Steve
February 04, 2013
On Sunday, 3 February 2013 at 08:16:08 UTC, Andrei Alexandrescu wrote:
> Walter and I have had a discussion on how to finalize properties.
>
> http://wiki.dlang.org/DIP23
>
> We got input from DIP21 (which we didn't want to clobber, hence the new DIP) and the recent discussion.
>
> The proposal probably won't be accepted in its current form because it breaks some code. We hope to bring it to good shape with everyone's help.
>
> In brief:
>
> * Optional parens stay.
>
> * Just mentioning a function or method without parens does NOT automatically take its address. (This is a change from the current behavior.)
>
> * Read properties (using @property) work as expected with the mention that they may NOT be called with the parens. Any parens would apply to the returned value.
>
> * Write properties (using @property) may only be used in the assignment form (no function-style call allowed).
>
> 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

IMO the concept of emulating a field with a function is proving to be an idea that should be simplified. Just look at the huge amount of wasted effort on these discussions, We have at least 5 threads open, two open DIPS and two superseded DIPS.

As it stands, I don't even know why there's such a strong desire to have properties that emulate variables. I read the arguments in favor, and they are all very weak IMO, and probably will result in maintenance issues. We all seem to be getting along just fine without full variable emulation, and what we have now for property seems good enough (although I agree it could be done better with a few simple adjustments).

If we must keep @property, then my advice is to keep the emulation simple and restricted to the cases where it can work without acrobatics (eg no address taking, no pass by ref or return by ref). What I see being proposed is going too far for very little gain.

BTW, I am wondering if the idea of "memberspaces" was considered, and if it was considered, then why was it dropped? I won't argue for them in here, just would like to know what the thinking is because I don't recall any feedback from Walter or Andrei.

--rt
February 04, 2013
On Monday, February 04, 2013 23:56:50 kenji hara wrote:
> 2013/2/4 Andrej Mitrovic <andrej.mitrovich@gmail.com>
> 
> > On 2/4/13, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:
> > > I'm unclear that's a problem.
> > 
> > The problem is you cannot replace a field with a @property function without breaking user-code when you take into account operator
> 
> > overloading. Consider:
> As an essential question, how often occurs rewriting fields to property?
> 
> As far as I thought, such rewriting will cause:
> 1. compile error by type mismatch (if you use &obj.field),
> 2. or, success of compilation *without any semantic breaking* (if you don't
> use &obj.field).
> 
> I think the result is not so harmful.

There's also the issue a variable being able to be passed by ref, which a property function can't emulate, which is why it would be quite valuable to be able to mark a variable as @property - either to indicate that it's illegal to do anything with it that you can't do with a property function or to make it so that it lowers to getter and setter property functions and therefore can't be used with anything which wouldn't work with a property function.

But if we could guarantee that swapping out variables and property functions wouldn't break code, then we could get rid of a _lot_ of property functions (since many of them don't do anything other than set and/or return the variable that they're wrapping). Because we currently allow stuff which only works with a variable or a function, we can't just seamlessly between variables and property functions, and it's not going to happen anywhere near as often for fear of breaking code. And many more people will simply create useless wrapper property functions around variables in case they need to add more code to them later (e.g. to validate the argument to the setter). We'd be much better off if anything which wasn't legal for both variables and property functions was made illegal for property functions and added a way to do the same for variables which are supposed to be treated as properties rather than explicitly being intended to be public variables like in a POD type.

We could save a lot of boilerplate code if we can simply make it variables and property functions guaranteed to be swappable without breaking code.

- Jonathan M Davis
February 04, 2013
On Monday, 4 February 2013 at 16:01:45 UTC, Steven Schveighoffer wrote:
> @property int foo();
>
> auto x = &foo; // error
> int delegate() x = &foo; // ok
>
> -Steve

I was going to submit the same suggestion, but didn't find time to until just now.

gets my vote.