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