{"id":535,"date":"2019-05-13T22:52:49","date_gmt":"2019-05-14T02:52:49","guid":{"rendered":"https:\/\/lennycheng.com\/blog\/?p=535"},"modified":"2019-05-13T22:52:51","modified_gmt":"2019-05-14T02:52:51","slug":"c-templates-and-java-generics-two-different-approaches-to-generic-programming","status":"publish","type":"post","link":"http:\/\/lennycheng.com\/blog\/2019\/05\/13\/c-templates-and-java-generics-two-different-approaches-to-generic-programming\/","title":{"rendered":"C++ Templates and Java Generics: Two different approaches to generic programming"},"content":{"rendered":"\n<h2>Intro<\/h2>\n\n\n\n<p>Generic programming is the ability to abstract away concrete types and was first introduced in the 1970s. It facilitates code maintenance, reduces redundant code, and enables optimizations. Rather than writing the same algorithm again and again, but with different data types each time, the programmer only needs to write it out once. Eg, defining <code>size_t sum(T)<\/code> rather than three definitions for <code>size_t sum(int)<\/code>, <code>size_t sum(long)<\/code>, and <code>size_t sum(double)<\/code>. <\/p>\n\n\n\n<p>C++ allows generic programming via templates, which were included in the 1998 standard but had appeared years earlier in The Annotated C++ Reference Manual. Java allows generic programming via generics, which was introduced with Java 5 in 2004.<\/p>\n\n\n\n<h2>Two Different Paradigms<\/h2>\n\n\n\n<p>They might look\nsimilar on the surface but have contrasting design paradigms. <strong>C++ templates uses code generation whereas\nJava generics uses type erasure. <\/strong><\/p>\n\n\n\n<p>Type erasure removes the type of an object and adds a cast in the compiled bytecode. It doesn\u2019t actually add anything new to the language. For example, as described in <a href=\"https:\/\/www.amazon.com\/Java-Generics-Collections-Development-Process\/dp\/0596527756\/\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Java Generics and Collections (opens in a new tab)\">Java Generics and Collections<\/a>, the bytecode of: <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>List words = new ArrayList();\nwords.add(\u201cHello\u201d);\nString s = (String) words.get(0);<\/code><\/pre>\n\n\n\n<p>and <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>List&lt;String> words = new ArrayList&lt;>();\nwords.add(\u201cHello\u201d);\nString s = words.get(0)<\/code><\/pre>\n\n\n\n<p>are identical! This is curious, if the syntax is so different, why would  the Java committee decide they should output the same bytecode? After  all, it seems like inserting a cast and removing the type would prevent  potential optimizations.  <\/p>\n\n\n\n<p>The\nalternative is for generics to introduce different bytecode. However, code that\nuses generics and compiled with Java 5 would no longer be compatible with code compiled\nwritten without generics before it. Businesses that were already using Java\nwould be hesitant to migrate to the newer version. Type erasure was a compromise\nbetween business needs and language enhancements.<\/p>\n\n\n\n<p>Type erasure also ensures that there would only ever be one implementation of a generic type. For example, <code>List&lt;String><\/code>, <code>List&lt;Integer><\/code>, and <code>List&lt;MyClass><\/code> all have the same implementation of List. Contrasting this with C++ templates, which was included in the standards from the beginning and uses code generation, <code>vector&lt;string><\/code>, <code>vector&lt;int><\/code>, and <code>vector&lt;MyClass><\/code> each has its own implementation. Although this may increase the size of each translation unit and the final executable, implementation-specific types offer the programmer greater flexibility, including:<\/p>\n\n\n\n<ol><li>Specialization of template functions and classes to enable optimizations. An example is vector&lt;bool>, which is a space-efficient version of <code>vector&lt;T><\/code><\/li><li>Creating member variables of the same type. In Java, type erasure makes is almost impossible to instantiate a variable of the type, such as <code>T[] t = new T[10]<\/code>; In addition, static member variables can\u2019t refer to a generic type<\/li><li>Static polymorphism, such as STL containers and using typedefs to make generic operations, such as using iterators<\/li><li>A lot of complicated stuff like policy traits and meta-programming, which can compute prime numbers at compile-time!<\/li><\/ol>\n\n\n\n<p>The impact of\ncode generation vs type erasure affects the performance and readability of the\nlanguages. While templates offer more flexibility to the programmer, they\u2019re harder\nto use because of tricky rules that cause inconvenient bugs. Also, nothing\u2019s\nquite as dry as reading cryptic error messages that span hundreds of\ncharacters. <\/p>\n\n\n\n<p>To briefly summarize,\nC++ and Java have different models to enable generic programming. C++ uses\ntemplates and code generation whereas Java uses generics and type erasure.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro Generic programming is the ability to abstract away concrete types and was first introduced in the 1970s. It facilitates code maintenance, reduces redundant code, and enables optimizations. Rather than&#8230;<\/p>\n","protected":false},"author":1,"featured_media":536,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[10],"tags":[],"_links":{"self":[{"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/posts\/535"}],"collection":[{"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/comments?post=535"}],"version-history":[{"count":3,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/posts\/535\/revisions"}],"predecessor-version":[{"id":541,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/posts\/535\/revisions\/541"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/media\/536"}],"wp:attachment":[{"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/media?parent=535"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/categories?post=535"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/lennycheng.com\/blog\/wp-json\/wp\/v2\/tags?post=535"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}