February 27, 2013
On Wednesday, 27 February 2013 at 06:15:29 UTC, dennis luehring wrote:
> Am 27.02.2013 06:54, schrieb deadalnix:
>>> In current D, the ambiguity is _already_ resolved - if you want
>>> to function
>>> address, use & operator.
>>>
>>
>> D behave very much like C on that regard, so I don't really see
>> how this can be true.
>
> void (*functionPtr)();
>
> //both are valid and working in C
> functionPtr xyz = &foo;
> functionPtr zxy = foo; //<- this is solved in D

I don't think D solved that. Only partially. Both are conflated here for instance :

void foo() {}
foo(); <=> (&foo)();

Is another presentation of the same conflation.

The DIP propose to effectively solve that by removing completely the entity represented by foo in &foo . You can't have conflation with something that do not exists.
February 27, 2013
On 02/27/2013 03:30 AM, deadalnix wrote:
> On Tuesday, 26 February 2013 at 21:01:04 UTC, Timon Gehr wrote:
>> On 02/26/2013 05:16 PM, deadalnix wrote:
>>> ...
>>> As usual, destroy, I don't expect to get unanimity on that. But I tried
>>> very hard to get most benefit of actual situation, including the
>>> possibility of optional parentheses in some situations (even if I'm not
>>> the biggest fan of it, I recognize that they are nice).
>>
>> If breaking code is an option, this is almost fine.
>>
>> Change the optional parens part to "optional parentheses are valid for
>> CTFE calls", and you might have me on board. It is also simpler, less
>> ad-hoc, and easier to implement than what the DIP currently states.
>
> Can you elaborate on that ? I'm not 100M satisfied with that part of the
> DIP, where I see everything else as a major improvement over current
> situation.

I'm not sure why elaboration would be necessary.
Remove the optional parens part, then:

int foo(int x){ ... }

2.foo // <- no meaning assigned by your DIP, make it a function call
February 27, 2013
2013/2/27 deadalnix <deadalnix@gmail.com>

> On Wednesday, 27 February 2013 at 06:15:29 UTC, dennis luehring wrote:
>
>> Am 27.02.2013 06:54, schrieb deadalnix:
>>
>>> In current D, the ambiguity is _already_ resolved - if you want
>>>> to function
>>>> address, use & operator.
>>>>
>>>>
>>> D behave very much like C on that regard, so I don't really see how this can be true.
>>>
>>
>> void (*functionPtr)();
>>
>> //both are valid and working in C
>> functionPtr xyz = &foo;
>> functionPtr zxy = foo; //<- this is solved in D
>>
>
> I don't think D solved that. Only partially. Both are conflated here for instance :
>
> void foo() {}
> foo(); <=> (&foo)();
>
> Is another presentation of the same conflation.
>
> The DIP propose to effectively solve that by removing completely the entity represented by foo in &foo . You can't have conflation with something that do not exists.
>

In D, function symbol and function pointer are distinct entities. The former is just accessible by its name and it has _no_ runtime value. The latter is a runtime value which generated by applying address operator to function symbol.

Also in C, essentially these entities are distinct, but C's semantic analyzer will implicitly apply address operator against the use of function name. Finally 'foo' has the same meaning as '&foo'. That has still introduced confusion to many programmer's.

Back to D, the two entities explicitly separated syntactically, and the use of function name is newly assigned as 'property call' (note that, the definition of 'property' is still debatable). So, applying DIP27 is just equivalent to discarding property feature.

Kenji Hara


February 27, 2013
On 02/27/2013 04:33 AM, kenji hara wrote:
> ...
> I agree with Jonathan. DIP27 is a recurrence of C's mistake.
> ...

No it is not.
February 27, 2013
On Wednesday, 27 February 2013 at 09:38:56 UTC, Timon Gehr wrote:
> I'm not sure why elaboration would be necessary.
> Remove the optional parens part, then:
>
> int foo(int x){ ... }
>
> 2.foo // <- no meaning assigned by your DIP, make it a function call

I considered optional parentheses where you would have an error, but I'm afraid that this could create weird effect with function overloads.

