<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: hirrolot</title>
    <description>The latest articles on DEV Community by hirrolot (@hirrolot).</description>
    <link>https://dev.to/hirrolot</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F569812%2Fde765279-f6ca-4473-891c-eb748099accc.jpg</url>
      <title>DEV Community: hirrolot</title>
      <link>https://dev.to/hirrolot</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hirrolot"/>
    <language>en</language>
    <item>
      <title>Compiling Algebraic Data Types in Pure C99</title>
      <dc:creator>hirrolot</dc:creator>
      <pubDate>Tue, 25 May 2021 10:18:07 +0000</pubDate>
      <link>https://dev.to/hirrolot/compiling-algebraic-data-types-in-pure-c99-5225</link>
      <guid>https://dev.to/hirrolot/compiling-algebraic-data-types-in-pure-c99-5225</guid>
      <description>&lt;p&gt;Lots of people have been constantly asking me how &lt;a href="https://github.com/Hirrolot/datatype99" rel="noopener noreferrer"&gt;Datatype99&lt;/a&gt; works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;datatype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;BinaryTree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BinaryTree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BinaryTree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BinaryTree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rhs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rhs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This library implements &lt;a href="https://en.wikipedia.org/wiki/Algebraic_data_type" rel="noopener noreferrer"&gt;algebraic data types (ADT)&lt;/a&gt; for pure C99. This allows you to design convenient, type-safe interfaces while sticking to plain old C with zero runtime dependencies. Today I would like to explain what the hell it does under the hood!&lt;/p&gt;

&lt;p&gt;If you are not acquainted with the concept of algebraic data types, please read &lt;a href="https://medium.com/@hirrolot/unleashing-sum-types-in-pure-c99-31544302d2ba" rel="noopener noreferrer"&gt;&lt;em&gt;Unleashing Sum Types in Pure C99&lt;/em&gt;&lt;/a&gt; first.&lt;/p&gt;

&lt;p&gt;To study the formal system on a concrete example, it is helpful to read this post along with the &lt;a href="https://godbolt.org/z/vq1M3nWYa" rel="noopener noreferrer"&gt;generated output&lt;/a&gt; of &lt;a href="https://github.com/Hirrolot/datatype99/blob/master/examples/binary_tree.c" rel="noopener noreferrer"&gt;&lt;code&gt;examples/binary_tree.c&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Data layout
&lt;/h1&gt;

&lt;p&gt;First of all, we want to generate a data layout for a sum type. This is achieved by a tagged union: a union of possible variants data paired with a tag (discriminant). The latter is an integer designating which particular variant is active now.&lt;/p&gt;

&lt;p&gt;Provided that multiple parameters can be specified in a single variant definition, we must gather them all into a separate C structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef struct &amp;lt;datatype-name&amp;gt;&amp;lt;variant-name&amp;gt; {
    &amp;lt;type&amp;gt;0 _0;
    ...
    &amp;lt;type&amp;gt;N _N;
} &amp;lt;datatype-name&amp;gt;&amp;lt;variant-name&amp;gt;;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Metavariables:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;datatype-name&amp;gt;&lt;/code&gt; is a sum type name.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;variant-name&amp;gt;&lt;/code&gt; is a variant name.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;type&amp;gt;I&lt;/code&gt; is a type of Ith variant parameter.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far so good. Now, in order to collect all variant data structures into a single entity, we must put them into a union:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef union &amp;lt;datatype-name&amp;gt;Variants {
    char dummy;

    &amp;lt;datatype-name&amp;gt;&amp;lt;variant-name&amp;gt;0 &amp;lt;variant-name&amp;gt;0;
    ...
    &amp;lt;datatype-name&amp;gt;&amp;lt;variant-name&amp;gt;N &amp;lt;variant-name&amp;gt;N;
} &amp;lt;datatype-name&amp;gt;Variants;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;char dummy;&lt;/code&gt; is very important: consider a situation where a &lt;code&gt;datatype&lt;/code&gt; definition is analogous to a plain &lt;code&gt;enum&lt;/code&gt; in C. In this case, &lt;code&gt;&amp;lt;datatype-name&amp;gt;Variants&lt;/code&gt; would contain only &lt;code&gt;char dummy;&lt;/code&gt;. If it was not present, the union would be empty, thus violating the C standard.&lt;/p&gt;

