Three Unlikely Successful Features of D
Rene Zwanenburg
renezwanenburg at gmail.com
Tue Mar 20 18:41:26 PDT 2012
On Tuesday, 20 March 2012 at 19:02:16 UTC, Andrei Alexandrescu
wrote:
> I plan to give a talk at Lang.NEXT
> (http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012) with
> the subject above. There are a few features of D that turned
> out to be successful, in spite of them being seemingly
> unimportant or diverging from related consecrated approaches.
>
> What are your faves? I have a few in mind, but wouldn't want to
> influence answers.
>
>
> Thanks,
>
> Andrei
I've seen most of D's cool features mentioned, but I believe
nobody mentioned mixins yet. Mixins are messy to maintain, but
together with CTFE they can be used to create some really neat
code if used properly.
One of the first things I wrote while learning D is a vector
class. In GLSL vectors can be 'swizzled', for example:
vec3(1, 2, 3).zyx == vec3(3, 2, 1);
Swizzles are often useful in graphics or physics code. I don't
know of any non-shading language that allows me to use swizzle
syntax. As the following code shows, it's quite easy to do in D:
module main;
import std.stdio;
import std.process;
import std.conv;
int main(string[] argv) {
alias Vec!4 Vec4;
Vec4 v = Vec4(1, 2, 3, 4);
writeln(v.bgra); // Prints Vec!(4)([3, 2, 1, 4])
writeln(v.rg); // Prints Vec!(2)([1, 2])
return 0;
}
private immutable (char[][]) elementNames = [['x', 'y', 'z',
'w'], ['r', 'g', 'b', 'a'], ['s', 't', 'p', 'q']];
struct Vec(size_t size) {
alias size Size;
mixin(generateConstructor(Size));
mixin(generateProperties(Size));
auto opDispatch(string s)() {
mixin(generateSwizzle(s));
}
float v[Size];
}
private string generateConstructor(size_t size) {
string constructorParams;
string constructorBody;
foreach(i; 0..size) {
string paramName = "v" ~ to!string(i);
constructorParams ~= "float " ~ paramName ~ "=0,";
constructorBody ~= "v[" ~ to!string(i) ~ "] = " ~ paramName ~
";";
}
return "this(" ~ constructorParams[0..$-1] ~ "){" ~
constructorBody ~ "}";
}
private string generateProperties(size_t size) {
string props;
foreach(names; elementNames) {
foreach(i, name; names[0..size]) {
props ~= "@property float " ~ name ~ "() const { return v["
~ to!string(i) ~ "]; }";
props ~= "@property void " ~ name ~ "(float f) { v[" ~
to!string(i) ~ "] = f; }";
}
}
return props;
}
private string generateSwizzle(string elements) {
string swizzleImpl = "return Vec!" ~ to!string(elements.length)
~ "(";
foreach(e; elements) {
swizzleImpl ~= e ~ ",";
}
return swizzleImpl[0..$-1] ~ ");";
}
More information about the Digitalmars-d
mailing list