{"id":1878,"date":"2012-10-24T20:00:01","date_gmt":"2012-10-24T19:00:01","guid":{"rendered":"https:\/\/www.reenigne.org\/blog\/?p=1878"},"modified":"2016-01-31T17:44:33","modified_gmt":"2016-01-31T17:44:33","slug":"variadic-templates-in-alfe","status":"publish","type":"post","link":"https:\/\/www.reenigne.org\/blog\/variadic-templates-in-alfe\/","title":{"rendered":"Variadic templates in ALFE"},"content":{"rendered":"<p><a href=\"https:\/\/www.reenigne.org\/blog\/function-types-in-alfe\">Some of<\/a> <a href=\"https:\/\/www.reenigne.org\/blog\/sum-types-in-alfe\">the<\/a> <a href=\"https:\/\/www.reenigne.org\/blog\/product-types-in-alfe\">types<\/a> in ALFE are templates which can accept different numbers of parameters &#8211; in other words, variadic templates. How does this fit in with the <a href=\"https:\/\/www.reenigne.org\/blog\/templates-and-kinds-in-alfe\">Kind system I wrote about before<\/a>?<\/p>\n<p>As well as the Kind constructors &#8220;<strong>&lt;&gt;<\/strong>&#8221; (template) and &#8220;&#8221; (type), we need a third Kind constructor which represents zero or more Kinds in a sequence suitable for template arguments. Let&#8217;s call this Kind constructor &#8220;<strong>&#8230;<\/strong>&#8220;. As with C++ templates, we should allow the members of the sequence to have arbitrary kind. So <strong>&lt;&#8230;&gt;<\/strong> is the kind of a template that takes zero or more arguments whose kinds are type, while <strong>&lt;&lt;&gt;&#8230;&gt;<\/strong> is the kind of a template that takes zero or more arguments whose kinds are <strong>&lt;&gt;<\/strong> (a single argument template whose argument is of kind type). The kind of <strong>Function<\/strong> is <strong>&lt;, &#8230;&gt;<\/strong> (the comma is required because <strong>Function<\/strong> has one or more arguments rather than zero or more). More complicated kinds like <strong>&lt;&lt;&#8230;&gt;, &#8230;&gt;<\/strong> are also possible.<\/p>\n<p>To actually create a variadic template, we need to implement &#8220;recursive case&#8221; and &#8220;base case&#8221; templates and have the compiler choose between them by pattern matching, just as in C++. So the definition of <strong>Tuple<\/strong> might look something like:<\/p>\n<pre lang=\"cpp\">\r\nTuple<@T, ...> = Structure { T first; Tuple<...> rest; };\r\nTuple<> = Structure { };\r\n<\/pre>\n<p>Is that enough? Well, I believe this gives ALFE&#8217;s kind system parity with C++&#8217;s. <del>However, there is one more possible Kind constructor that I can imagine &#8211; the Kind constructor which can represent any Kind at all &#8211; let&#8217;s call it <strong>$<\/strong>. A template with an argument of this kind (i.e. has kind <strong>&lt;$&gt;<\/strong>) can be instantiated with an argument of any kind. So you could have:<\/del><\/p>\n<pre lang=\"cpp\" style=\"text-decoration: line-through;\">\r\nFoo<@T> = { ... };\r\nFoo<@T<>> = { ... };\r\nFoo<@T<@R<$>>> = { ... };\r\n<\/pre>\n<p><del>The first template is used when <strong>Foo<\/strong> is instantiated with a type, the second is used when it&#8217;s instantiated with a template of kind <strong>&lt;&gt;<\/strong> and the third is used when it&#8217;s instantiated with any other single-argument template, no matter what the kind of the argument is. The third template could then pass <strong>R<\/strong> as an argument to another instantiation of <strong>Foo<\/strong> and thereby &#8220;peel apart&#8221; the kind of the argument (as long as none of the kinds involved have multiple arguments).<\/del><\/p>\n<p><del>By combining <strong>$<\/strong> with <strong>&#8230;<\/strong> I think we could potentially peel apart completely arbitrary kinds. However, I&#8217;m not sure if this is worth implementing since I can&#8217;t think of any use for such a thing. Still, it&#8217;s good to have some idea about how to proceed if I do eventually come across such a use!<\/del><\/p>\n<p>Edited 31st January 2016: Since writing the above, I have realized that the concept of the <strong>$<\/strong> Kind specifier has a fatal flaw. Just because our <strong>Foo<\/strong> template has been instantiated with a template of a particular kind, does not mean that we have any way of obtaining type constructors of suitable kinds for instantiating that template. We can&#8217;t pass <strong>R<\/strong> as an argument to another instantiation of <strong>Foo<\/strong> because we have no way to find such a thing to pass &#8211; all we have is a template that we know takes such a thing. There might be no suitable type constructors in the entire program! So there is really nothing we can do with our <strong>T<\/strong> here at all &#8211; we can&#8217;t instantiate it (even partially) since we don&#8217;t know the kind of its first argument. We could pass it to another template, but that just moves the problem around without making any progress on it. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>Some of the types in ALFE are templates which can accept different numbers of parameters &#8211; in other words, variadic templates. How does this fit in with the Kind system I wrote about before? As well as the Kind constructors &#8220;&lt;&gt;&#8221; (template) and &#8220;&#8221; (type), we need a third Kind constructor which represents zero or [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,27],"tags":[],"class_list":["post-1878","post","type-post","status-publish","format-standard","hentry","category-computer","category-language"],"_links":{"self":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/1878","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/comments?post=1878"}],"version-history":[{"count":4,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/1878\/revisions"}],"predecessor-version":[{"id":1990,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/posts\/1878\/revisions\/1990"}],"wp:attachment":[{"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/media?parent=1878"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/categories?post=1878"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.reenigne.org\/blog\/wp-json\/wp\/v2\/tags?post=1878"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}