## A quick look at D

@Date: 15 Jan 2017, @Author: Dr. Chibisi Chima-Okereke

### Introduction

I came across the D programming language some time ago while researching C++ templates and found D much clearer in syntax and approach. D has very powerful template programming features for generic and metaprogramming, this is what excited me and has drawn me into the language.

D is a static programming language that some regard as an upgrade to C++, D is also influenced by Java and various other programming languages. It aims to have the performance and safety of compiled languages while allowing the user the expressiveness of a dynamic programming language like Python. D embraces different programming paradigms including imperative, object oriented, and functional programming. There is also support for concurrency and parallel programming. More information about the D programming language can be found at the D official website and wikipedia

In this article, we present basic approaches one can take to writing code for numeric computing in D. Our examples focus on two simplified BLAS (Basic Linear Algebra Subroutine) functions. The `scal` function is for scaling the elements of an array or vector by some numerical factor and the `dot` function calculates the dot product of two vectors (or arrays), see IBM’s ESSL documentation for more details. Our versions do not worry about incrementation different from 1. The code for this article is located in our GitHub repo

### Writing a D function

Below is one approach you can take for a simplified `scal` function using a foreach loop:

``````/* File name: scal.d */
import std.stdio : writeln;

double[] scal_double(double[] x, in double a)
{
foreach(i, el; x)
{
x[i] *= a;
}
return x;
}

void main(){
double[] x = [1, 2, 3, 4, 5, 6];
writeln(scal_double(x, 3));
}
``````

#### Compiling the output

There are three D compilers, the reference compiler DMD, the GCC-based compiler GDC, and the LLVM compiler LDC. To compile with LDC on Linux:

``````ldc2 scal.d -boundscheck=off && ./scal
``````

As a general tip, if we are confident that our index remains in the bounds of our array, we can turn off bounds check which gives us a performance boost. One thing you will notice if you go on to write more D code is that the compiler is FAST - much faster than C/C++. You will also notice that if you make a mistake, the error output you get is clear and informative. Features like this make working in the D language feel seamless from code to output

If you have never seen D code before, the `import` command is used to obtain the `writeln` function from `std.stdio` D’s i/o module and `double[]` means an array of doubles. The `scal_double` function takes in a double array `x`, and a double `a` and multiplies each element of `x` by `a` and returns the result as a double array. The curious `in` keyword next to the `double a` declaration makes it clear that `a` is an input to the function, and an error will occur if you attempt to modify it. Effectively `in` declares the variable `a` as `const` exactly how it would be specified in C/C++. So I could have used `const` or more strictly `immutable` for the `double a` parameter with a similar effect, however marking an input parameter as `immutable` requires that the variable input also be immutable.

D also supports C/C++ style for loops:

``````for(int i = 0; i < x.length; ++i)
{
x[i] *= a;
}
``````

### Template functions

But what if I want this function to work for types other than doubles? I could violate the don’t repeat yourself (DRY) principle and write more functions substituting `double` for my required type or we could use function templates to make the function generic - the same principle as C++ templates but so much easier to write in D.

Below is the `scal` function written using D’s function template shorthand:

``````X[] scal(X)(X[] x, in X a)
{
foreach(i, el; x)
{
x[i] *= a;
}
return x;
}
``````

This same type of shorthand is also valid for structs, classes and interfaces - come on, is this not much nicer and clearer than C++ angle bracket template notation? If you have not come across templates previously, think of `X` as a placeholder for any specified type. The long-form template notation is given below:

``````template scal(X)
{
X[] scal(X[] x, in X a)
{
foreach(i, el; x)
{
x[i] *= a;
}
return x;
}
}
``````

This long-form reveals that the template is eponymous.

Now that we have made the function generic, we can call the function using:

``````import std.stdio : writeln;

X[] scal(X)(X[] x, in X a)
{
foreach(i, el; x)
{
x[i] *= a;
}
return x;
}

void main(){
float[] x = [1, 2, 3, 4, 5, 6];
/* explicit notation */
writeln(scal!(float)(x, 3));
/* Short cut notation */
writeln(scal(x, 3));
}
``````

D’s full template instantiation notation uses an exclamation mark. At the point you write `scal!(float)` a float version of the `scal` function is created, the full declaration is then `scal!(float)(x, 3)`, note that for single parameter templates, the form `scal!float(x, 3)` is also acceptable. The D compiler is clever enough to infer type from `scal(x, 3)`.

The simplified `dot` BLAS function calculates the dot product of two arrays. Here is the template version using a loop:

``````X dot(X)(in X[] x, in X[] y)
{
X output = X(0);
foreach(i, el; x)
{
output += el*y[i];
}
return output;
}
``````

### Array notation

If all I am doing is multiplying an array by a number, do I really have to use a loop? It turns out that D has some builtin array sugar for such situations:

``````X[] scal(X)(X[] x, in X a)
{
x[] *= a;
return x;
}
``````

Array notation for the `dot` case is given below:

``````import std.algorithm.iteration: sum;
X dot(X)(X[] x, X[] y)
{
x[] *= y[];
return sum(x);
}
``````

### Uniform Function Call Syntax

D also has uniform function call syntax (UFCS) that allows a function to be called using the receiver as the first parameter:

``````auto x = [1, 2, 3, 4, 5, 6];
writeln(x.scal(3));
``````

It allows us to have chaining notation which dovetails nicely with function programming styles. The `auto` keyword is for automatic type deduction, it means we do not have to explicitly specify the type of `x`, note however that the output of `x.scal(3)` will now be an `int` array.

### Functional programming

Functional programming (FP) is now popular in emerging programming languages and is being added to those that are already established. Not only does D have FP support, it is the only major programming language where purity in functions can be optionally enforced (in the case of D by using the `pure` keyword). The FP version of the `scal` function is:

``````import std.algorithm.iteration: sum, map;
import std.array: array;

X[] scal(X)(X[] x, X a)
{
return x.map!((xi) => xi*a).array();
}
``````

The functional version of `dot`:

``````import std.stdio : writeln;
import std.range : zip;
import std.algorithm.iteration: sum, map;

X dot(X)(X[] x, X[] y)
{
return zip(x, y).map!(a => a*a).sum;
}

void main(){
double[] x = [1, 2, 3, 4, 5, 6];
double[] y = [3, 6, 9, 12, 15, 18];
writeln(dot(x, y));
}

``````

### C-Style Programming

D also has C-style syntax (in fact D is fully compatible with C and can call and can be called from C). The `scal` function in pointer style is given below:

``````import std.stdio : writeln;

void scal(N, X)(N n, in X a, X* x)
{
while(n)
{
*x *= a;
x += 1;
--n;
}
}

void main(){
double[] x = [1, 2, 3, 4, 5, 6];
scal(6, 3, x.ptr);
writeln(x);
}

``````

In D the `.ptr` append returns a pointer to the array.

### Summary

From this article, it should be clear that D is not dogmatic but rather quite accepting of different programming paradigms and it has a flexible syntax. This blog post did not touch on some of the programming approaches available in D for instance objects and inheritance, however the standard library and language reference is available on the D Programming Language official website and Ali Çehreli’s Programming in D book is a fantastic resource for learning how to program in D.