{"id":628,"date":"2017-02-13T14:19:04","date_gmt":"2017-02-13T14:19:04","guid":{"rendered":"http:\/\/dlang.org\/blog\/?p=628"},"modified":"2021-10-08T11:08:43","modified_gmt":"2021-10-08T11:08:43","slug":"a-new-import-idiom","status":"publish","type":"post","link":"https:\/\/dlang.org\/blog\/2017\/02\/13\/a-new-import-idiom\/","title":{"rendered":"A New Import Idiom"},"content":{"rendered":"<p><em>Daniel Nielsen is an Embedded Software Engineer. He is currently using D in his spare time for an unpublished Roguelike and warns that he &#8220;may produce bursts of D Evangelism&#8221;.<\/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\" \/>I remember one day in my youth, before the dawn of Internet, telling my teachers about &#8220;my&#8221; new algorithm, only to learn it had been discovered by the ancient Greeks in ~300 BC. This is the story of my life and probably of many who are reading this. It is easy to &#8220;invent&#8221; something; being the first, not so much!<\/p>\n<p>Anyway, this is what all the fuss is about this time:<\/p>\n<pre class=\"prettyprint lang-d\">template from(string moduleName)\r\n{\r\n  mixin(\"import from = \" ~ moduleName ~ \";\");\r\n}<\/pre>\n<p>The TL;DR version: A new idiom to achieve even lazier imports.<\/p>\n<p>Before the C programmers start running for the hills, please forget you ever got burned by C++ templates. The above snippet doesn&#8217;t look that complicated, now does it? If you enjoy inventing new abstractions, take my advice and <a href=\"http:\/\/ddili.org\/ders\/d.en\/index.html\">give D a try<\/a>. Powerful, yet an ideal beginner&#8217;s language. No need to be a template archwizard.<\/p>\n<p>Before we proceed further, I&#8217;d like to call out Andrei Alexandrescu for identifying that there is a problem which needs solving. Please see his in depth motivation <a href=\"https:\/\/github.com\/dlang\/DIPs\/blob\/master\/DIPs\/DIP1005.md\">in DIP 1005<\/a>. Many thanks also to Dominikus Dittes Scherkl, who helped trigger the magic spark by making his own counter proposal and questioning if there really is a need to change the language specification in order to obtain Dependency-Carrying Declarations (DIP 1005).<\/p>\n<p>D, like many modern languages, has <a href=\"http:\/\/dlang.org\/spec\/module.html\">a fully fledged module system<\/a> where symbols are directly imported (unlike the infamous C <code>#include<\/code>). This has ultimately resulted in the widespread use of local imports, limiting the scope as much as possible, in preference to the somewhat slower and less maintainable module-level imports:<\/p>\n<pre class=\"prettyprint lang-d\">\/\/ A module-level import\r\nimport std.datetime;\r\n  \r\nvoid fun(SysTime time)\r\n{\r\n  import std.stdio; \/\/ A local import\r\n  ...\r\n}<\/pre>\n<p>Similar lazy import idioms are possible in other languages, for instance Python.<\/p>\n<p>The observant among you might notice that because <code>SysTime<\/code> is used as the type of a function parameter, <code>std.datetime<\/code> must be imported at module level. Which brings us to the point of this blog post (and DIP 1005). How can we get around that?<\/p>\n<pre class=\"prettyprint lang-d\">void fun(from!\"std.datetime\".SysTime time)\r\n{\r\n  import std.stdio;\r\n  ...\r\n}<\/pre>\n<p>There you have it, the Scherkl-Nielsen self-important lookup.<\/p>\n<p>In order to fully understand what&#8217;s going on, you may need to learn some D-isms. Let&#8217;s break it down.<\/p>\n<ol>\n<li>When <a href=\"http:\/\/dlang.org\/spec\/template.html\">instantiating a template<\/a> (via the <code>!<\/code> operator), if the <strong>TemplateArgument<\/strong> is one token long, the parentheses can be omitted from the template parameters. So <code>from!\"std.datetime\"<\/code> is the same as <code>from!(\"std.datetime\")<\/code>. It may seem trivial, but you&#8217;d be surprised how much readability is improved by avoiding ubiquitous punctuation noise.<\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/template.html#implicit_template_properties\">Eponymous templates<\/a>. The declaration of a template looks like this:\n<pre class=\"prettyprint lang-d\">template y() {\r\n    int x;\r\n}<\/pre>\n<p>With that, you have to type <code>y!().x<\/code> in order to reach the int. Oh, ze horror! Is that a smiley? Give me <code>x<\/code> already! That&#8217;s exactly what eponymous templates accomplish:<\/p>\n<pre class=\"prettyprint lang-d\">template x() {\r\n    int x;\r\n}<\/pre>\n<p>Now that the template and its only member have the same name, <code>x!().x<\/code> can be shortened to simply <code>x<\/code>.<\/li>\n<li><a href=\"https:\/\/dlang.org\/spec\/module.html#renamed_imports\">Renamed imports<\/a> allow accessing an imported module via a user-specified namespace. Here, <code>std.stdio<\/code> is imported normally:\n<pre class=\"prettyprint lang-d\">void printSomething(string s) {\r\n    import std.stdio;\r\n    writeln(s);           \/\/ The normal way\r\n    std.stdio.writeln(s)  \/\/ An alternative using the fully qualified \r\n                          \/\/ symbol name, for disambiguation\r\n}<\/pre>\n<p>Now it&#8217;s imported and renamed as <code>io<\/code>:<\/p>\n<pre class=\"prettyprint lang-d\">void printSomething(string s) {\r\n    import io = std.stdio;\r\n    io.writeln(s);         \/\/ Must be accessed like this.\r\n    writeln(s);            \/\/ Error\r\n    std.stdio.writeln(s);  \/\/ Error\r\n}<\/pre>\n<p>Combining what we have so far:<\/p>\n<pre class=\"prettyprint lang-d\">template dt() {\r\n    import dt = std.datetime; \r\n}\r\nvoid fun(dt!().SysTime time) {}<\/pre>\n<p>It works perfectly fine. The only thing which remains is to make it generic.<\/li>\n<li>String concatenation is achieved with the <code>~<\/code> operator.\n<pre class=\"prettyprint lang-d\">string hey = \"Hello,\" ~ \" World!\";\r\nassert(hey == \"Hello, World!\");<\/pre>\n<\/li>\n<li><a href=\"https:\/\/dlang.org\/mixin.html\">String mixins<\/a> put the power of a compiler writer at your fingertips. Let&#8217;s generate code at compile time, then compile it. This is typically used for domain-specific languages (see <a href=\"https:\/\/github.com\/PhilippeSigaud\/Pegged\">Pegged<\/a> for one prominent use of a DSL in D), but in our simple case we only need to generate one single statement based on the name of the module we want to import. Putting it all together, we get the final form, allowing us to import any symbol from any module inline:\n<pre class=\"prettyprint lang-d\">template from(string moduleName)\r\n{\r\n  mixin(\"import from = \" ~ moduleName ~ \";\");\r\n}<\/pre>\n<\/li>\n<\/ol>\n<p>In the end, is it all really worth the effort? Using one comparison made by Jack Stouffer:<\/p>\n<pre class=\"prettyprint lang-d\">import std.datetime;\r\nimport std.traits;\r\n\r\nvoid func(T)(SysTime a, T value) if (isIntegral!T)\r\n{\r\n    import std.stdio : writeln;\r\n    writeln(a, value);\r\n}<\/pre>\n<p>Versus:<\/p>\n<pre class=\"prettyprint lang-d\">void func(T)(from!\"std.datetime\".SysTime a, T value)\r\n    if (from!\"std.traits\".isIntegral!T)\r\n{\r\n    import std.stdio : writeln;\r\n    writeln(a, value);\r\n}<\/pre>\n<p>In this particular case, the total compilation time dropped to ~30% of the original, while the binary size dropped to ~41% of the original.<\/p>\n<p>What about the linker, I hear you cry? Sure, it can remove unused code. But it&#8217;s not always as easy as it sounds, in particular due to module constructors (think <code>__attribute__((constructor))<\/code>). In either case, it&#8217;s always more efficient to avoid generating unused code in the first place rather than removing it afterwards.<\/p>\n<p>So this combination of D features was waiting there to be used, but somehow no one had stumbled on it before. I agreed with the need Andrei identified for Dependency-Carrying Declarations, yet I wanted even more. I wanted Dependency-Carrying <em>Expressions<\/em>. My primary motivation comes from being exposed to way too much legacy C89 code.<\/p>\n<pre class=\"prettyprint lang-c_cpp\">void foo(void)\r\n{\r\n#ifdef XXX \/* needed to silence unused variable warnings *\/\r\n  int x;\r\n#endif\r\n... lots of code ...\r\n#ifdef XXX\r\n  x = bar();\r\n#endif\r\n}<\/pre>\n<p>Variables or modules, in the end they&#8217;re all just symbols. For the same reason C99 allowed declaring variables in the middle of functions, one should be allowed to import modules where they are first used. D already allows importing anywhere in a scope, but not in declarations or expressions. It was with this mindset that I saw <a href=\"http:\/\/forum.dlang.org\/thread\/tzqzmqhankrkbrfsrmbo@forum.dlang.org?page=1\">Dominikus Dittes Scherkl&#8217;s snippet<\/a>:<\/p>\n<pre class=\"prettyprint lang-d\">fun.ST fun()\r\n{\r\n   import someModule.SomeType;\r\n   alias ST = SomeType;\r\n   ...\r\n}<\/pre>\n<p>Clever, yet for one thing it doesn&#8217;t adhere to the DRY principle. Still, it was that tiny dot in <code>fun.ST<\/code> which caused the spark. There it was again, the Dependency-Carrying Expression of my dreams.<\/p>\n<p>Criteria:<\/p>\n<ul>\n<li>It must not require repeating <code>fun<\/code>, since that causes problems when refactoring<\/li>\n<li>It must be lazy<\/li>\n<li>It must be possible today with no compiler updates<\/li>\n<\/ul>\n<p>Templates are the poster children of lazy constructs; they don&#8217;t generate any code until instantiated. So that seemed a good place to start.<\/p>\n<p>Typically when using eponymous templates, you would have the template turn into a function, type, variable or alias. But why make the distinction? Once again, they&#8217;re all just symbols in the end. We could have used an alias to the desired module (see Scherkl&#8217;s snippet above); using the renamed imports feature is just a short-cut for import and alias. Maybe it was this simplified view of modules that made me see more clearly.<\/p>\n<p>Now then, is this the only solution? No. As a challenge to the reader, try to figure out what this does and, more importantly, its flaw. Can you fix it?<\/p>\n<pre class=\"prettyprint lang-d\">static struct STD\r\n{\r\n  template opDispatch(string moduleName)\r\n  {\r\n    mixin(\"import opDispatch = std.\" ~ moduleName ~ \";\");\r\n  }\r\n}<\/pre>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Daniel Nielsen is an Embedded Software Engineer. He is currently using D in his spare time for an unpublished Roguelike and warns that he &#8220;may produce bursts of D Evangelism&#8221;. I remember one day in my youth, before the dawn of Internet, telling my teachers about &#8220;my&#8221; new algorithm, only to learn it had been [&hellip;]<\/p>\n","protected":false},"author":14,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[9,20],"tags":[],"_links":{"self":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/628"}],"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\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/comments?post=628"}],"version-history":[{"count":26,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/628\/revisions"}],"predecessor-version":[{"id":654,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/posts\/628\/revisions\/654"}],"wp:attachment":[{"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/media?parent=628"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/categories?post=628"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dlang.org\/blog\/wp-json\/wp\/v2\/tags?post=628"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}