2011/12/11 Timon Gehr <timon.g...@gmx.ch>: > 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;
In here, x and y are variables, not types. Perhaps your assuming is: alias void delegate() x; alias void function() y; > static assert(is(x == delegate)); // fine > static assert(is(y == function)); // fail Yes, it is syntactic problem. Better syntax and keyword would become the learning more easier. Kenji Hara