On Mon, Dec 20, 2010 at 1:06 AM, loser <[email protected]> wrote: > Daniel Gibson Wrote: > >> On Sun, Dec 19, 2010 at 5:44 PM, Andrei Alexandrescu >> <[email protected]> wrote: >> > On 12/19/10 10:35 AM, Ary Borenszweig wrote: >> >> >> >> On 12/19/2010 01:21 PM, Andrei Alexandrescu wrote: >> >>> >> >>> On 12/19/10 9:32 AM, Ary Borenszweig wrote: >> >>>> >> >>>> I have this code: >> >>>> >> >>>> --- >> >>>> import std.stdio; >> >>>> >> >>>> int foobar(int delegate(int) f) { >> >>>> return f(1); >> >>>> } >> >>>> >> >>>> int foobar2(string s)() { >> >>>> int x = 1; >> >>>> mixin("return " ~ s ~ ";"); >> >>>> } >> >>>> >> >>>> void main() { >> >>>> writefln("%d", foobar((int x) { return 2*x; })); >> >>>> writefln("%d", foobar2!("9876*x")); >> >>>> } >> >>>> --- >> >>>> >> >>>> When I compile it with -O -inline I can see with obj2asm that for the >> >>>> first writefln the delegate is being called. However, for the second >> >>>> it just passes >> >>>> 9876 to writefln. >> >>>> >> >>>> From this I can say many things: >> >>>> - It seems that if I want hyper-high performance in my code I must use >> >>>> string mixins because delegate calls, even if they are very simple and >> >>>> the >> >>>> functions that uses them are also very simple, are not inlined. This >> >>>> has the drawback that each call to foobar2 with a different string >> >>>> will generate a >> >>>> different method in the object file. >> >>> >> >>> You forgot: >> >>> >> >>> writefln("%d", foobar2!((x) { return 2*x; })()); >> >>> >> >>> That's a real delegate, not a string, but it will be inlined. >> >>> >> >>> >> >>> Andrei >> >> >> >> Sorry, I don't understand. I tried these: >> >> >> >> 1. >> >> int foobar3(int delegate(int) f)() { >> >> return f(1); >> >> } >> >> >> >> writefln("%d", foobar3!((int x) { return 2*x; })()); >> >> >> >> => foo.d(12): Error: arithmetic/string type expected for >> >> value-parameter, not int delegate(int) >> >> >> >> 2. >> >> int foobar3()(int delegate(int) f) { >> >> return f(1); >> >> } >> >> >> >> writefln("%d", foobar3!()((int x) { return 2*x; })); >> >> >> >> => Works, but it doesn't get inlined. >> >> >> >> And I tried that "(x) { ... }" syntax and it doesn't work. >> >> >> >> Sorry, it must be my fault I'm doing something wrong. What's the correct >> >> way of writing optimized code in D, code that I'm sure the compiler will >> >> know how to optimize? >> > >> > void foobar3(alias fun)() { >> > return fun(1); >> > } >> > >> > >> > Andrei >> > >> >> I think using an alias makes the code less readable. >> "int foobar(int delegate(int) f)" tells you that the argument should be (a >> delegate of) a function that accepts an int and returns an int. >> "foobar3(alias fun)()" tells you almost nothing. You know that some kind of >> template parameter is expected, but not if it's a function or whatever, and >> even less what signature that function should have. >> >> IMHO some other syntax than just "alias fun" should be used for this purpose >> (inlined delegates known at compile time) - some syntax that documents the >> signature of the expected function, like with real delegates. > > Hear, hear. Another problem with this approach I couldn't even think of. With > luck, illegal code may compile. You have no clean way to enforce/document the > domain of the comparator/predicate. >
I don't think illegal code would compile, when fun is called in foobar() the compiler will check if the function aliased by fun has a suitable signature. My point concerns only readability of function-signatures, I think. IMHO when you look at a function signature you should know what kind of parameters are expected, at least in a strongly typed language.
