The One-Letter Nested Function - a sample article for some kind of D "gems" website
Zach the Mystic
reachzachatgooglesmailservice at dot.com
Mon Feb 13 05:19:36 PST 2012
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.
More information about the Digitalmars-d
mailing list