static map as a type function

Timon Gehr timon.gehr at gmx.ch
Thu Sep 24 10:08:30 UTC 2020


On 24.09.20 05:51, Paul Backus wrote:
> 
> I feel the same way about the naive recursive version:
> 
> template staticMap!(alias F, Args...) {
>      static if (Args.length == 0)
>          alias staticMap = AliasSeq!();
>      else
>          alias staticMap = AliasSeq!(F!(Args[0]), staticMap!(F, Args[1 
> .. $]));
> }
> 
> One base case, one recursive case, one line for each. The code 
> practically writes itself. How could it be any clearer or more obvious?
> 
> Making it tail-recursive takes away some of the elegance, but doesn't 
> make it any more "interesting":
> 
> template staticMap(alias F, Args...) {
>      template loop(size_t i, Args...) {
>          static if (start == Args.length)
>              alias loop = Args;
>          else
>              alias loop = loop!(i + 1, Args[0 .. i], F!(Args[i]), 
> Args[i+1 .. $]);
>      }
>      alias staticMap = loop!(0, Args);
> }
> 
> If you have spent any time at all writing code in a functional language 
> with tail-call elimination, this pattern will be immediately familiar to 
> you. There's nothing about it that's hard to understand, or difficult to 
> follow. It's completely textbook.
> ...

True, only a novice would use explicit recursion. map=(`foldr`[]).((:).)

> Of course, for someone who lacks that background, it might very well 
> look bewildering--in the same way that, say, the Visitor pattern might 
> look bewildering to someone unfamiliar with the idioms of OOP. Does that 
> mean it's a bad pattern? Or does it just mean it's a pattern they 
> haven't learned yet?

It means your programming language lacks features to write the code in a 
better way. Note that D templates form a very ugly programming language 
with a semantics that is hard to implement efficiently.


More information about the Digitalmars-d mailing list