{"id":30,"date":"2005-03-03T22:18:43","date_gmt":"2005-03-03T21:18:43","guid":{"rendered":"http:\/\/ken.friislarsen.net\/blog\/?p=30"},"modified":"2005-03-03T22:18:43","modified_gmt":"2005-03-03T21:18:43","slug":"gadt-in-c","status":"publish","type":"post","link":"http:\/\/ken.friislarsen.net\/blog\/2005\/03\/03\/gadt-in-c\/","title":{"rendered":"GADTs in C++"},"content":{"rendered":"<p>My good friends <a href=\"http:\/\/research.microsoft.com\/~crusso\">Claudio Russo<\/a> and <a href=\"http:\/\/research.microsoft.com\/~akenn\">Andrew Kennedy<\/a> have been kind enough to send me a draft paper about Generalized Algebraic Data Types (GADTs) and Object-Oriented Programming.  GADTs generalize the datatypes of ML and Haskell by permitting constructors to produce different type-instantiations of the same datatype.  One of Andrew and Claudio&#8217;s examples is a slightly modified version of Peter Sestoft&#8217;s example of <a href=\"http:\/\/www.dina.kvl.dk\/~sestoft\/gcsharp\/index.html#expr\">representing abstract syntax trees for typed expressions<\/a> in Generic C#.  To get a better feeling of the difference between the generics in C#\/Java and the generics in C++ I have rewritten the the example in C++.<\/p>\n<p>To recap the example: we want to represent abstract syntax trees for a tiny language of simple expressions. Futhermore, we want representation to be type safe.  That is, we do not want to be able to represent the nonsense expression &#8220;<code>true + 42<\/code>&#8220;.  We shall represent the abstract syntax trees the standard OO way with an abstract base class <code>Exp<\/code> for the general type of expressions and the concreate subclasses for each node type. To enforce the type safety of our embedded language we use generics.  That is, a value with type <code>Exp&lt;R&gt;<\/code> is an abstract syntax tree for an expression that evaluates to a value of type <code>R<\/code>.<\/p>\n<p>First the base class.<\/p>\n<p>Peter&#8217;s Generic C# version:<\/p>\n<pre>\nabstract class Exp&lt;R&gt; {   \/\/ R = result type\n  abstract public R eval();\n}\n<\/pre>\n<p>C++ version:<\/p>\n<pre>\ntemplate&lt; typename R &gt;  \/\/ R = result type\nclass Exp {\npublic:\n  virtual R eval() const = 0;\n  virtual ~Exp() {}\n};\n<\/pre>\n<p>Note that in C++ we need to remember to define a virtual destructor because we plan to inherit from <code>Exp<\/code> and we also want to be able to dynamically allocate subclasses of <code>Exp<\/code>.<\/p>\n<p>Next up is the class for literals.<\/p>\n<p>Peter&#8217;s Generic C# version:<\/p>\n<pre>\nclass Lit&lt;R&gt; : Exp&lt;R&gt; {\n  private readonly R v;\n  public Lit(R v) {\n    this.v = v;\n  }\n  public override R eval() {\n    return v;\n  }\n}\n<\/pre>\n<p>C++ version:<\/p>\n<pre>\ntemplate&lt; typename R &gt;\nclass Lit : public Exp&lt;R&gt; {\npublic:\n  virtual R eval() const {\n    return val;\n  }\n  explicit Lit(R val_) : val(val_) {}\nprivate:\n  R const val;\n};\n<\/pre>\n<p>No surprises here.<\/p>\n<p>But for binary expressions like plus, for instances, it starts to get a bit more tricky.  Here I&#8217;ll use a simpler version of the class for representing plus nodes than the version Peter uses.<\/p>\n<p>Generic C# version:<\/p>\n<pre>\nclass Plus : Exp&lt;int&gt; {\n  private readonly Exp&lt;int&gt; lhs, rhs;\n  public Plus(Exp&lt;int&gt; lhs, Exp&lt;int&gt; rhs) {\n    this.lhs = lhs; this.rhs = rhs;\n  }\n  public override int eval() {\n    return lhs.eval() + rhs.eval();\n  }\n}\n<\/pre>\n<p>First cut at a C++ version:<\/p>\n<pre>\nclass Plus : public Exp&lt;int&gt; {\npublic:\n  virtual int eval() const {\n    return lhs.eval() + rhs.eval();\n  }\n  explicit Plus(Exp&lt;int&gt; const lhs_, Exp&lt;int&gt; const rhs_)\n    : lhs(lhs_), rhs(rhs_)\n  {}\nprivate:\n  Exp&lt;int&gt; lhs, rhs;\n};\n<\/pre>\n<p>Alas, this is not valid C++ because we are not allowed to declare fields and parameters of type <code>Exp&lt;int&gt;<\/code> because this class has an abstract virtual function, namely <code>eval<\/code> (and besides if we could, for example by modifying the class <code>Exp<\/code>, the code would not do what we expects).  These problems has nothing to do with the generics in C++, they are just the usual C++ OO quirks.  And the solution is straightforward: we must use a pointer to values of type <code>Exp<\/code>.  But then we have to make decisions about ownership: should we make a deep copy of subexpressions? should we share subexpressions? and if so who should take take of freeing resources? should we use ref counting? or what? Here we shall just use one of the the wonderful smart pointers from <a href=\"http:\/\/boost.org\/\">Boost<\/a>: <code>shared_ptr<\/code> which will take care of the refcounting and deletion of expressions.   Thus, first we make a couple of convenient typedefs for integer expressions and shared pointers to integer expressions (and similar for boolean expressions):<\/p>\n<pre>\ntypedef Exp&lt; int &gt; IntExp;\ntypedef boost::shared_ptr&lt; IntExp &gt; IntExpPtr;\n<\/pre>\n<p>Then the class for plus nodes looks like this:<\/p>\n<pre>\nclass Plus : public IntExp {\npublic:\n  virtual int eval() const {\n    return lhs-&gt;eval() + rhs-&gt;eval();\n  }\n  explicit Plus(IntExpPtr const &amp; lhs_, IntExpPtr const &amp; rhs_)\n    : lhs(lhs_), rhs(rhs_)\n  {}\nprivate:\n  IntExpPtr lhs, rhs;\n};\n<\/pre>\n<p>and a wrapper for constructing shared pointers for new plus expressions:<\/p>\n<pre>\nIntExpPtr plus(IntExpPtr const &amp; lhs, IntExpPtr const &amp; rhs) {\n  return IntExpPtr( new Plus( lhs, rhs ) );\n}\n<\/pre>\n<p>Similar to the <code>Plus<\/code> class we can define a class for representing condtional expressions:<\/p>\n<p>Generic C# version:<\/p>\n<pre>\nclass Cond&lt;R&gt; : Exp&lt;R&gt; {\n  private readonly E&lt;bool&gt; cond;\n  private readonly E&lt;R&gt; truth, falsehood;\n  public Cond(E&lt;bool&gt; cond, E&lt;R&gt; truth, E&lt;R&gt; falsehood) {\n    this.cond = cond; this.truth = truth; this.falsehood = falsehood;\n  }\n  public override R eval() {\n    return cond.eval() ? truth.eval() : falsehood.eval();\n  }\n}\n<\/pre>\n<p>C++ version:<\/p>\n<pre>\ntemplate &lt; typename R &gt;\nclass Cond : public Exp&lt;R&gt; {\npublic:\n  typedef boost::shared_ptr&lt; Exp&lt;R&gt; &gt; SubExpPtr;\n  virtual R eval() const {\n    return cond-&gt;eval() ? truth-&gt;eval() : falsehood-&gt;eval();\n  }\n  explicit Cond(BoolExpPtr const &amp; cond_,\n                SubExpPtr const &amp; truth_,\n                SubExpPtr const &amp; falsehood_) :\n    cond(cond_), truth(truth_), falsehood(falsehood_)\n  {}\nprivate:\n  BoolExpPtr cond;\n  SubExpPtr truth, falsehood;\n};\n<\/pre>\n<p>The interesting things to note about this class are that <code>Cond<\/code> contains subexpressions of different types, that <code>Cond<\/code> is polymorphic in the result type, that <code>Cond<\/code> enforces that the two branches of a condtional expression must have the same type, and the only one of the branchs is evaluated based on the evaluation of the condition.<\/p>\n<p>Using these classes we can define a function that builds an expression for calculating the <i>n<\/i>&#8216;th fibonacci number:<\/p>\n<pre>\nIntExpPtr fib(int n) {\n  IntExpPtr fib0( lit(0) ), fib1( lit(1) );\n  switch ( n ) {\n  case 0: return fib0;\n  case 1: return fib1;\n  default:\n    for(int i = 1; i != n; ++i) {\n      IntExpPtr tmp( fib1 );\n      fib1 = plus( fib0, fib1 );\n      fib0 = tmp;\n    }\n    return fib1;\n  }\n}\n<\/pre>\n<p>This function builds an expression that takes linear, <i>O(n)<\/i>, space, but it will use exponential time, <i>O(2<sup>n<\/sup>)<\/i>, to be evaluated.<\/p>\n<p><strong>Conclusion<\/strong><br \/>\nNon-surprising this GADT example can be translated more or less straight forward from generinc C# to C++.  The things that are a bit tedious are just the normal C++ oddities and has nothing to do with generics.  In fact, we would have had the exact same problems without generics.<\/p>\n<p>Next up is to try and translate a few more of Claudio and Andrews examples.  The statically typed <code>printf<\/code> and the typed LR parsing looks nifty.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My good friends Claudio Russo and Andrew Kennedy have been kind enough to send me a draft paper about Generalized Algebraic Data Types (GADTs) and Object-Oriented Programming. GADTs generalize the datatypes of ML and Haskell by permitting constructors to produce different type-instantiations of the same datatype. One of Andrew and Claudio&#8217;s examples is a slightly <a class=\"read-more\" href=\"http:\/\/ken.friislarsen.net\/blog\/2005\/03\/03\/gadt-in-c\/\">[&hellip;]<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,4,3],"tags":[],"class_list":["post-30","post","type-post","status-publish","format-standard","hentry","category-c","category-coding","category-general"],"_links":{"self":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/posts\/30","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/comments?post=30"}],"version-history":[{"count":0,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/posts\/30\/revisions"}],"wp:attachment":[{"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/media?parent=30"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/categories?post=30"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/ken.friislarsen.net\/blog\/wp-json\/wp\/v2\/tags?post=30"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}