views:

167

answers:

2

I'm currently learning D, and one of the things I've wondered about is whether D has a way of duplicating the code generation capabilities of JVM languages.

Here's a scenario: I have an object, and I want to generate a string based on that object that gives it's name and all its fields. In Java/Scala, I could just use reflection, but suppose speed is an issue. I could use a bytecode generation library to dynamically generate and compile a class that does this without reflection. The implementation would break down to iterating through the object's fields and getting it's name through recursion, and using that information to dynamically generate Java (or bytecode) that accesses the fields directly.

If you don't like that scenario because it's weak and/or unrealistic, another one that might be more realistic is optimized object serialization.

I've seen examples where D's compile time evaluation and/or template metaprogramming is used for things like precalculating the fibonacci sequence at compile time and other recursive algorithms, but is there a way of doing things like this with just the language and a compiler, or would you need to develop a separate code-generator and run it before the compiler to get this sort of functionality?

+3  A: 

String mixins can access the namespace they're mixed into. That includes this.tupleof, which can be used for iterating the fields of a class. A serialization template might take advantage of that, or otherwise force the user to specify the fields to serialize by hand; ie. class Class : ISerializable { int foo; Forble bar; mixin(genSerialize("foo, bar")); ... }

FeepingCreature
+2  A: 

Not only can this be done, it's practically done for you in D2. All you need is a small mixin to turn these from compile time features into runtime features. For the class name, all you need to do is evaluate typeof(this).stringof inside the class's scope. For a list of all fields, try __traits(allMembers, typeof(this)) and then filter out the stuff that's not a field (std.traits will be useful here).

dsimcha