    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: The Expressive C++ Coding Challenge in D</title>
        <link>https://members.accu.org/index.php/journals/2478</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>


        <h2>Journal Articles</h2>


<div class="xar-mod-head"><span class="xar-mod-title">CVu Journal Vol 30, #1 - March 2018 + Programming Topics</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c383/">301</a>
                    (10)
<br />

                                            <a href="https://members.accu.org/index.php/journals/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/journals/c65/">Programming</a>
                    (877)
<br />

                                            <a href="https://members.accu.org/index.php/journals/c383-65/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/journals/c383+65/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;The Expressive C++ Coding Challenge in D</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 06 March 2018 16:22:44 +00:00 or Tue, 06 March 2018 16:22:44 +00:00</p>
<p><strong>Summary:</strong>&nbsp;Sebastian Wilzbach presents a D language solution to a C++ problem.</p>
<p><strong>Body:</strong>&nbsp;<p>You might have seen that I have been coding a lot in D lately and as a few weeks ago there was the â€˜Expressive C++17 Coding Challengeâ€™ <a href="#[1]">[1]</a> with its solution in C++ <a href="#[2]">[2]</a> and Rust <a href="#[3]">[3]</a> now being public, I thought this is an excellent opportunity to show why I like D so much.</p>

<h2>The requirements</h2>

<p>Let me first recap the requirements of this challenge:</p>

<p class="blockquote">This command line tool should accept the following arguments:</p>

<ul class="blockquote">
	<li>the filename of a CSV file,</li>
	<li>the name of the column to overwrite in that file,</li>
	<li>the string that will be used as a replacement for that column,</li>
	<li>the filename where the output will be written.</li>
</ul>

<pre class="programlisting">
./program &lt;input.csv&gt; &lt;colum-name&gt; &lt;replacement-
string&gt; &lt;output.csv&gt;</pre>

<h2>Example input</h2>

<p>Given this simple CSV as input</p>

<pre class="programlisting">
  name,surname,city,country
  Adam,Jones,Manchester,UK
  Joe,Doe,Cracow,Poland
  Michael,Smith,Paris,France
  Alex,McNeil,Gdynia,Poland</pre>

<p>the program called with:</p>

<pre class="programlisting">
  ./program input.csv city London output.csv</pre>

<p>should write:</p>

<pre class="programlisting">
  name,surname,city,country
  Adam,Jones,London,UK
  Joe,Doe,London,Poland
  Michael,Smith,London,France
  Alex,McNeil,London,Poland</pre>

<p>Sounds fairly trivial, right?</p>

<p>Please have a short look first at the â€˜bestâ€™ C++ <a href="#[4]">[4]</a> and Rust <a href="#[3]">[3]</a> solutions before you look at the D solution.</p>

<h2>The solution</h2>

<p>Okay, so Listing 1 is one way to solve this in D.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#!/usr/bin/env rdmd
import std.algorithm, std.exception, std.format, std.range, std.stdio;
void main(string[] args) {
  enforce(args.length == 5, &quot;Invalid args\n&quot; ~
  &quot;./tool &lt;input.csv&gt; &lt;colum-name&gt;
    &lt;replacement-string&gt; &lt;output.csv&gt;&quot;);
  auto inFile = args[1], columName = args[2],
    replacement = args[3], outFile = args[4];
  auto lines = File(inFile).byLine.map!(a
    =&gt; a.splitter(&quot;,&quot;));
  auto colIndex = lines.front.countUntil(
    columName);
  enforce(colIndex &gt;= 0,
    &quot;Invalid column. Valid columns: %(%s,
    %)&quot;.format(lines.front));
  auto os = File(outFile, &quot;w&quot;);
  os.writefln(&quot;%(%s, %)&quot;, lines.front);
  foreach (line; lines.dropOne) {
    auto r = line
      .enumerate // iterate with an (index,
                 // value) tuple
      .map!(a =&gt; a.index == colIndex
         ? replacement : a.value)
      .joiner(&quot;,&quot;);
    os.writeln(r);
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<p>If you are scared at the moment â€“ donâ€™t worry. I will explain it line by line below.</p>

<h3>So how does this compare to C++17 and Rust?</h3>

<table>
		<tr>
			<th>Language</th>
			<th>LoC</th>
			<th>Time</th>
		</tr>
		<tr>
			<td>C++</td>
			<td>125</td>
			<td>15s</td>
		</tr>
		<tr>
			<td>Rust</td>
			<td>83</td>
			<td>6s</td>
		</tr>
		<tr>
			<td>D</td>
			<td>19</td>
			<td>12s</td>
		</tr>
		<tr>
			<td>D (slightly tweaked)</td>
			<td>25</td>
			<td>6s</td>
		</tr>
</table>

<p>Later in the article I will present a solution which only uses 12 lines, but it also uses the built-in <code>std.csv</code> module and I think D doesnâ€™t need to cheat.</p>

<p>I used the following D script to generate a simple CSV file with 10 fields and 10 million lines:</p>

<pre class="programlisting">
  rdmd --eval='10.iota.map!(
    a=&gt; &quot;field&quot;.text(a)).join(&quot;,&quot;)
  .repeat(10_000_000).joiner(&quot;\n&quot;).writeln'
    &gt; input_big.csv</pre>

<p>The resulting <span class="filename">input_big.csv</span> has a size of 668M.</p>

<p><em>Arenâ€™t you concerned that Rust is faster in this benchmark?</em></p>

<p>Not at all. The challenge was to write <em>expressive</em> code.</p>

<p>When performance really matters, D provides the same tools as C or C++ and D even supports native interoperability with C and most of C++.</p>

<p>In this example, however, I/O is the bottleneck and D provides a few convenience features like using locked file handles, s.t. accessing files is thread-safe by default, or supporting unicode input.</p>

<p>However, itâ€™s easy to opt out of such productivity features and use other tricks like memory mapped files <a href="#[5]">[5]</a>. For interested readers, I have included a slightly optimized version at the end (Listing 6).</p>

<p>In addition, if you are interested in performance, Jon Degenhardt (member of eBayâ€™s data science team), has made an excellent performance benchmark <a href="#[6]">[6]</a> between eBayâ€™s tsv-utils and existing CSV/TSV processing tools written in C, Go, and Rust.</p>

<h2>1) What is #!/usr/bin/env rdmd?</h2>

