On 12/11/2011 12:35 AM, kenji hara wrote:
2011/12/11 deadalnix<deadal...@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








Reply via email to