About function keyword

Timon Gehr timon.gehr at gmx.ch
Sat Dec 10 15:51:39 PST 2011


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;

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










More information about the Digitalmars-d mailing list