<p>One of my favorite parts of D is that it has a blazingly fast compiler. Period. I can compile the entire D front-end of the compiler (~200 kLoC) in less than two seconds or the entire standard library with lots and lots of compile-time function evaluation and templates and &gt; 300 kLoC in 5 seconds <em>from scratch without any cache or incremental compilation</em>.</p>

<p>This means that the compiler is almost as fast as an interpreter and the <code>rdmd</code> tool allows you to use D as â€˜pseudo-interpretedâ€™ language. You can invoke <code>rdmd</code> with any file and it will automatically figure out all required files based on your dependencies and pass them to the compiler.</p>

<p>Itâ€™s very popular in the D community because for small scripts one doesnâ€™t even notice that the program is compiled to real machine code under the hood. Also if the shebang header is added and the file is executable, D scripts can be used as if they were script files:</p>

<pre class="programlisting">
  ./main.d input.csv city London output.csv</pre>

<h3>2) So you import a bunch of libraries. What do they do?</h3>

<pre class="programlisting">
  import std.algorithm, std.exception, std.format,
  std.range, std.stdio;</pre>

<p>In short <code>std.stdio</code> is for input and output, <code>std.range</code> is about Dâ€™s magic streams called â€˜rangesâ€™ and <code>std.algorithm</code> abstracts on top of them and provides generic interfaces for a lot of sophisticated algorithms.</p>

<p>Moreover, <code>std.exception</code> offers methods for working with exceptions like <code>enforce</code> and finally <code>std.format</code> bundles methods for string formatting.</p>

<p>Donâ€™t worry â€“ the functionality imported from these modules will be explained soon.</p>

<h3>3) Your program has a main function. Whatâ€™s so special about it compared to C or C++?</h3>

<pre class="programlisting">
  void main(string[] args) {
    â€¦</pre>

<p>For starters, arrays in D have a length. Try:</p>

<pre class="programlisting">
  args[5].writeln;</pre>

<p>Compared to C/C++ null-terminated strings and arrays, it wonâ€™t segfault. It would just throw a nice Error (see Figure 1).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
core.exception.RangeError@./main.d(10): Range violation
----------------
??:? _d_arrayboundsp [0x43b622]
prog.d:9 void main.foo(immutable(char)[][]) [0x43ac93]
prog.d:4 _Dmain [0x43ac67]</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Figure 1</td>
	</tr>
</table>

<p><em>Oh so D performs automatic bounds-checking before accessing the memory. Isnâ€™t that expensive?</em></p>

<p>Itâ€™s almost negligible compared to the safety it buys, but D is a language for everyone, so the people who want to squeeze out the last cycles of their processor can do so by simply compiling with <code>-boundscheck=off</code> (for obvious reasons this isnâ€™t recommended).</p>

<p>In D, strings are arrays too and thereâ€™s another nice property about Dâ€™s arrays. They are only a view on the actual memory and you donâ€™t copy the array, but just the view of the memory (in D itâ€™s called a slice).</p>

<p>Consider this example:</p>

<pre class="programlisting">
  int[] arr = [1, 2, 3];
  auto bArr = arr[1 .. $];
  bArr[] += 2; // this is a vectorized operation

  arr.writeln; // [1, 4, 5]
</pre>

<p>There many other things D has learned from C and C++.</p>

<p>Walter has recently written a great article <a href="#[7]">[7]</a> on how D helps to <em>vanquish forever these bugs that blasted your kingdom</em>, which I highly recommend if you have a C/C++ background.</p>

<h3>4) Whatâ€™s up with this â€˜enforceâ€™?</h3>

<pre class="programlisting">
  enforce(args.length == 5, &quot;Invalid args.\n&quot; ~
  &quot;./tool &lt;input.csv&gt; &lt;colum-name&gt; &lt;replacement-
    string&gt; &lt;output.csv&gt;&quot;);</pre>

<p><em>I have never seen the </em><code>~</code><em> operator before!</em></p>

<p>Itâ€™s the string concatenation (or more general array concatenation) operator. How often how you encountered code like <code>a + b</code> and needed to know the types of <code>a</code> and <code>b</code> to know whether itâ€™s a addition or concatenation?</p>

<p><em>Why donâ€™t you use an </em><code>if</code><em> statement and terminate the program explicitly?</em></p>

