{"id":1534,"date":"2018-05-21T14:29:49","date_gmt":"2018-05-21T14:29:49","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=1534"},"modified":"2021-10-08T11:04:11","modified_gmt":"2021-10-08T11:04:11","slug":"complicated-types-prefer-alias-this-over-alias-for-easier-to-read-error-messages","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2018\/05\/21\/complicated-types-prefer-alias-this-over-alias-for-easier-to-read-error-messages\/","title":{"rendered":"Complicated Types: Prefer &#8220;alias this&#8221; Over &#8220;alias&#8221; For Easier-To-Read Error Messages"},"content":{"rendered":"<p><em>Nick Sabalausky is a long-time D user and contributor. He is the maintainer of <a href=\"https:\/\/github.com\/mysql-d\/mysql-native\">mysql-native<\/a> and <a href=\"https:\/\/github.com\/Abscissa\/scriptlike\">Scriptlike<\/a>. In this post, he presents a way to use a specific D language feature to improve error messages involving aliased types.<\/em><\/p>\n<hr \/>\n<p><img loading=\"lazy\" class=\"alignleft size-full wp-image-181\" src=\"http:\/\/dlang.org\/blog\/wp-content\/uploads\/2016\/08\/d6.png\" alt=\"\" width=\"200\" height=\"200\" \/>In <a href=\"http:\/\/dlang.org\">the D programming language<\/a>, <code>alias<\/code> is a common and handy feature that can be used to provide a simple name for a complex and verbose templated type.<\/p>\n<p>As an example, consider the case of an algebraic type or tagged union:<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ A type that can be either an int or a string\r\nAlgebraic!(int, string) someVariable;<\/pre>\n<p>That\u2019s a fairly simple example. Much more complicated type names are common in D. This sort of thing can be a pain to repeat everywhere it\u2019s used, and can make code difficult to read. <code>alias<\/code> is often used in situations like this to create a simpler shorthand name:<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ A type that can be either an int or a string\r\nalias MyType = Algebraic!(int, string);\r\n\r\n\/\/ Ahh, much nicer!\r\nMyType someVariable;<\/pre>\n<p>There\u2019s one problem this still doesn\u2019t solve. Anytime a compiler error message shows a type name, it shows the <em>full<\/em> original name, not the convenient easy-to-read alias. Instead of errors saying <code>MyType<\/code>, they\u2019ll still say <code>Algebraic!(int, string)<\/code>. This can be especially unfriendly if <code>MyType<\/code> is in the public API of a library and happens to be constructed using some private, internal-only template.<\/p>\n<p>That can be fixed, and error messages forced to provide the customized name, by creating <code>MyType<\/code> as a separate type on its own, rather than an alias. But how? If this was C or C++, <code>typedef<\/code> would do the job nicely. There is a D equivalent, <code>std.typecons.Typedef!T<\/code>, which will create a separate type. But naming the type still involves <code>alias<\/code>, which just leads back to the same problem.<\/p>\n<p>Luckily, D has another feature which can help simulate a C-style <code>typedef<\/code>: <code>alias this<\/code>. Used inside a struct (or class), <code>alias this<\/code> allows the struct to be implicitly converted to and behave just like any one of its members.<\/p>\n<p>Incidentally, although <code>alias<\/code> and <code>alias this<\/code> are separate features of the language, they do have a shared history as their names suggest. Originally, <code>alias<\/code> was intended to be a variation on C\u2019s <code>typedef<\/code>, one which would result in two names for the same type instead of two separate types. At the time, D had <code>typedef<\/code> as well, but it was eventually dropped as a language feature in favor of a standard library solution (the aforementioned <code>std.typecons.Typedef<\/code> template). As a variant of <code>typedef<\/code>, <code>alias<\/code> used the same syntax (<code>alias TypeName AliasName;<\/code>). Later, <code>alias<\/code> spawned the <code>alias this<\/code> feature, which was given a similar syntax: <code>alias memberName this<\/code>. When <code>alias<\/code> gained its modern syntax (<code>alias AliasName = TypeName<\/code>), a lengthy debate resulted in keeping the existing syntax for <code>alias this<\/code>.<\/p>\n<p>Here is how <code>alias this<\/code> can be used to solve our problem:<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ A type that can be either an int or a string\r\nstruct MyType {\r\n    private Algebraic!(int, string) _data;\r\n    alias _data this;\r\n}\r\n\r\n\/\/ Ahh, much nicer! And now error messages say \"MyType\"!\r\nMyType someVariable;<\/pre>\n<p>There\u2019s an important difference to be aware of, though. Before, when using <code>alias<\/code>, <code>MyType<\/code> and <code>Algebraic!(int, string)<\/code> were considered the same type. Now, they\u2019re not. Is that a problem? What does that imply? Mainly, it means two things:<\/p>\n<ol>\n<li style=\"list-style-type: none\">\n<ol>\n<li>Although this doesn\u2019t affect any actual code, it <em>can<\/em> mean the compiler generates extra, duplicate template instantiations. If <code>MyType<\/code> is passed to one template, and somewhere else <code>Algebraic!(int, string)<\/code> is passed to the same template, the compiler will now generate two separate template instantiations instead of just one.<br \/>\nIn practice though, this shouldn\u2019t be a problem unless you\u2019re already in a genuine template-bloat situation and are trying to reduce template instantiations. Usually, this won\u2019t be an issue.<\/li>\n<li>Although the <code>alias this<\/code> means <code>MyType<\/code> can still be implicitly converted to <code>Algebraic!(int, string)<\/code>, the other way around no longer works. An <code>Algebraic!(int, string)<\/code> can no longer be implicitly converted to a <code>MyType<\/code>.<br \/>\nArguably, this can be considered a good thing if you believe, as I do, in using <a href=\"http:\/\/programmer.97things.oreilly.com\/wiki\/index.php\/Prefer_Domain-Specific_Types_to_Primitive_Types\">domain-specific types<\/a>. But in any case, you can still manually convert the original type to your <code>MyType<\/code> with the basic built-in struct constructor:<\/p>\n<pre class=\"prettyprint lang-d\">Algebraic!(int, string) algebVar;\r\nauto myVar = MyType(algebVar);<\/pre>\n<\/li>\n<\/ol>\n<p>So when you\u2019re aliasing a large, complicated type name to a simpler name, consider using a struct and <code>alias this<\/code> instead, especially if it\u2019s a type on offer in a library. There\u2019s little downside, and it will greatly improve the readability of error messages for both yourself and your library\u2019s users.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nick Sabalausky presents a simple and effective D tip for improving error messages involving aliased types.<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[26,30],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1534"}],"collection":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=1534"}],"version-history":[{"count":8,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1534\/revisions"}],"predecessor-version":[{"id":1542,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/1534\/revisions\/1542"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=1534"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=1534"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=1534"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}