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