<pre class="programlisting">
  if (args.length &lt; 5) {
    writeln(&quot;Invalid args.&quot;);
    writeln(&quot;./tool &lt;input.csv&gt; &lt;colum-name&gt;
      &lt;replacement-string&gt; &lt;output.csv&gt;&quot;);
    return 1;
  }</pre>

<p>Thatâ€™s valid D too. D allows a lot of different programming styles, but this article is intended to highlight a few specific <em>D styles</em> like <code>enforce</code>.</p>

<p><code>enforce</code> <a href="#[8]">[8]</a> is a function defined in <code>std.exception</code> and throws an exception if its first argument has a falsy value.</p>

<p><em>Hmm, I looked at the documentation </em><a href="#[8]">[8]</a><em> and saw this monster. I thought it simply throws an exception?</em></p>

<pre class="programlisting">
  auto enforce(E : Throwable = Exception, T)
    (T value, lazy string msg = null, string file =
    __FILE__, size_t line = __LINE__)</pre>

<p>I donâ€™t have the time to fully dive into Dâ€™s syntax, but <code>auto</code> instructs the compiler to infer the return type for you. This leads to the interesting <em>Voldemort</em> return types <a href="#[9]">[9]</a> as they canâ€™t be named by the user, but thatâ€™s a good topic for another article.</p>

<p>The next part looks a bit complicated <code>(E : Throwable = Exception, T)</code>, but donâ€™t worry yet. It means that <code>E</code> is a template parameter which needs to inherit from <code>Throwable</code> (the root of all exceptions), and is by default <code>Exception</code>. <code>T</code> is the template type of <code>value</code>.</p>

<p><em>Wait. I just instantiated a template without specifying its template parameters?</em></p>

<p>Yes, the D compiler does all the hard work for you.</p>

<p>The technical term is Implicit Function-Template Instantiation <a href="#[10]">[10]</a> (IFTI). Of course, we could have instructed <code>enforce</code> to throw a custom exception, but more on template instantiation later.</p>

<p><em>Alright. So this function takes a generic </em><code>value</code><em> and a </em><code>msg</code><em>, but a </em><code>lazy string msg</code><em>?</em></p>

<p><code>lazy</code> is a special keyword in D and tells the compiler to defer the evaluation of an argument expression until is actually needed.</p>

<p><em>I donâ€™t understand. </em><code>msg</code><em> seems to be a string concatenation of two strings. Isnâ€™t this done </em><strong>before</strong><em> the </em><code>enforce</code><em> is called?</em></p>

<pre class="programlisting">
  &quot;Invalid args.\n&quot; ~ &quot;./tool &lt;input.csv&gt;
    &lt;colum-name&gt; &lt;replacement-string&gt; &lt;output.csv&gt;&quot;</pre>

<p>No, <code>lazy</code> is lazy and the string concatenation doesnâ€™t happen at the caller site, but can be requested explicitly by the callee.</p>

<p>It gets a bit clearer if we look at the second <code>enforce</code>:</p>

<pre class="programlisting">
  enforce(colIndex &lt; 0, &quot;Invalid column name. Valid
    are: %(%s, %)&quot;.format(lines.front));</pre>

<p><code>format</code> and all the expensive work of formatting the error message is never done on the default path, but only if an exception actually gets thrown. Ignore the <code>%(%s, %)</code> formatting string for a bit, it will be explained soon.</p>

<p><em>Ok, but how does that work?</em></p>

<p>In short: the compiler performs some smart formatting for you and creates an anonymous lambda. For more details, see this advanced article about Dâ€™s <code>lazy</code> <a href="#[10]">[10]</a>.</p>

<p><em>But thereâ€™s more magic here. Whatâ€™s </em><code>__FILE__</code> <em>and </em><code>__LINE__</code><em>?</em></p>

<pre class="programlisting">
  string file = __FILE__, size_t line = __LINE__</pre>

<p>Remember that D is a compiled language and accessing the stack isnâ€™t as easy as asking the interpreter nicely. These two default arguments are automatically set by the compiler with the file and line number of the caller. This is important for logging or throwing exceptions like we have done here.</p>

<p>So an API author can simply say â€œHey, I would like to know the line number of my caller.â€ and doesnâ€™t depend on the user hacking the replacements as youâ€™d have to do in C/C++ with the preprocessor macros:</p>

<pre class="programlisting">
  #ifdef SPDLOG_DEBUG_ON
  #define SPDLOG_DEBUG(logger, ...) logger-&gt; \
    debug(__VA_ARGS__)  &lt;&lt; &quot; (&quot; &lt;&lt; __FILE__  \
    &lt;&lt; &quot; #&quot; &lt;&lt; __LINE__ &lt;&lt;&quot;)&quot;;
  #else
  #define SPDLOG_DEBUG(logger, ...)
  #endif</pre>

<p>In fact, D doesnâ€™t even have a preprocessor.</p>

<h3>5) auto and a statically typed language</h3>

<pre class="programlisting">
  auto inFile = args[1], columName = args[2],
    replacement = args[3], outFile = args[4];</pre>

<p><em>Hmm, but whatâ€™s </em><code>auto</code><em>? I thought D was a statically typed system?</em></p>

