About function keyword

kenji hara k.hara.pg at gmail.com
Sat Dec 10 16:10:27 PST 2011


2011/12/11 Timon Gehr <timon.gehr at gmx.ch>:
> On 12/11/2011 12:35 AM, kenji hara wrote:
>>
>> 2011/12/11 deadalnix<deadalnix at gmail.com>:
>>>
>>> Hi,
>>>
>>> I was working with std.concurrency and discovered a (now reported) bug
>>> about
>>> receive and function. It lead me to some experimentations with fucntions.
>>> consider the code bellow :
>>>
>>> module funtest;
>>>
>>> import std.stdio;
>>>
>>> void infos(T)(T fun) {
>>>        writeln(typeof(fun).stringof);
>>>        writeln("is function ? : ", is(T == function)); // Always false
>>>        writeln("is delegate ? : ", is(T == delegate)); // true if we have
>>> a
>>> delegate
>>> }
>>>
>>> int doNothing() { return 0; }
>>>
>>> void main() {
>>>        infos(doNothing); // Evaluate even if it isn't @property .
>>> Expected
>>> behaviour ?
>>>        infos(&doNothing);
>>>        auto fun =&doNothing; infos(&fun);
>>>
>>>        infos(function int() { return 0; });
>>>        infos(delegate int() { return 0; });
>>>        infos(() { return 0; }); // Delegate ??
>>> }
>>>
>>> And its output :
>>>
>>> int
>>> is function ? : false
>>> is delegate ? : false
>>> int function()
>>> is function ? : false
>>> is delegate ? : false
>>> int function()*
>>> is function ? : false
>>> is delegate ? : false
>>> int function() pure nothrow @safe
>>> is function ? : false
>>> is delegate ? : false
>>> int delegate() pure nothrow @safe
>>> is function ? : false
>>> is delegate ? : true
>>> int delegate() pure nothrow
>>> is function ? : false
>>> is delegate ? : true
>>>
>>> Now some strange stuff happens. I wonder if they all are intended. First
>>> of
>>> all, in the first case, doNothing is evaluated, even with no () . This
>>> function isn't @property, so this behaviour is somehow misleading and
>>> error
>>> prone.
>>
>>
>> If you don't specify -property switch in command line, `doNothing` is
>> implicitly converted to `doNothing()` for backward compatibility. It
>> is correct behavior.
>>
>>> When passing a delegate, is(T == delegate) is true, but when passing a
>>> function is(T == function) is false. This is also misleading and
>>> inconsistent. This lead to the bugs in std.concurrency I faced.
>>>
>>> When it is not specifiate if something is a delegate or a function, the
>>> compiler always makes it a delegate. Is it intended ? This can create
>>> some
>>> overhead in many cases for nothing. Plus, this si always possible to wrap
>>> a
>>> function into a delegate, but the other way around isn't possible. So the
>>> compiler should do its best to make a function whatever can be one.
>>>
>>> Even if it is not in the code snippet, typeof(doNothing).stringof is
>>> int() .
>>> When doNothing is passed, it is evaluated, and we get an int. Theses 2
>>> results are counter intuitives, and this is a types of things that we
>>> want
>>> to avoid in D.
>>>
>>> So, what is a bug ? What is an expected behaviour ? What isn't
>>> defined/decided yet ? And what do we decide if it is so ?
>>
>>
>> is(X == function) checks whether the X is a function type.
>> For example, this code can compile without error.
>>
>> static assert(is(typeof(doNothing) == function));
>>
>> doNothing is non-property free function, so its type is function type.
>>
>> I agree that is(X == function) is bit difficult to understand, but it
>> is consistent feature and there is no bug.
>>
>> Kenji Hara
>
>
> There is no bug, but it is not consistent.
>
> void delegate() x;
> void function() y;

In here, x and y are variables, not types. Perhaps your assuming is:
alias void delegate() x;
alias void function() y;

> static assert(is(x == delegate)); // fine
> static assert(is(y == function)); // fail

Yes, it is syntactic problem.
Better syntax and keyword would become the learning more easier.

Kenji Hara


More information about the Digitalmars-d mailing list