\documentclass[paper=a4,parskip=half,11pt,english,oneside,open=any,draft=false]{scrreprt} \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} \usepackage{lmodern} \usepackage{babel} \usepackage{csquotes} \usepackage{listings} \usepackage{xcolor} \usepackage{textcomp} \usepackage{applekeys} \usepackage{hyperref} \hypersetup{pdfinfo={Title={Hands-On DLang}, Author={Johannes Loher}}} \lstdefinestyle{D}{ language=C, emptylines=1, breaklines=true, basicstyle=\footnotesize\ttfamily, keywordstyle=\bfseries\color{green!50!black}, commentstyle=\itshape\color{white!50!black}, numbers=left, frame=single, showstringspaces=false } \lstdefinestyle{bash}{ language=bash, emptylines=1, breaklines=true, basicstyle=\footnotesize\ttfamily, numbers=left, frame=single, showstringspaces=false } \setkomafont{descriptionlabel}{\normalfont} \begin{document} \title{Hands-On DLang} \author{Johannes Loher} \date{\today} \maketitle \tableofcontents \chapter{Setup} \section{Installing DMD and DUB} \subsection{OS X} \subsubsection{Installing with Homebrew (recommended)} \begin{lstlisting}[style=bash] brew install dmd brew install dub \end{lstlisting} \subsubsection{Installing locally using the install script} \begin{lstlisting}[style=bash] curl -fsS https://dlang.org/install.sh | bash -s dmd echo "~/.dlang/dmd-2.079.0/activate" >> ~/.profile # Add dmd and dub to PATH on starting a bash shell \end{lstlisting} \subsubsection{Installing using the installer} \begin{enumerate} \item Download \url{http://downloads.dlang.org/releases/2.x/2.079.0/dmd.2.079.0.dmg}. \item Open \texttt{dmd.2.079.0.dmg}. \item Run \texttt{DMD2.pkg} (you might need to activate the \enquote{allowinstalling applications from unverified developers} option in your security settings) and install with the default settings. \end{enumerate} \subsection{Windows} \begin{enumerate} \item Download \url{http://downloads.dlang.org/releases/2.x/2.079.0/dmd-2.079.0.exe}. \item Run \texttt{dmd-2.079.0.exe} and install with the default settings (this will also install Visual Studio if you do not have it installed yet). \end{enumerate} \section{Recommended editor setup} Visual Studio Code is the recommended editor, because it has the best D integration at the moment. If you want to use another editor or IDE, that is perfectly fine. However, instructions will only be provided for Visual Studio Code. \subsection{Installation of Visual Studio Code} Download and install Visual Studio Code from here: \url{https://code.visualstudio.com/}. OS X users can also install it using Homebrew: \begin{lstlisting}[style=bash] brew tap caskroom/cask brew cask install visual-studio-code \end{lstlisting} \subsection{Extension setup} \begin{enumerate} \item Open the Extension view in the sidebar: \begin{tabular}{ll} OS X: & \cmdkey{} + \shiftkey{} + X\\ Windows: & \ctlkey{} + \shiftkey{} + X \end{tabular} \item Install the extension \enquote{D Programming Language (code-d)} (requires that git is installed). \item Restart Visual Studio Code. \end{enumerate} \chapter{Basics} \section{Hello World} \begin{lstlisting}[style=D] import std.stdio; void main() { writeln("Hello World"); } \end{lstlisting} \section{Imports and modules} D has the concept of \emph{modules} and \emph{packages}. By importing a certain module with the \texttt{import} statement,all public symbols from module become available. The standard library, called Phobos, is located in the \texttt{package}. E.g. in order to import the \texttt{file} module from Phobos, you would write: \begin{lstlisting}[style=D] import std.file; \end{lstlisting} \subsection{Selective imports} It is possible (and often good style) to import symbols selectively from a module: \begin{lstlisting}[style=D] import std.stdio: writeln, writefln; \end{lstlisting} \subsection{Scoped imports} It is not necessary to place imports at the beginning of a file. They can be located anywhere in the code. If they appear inside a certain scope (delimited by braces), the imported symbols are only available inside that scope. Here is an alternative version of the hello world program: \begin{lstlisting}[style=D] void main() { import std.stdio: writeln; writeln("Hello World"); } /* writeln is not available outside of the main function */ \end{lstlisting} \subsection{Imports match files and directories} The module system is entirely based on files. E.g. \texttt{my.thing} refers to a file \texttt{thing.d} in the folder \texttt{my/}. \section{Basic Types} D has the following basic types: \begin{tabular}{ll} \texttt{bool} & 8-bit\\ \texttt{byte}, \texttt{ubyte}, \texttt{char} & 8-bit\\ \texttt{short}, \texttt{ushort}, \texttt{wchar} & 16-bit\\ \texttt{int}, \texttt{uint}, \texttt{dchar}, \texttt{float} & 32-bit\\ \texttt{long}, \texttt{ulong}, \texttt{double} & 64-bit\\ \texttt{real} & $\ge$ 64-bit (generally 64-bit, but 80-bit on Intel x86 32-bit) \end{tabular} \texttt{char} represents UTF-8 characters, \texttt{wchar} represents UTF-16 characters, and \texttt{dchar} represents UTF-32 characters. \subsection{Type conversion} For integer types, automatic type conversion is only allowed if no precision is lost (e.g. \texttt{int} to \texttt{long}). All conversion between floating point types are allowed (e.g. \texttt{double} to \texttt{float}). Manual type conversion is achieved with the \texttt{cast} expression: \begin{lstlisting}[style=D] long a = 1; int b = cast(int) a; \end{lstlisting} \subsection{Type properties} All types have a property \texttt{.init} to which variables of that type are initialized, if they are not initialized explicitly. For integer types, this is \texttt{0} and for floating point types it is \texttt{nan}. Every type also has a \texttt{.stringof} property which yields its name as a string. Integer types have some more properties: \begin{tabular}{ll} \texttt{.max} & The maximum value the type can hold\\ \texttt{.min} & The minimum value the type can hold \end{tabular} And so do floating point types: \begin{tabular}{ll} \texttt{.max} & The maximum value the type can hold\\ \texttt{.min\_normal} & The smallest representable normalized value that is not \texttt{0}\\ \texttt{.nan} & NaN value\\ \texttt{.infinity} & Infinity value\\ \texttt{.dig} & number of decimal digits of precisions\\ \texttt{.mant\_dig} & number of bits in mantissa\\ \dots \end{tabular} \subsection{Indexing} For indexing, usually the alias type \texttt{size\_t} is used, which is large enough to represent an offset into all addressable memory. \section{Variable declarations} Variables are declared by writing the type followed by the variable name: \begin{lstlisting}[style=D] int myVar; \end{lstlisting} They can also be explicitly initialized: \begin{lstlisting}[style=D] int myVar = 42; \end{lstlisting} It is also possible to declare several variables at once: \begin{lstlisting}[style=D] int myVar, someOtherVar; \end{lstlisting} D has automatic type deduction, so when explicitly initializing a variable, it is not necessary to mention the type. Instead we can use the \texttt{auto} keyword: \begin{lstlisting}[style=D] auto myVar = 42; \end{lstlisting} Here is a combination of the above notations: \begin{lstlisting}[style=D] auto myInt = 42, myFloat = 4.2f; \end{lstlisting} \section{Functions} The basic syntax for functions is very similar to C: \begin{lstlisting}[style=D] int add(int lhs, int rhs) { return lhs + rhs; } \end{lstlisting} \subsection{Return type deduction} A functions return type can be defined to be \texttt{auto}. In this case, the return type will be infered. Multiple return statements are possible, but must return compatible types. \begin{lstlisting}[style=D] auto add(int lhs, int rhs) { // returns `int` return lhs + rhs; } auto lessOrEqual(int lhs, int rhs) { // returns `double` if (lhs <= rhs) return 0; else return 1.0; } \end{lstlisting} \subsection{Default arguments} Those also work the same as in C and other languages: \begin{lstlisting}[style=D] void plot(string msg, string color = "red") { /* ... */ } plot("D rocks"); plot("D rocks", "blue"); \end{lstlisting} \subsection{Local functions} It is possible to define functions locally (even inside other functions). Those functions are not visible outside their parents scope. \begin{lstlisting}[style=D] void fun() { int local = 10; int fun_secret() { local++; // that's legal } /* ... */ } static assert(!__traits(compiles, fun_secret())); // fun_secret is not visible here \end{lstlisting} \section{Control flow} \subsection{if\ldots{}else} Very similar to how it is defined in other languages: \begin{lstlisting}[style=D] if (a == 5) { writeln("Condition is met"); } else if (a > 10) { writeln("Another condition is met"); } else { writeln("Nothing is met!"); } \end{lstlisting} \subsection{switch\ldots{}case} Also very similar to how it is defined in other languages, but for it works for integer types, bools and strings (which will be covered later). \begin{lstlisting}[style=D] string myString; /* ... */ switch(myString) { case "foo": writeln("Cool, myString was \"foo\""); break; default: writeln("Meh, myString was something boring"); break; } \end{lstlisting} For integer types, it is also possible to define ranges: \begin{lstlisting}[style=D] int c = 5; switch(c) { case 0: .. case 9: writeln(c, " is within 0-9"); break; // necessary! case 10: writeln("A Ten!"); break; default: // if nothing else matches writeln("Nothing"); break; } \end{lstlisting} \subsection{Loops} \texttt{while}-, \texttt{do\ldots{}while}- and classical \texttt{for}-loops all work the same as in C++/Java etc. \subsubsection{Breaking out of outer loops} As usual, you can break out of a loop immediately by using the \texttt{break} keyword. Additionally, you can also break out of outer loops by using labels: \begin{lstlisting}[style=D] outer: for (int i = 0; i < 10; ++i) { for (int j = 0; j < 5; ++j) { /*...*/ break outer; // breaks out of the outer loop } } \end{lstlisting} \end{document}