About function keyword

kenji hara k.hara.pg at gmail.com
Sat Dec 10 15:35:21 PST 2011


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


More information about the Digitalmars-d mailing list