It may be limited to the case where expression can't be used as statement because it has no effect.
February 27, 2013
On 02/27/2013 11:24 AM, deadalnix wrote:
> On Wednesday, 27 February 2013 at 09:38:56 UTC, Timon Gehr wrote:
>> I'm not sure why elaboration would be necessary.
>> Remove the optional parens part, then:
>>
>> int foo(int x){ ... }
>>
>> 2.foo // <- no meaning assigned by your DIP, make it a function call
>
> I considered optional parentheses where you would have an error, but I'm
> afraid that this could create weird effect with function overloads.
>

There are no weird effects with function overloads in what I propose. What is the issue you are seeing?

> It may be limited to the case where expression can't be used as
> statement because it has no effect.

Then it is not worth it.
February 27, 2013
On 02/26/2013 10:01 PM, Timon Gehr wrote:
> On 02/26/2013 05:16 PM, deadalnix wrote:
>> ...
>> As usual, destroy, I don't expect to get unanimity on that. But I tried
>> very hard to get most benefit of actual situation, including the
>> possibility of optional parentheses in some situations (even if I'm not
>> the biggest fan of it, I recognize that they are nice).
>
> If breaking code is an option, this is almost fine.
>
> Change the optional parens part to "optional parentheses are valid for
> CTFE calls",

Ugh. Should be "UFCS calls".

> and you might have me on board. It is also simpler, less
> ad-hoc, and easier to implement than what the DIP currently states.

February 27, 2013
On Wednesday, 27 February 2013 at 10:41:01 UTC, Timon Gehr wrote:
> On 02/26/2013 10:01 PM, Timon Gehr wrote:
>> On 02/26/2013 05:16 PM, deadalnix wrote:
>>> ...
>>> As usual, destroy, I don't expect to get unanimity on that. But I tried
>>> very hard to get most benefit of actual situation, including the
>>> possibility of optional parentheses in some situations (even if I'm not
>>> the biggest fan of it, I recognize that they are nice).
>>
>> If breaking code is an option, this is almost fine.
>>
>> Change the optional parens part to "optional parentheses are valid for
>> CTFE calls",
>
> Ugh. Should be "UFCS calls".
>

Oh ! That make much more sense :D

Yes, UFCS is a nice use case for optional (). The actual proposal allow for chained UFCS calls, except the last one. Which is already a big win.
February 27, 2013
On Wednesday, 27 February 2013 at 10:38:05 UTC, Timon Gehr wrote:
>> I considered optional parentheses where you would have an error, but I'm
>> afraid that this could create weird effect with function overloads.
>>
>
> There are no weird effects with function overloads in what I propose. What is the issue you are seeing?
>

Consider the following situation :

void foo(uint a) {
    writeln("a is ", a);
}

uint bar() {
    return 0;
}

foo(bar); // a is 0

Later, this function is added :
void foo(uint function() a) {
    writeln("function not executed");
}

The statement above become :
foo(bar); // function not executed

Note that foo can be in other modules, so it may not be obvious. It can be solved in various ways, and I actually implemented some to play around. I was not satisfied with the result.

>> It may be limited to the case where expression can't be used as
>> statement because it has no effect.
>
> Then it is not worth it.

It would kick in with the example you gave.
February 27, 2013
On 02/27/2013 11:57 AM, deadalnix wrote:
> On Wednesday, 27 February 2013 at 10:38:05 UTC, Timon Gehr wrote:
>>> I considered optional parentheses where you would have an error, but I'm
>>> afraid that this could create weird effect with function overloads.
>>>
>>
>> There are no weird effects with function overloads in what I propose.
>> What is the issue you are seeing?
>>
>
> Consider the following situation :
>
> void foo(uint a) {
>      writeln("a is ", a);
> }
>
> uint bar() {
>      return 0;
> }
>
> foo(bar); // a is 0
>

error: incompatible argument types (uint function()) to function foo(uint a)

> Later, this function is added :
> void foo(uint function() a) {
>      writeln("function not executed");
> }
>
> The statement above become :
> foo(bar); // function not executed
>
> Note that foo can be in other modules, so it may not be obvious. It can
> be solved in various ways, and I actually implemented some to play
> around. I was not satisfied with the result.
>

I see. This problem does not occur. (There is no UFCS in the above code.)

>>> It may be limited to the case where expression can't be used as
>>> statement because it has no effect.
>>
>> Then it is not worth it.
>
> It would kick in with the example you gave.

Not necessarily, it would depend on the context of the expression I gave.