5

I'm still evaluating if i should start using D for prototyping numerical code in physics.

One thing that stops me is I like boost, specifically fusion and mpl.

D is amazing for template meta-programming and i would think it can do mpl and fusion stuff but I would like to make sure.

Even if i'll start using d, it would take me a while to get to the mpl level. So i'd like someone to share their experience.

(by mpl i mean using stl for templates and by fusion, i mean stl for tuples.)

a note on performance would be nice too, since it's critical in physics simulations.

kirill_igum
  • 3,953
  • 5
  • 47
  • 73
  • You shouldn't really need *template* metaprogramming; D has compile-time function evaluation. – user541686 Jan 11 '13 at 22:13
  • @Mehrdad for everything? you can do find_if or transform on template parameters? – kirill_igum Jan 11 '13 at 22:15
  • Not for everything (there are still bugs to be fixed), but for quite a lot of things. It's hard to give a generic answer but if you have a particular example please post it and I'll see if I can find a CTFE version of it and show you. – user541686 Jan 11 '13 at 22:19
  • I was looking for a generic answer or some thoughts on the issue. but a specific example can be an example in this http://www.boost.org/doc/libs/1_52_0/libs/mpl/doc/refmanual/accumulate.html – kirill_igum Jan 11 '13 at 22:30
  • @Mehrdad the link is empty – kirill_igum Jan 11 '13 at 22:47
  • Oops, I think the dollar sign got messed up, sorry. Try it again by clicking [here](http://liveworkspace.org/code/2rARP3$2). – user541686 Jan 11 '13 at 22:48
  • @Mehrdad thank you, it makes sense. I have some additional questions. I see that your code sums up values rather then types. i guess you can replace the values by types, right?. also it outputs the result as a compilation warning rather then a compiled value. it's a bit different from what I expected (i didn't expect to use pragma, i thought compile time is automatic). I also re-read chapter 5.12 (compile-time evaluation) of d.lang book and couldn't find much on types. so it seems that it's possible to use MPL functionality in D but through hacks rather than a standardize approach. right? – kirill_igum Jan 11 '13 at 23:34
  • 1
    Yeah definitely, I only put it in a pragma to illustrate that it's happening at compile-time. If you put it in normal code which doesn't *require* the value to be known at compile time then there's no guarantee that it will be evaluated at compile time (but it might be). As for "summing types", you can easily say `typeof(Type1.init + Type2.init)` to get the type that represents the sum of variables of type `Type1` and `Type2`... that should get you what you need. – user541686 Jan 11 '13 at 23:38
  • @Mehrdad ok. makes sense. i'm still looking for a more general answer but if nothing else comes, you answered my question. up to you if you want to sum it up as an answer (or i can do it a bit later). – kirill_igum Jan 11 '13 at 23:49
  • Haha I don't have much to say, feel free to post your own if you'd like. If I come up with a good one I'll post it I guess. – user541686 Jan 11 '13 at 23:50

1 Answers1

7

In D, for the most part, meta-programming is just programming. There's not really any need for a library like boost.mpl

For example, consider the lengths you would have to go to in C++ to sort an array of numbers at compile time. In D, you just do the obvious thing: use std.algorithm.sort

import std.algorithm;

int[] sorted(int[] xs)
{
    int[] ys = xs.dup;
    sort(ys);
    return ys;
}

pragma(msg, sorted([2, 1, 3]));

This prints out [1, 2, 3] at compile time. Note: sort is not built into the language and has absolutely no special code for working at compile time.

Here's another example that builds a lookup table for Fibonacci sequence at compile time.

int[] fibs(int n)
{
    auto fib = recurrence!("a[n-1] + a[n-2]")(1, 1);
    int[] ret = new int[n];
    copy(fib.take(n), ret);
    return ret;
}

immutable int[] fibLUT = fibs(10).assumeUnique();

Here, fibLUT is constructed entirely at compile time, again without any special compile time code needed.

If you want to work with types, there are a few type meta functions in std.typetuple. For example:

static assert(is(Filter!(isUnsigned, int, byte, ubyte, dstring, dchar, uint, ulong) ==
              TypeTuple!(ubyte, uint, ulong)));

That library, I believe, contains most of the functionality you can get from Fusion. Remember though, you really don't need to use much of template meta-programming stuff in D as much as you do in C++, because most of the language is available at compile time anyway.

I can't really comment on performance because I don't have vast experience with both. However, my instinct would be that D's compile time execution is faster because you generally don't need to instantiate numerous templates. Of course, C++ compilers are more mature, so I could be wrong here. The only way you'll really find out is by trying it for your particular use case.

Peter Alexander
  • 53,344
  • 14
  • 119
  • 168