<p>Yes D is statically typed, but the compiler is pretty smart, so we can let it do all the hard for us. <code>auto</code> is a filler word for the compiler that means â€˜whatever the type of the assignment, use this as type of this variableâ€™.</p>

<h3>6) What the hell is UFCS?</h3>

<pre class="programlisting">
  auto lines = File(inFile).byLine.map!(a =&gt;
    a.splitter(&quot;,&quot;));</pre>

<p>One of the major features of D is the Unified Function Call Syntax (UFCS) <a href="#[11]">[11]</a>. In short, the compiler will look up a function in the current namespace if itâ€™s not found as a member function of a type, but letâ€™s go through this step by step.</p>

<p><em>I looked at the documentation of </em><code>File</code><em> </em><a href="#[12]">[12]</a><em> and it has a method </em><code>byLine</code><em> </em><a href="#[13]">[13]</a><em>. So whereâ€™s the magic?</em></p>

<p>Have another look at <code>map</code> <a href="#[14]">[14]</a>, itâ€™s located in <code>std.algorithm</code>.</p>

<p><em>Okay, wait. How does this work?</em></p>

<p>The compiler internally rewrites the expression <code>File.byLine.map</code> to the following:</p>

<pre class="programlisting">
  map(File.byLine());</pre>

<p>Missing parenthesis are allowed too â€“ after all, the compiler knows that the symbol is a function.</p>

<p><em>Okay, but whatâ€™s up with this </em><code>!(a =&gt; a.splitter(&quot;,&quot;)))</code><em>?</em></p>

<p><code>!</code> is similar to C++/Javaâ€™s <code>&lt;&gt;</code> and declares a template. In this case itâ€™s a lambda function of <code>a =&gt; a.splitter(&quot;,&quot;)</code>. Notice that for <code>splitter</code> <a href="#[15]">[15]</a>, UFCS is used again and your brain might be more used to reading <code>splitter(a, &quot;,&quot;)</code> for now.</p>

<h3>7) Ranges</h3>

<p>Okay to recap, we have taken the input of a file, and split lines using commas <code>,</code>.</p>

<p><em>Wouldnâ€™t this result in a lot of unnecessary allocation?</em></p>

<p>The short answer is: D uses â€˜iterators on steroidsâ€™ which are lazy and work is only done when explicitly requested. Usually range algorithms donâ€™t even require any heap allocation as everything is done on the stack.</p>

<p>For example, in the next line <code>.front</code> returns the first line through which <code>countUntil</code> explicitly iterates:</p>

<pre class="programlisting">
  auto colIndex =
    lines.front.countUntil(columnName);</pre>

<p>So <code>lines.front</code> looks something like:</p>

<pre class="programlisting">
  [&quot;name&quot;, &quot;surname&quot;, &quot;city&quot;, &quot;country&quot;]</pre>

<p><code>countUntil</code> will return the line of the first match or <code>-1</code> otherwise. Itâ€™s a bit similar to an <code>indexOf</code> function familiar from, for example, JavaScript, but it accepts a template. So we could have supplied a custom predicate function:</p>

<pre class="programlisting">
  lines.front.countUntil!(a =&gt; a.endsWith(&quot;ty&quot;));</pre>

<h3>8) std.format: and compile-time checking of parameters</h3>

<p>The next lines are:</p>

<pre class="programlisting">
  enforce(colIndex &gt;= 0, &quot;Invalid column name.
    Valid are: %(%s, %)&quot;.format(lines.front));
  auto os = File(outFile, &quot;w&quot;);
  os.writefln(&quot;%(s, %)&quot;, lines.front);</pre>

<p><em>I have never seen </em><code>writefln(&quot;%(s, %)&quot;)</code><em> before. What happens here?</em></p>

<p><code>writefln</code> <a href="#[16]">[16]</a> is just a handy wrapper around Dâ€™s <code>format</code> <a href="#[17]">[17]</a> function.</p>

<p><code>format</code> itself provides a lot of options for serialization, but itâ€™s very similar to <code>printf</code>, although it does provide a few goodies like the special syntax for arrays <code>%(s, %)</code>.</p>

<p>This syntax opens an array formatting â€˜scopeâ€™ delimited by <code>%(</code> and closes it with <code>%)</code>. Within this array â€˜scopeâ€™ the elements should be formatted with <code>s</code> (their <code>string</code> serialization) and use <code>,</code>, a delimiter between the element.</p>

<p>Itâ€™s a shorthand syntax that often comes in handy, but if you donâ€™t like it there are many other ways to achieve the same result. For example, <code>joiner</code>:</p>

<pre class="programlisting">
  lines.front.joiner(&quot;,&quot;).writeln;</pre>

<p><em>What would such an error message look like?</em></p>

<p>It would look like Figure 2.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
  object.Exception@./main.d(9): Invalid column name. Valid are: &quot;name&quot;, &quot;surname&quot;, &quot;city&quot;, &quot;country&quot;
----------------
??:? pure @safe void std.exception.bailOut!(Exception).bailOut(immutable(char)[], ulong, const(char[])) [0x7a34b57e]
??:? pure @safe bool std.exception.enforce!(Exception, bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong) [0x7a34b4f8]
??:? _Dmain [0x7a34b17f]</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Figure 2</td>
	</tr>
</table>

<p><em>Okay, but isnâ€™t </em><code>printf</code><em> bad and unsafe? I heard that languages like Python are moving away from C-like formatting.</em></p>