&lt;p&gt;In order to allow exhaustive pattern matching (more on this later), a tag is represented as &lt;code&gt;enum&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef enum &amp;lt;datatype-name&amp;gt;Tag {
    &amp;lt;variant-name&amp;gt;0Tag, ..., &amp;lt;variant-name&amp;gt;NTag
} &amp;lt;datatype-name&amp;gt;Tag;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At least one variant must be specified in &lt;code&gt;datatype&lt;/code&gt;, so this enumeration will never be empty.&lt;/p&gt;

&lt;p&gt;Finalising a tagged union definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct &amp;lt;datatype-name&amp;gt; {
    &amp;lt;datatype-name&amp;gt;Tag tag;
    &amp;lt;datatype-name&amp;gt;Variants data;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now it can be used as any other manually written tagged union.&lt;/p&gt;

&lt;h1&gt;
  
  
  Value constructors
&lt;/h1&gt;

&lt;p&gt;A value constructor is an &lt;code&gt;inline static&lt;/code&gt; function which constructs a variant instance. Each variant has its own value constructor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;inline static &amp;lt;datatype-name&amp;gt; &amp;lt;variant-name&amp;gt;(...) {
    &amp;lt;datatype-name&amp;gt; result;
    result.tag = &amp;lt;variant-name&amp;gt;Tag;
    result.data.dummy = '\0';
    {
        result.data.&amp;lt;variant-name&amp;gt;._0 = _0;
        ...
        result.data.&amp;lt;variant-name&amp;gt;._N = _N;
    }
    return result;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(We set &lt;code&gt;result.data.dummy&lt;/code&gt; to &lt;code&gt;'\0'&lt;/code&gt; even if no variant payload is present, so that &lt;code&gt;.dummy&lt;/code&gt; is always initialised.)&lt;/p&gt;

&lt;p&gt;Contrary to manual initialisation (a.k.a. &lt;code&gt;{.tag = A, .data.A = { ... }}&lt;/code&gt;), a value constructor is&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More convenient to use.&lt;/li&gt;
&lt;li&gt;Safer: it automatically injects a corresponding tag, protecting a user from invalid combinations of tag + data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Pattern matching
&lt;/h1&gt;

&lt;p&gt;This is the most interesting part. Pattern matching is described by the following form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;match(val) {
    of(&amp;lt;variant-name&amp;gt;0, ...) &amp;lt;stmt&amp;gt;
    ...
    of(&amp;lt;variant-name&amp;gt;N, ...) &amp;lt;stmt&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How this can be implemented? The key idea is to use &lt;em&gt;statement prefixes&lt;/em&gt;. They were first introduced by Simon Tatham in his &lt;a href="https://www.chiark.greenend.org.uk/~sgtatham/mp/" rel="noopener noreferrer"&gt;Metaprogramming Custom Control Structures in C&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So what is actually a statement prefix? It is any C language construction that must precede a C statement. Here are some examples: &lt;code&gt;if (...)&lt;/code&gt;, &lt;code&gt;for (...)&lt;/code&gt;, &lt;code&gt;while (...)&lt;/code&gt;, &lt;code&gt;if (...) &amp;lt;stmt&amp;gt; else&lt;/code&gt;, a label, or a combination thereof. Moreover, a statement prefix together with a statement afterwards results in a single C statement. From my experience, &lt;code&gt;for (...)&lt;/code&gt; is the most flexible one so we are going to use it to implement &lt;code&gt;match&lt;/code&gt; &amp;amp; &lt;code&gt;of&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's start with &lt;code&gt;match(val)&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;match&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;All &lt;code&gt;of&lt;/code&gt; clauses must be able to access the provided value, therefore we must store it somewhere beforehand. We cannot just define it as usual: &lt;code&gt;void *datatype99_priv_matched_val = (void *)&amp;amp;(val);&lt;/code&gt; because&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The whole &lt;code&gt;match&lt;/code&gt; construction needs to be a single C statement, according to Datatype99's grammar.&lt;/li&gt;
&lt;li&gt;If two &lt;code&gt;match&lt;/code&gt; constructions in the same lexical scope output &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt;, compilation will fail.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;How can we overcome this? The following pattern will help:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
         &lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(&lt;code&gt;datatype99_priv_matched_val&lt;/code&gt; is named in such a way to respect &lt;a href="https://en.wikipedia.org/wiki/Hygienic_macro" rel="noopener noreferrer"&gt;macro hygiene&lt;/a&gt;, i.e. not to conflict with user-defined variables.)&lt;/p&gt;

&lt;p&gt;This single-iteration loop is a statement prefix. In order to avoid name clashes, it opens a new lexical scope and introduces &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt; into it. After it, we put &lt;code&gt;switch&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch ((val).tag)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this &lt;code&gt;switch&lt;/code&gt;, a user will specify a number of braced &lt;code&gt;of&lt;/code&gt; clauses, thus completing the initial statement prefix &lt;code&gt;for (...)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;match(val)&lt;/code&gt; is done. Let's move on to &lt;code&gt;of&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;of&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Logically, one &lt;code&gt;of&lt;/code&gt; branch must boil down to one &lt;code&gt;case&lt;/code&gt; branch, but think about &lt;code&gt;break&lt;/code&gt;: it cannot be put &lt;em&gt;after&lt;/em&gt; a user-provided statement &lt;code&gt;&amp;lt;stmt&amp;gt;&lt;/code&gt; following &lt;code&gt;of&lt;/code&gt; because our macro just has not got access to this piece of code. Instead, we put it &lt;em&gt;before&lt;/em&gt; &lt;code&gt;&amp;lt;stmt&amp;gt;&lt;/code&gt;! Thus, instead of&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch(...) {
    case A: &amp;lt;stmt&amp;gt; break;
    case B: &amp;lt;stmt&amp;gt; break;
    case C: &amp;lt;stmt&amp;gt; break;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;we generate&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch(...) {
    break; case A: &amp;lt;stmt&amp;gt;
    break; case B: &amp;lt;stmt&amp;gt;
    break; case C: &amp;lt;stmt&amp;gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The first &lt;code&gt;break&lt;/code&gt; does nothing: the control flow will never reach it.&lt;/li&gt;
&lt;li&gt;The last &lt;code&gt;break&lt;/code&gt; is absent: the control flow will nonetheless fall into the next instruction after &lt;code&gt;switch(...)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now the bindings need to be generated somehow (i.e. variable names provided to &lt;code&gt;of&lt;/code&gt;). All the information we have in &lt;code&gt;of&lt;/code&gt; is&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the variant name &lt;code&gt;&amp;lt;variant-name&amp;gt;&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;a list of bindings,&lt;/li&gt;
&lt;li&gt;the matched value &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each binding must&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Boil down to a variable definition.&lt;/li&gt;
&lt;li&gt;Be initialised to a corresponding variant argument taken from &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For this to happen, we need to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Deduce the type of each binding.&lt;/li&gt;
&lt;li&gt;Deduce the previously erased type of &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Type deduction
&lt;/h3&gt;

&lt;p&gt;Hopefully, all the types are already known to us at the stage of &lt;code&gt;datatype&lt;/code&gt; generation. The trick is to &lt;code&gt;typedef&lt;/code&gt; them appropriately:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To deduce the type of the Ith binding, we can take the provided &lt;code&gt;&amp;lt;variant-name&amp;gt;&lt;/code&gt; and concatenate it with &lt;code&gt;_I&lt;/code&gt;, thereby obtaining a type alias to the corresponding parameter type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To deduce the type of &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt;, we can take the provided &lt;code&gt;&amp;lt;variant-name&amp;gt;&lt;/code&gt; and concatenate it with &lt;code&gt;SumT&lt;/code&gt;, thereby obtaining a type alias to the outer sum type.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make it formal, for each variant the following type definitions are generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef struct &amp;lt;datatype-name&amp;gt; &amp;lt;variant-name&amp;gt;SumT;

typedef &amp;lt;type&amp;gt;0 &amp;lt;variant-name&amp;gt;_0;
...
typedef &amp;lt;type&amp;gt;N &amp;lt;variant-name&amp;gt;_N;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, inside &lt;code&gt;of&lt;/code&gt;, this is how each binding is generated:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;tag_&lt;/span&gt;&lt;span class="err"&gt;##&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="err"&gt;##&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;tag_&lt;/span&gt;&lt;span class="err"&gt;##&lt;/span&gt;&lt;span class="n"&gt;SumT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag_&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="err"&gt;##&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt; stands for the binding name.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tag_##_##i&lt;/code&gt; stands for the type alias &lt;code&gt;&amp;lt;variant-name&amp;gt;_I&lt;/code&gt;. This is the type of the binding.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tag_##SumT&lt;/code&gt; stands for the type alias &lt;code&gt;&amp;lt;variant-name&amp;gt;SumT&lt;/code&gt;. This is the type of &lt;code&gt;datatype99_priv_matched_val&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you might have already noticed, this is a single-iteration loop too. But it has quite different structure than the previous one: instead of using &lt;code&gt;x&lt;/code&gt; to terminate the cycle, we employ the second variable &lt;code&gt;ml99_priv_break&lt;/code&gt; (originated from &lt;a href="https://github.com/Hirrolot/metalang99" rel="noopener noreferrer"&gt;Metalang99&lt;/a&gt;, the underlying metaprogramming library). Why? Because otherwise, if &lt;code&gt;x&lt;/code&gt; is leaved unused by a user, a compiler will not emit a warning, which is undesirable in our case.&lt;/p&gt;

&lt;p&gt;Why we generate the long chains of statement prefix loops instead of plain variable definitions? Because all &lt;code&gt;case&lt;/code&gt; branches in &lt;code&gt;switch&lt;/code&gt; share a single lexical scope, meaning that two variables with the same name cannot be defined in two different &lt;code&gt;case&lt;/code&gt; branches. In contrast to this, &lt;code&gt;for (...)&lt;/code&gt; opens a new lexical scope, thus allowing for the same binding names in two distinct &lt;code&gt;of&lt;/code&gt; branches.&lt;/p&gt;

&lt;p&gt;So what we have in summary? Consider this code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;datatype&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;BinaryTree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BinaryTree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;BinaryTree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;BinaryTree&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rhs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lhs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rhs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;code&gt;of(Leaf, x)&lt;/code&gt; expands to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Leaf_0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;LeafSumT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;, while &lt;code&gt;of(Node, lhs, x, rhs)&lt;/code&gt; expands to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node_0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;lhs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;NodeSumT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
     &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node_1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;NodeSumT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Node_2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;rhs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;NodeSumT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;datatype99_priv_matched_val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
             &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;ml99_priv_break&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After both of them, a &lt;code&gt;return&lt;/code&gt; statement follows, thus completing the statement prefixes chain.&lt;/p&gt;

&lt;h1&gt;
  
  
  Exhaustive pattern matching
&lt;/h1&gt;

&lt;p&gt;Datatype99 has yet another neat feature: a sane compiler will emit a warning if not all variants are handled in &lt;code&gt;match&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;playground.c: In function ‘sum’:
playground.c:6:5: warning: enumeration value ‘NodeTag’ not handled in switch [-Wswitch]
    6 |     match(*tree) {
      |     ^~~~~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is called exhaustive pattern matching. In fact, Datatype99 does nothing to achieve it -- provided that we desugar &lt;code&gt;match&lt;/code&gt; into a proper &lt;code&gt;switch&lt;/code&gt;, a C compiler can do case analysis for us! For example, the following code compiles with a warning as well:&lt;/p&gt;

&lt;p&gt;[&lt;a href="https://godbolt.org/z/MeY3bbY1a" rel="noopener noreferrer"&gt;godbolt&lt;/a&gt;]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bar&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="n"&gt;MyEnum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MyEnum&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;source&amp;gt;:8:5: warning: enumeration value 'Bar' not handled in switch [-Wswitch]
    8 |     switch (foo) {
      |     ^~~~~~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Final words
&lt;/h1&gt;

&lt;p&gt;We have not considered some utility macros like &lt;code&gt;ifLet&lt;/code&gt; and &lt;code&gt;matches&lt;/code&gt; since nothing special lies in them -- they are very similar to what we have already seen. For more details, feel free to investigate the &lt;a href="https://github.com/Hirrolot/datatype99/blob/master/datatype99.h" rel="noopener noreferrer"&gt;source code&lt;/a&gt; of Datatype99. Thanks to the rich functionality of &lt;a href="https://github.com/Hirrolot/metalang99" rel="noopener noreferrer"&gt;Metalang99&lt;/a&gt;, it fits in just ~400 LoC single header file.&lt;/p&gt;

&lt;p&gt;It took me almost a year to figure out how to implement Datatype99 properly. Now it is a well-tested and stable v1.x.y project, so you can use it without fear that something will be broken in the next release.&lt;/p&gt;

&lt;p&gt;Happy hacking!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://patreon.com/hirrolot" rel="noopener noreferrer"&gt;Support me on Patreon &amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Hirrolot/datatype99#installation" rel="noopener noreferrer"&gt;Try out Datatype99 &amp;gt;&amp;gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>c</category>
      <category>functional</category>
      <category>programming</category>
      <category>computerscience</category>
    </item>
    <item>
      <title>Expression-Oriented Programming in C: The FMT Macro</title>
      <dc:creator>hirrolot</dc:creator>
      <pubDate>Thu, 13 May 2021 19:50:51 +0000</pubDate>
      <link>https://dev.to/hirrolot/expression-oriented-programming-in-c-the-fmt-macro-43jo</link>
      <guid>https://dev.to/hirrolot/expression-oriented-programming-in-c-the-fmt-macro-43jo</guid>
      <description>&lt;p&gt;Have you ever created useless intermediate variables like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Your fee is %d USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;reply_to_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you programmed in C before, the answer should be "yes". This language design drawback arises from the fact that C is a &lt;em&gt;statement-oriented&lt;/em&gt; language, meaning that if you want to perform some simple task, big chances that you need to allocate a separate variable and manipulate its pointer here and there.&lt;/p&gt;

&lt;p&gt;This blog post explains how to overcome this unpleasantness by designing APIs which facilitate &lt;em&gt;expression-oriented&lt;/em&gt; programming. In the end, we will come up with a handy &lt;code&gt;FMT&lt;/code&gt; string formatting macro that mimics &lt;a href="https://doc.rust-lang.org/std/macro.format.html" rel="noopener noreferrer"&gt;&lt;code&gt;std::format!&lt;/code&gt;&lt;/a&gt; of Rust:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;fee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;reply_to_user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FMT&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s"&gt;"Your fee is %d USD"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fee&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  sprintf
&lt;/h1&gt;

&lt;p&gt;Why &lt;code&gt;sprintf&lt;/code&gt; (and its friends) requires a named variable to store a formatted string? Well, let us envision &lt;code&gt;sprintf&lt;/code&gt; in an ideal world where every meaningful operation fits in a single line -- how would then the signature look? Something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note: &lt;a href="https://en.cppreference.com/w/c/language/restrict" rel="noopener noreferrer"&gt;&lt;code&gt;restrict&lt;/code&gt;&lt;/a&gt; here means that an object referenced by &lt;code&gt;format&lt;/code&gt; will be accessed only through &lt;code&gt;format&lt;/code&gt;.)&lt;/p&gt;

&lt;p&gt;But the gross truth is that it is completely unviable in C: this &lt;code&gt;sprintf&lt;/code&gt; then needs to allocate memory by itself, whilst many use cases require caller-allocated memory. Let's fix it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the signature is the same as the standard library counterpart, except that we return the passed buffer instead of how many bytes have been written so far. Good. But no one uses it anyway, so we can freely get rid of it. Let's then define our superior &lt;code&gt;sprintf&lt;/code&gt; wrapper.&lt;/p&gt;

&lt;h1&gt;
  
  
  Superior sprintf
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdarg.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define FMT(buffer, fmt, ...) fmt_str((buffer), (fmt), __VA_ARGS__)
&lt;/span&gt;
&lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;fmt_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;va_list&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;va_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;vsprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;va_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See? What we have done is just paraphrasing the old but not obsolete &lt;code&gt;sprintf&lt;/code&gt;: now we can obtain the resulting string immediately from an invocation of &lt;code&gt;FMT&lt;/code&gt;, without auxiliary variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FMT&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;char&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;]){&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="s"&gt;"%s %d %f"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"hello world"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;89&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;209&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are curious about &lt;code&gt;(char[128]){0}&lt;/code&gt;, it is called a &lt;a href="https://en.cppreference.com/w/c/language/compound_literal" rel="noopener noreferrer"&gt;compound literal&lt;/a&gt;: it represents an lvalue with the automatic storage duration that is needed only once. Here, the type of the compound literal is &lt;code&gt;char[128]&lt;/code&gt;, a &lt;code&gt;char&lt;/code&gt; array of 128 elements, all initialised to zero.&lt;/p&gt;

&lt;h1&gt;
  
  
  The snprintf counterpart
&lt;/h1&gt;

&lt;p&gt;We can modify our &lt;code&gt;FMT&lt;/code&gt; and &lt;code&gt;fmt_str&lt;/code&gt; to use the safe alternative to &lt;code&gt;sprintf&lt;/code&gt;, &lt;code&gt;snprintf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stddef.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdarg.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="cp"&gt;#define FMT(buffer, fmt, ...) fmt_str(sizeof(buffer), (buffer), (fmt), __VA_ARGS__)
&lt;/span&gt;
&lt;span class="kr"&gt;inline&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;fmt_str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kr"&gt;restrict&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;va_list&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;va_start&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;vsnprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;va_end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now if the passed buffer is not sufficient to hold the formatted data, we will not write past the end of it. Notice how beautiful &lt;code&gt;sizeof(buffer)&lt;/code&gt; inside &lt;code&gt;FMT&lt;/code&gt; works: provided it is an array type, its size will be computed correctly, contrary to just a pointer to the first element of an array.&lt;/p&gt;

&lt;p&gt;If you are curious about the &lt;code&gt;char buffer[restrict static len]&lt;/code&gt; syntax, it defines a &lt;code&gt;restrict&lt;/code&gt; pointer parameter that points to the first element of some array &lt;a href="https://en.cppreference.com/w/c/language/array" rel="noopener noreferrer"&gt;whose length is at least &lt;code&gt;len&lt;/code&gt; bytes long&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;What can we learn from it? At least, there is a certain kind of functions that write to a memory area, and their invocation naturally expresses the whole result of an operation. In order to be suitable for expression-oriented programming, these must return the passed memory area. &lt;code&gt;FMT&lt;/code&gt; is a perfect example.&lt;/p&gt;

&lt;p&gt;Compound literals facilitate expression-oriented programming too. They represent arbitrary values that need to be accessed only once. I encourage you to use them in all cases where a separate variable is superfluous. (Although you might still prefer to give descriptive names to program entities in certain cases.)&lt;/p&gt;

&lt;p&gt;I hope you enjoyed the post. Feel free to give your feedback and &lt;a href="https://patreon.com/hirrolot" rel="noopener noreferrer"&gt;support me on Patreon&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>c</category>
    </item>
  </channel>
</rss>
