Imperative templates

Jonathan M Davis jmdavisProg at gmx.com
Sat Jul 16 15:36:17 PDT 2011


On Saturday 16 July 2011 16:58:25 Robert Clipsham wrote:
> So in several presentations given about D that I've seen there's a list
> of supported paradigms given which looks something like this:
> 
>   - Imperative
>   - Metal
>   - Object-oriented
>   - RAII
>   - Functional
>   - Generic
>   - Generative
>   - Concurrent
> 
> (That list from
> http://assets.en.oreilly.com/1/event/45/The%20D%20Programming%20Language%20P
> resentation.pdf ). But if this is the case, why do we not get this choice
> for template programming?
> 
> Currently templates have to be written in a functional manner, which is
> incredibly difficult if you're used to imperative programming, and I've
> found the code that it leads to is really difficult to maintain, even if
> it's well commented (this may not be the case for folk that are well
> versed in functional programming).
> 
> What I'd like to suggest is something like this:
> ----
> /// Template to get every other type in a type tuple
> template AlternateEven(T...)
> {
>      enum U = TypeTuple!();
>      for (size_t i = 0; i < T.length; i++)
>      {
>          if ((i & 1) == 0)
>          {
>              U ~= T[i];
>          }
>      }
>      alias U AlternateEven;
> }
> ----
> 
> To do this currently you need something like:
> ----
> template AlternateEven(T...)
> {
>      alias AlternateEvenImpl!(0, T) AlternateEven;
> }
> 
> template AlternateEvenImpl(size_t i, T...) if ((i & 1) == 0)
> {
>      static if (i < T.length)
>      {
>          alias TypeTuple!(T[i], AlternateEvenImpl!(i + 1, T))
> AlternateEvenImpl;
>      }
>      else
>      {
>          alias TypeTuple!() AlternateEvenImpl;
>      }
> }
> 
> template AlternateEvenImpl(size_t i, T...) if ((i & 1) != 0)
> {
>      static if (i < T.length)
>      {
>          alias AlternateEvenImpl!(i + 1, T) AlternateEvenImpl;
>      }
>      else
>      {
>          alias TypeTuple!() AlternateEvenImpl;
>      }
> }
> ----
> 
> Which is a lot more code, and a lot harder to understand at a quick
> glance. It gets even worse if you want to do something more
> complicated[1][2].
> 
> I don't think my example is the best example for a possible syntax, but
> that could be worked on. What does anyone else think?
> 
> [1] https://github.com/mrmonday/dmd/blob/js/dsrc/bind/util.d#L134
> [2]
> https://github.com/mrmonday/serenity/blob/master/serenity/persister/Sqlite.d
> #L126

You can actually do that a lot more simply than that:

template AlternateEven(T...)
{
    static if(T.length  == 0)
        alias TypeTuple!() AlternateEven;
    else static if(T.length  == 1)
        alias TypeTuple!(T[0]) AlternateEven;
    else
        alias TypeTuple!(T[0], AlternateEven!(T[2 .. $])) AlternateEven;
}

But it is true that template metaprogramming is functional in nature. In fact, 
I'd recommend reading this:

http://bartoszmilewski.wordpress.com/2009/10/21/what-does-haskell-have-to-do-
with-c/

It talks about how template metaprogramming in C++ is very much like Haskell, 
and even suggests essentially writing such templates as Haskell first 
(primarily because Haskell's syntax is so clean and C++'s template syntax is 
so insanely ugly). The basic concepts carry over to template metaprogramming 
in D, since it's essentially the same problem - we just have better syntax for 
it (so, designing your templates in Haskell first really shouldn't be 
necessary, but the concepts covered in that article would be good for you to 
go over).

Now, as for implementing templates in an imperative style... I don't know how 
feasible that is. You're essentially asking for a CTFE function which 
processes types. Instead of the type system handling it all, you're trying to 
run arbitrary code which does it. It's not an altogether unreasonable request, 
but I'd expect it to be a hard problem to solve. It's probably something that 
should be considered, since it would make life much easier for those who 
aren't familiar with how to program with functional languages, but it would 
probably take a lot of work to do, so I wouldn't expect it anytime soon.

Now, just for your general growth as a programmer, I'd suggest that you learn 
a functional language like Haskell. It definitely takes some getting use to, 
but there are some types of problems that are solved much more easily in a 
functional style, and having that in your programming toolbox would be of 
definite value to you (completely aside from the template metaprogramming 
issue).

So, I think that your request makes good sense as long as it can be reasonably 
implemented, but it's likely to take a lot of work to do it, and there may be 
some underlying issue that I don't see which makes it completely infeasible. 
So, it may happen, but it's the sort of thing that's likely to be a D3 feature 
if it every happens.

- Jonathan M Davis


More information about the Digitalmars-d mailing list