And there goes the formatting, here's a pastebin version:
http://pastebin.com/dHdiG0ce

On Wednesday, 21 March 2012 at 01:41:27 UTC, Rene Zwanenburg wrote:
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] ~ ");";
}


Reply via email to