The One-Letter Nested Function - a sample article for some kind of D gems website
I wrote this article because I felt like helping other people coming to D, but I'm not sure where the appropriate place to make such a contribution is. Maybe a Learning Articles or an Idioms section. The One-Letter Nested Function As a programmer new to D I wanted to share an idiom I've been using. This article will share two cases in which I've found the one-letter nested function to come in very handy. The following function has a lot of ugly cast( code. void setRandomColorPair( ref ColorPair cp ) { import std.random; cp.foreground = Color( cast(ubyte) uniform(40,200), cast(ubyte) uniform(50,100), cast(ubyte) uniform(150, 250) ); cp.background = Color( cast(ubyte) uniform(40,200), cast(ubyte) uniform(50,100), cast(ubyte) uniform(200, 250) ); } But with the one-letter nested function, the above became: void setRandomColorPair( ref ColorPair cp ) { import std.random; ubyte u(int a, int b) { return cast(ubyte) uniform(a,b); } cp.foreground = Color( u(40,200), u(50,100), u(150, 250) ); cp.background = Color( u(40,200), u(50,100), u(200, 250) ); } It was a mild gain, but it really started to add up when I was assigning to more than just two variables. The next example is for C programmers. Suppose you're faced with translating this code written in C: void print_init_flags(int flags) { #define PFLAG(a) if( flags INIT_##a ) printf(#a ) PFLAG(FLAC); PFLAG(MOD); PFLAG(MP3); PFLAG(OGG); if(!flags) printf(None); printf(\n); } That #define macro is actually quite efficient, and since D doesn't have literal macros it looks like the D replacement could get pretty wordy, since we're going to need string mix-ins. But D *does* have nested functions. Look: void printInitFlags( int flags ) { string w(string f) { return `if( flags INIT_`~f~` ) write(MIX_INIT_`~f~` );`; } mixin( w(FLAC) ); mixin( w(MOD) ); mixin( w(MP3) ); mixin( w(OGG) ); if(!flags) write (None); writeln(); } This is, I think, one of the rare cases where the C code is actually more concise than the translated D code, but when I tried the one-letter nested function idiom, it became a moot point.
Re: The One-Letter Nested Function - a sample article for some kind of D gems website
With 2.058 the single-letter function can become: auto u = (int a, int b) = cast(ubyte)uniform(a, b); It's not much of savings in typing. The only problem is I can't seem to make it static: static u = (int a, int b) = cast(ubyte)uniform(a, b); Error: non-constant nested delegate literal expression __lambda1 It would be better if you didn't have to specify the argument types. I think bear asked for templated lambdas, so this could eventually become: auto u = (a, b) = cast(ubyte)uniform(a, b); Which would make 'u' a template. I'm not sure what the exact syntax was that was requested though.
Re: The One-Letter Nested Function - a sample article for some kind of D gems website
On 2/13/12 2:43 PM, Andrej Mitrovic wrote: auto u = (a, b) = cast(ubyte)uniform(a, b); Which would make 'u' a template. I'm not sure what the exact syntax was that was requested though. This could never work without major changes to the language, because 'u' cannot be assigned a type. David
Re: The One-Letter Nested Function - a sample article for some kind of D gems website
On 2/13/12, David Nadlinger s...@klickverbot.at wrote: This could never work without major changes to the language, because 'u' cannot be assigned a type. Yeah, the syntax is wrong. I found bear's post and the syntax: alias (x = x ^^ 2) sqrTemplate; So it would be: alias ((a, b) = cast(ubyte)uniform(a, b)) u;
Re: The One-Letter Nested Function - a sample article for some kind of D gems website
On 13/02/2012 14:21, Andrej Mitrovic wrote: On 2/13/12, David Nadlingers...@klickverbot.at wrote: This could never work without major changes to the language, because 'u' cannot be assigned a type. Yeah, the syntax is wrong. I found bear's post and the syntax: alias (x = x ^^ 2) sqrTemplate; So it would be: alias ((a, b) = cast(ubyte)uniform(a, b)) u; Here 'alias name = expression' syntax helps shed brackets: alias u = (a, b) = cast(ubyte)uniform(a, b); That looks nice IMO.
Re: The One-Letter Nested Function - a sample article for some kind of D gems website
On 2/13/12 7:46 AM, David Nadlinger wrote: On 2/13/12 2:43 PM, Andrej Mitrovic wrote: auto u = (a, b) = cast(ubyte)uniform(a, b); Which would make 'u' a template. I'm not sure what the exact syntax was that was requested though. This could never work without major changes to the language, because 'u' cannot be assigned a type. David alias (a, b) = cast(ubyte)uniform(a, b) u; should work. This makes is a case where the discussed syntax alias defined = definee; would be helpful. Andrei