<p>A Python library can only realize that arguments and formatted string donâ€™t fit when itâ€™s called. In D the compiler knows the types of the arguments and if you pass the format string at compile-time, guess what, the format can be checked compile-time. Try to compile a format string that tries to format strings as numbers:</p>

<pre class="programlisting">
  writefln!&quot;%d&quot;(&quot;foo&quot;);</pre>

<p>The compiler will complain:</p>

<pre class="programlisting">
  /dlang/dmd/linux/bin64/../../src/phobos/std/
  stdio.d(3876): Error: static assert  &quot;Incorrect
  format specifier for range: %d&quot;
  onlineapp.d(4):        instantiated from here:
  writefln!(&quot;%d&quot;, string)</pre>

<p><em>Wow, thatâ€™s really cool. How does this work?</em></p>

<p>D has another unique feature: compile-time function evaluation (CTFE) that allows to execute almost any function at compile-time. All that happens is that <code>writefln</code> is instantiated at compile-time with the string as template argument and then it calls the same <code>format</code> function that would normally be called at run-time with the known string. The coolest part about this is that thereâ€™s no special casing in the compiler and everything is just a few lines of library code.</p>

<h3>9) Letâ€™s parse the file</h3>

<p>Now that we have found the index of the replacement column, have opened the output csv file and have already written the header to it, all thatâ€™s left is to go over the input CSV file line by line and replace the specific CSV column with the <code>replacement</code> (Listing 2).</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
foreach (line; lines.dropOne)
  // remove the header
{
  auto r = line
    .enumerate // iterate with an (index, value)
             // tuple and lazily map a different
             // value for the specific CSV column
    .map!(a =&gt; a.index == colIndex ? replacement
      : a.value),
    .joiner(&quot;,&quot;); // join the lines back to a CSV
                  // format
    os.writeln(r);
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<p>One of the cool parts of D ranges is that they are so flexible. You want to do everything in a functional way? D has you covered (Listing 3).</p>
<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
alias csvPipe = pipe!(enumerate,
  map!(a =&gt; a.index == colIndex ? replacement
    : a.value), partial!(reverseArgs!joiner,
    &quot;_&quot;),);
lines.dropOne.map!csvPipe.each!(
  a =&gt; os.writeln(a));
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<p>Thereâ€™s another cool thing about D â€“ <code>std.parallelism</code>. Have you ever been annoyed that a loop takes too long, but didnâ€™t know a quick way to parallelize your code? Again, D has you covered with <code>.parallel</code> <a href="#[18]">[18]</a>:</p>

<pre class="programlisting">
  foreach (line; lines.parallel)
    // expensive operation in parallel</pre>

<p><em>No way. I donâ€™t believe this can be so simple.</em></p>

<p>Just try it yourself <a href="#[19]">[19]</a>.</p>

<h2>The Garbage Collector (GC)</h2>

<p>On the internet and especially on reddit and HackerNews thereâ€™s a huge criticism of Dâ€™s decision to do use a GC. Go, Java, Ruby, JavaScript, etc. all use a GC, but I canâ€™t better phrase it than Adam D. Ruppe:</p>

<p class="blockquote">D is a pragmatic language aimed toward writing fast code, fast. Garbage collection has proved to be a smashing success in the industry, providing productivity and memory-safety to programmers of all skill levels. Dâ€™s GC implementation follows in the footsteps of industry giants without compromising expertâ€™s ability to tweak even further.</p>

<p>So ask your question:</p>

<p><em>Okay, â€œability to tweak even furtherâ€ sounds a bit vague, what does this mean? I can tweak the memory usage?</em></p>

<p>Well, of course you can do that, but thatâ€™s something most languages with a GC allow you to do. D allows you to get the benefit of both worlds: profit from the convenience of the GC <em>and</em> use manual allocation methods for the hot paths in your program. This is great, because you can use <em>the same language</em> for prototyping and shipping your application.</p>

<p>A short and simplified summary of allocation patterns in D:</p>

<ul>
	<li><code>malloc</code> and friends are available in D (everything from C is)</li>

	<li>RAII is supported (e.g. <code>File</code> you saw earlier is reference-counted and automatically deallocates its buffer and close the file once all references are dead)</li>

	<li>thereâ€™s <code>std.experimental.allocator</code> for everyone with custom allocation needs</li>

	<li><code>std.typecons</code> provides a lot of library goodies like <code>Unique</code>, <code>Scoped</code>, <code>RefCounted</code> for <code>@nogc</code> allocation.</li>
</ul>

<p>Mike Parker has recently started an extensive GC Series <a href="#[20]">[20]</a> on the DBlog which I recommend to everyone who prefers performance over convenience.</p>

<h2>Other goodies</h2>

<h3>std.csv</h3>

<p><em>Hey, I saw that thereâ€™s </em><code>std.csv</code><em> in D, why didnâ€™t you use it?</em></p>

<p>Simple â€“ it felt like cheating. See Listing 4.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
import std.algorithm, std.csv, std.functional,
  std.file, std.range;

void main(string[] args)
{
  auto inputFile = args[1], columnName = args[2],
    replacement = args[3], outputFile = args[4];
  auto records = inputFile.readText.csvReader!(
    string[string])(null);
  outputFile.write(records.map!((r) {
    r[columnName] = replacement;
    return r;
  }).pipe!(rows =&gt; records.header.join(&quot;,&quot;) ~
    &quot;\n&quot; ~ rows.map!(
    r =&gt; records.header.map!(
    h =&gt; r[h]).join(&quot;,&quot;)).join(&quot;\n&quot;)
  ));
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<h3>std.getopt</h3>

<p>One of the reasons why this challenge used positional arguments and no flags is that argument parsing is pretty hard in C++. Itâ€™s not in D. <code>std.getopt</code> provides convenience for everything out of the box. See Listing 5.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
import std.getopt;
int main(string[] args)
{
  string input, output, selectedColumn,
    fill = &quot;FOO&quot;;
  auto opts = getopt(args,
    &quot;i|input&quot;, &amp;input,
    &quot;o|output&quot;, &amp;output,
    &quot;s|select&quot;, &quot;Select a column to overwrite&quot;,
      &amp;selectedColumn,
    &quot;f|fill&quot;, &quot;Overwrite (default: FOO)&quot;, &amp;fill,
  );
  if (opts.helpWanted || input.length == 0) {
    defaultGetoptPrinter(&quot;./program&quot;,
      opts.options);
    return 1;
  }
  return 0;
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 5</td>
	</tr>
</table>

<h3>DMD, LDC and GDC</h3>

<p>One of the things that newcomers are often confused by is that D has three compilers. The short summary is:</p>

<ul>
	<li>DMD (DigitalMars D compiler) â€“ latest greatest features + fast compilation (= ideal for development)</li>

	<li>LDC (uses the LLVM backend) â€“ battle-tested LLVM backend + sophisticated optimizers + cross-compilation (=ideal for production)</li>

	<li>GDC (uses the GCC backend) â€“ similar points as LDC</li>
</ul>

<h3>Benchmark and performance</h3>

<p>Benchmarking a language compiler is a bit tricky as very often you end up benchmarking library functions. In general, D code can be as fast as C++ and often is even faster â€“ after all the LDC and GDC compilers have the same backend as clang++ or g++ with all its optimization logic. If you are interested to see how D programs perform against similar programs written in other languages, checkout Kostyaâ€™s benchmarks <a href="#[21]">[21]</a>.</p>

<p>Thereâ€™s also an excellent performance benchmark <a href="#[6]">[6]</a> from Jon Degenhardt (member of eBayâ€™s data science team) on how eBayâ€™s <code>tsv-utils </code><a href="#[6]">[6]</a> compare against existing CSV/TSV processing tools written in C, Go, and Rust.</p>

<h3>@safe</h3>

<p>Even though D is a system programming language that allows you to mess with pointers, raw memory and even inline assembly, it provides a sane way to deal with the dirty details. D has a <code>@safe</code> subset <a href="#[22]">[22]</a> <a href="#[23]">[23]</a> of the language in which the compiler will enforce that you donâ€™t do anything stupid thing and shoot yourself in the feet with e.g. accessing undefined memory.</p>

<h3>Unittest</h3>

<p>One strategic advantage of D is that unit-testing is so easy as itâ€™s built-in in the language and compiler. This is a valid D program:</p>

<pre class="programlisting">
  unittest {
    assert(1 == 2);
  }</pre>

<p>And with <code>-unittest</code> the compiler can be instructed to emit a unittest block to the object files or binary. Here, <code>rdmd</code> is again a friendly tool and you can directly go ahead and test your line with you this:</p>

<pre class="programlisting">
  rdmd -main -unittest test.d</pre>

<p>No advanced tooling setup required. Of course, this also means that itâ€™s particulary easy to automatically verify all examples that are listed in the documentation, because they are part of the testsuite. I even went one step further and made it possible to edit and run the examples on dlang.org <a href="#[23]">[23]</a>.</p>

<h3>Other cool D features</h3>

<p>There are many other cool features that D offers that didnâ€™t make it into this article, but as a teaser for future articles:</p>

<ul>
	<li>Code generation within the language (cut down your boilerplate)</li>

	<li>Strong and easy Compile-Time introspection (Meta-programming)</li>

	<li><code>alias this</code> for subtyping</li>

	<li><code>-betterC</code> (using D without a runtime)</li>

	<li><code>mixin</code> for easily generating code</li>

	<li>A module system that doesnâ€™t suck</li>

	<li><code>debug</code> attribute to break out of <code>pure</code> code</li>

	<li>Built-in documentation</li>

	<li>Contracts and invariants</li>

	<li><code>scope(exit)</code> and <code>scope(failure)</code> for structuring creation with its destruction</li>

	<li>Native interfacing with C (and most of C++)</li>

	<li><code>with</code> for loading symbols into the current name</li>

</ul>

<p>For a full list, see the â€˜Overview of Dâ€™ <a href="#[24]">[24]</a> and donâ€™t forget that the full language specification <a href="#[25]">[25]</a> is readable in one evening.</p>

<h2>Downsides</h2>

<p><em>Okay, so you say D is so great, but why hasnâ€™t it taken off?</em></p>

<p>Thereâ€™s a lot more to a programming language than just the language and compiler. D has to fight with the problems all young languages have to deal with e.g. small ecosystem, few tutorials/sparse documentation and occasional rough edges. Languages like Kotlin, Rust or Go have it a lot easier, because they have a big corporate sponsor which gives these language a big boost.</p>

<p>Without such a boost, itâ€™s a chicken/egg problem: if nobody is learning D, it also means that no one can write tutorials or better documentation. Also many people have learnt a few languages and use them in production. Thereâ€™s little incentive for them to redesign their entire stack.</p>

<p>However, things improved greatly over the last years and nowadays even companies like Netflix, eBay, or Remedy Games use D. A few examples:</p>

<ul>
	<li>the fastest parallel file system for High Performance Computing <a href="#[26]">[26]</a> is written in D</li>
	<li>if you drive by train in Europe, chances are good that you were guided by D (Funkwerk <a href="#[27]">[27]</a> â€“ the company that manages the transport passenger information system â€“ develops their software in D)</li>
	<li>if you donâ€™t use an Adblocker, chances are good that algorithms written in D bid in real-time for showing you advertisement (two of the leading companies in digital advertising (Sociomantic and Adroll) use D)</li>
</ul>

<p>The â€˜organizations using Dâ€™ page <a href="#[28]">[28]</a> lists more of these success stories.</p>

<p>Of course, D â€“ like every other language â€“ has its â€˜uglyâ€™ parts, but thereâ€™s always work in progress to fix these and compared to all other languages I have worked with, the ugly parts are relatively tiny.</p>

<h2>Where to go from here?</h2>

<p><em>Okay that sounds great, but how do I install D on my system?</em></p>

<p>Use the install script <a href="#[29]">[29]</a>:</p>

<pre class="programlisting">
  curl https://dlang.org/install.sh | bash -s</pre>

<p>or use your package manager <a href="#[30]">[30]</a>.</p>

<p>And start hacking!</p>

<p>Itâ€™s possible to do three easy tweaks to make I/O faster in D:</p>

<ul>
	<li>disabling auto-decoding with <code>byCodeUnit</code></li>
	<li>non-thread-safe I/O with <code>lockingTextWriter</code></li>
	<li>use of <code>std.mmfile</code> <a href="#[5]">[5]</a></li>
</ul>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#!/usr/bin/env rdmd
import std.algorithm, std.exception, std.format,
  std.mmfile, std.range, std.stdio, std.utf;

void main(string[] args) {
  enforce(args.length == 5, &quot;Invalid args\n&quot; ~
  &quot;./tool &lt;input.csv&gt; &lt;colum-name&gt;
  &lt;replacement-string&gt; &lt;output.csv&gt;&quot;);
  auto inFile = args[1], columName = args[2],
    replacement = args[3].byCodeUnit,
    outFile = args[4];
  scope mmFile = new MmFile(args[1]);
  auto lines = (
    cast(string) mmFile[0..mmFile.length])
    .splitter('\n').map!(
    a =&gt; a.byCodeUnit.splitter(&quot;,&quot;));
    auto colIndex =
      lines.front.countUntil!equal(columName);
    enforce(colIndex &gt;= 0,
      &quot;Invalid column. Valid columns: %(%s, %)&quot;
      .format(lines.front));
    auto os = File(outFile, &quot;w&quot;);
    os.writefln(&quot;%(%s, %)&quot;, lines.front);
    auto w = os.lockingTextWriter;
    foreach (line; lines.dropOne) {
      auto r = line
      .enumerate // iterate with an
                 // (index, value) tuple
     .map!(a =&gt; choose(a.index == colIndex,
       replacement, a.value))
     .joiner(&quot;,&quot;.byCodeUnit);
    w.put(r);
    w.put('\n');
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 6</td>
	</tr>
</table>

<h2>Acknowledgements</h2>

<p>Thanks a lot to Timothee Cour, Juan Miguel Cejuela, Jon Degenhardt, Lio Lunesu, Mike Franklin, Simen KjÃ¦rÃ¥s, Arredondo, Martin Tschierschke, Nicholas Wilson, Arun Chandrasekaran, jmh530, Dukc, and ketmar for their helpful feedback.</p>

<h2>References</h2>

<p class="bibliomixed"><a id="[1]"></a>[1]	<a href="https://www.fluentcpp.com/2017/09/25/expressive-cpp17-coding-challenge/">https://www.fluentcpp.com/2017/09/25/expressive-cpp17-coding-challenge/</a></p>

<p class="bibliomixed"><a id="[2]"></a>[2]	<a href="https://www.fluentcpp.com/2017/10/23/results-expressive-cpp17-coding-challenge/">https://www.fluentcpp.com/2017/10/23/results-expressive-cpp17-coding-challenge/</a></p>

<p class="bibliomixed"><a id="[3]"></a>[3]	<a href="https://gist.github.com/steveklabnik/ad0a33acc82e21ca3f763e4278ad31a5#file-main-rs-L36">https://gist.github.com/steveklabnik/ad0a33acc82e21ca3f763e4278ad31a5#file-main-rs-L36</a></p>

<p class="bibliomixed"><a id="[4]"></a>[4]	<a href="http://coliru.stacked-crooked.com/a/70f762ee7f9c2606">http://coliru.stacked-crooked.com/a/70f762ee7f9c2606</a></p>

<p class="bibliomixed"><a id="[5]"></a>[5]	Memory mapped files: <a href="https://dlang.org/phobos/std_mmfile.html">https://dlang.org/phobos/std_mmfile.html</a></p>

<p class="bibliomixed"><a id="[6]"></a>[6]	Performance benchmark: <a href="https://github.com/eBay/tsv-utils-dlang/blob/master/docs/Performance.md">https://github.com/eBay/tsv-utils-dlang/blob/master/docs/Performance.md</a></p>

<p class="bibliomixed"><a id="[7]"></a>[7]	<a href="https://dlang.org/blog/2018/02/07/vanquish-forever-these-bugs-that-blasted-your-kingdom/">https://dlang.org/blog/2018/02/07/vanquish-forever-these-bugs-that-blasted-your-kingdom/</a></p>

<p class="bibliomixed"><a id="[8]"></a>[8]	<a href="https://dlang.org/phobos/std_exception.html#enforce">https://dlang.org/phobos/std_exception.html#enforce</a></p>

<p class="bibliomixed"><a id="[9]"></a>[9]	<a href="https://wiki.dlang.org/Voldemort_types">https://wiki.dlang.org/Voldemort_types</a></p>

<p class="bibliomixed"><a id="[10]"></a>[10]	<a href="https://dlang.org/articles/lazy-evaluation.html">https://dlang.org/articles/lazy-evaluation.html</a></p>

<p class="bibliomixed"><a id="[11]"></a>[11]	<a href="https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs">https://tour.dlang.org/tour/en/gems/uniform-function-call-syntax-ufcs</a></p>

<p class="bibliomixed"><a id="[12]"></a>[12]	<a href="https://dlang.org/phobos/std_stdio.html#.File">https://dlang.org/phobos/std_stdio.html#.File</a></p>

<p class="bibliomixed"><a id="[13]"></a>[13]	<a href="https://dlang.org/phobos/std_stdio.html#.File.byLine">https://dlang.org/phobos/std_stdio.html#.File.byLine</a></p>

<p class="bibliomixed"><a id="[14]"></a>[14]	<a href="https://dlang.org/phobos/std_algorithm_iteration.html#.map">https://dlang.org/phobos/std_algorithm_iteration.html#.map</a></p>

<p class="bibliomixed"><a id="[15]"></a>[15]	<a href="https://dlang.org/phobos/std_algorithm_iteration.html#splitter">https://dlang.org/phobos/std_algorithm_iteration.html#splitter</a></p>

<p class="bibliomixed"><a id="[16]"></a>[16]	<a href="https://dlang.org/phobos/std_stdio.html#.File.writefln">https://dlang.org/phobos/std_stdio.html#.File.writefln</a></p>

<p class="bibliomixed"><a id="[17]"></a>[17]	<a href="https://dlang.org/phobos/std_format.html#.format">https://dlang.org/phobos/std_format.html#.format</a></p>

<p class="bibliomixed">[18]<a id="[18]"></a>	<a href="https://dlang.org/phobos/std_parallelism.html#.parallel">https://dlang.org/phobos/std_parallelism.html#.parallel</a></p>

<p class="bibliomixed"><a id="[19]"></a>[19]	<a href="https://run.dlang.io/is/9fbtpQ">https://run.dlang.io/is/9fbtpQ</a></p>

<p class="bibliomixed">[20]<a id="[20]"></a>	<a href="https://dlang.org/blog/the-gc-series/">https://dlang.org/blog/the-gc-series/</a></p>

<p class="bibliomixed"><a id="[21]"></a>[21]	<a href="https://github.com/kostya/benchmarks">https://github.com/kostya/benchmarks</a></p>

<p class="bibliomixed"><a id="[22]"></a>[22]	<a href="https://dlang.org/articles/safed.html">https://dlang.org/articles/safed.html</a></p>

<p class="bibliomixed"><a id="[23]"></a>[23]	<a href="https://dlang.org/blog/2017/03/08/editable-and-runnable-doc-examples-on-dlang-org/">https://dlang.org/blog/2017/03/08/editable-and-runnable-doc-examples-on-dlang-org/</a></p>

<p class="bibliomixed"><a id="[24]"></a>[24]	<a href="https://dlang.org/overview.html">https://dlang.org/overview.html</a></p>

<p class="bibliomixed"><a id="[25]"></a>[25]	<a href="https://dlang.org/spec/spec.html">https://dlang.org/spec/spec.html</a></p>

<p class="bibliomixed"><a id="[26]"></a>[26]	<a href="https://www.theregister.co.uk/2017/12/22/a_dive_into_wekaios_parallel_file_system_tech/">https://www.theregister.co.uk/2017/12/22/a_dive_into_wekaios_parallel_file_system_tech/</a></p>

<p class="bibliomixed"><a id="[27]"></a>[27]	<a href="https://dlang.org/blog/2017/07/28/project-highlight-funkwerk/">https://dlang.org/blog/2017/07/28/project-highlight-funkwerk/</a></p>

<p class="bibliomixed"><a id="[28]"></a>[28]	<a href="https://dlang.org/orgs-using-d.html">https://dlang.org/orgs-using-d.html</a></p>

<p class="bibliomixed"><a id="[29]"></a>[29]	<a href="Install script: https://dlang.org/install.html">Install script: https://dlang.org/install.html</a></p>

<p class="bibliomixed"><a id="[30]"></a>[30]	<a href="Package manager: https://dlang.org/download.html">Package manager: https://dlang.org/download.html</a></p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
