About function keyword

deadalnix deadalnix at gmail.com
Sat Dec 10 14:41:21 PST 2011


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.

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 ?


More information about the Digitalmars-d mailing list