title: Does C++11 support types recursion in templates?
body: <p>I want to explain the question in detail. In many languages with strong type systems (like Felix, Ocaml, Haskell) you can define a polymorphic list by composing type constructors. Here's the Felix definition:</p>
  
  <pre><code>typedef list[T] = 1 + T * list[T];
  typedef list[T] = (1 + T * self) as self;
  </code></pre>
  
  <p>In Ocaml:</p>
  
  <pre class="lang-ml prettyprint-override"><code>type 'a list = Empty | Cons ('a, 'a list)
  </code></pre>
  
  <p>In C, this is recursive but neither polymorphic nor compositional:</p>
  
  <pre><code>struct int_list { int elt; struct int_list *next; };
  </code></pre>
  
  <p>In C++ it would be done like this, if C++ supported type recursion:</p>
  
  <pre><code>struct unit {};
  template&lt;typename T&gt;
      using list&lt;T&gt; = variant&lt; unit, tuple&lt;T, list&lt;T&gt;&gt; &gt;;
  </code></pre>
  
  <p>given a suitable definition for tuple (aka pair) and variant (but not the broken one used in Boost). Alternatively:</p>
  
  <pre><code>    using list&lt;T&gt; = variant&lt; unit, tuple&lt;T, &amp;list&lt;T&gt;&gt; &gt;;
  </code></pre>
  
  <p>might be acceptable given a slightly different definition of variant. It was not possible to even write this in C++ &lt; C++11 because without template typedefs, there's no way to get polymorphism, and without a sane syntax for typedefs, there's no way to get the target type in scope. The using syntax above solves both these problems, however this does not imply recursion is permitted.</p>
  
  <p>In particular please note that allowing recursion has a major impact on the ABI, i.e. on name mangling (it can't be done unless the name mangling scheme allows for representation of fixpoints).</p>
  
  <p>My question: is required to work in C++11?
  [Assuming the expansion doesn't result in an infinitely large struct]</p>
  
  <hr>
  
  <p>Edit: just to be clear, the requirement is for general structural typing. Templates provide precisely that, for example</p>
  
  <pre><code>pair&lt;int, double&gt;
  pair&lt;int, pair &lt;long, double&gt; &gt;
  </code></pre>
  
  <p>are anonymously (structurally) typed, and pair is clearly polymorphic. However recursion in C++ &lt; C++11 cannot be stated, not even with a pointer. In C++11 you can state the recursion, albeit with a template typedef (with the new using syntax the expression on the LHS of the = sign is in scope on the RHS).</p>
  
  <p>Structural (anonymous) typing with polymorphism and recursion are minimal requirements for a type system. </p>
  
  <p>Any modern type system must support polynomial type functors or the type system is too clumbsy to do any kind of high level programming. The combinators required for this are usually stated by type theoreticians like:</p>
  
  <pre><code>1 | * | + | fix
  </code></pre>
  
  <p>where 1 is the unit type, * is tuple formation, + is variant formation, and fix is recursion. The idea is simply that:</p>
  
  <p>if t is a type and u is a type then t + u and t * u are also types</p>
  
  <p>In C++, struct unit{} is 1, tuple  is *, variant  is + and fixpoints might be obtained with the using = syntax. It's not quite anonymous typing because the fixpoint would require a template typedef.</p>
  
  <hr>
  
  <p>Edit: Just an example of polymorphic type constructor in C:</p>
  
  <pre><code>T*          // pointer formation
  T (*)(U)    // one argument function type
  T[2]        // array
  </code></pre>
  
  <p>Unfortunately in C, function values aren't compositional, and pointer formation is subject to lvalue constraint, and the syntactic rules for type composition are not themselves compositional, but here we can say:</p>
  
  <pre><code>if T is a type T* is a type
  if T and U are types, T (*)(U) is a type
  if T is a type T[2] is a type
  </code></pre>
  
  <p>so these type constuctors (combinators) can be applied recursively to get new types without having to create a new intermediate type. In C++ we can easily fix the syntactic problem:</p>
  
  <pre><code>template&lt;typename T&gt; using ptr&lt;T&gt; = T*;
  template&lt;typename T, typename U&gt; using fun&lt;T,U&gt; = T (*)(U);
  template&lt;typename T&gt; using arr2&lt;T&gt; = T[2];
  </code></pre>
  
  <p>so now you can write:</p>
  
  <pre><code>arr2&lt;fun&lt;double, ptr&lt;int&gt;&gt;&gt;
  </code></pre>
  
  <p>and the syntax is compositional, as well as the typing.</p>