Header Ads


D Programming Tutorial

D Programming Tutorial

D Programming Tutorial

D programming language is an object-oriented multi-paradigm system programming language. D programming is actually developed by re-engineering C++ programming language, but it is distinct programming language that not only takes in some features of C++ but also some features of other programming languages such as Java, C#, Python, and Ruby. This tutorial covers various topics ranging from the basics of the D programming language to advanced OOP concepts along with the supplementary examples.

Audience

This tutorial is designed for all those individuals who are looking for a starting point of learning D Language. Both a beginner or advanced users can refer this tutorial as their learning material. Enthusiastic learners can refer it as their on-the-go reading reference. Ayn individual with logical mindset can enjoy learning D through this tutorial.

Prerequisites

Before proceeding with this tutorial, it is advisable for you to understand the basics concepts of computer programming. You just need to have a basic understanding of working with a simple text editor and command line.

Execute D Programming Online

For most of the examples given in this tutorial you will find Try it option, so just make use of this option to execute your D Programming programs at the spot and enjoy your learning.
Try following example using Try it option available at the top right corner of the below sample code box −
import std.stdio;

void main(string[] args) {
   writeln("Hello World!");
}

D Programming - Overview


D programming language is an object-oriented multi-paradigm system programming language developed by Walter Bright of Digital Mars. Its development started in 1999 and was first released in 2001. The major version of D(1.0) was released in 2007. Currently, we have D2 version of D.
D is language with syntax being C style and uses static typing. There are many features of C and C++ in D but also there are some features from these language not included part of D. Some of the notable additions to D includes,
  • Unit testing
  • True modules
  • Garbage collection
  • First class arrays
  • Free and open
  • Associative arrays
  • Dynamic arrays
  • Inner classes
  • Closures
  • Anonymous functions
  • Lazy evaluation
  • Closures

Multiple Paradigms

D is a multiple paradigm programming language. The multiple paradigms includes,
  • Imperative
  • Object Oriented
  • Meta programming
  • Functional
  • Concurrent

Example

import std.stdio; 
 
void main(string[] args) { 
   writeln("Hello World!"); 
}

Learning D

The most important thing to do when learning D is to focus on concepts and not get lost in language technical details.
The purpose of learning a programming language is to become a better programmer; that is, to become more effective at designing and implementing new systems and at maintaining old ones.

Scope of D

D programming has some interesting features and the official D programming site claims that D is convinient, powerful and efficient. D programming adds many features in the core language which C language has provided in the form of Standard libraries such as resizable array and string function. D makes an excellent second language for intermediate to advanced programmers. D is better in handling memory and managing the pointers that often causes trouble in C++.
D programming is intended mainly on new programs that conversion of existing programs. It provides built in testing and verification an ideal for large new project that will be written with millions of lines of code by large teams.

D Programming - Environment

Try it Option Online

You really do not need to set up your own environment to start learning D programming language. Reason is very simple, we already have set up D Programming environment online under “Try it” option. Using this option, you can build and execute all the given examples online at the same time when you are learning theory. This gives you confidence in what you are reading and checking the result with different options. Feel free to modify any example and execute it online.
Try following example using Try it option available at the top right corner of the below sample code box −
import std.stdio; 
 
void main(string[] args) { 
   writeln("Hello World!"); 
}
For most of the examples given in this tutorial, you will find Try itoption, so just make use of it and enjoy learning.

Local Environment Setup for D

If you are still willing to set up your environment for D programming language, you need the following two softwares available on your computer, (a) Text Editor,(b)D Compiler.

Text Editor for D Programming

This will be used to type your program. Examples of few editors include Windows Notepad, OS Edit command, Brief, Epsilon, EMACS, and vim or vi.
Name and version of text editor can vary on different operating systems. For example, Notepad will be used on Windows, and vim or vi can be used on windows as well as Linux or UNIX.
The files you create with your editor are called source files and contain program source code. The source files for D programs are named with the extension ".d".
Before starting your programming, make sure you have one text editor in place and you have enough experience to write a computer program, save it in a file, build it and finally execute it.

The D Compiler

Most current D implementations compile directly into machine code for efficient execution.
We have multiple D compilers available and it includes the following.
  • DMD − The Digital Mars D compiler is the official D compiler by Walter Bright.
  • GDC − A front-end for the GCC back-end, built using the open DMD compiler source code.
  • LDC − A compiler based on the DMD front-end that uses LLVM as its compiler back-end.
The above different compilers can be downloaded from D downloads
We will be using D version 2 and we recommend not to download D1.
Lets have a helloWorld.d program as follows. We will use this as first program we run on platform you choose.
import std.stdio; 
 
void main(string[] args) { 
   writeln("Hello World!"); 
}

Installation of D on Windows

Download the windows installer.
Run the downloaded executable to install the D which can be done by following the on screen instructions.
Now we can build and run a d file say helloWorld.d by switching to folder containing the file using cd and then using the following steps −
C:\DProgramming> DMD helloWorld.d 
C:\DProgramming> helloWorld
We can see the following output.
hello world
C:\DProgramming is the folder, I am using to save my samples. You can change it to the folder that you have saved D programs.

Installation of D on Ubuntu/Debian

Download the debian installer.
Run the downloaded executable to install the D which can be done by following the on screen instructions.
Now we can build and run a d file say helloWorld.d by switching to folder containing the file using cd and then using the following steps −
$ dmd helloWorld.d 
$ ./helloWorld
We can see the following output.
$ hello world 

Installation of D on Mac OS X

Download the Mac installer.
Run the downloaded executable to install the D which can be done by following the on screen instructions.
Now we can build and run a d file say helloWorld.d by switching to folder containing the file using cd and then using the following steps −
$ dmd helloWorld.d 
$ ./helloWorld
We can see the following output.
$ hello world

Installation of D on Fedora

Download the fedora installer.
Run the downloaded executable to install the D which can be done by following the on screen instructions.
Now we can build and run a d file say helloWorld.d by switching to folder containing the file using cd and then using the following steps −
$ dmd helloWorld.d 
$ ./helloWorld
We can see the following output.
$ hello world

Installation of D on OpenSUSE

Download the OpenSUSE installer.
Run the downloaded executable to install the D which can be done by following the on screen instructions.
Now we can build and run a d file say helloWorld.d by switching to folder containing the file using cd and then using the following steps −
$ dmd helloWorld.d 
$ ./helloWorld
We can see the following output.
$ hello world

D IDE

We have IDE support for D in the form of plugins in most cases. This includes,
  • Visual D plugin is a plugin for Visual Studio 2005-13
  • DDT is a eclipse plugin that provides code completion, debugging with GDB.
  • Mono-Dcode completion, refactoring with dmd/ldc/gdc support. It has been part of GSoC 2012.
  • Code Blocks is a multi-platform IDE that supports D project creation, highlighting and debugging.

D Programming - Basic Syntax

D is quite simple to learn and lets start creating our first D program!

First D Program

Let us write a simple D program. All D files will have extension .d. So put the following source code in a test.d file.
import std.stdio;  

/* My first program in D */ 
void main(string[] args) { 
   writeln("test!"); 
}
Assuming D environment is setup correctly, lets run the programming using −
$ dmd test.d 
$ ./test
We can see the following output.
test
Let us now see the basic structure of D program, so that it will be easy for you to understand basic building blocks of the D programming language.

Import in D

Libraries which are collections of reusable program parts can be made available to our project with the help of import. Here we import the standard io library which provides the basic I/O operations. writeln which is used in above program is a function in D's standard library. It is used for printing a line of text. Library contents in D are grouped into modules which is based on the types of tasks that they intend perform. The only module that this program uses is std.stdio, which handles data input and output.

Main Function

Main function is the starting of the program and it determines the order of execution and how other sections of the program should be executed.

Tokens in D

A D program consists of various tokens and a token is either a keyword, an identifier, a constant, a string literal, or a symbol. For example, the following D statement consists of four tokens −
writeln("test!");
The individual tokens are −
writeln (
   "test!"
)
;

Comments

Comments are like supporting text in your D program and they are ignored by the compiler. Multi line comment starts with /* and terminates with the characters */ as shown below −
/* My first program in D */ 
Single comment is written using // in the beginning of the comment.
// my first program in D

Identifiers

A D identifier is a name used to identify a variable, function, or any other userdefined item. An identifier starts with a letter A to Z or a to z or an underscore _ followed by zero or more letters, underscores, and digits (0 to 9).
D does not allow punctuation characters such as @, $, and % within identifiers. D is a case sensitive programming language. Thus Manpower and manpowerare two different identifiers in D. Here are some examples of acceptable identifiers −
mohd       zara    abc   move_name  a_123 
myname50   _temp   j     a23b9      retVal

Keywords

The following list shows few of the reserved words in D. These reserved words may not be used as constant or variable or any other identifier names.
abstractaliasalignasm
assertautobodybool
bytecasecastcatch
charclassconstcontinue
dchardebugdefaultdelegate
deprecateddodoubleelse
enumexportexternfalse
finalfinallyfloatfor
foreachfunctiongotoif
importininoutint
interfaceinvariantislong
macromixinmodulenew
nulloutoverridepackage
pragmaprivateprotectedpublic
realrefreturnscope
shortstaticstructsuper
switchsynchronizedtemplatethis
throwtruetrytypeid
typeofubyteuintulong
unionunittestushortversion
voidwcharwhilewith

Whitespace in D

A line containing only whitespace, possibly with a comment, is known as a blank line, and a D compiler totally ignores it.
Whitespace is the term used in D to describe blanks, tabs, newline characters and comments. Whitespace separates one part of a statement from another and enables the interpreter to identify where one element in a statement, such as int, ends and the next element begins. Therefore, in the following statement −
local age
There must be at least one whitespace character (usually a space) between local and age for the interpreter to be able to distinguish them. On the other hand, in the following statement
int fruit = apples + oranges   //get the total fruits
No whitespace characters are necessary between fruit and =, or between = and apples, although you are free to include some if you wish for readability purpose.

D Programming - Variables

A variable is nothing but a name given to a storage area that our programs can manipulate. Each variable in D has a specific type, which determines the size and layout of the variable's memory; the range of values that can be stored within that memory; and the set of operations that can be applied to the variable.
The name of a variable can be composed of letters, digits, and the underscore character. It must begin with either a letter or an underscore. Upper and lowercase letters are distinct because D is case-sensitive. Based on the basic types explained in the previous chapter, there will be the following basic variable types −
Sr.No.Type & Description
1
char
Typically a single octet (one byte). This is an integer type.
2
int
The most natural size of integer for the machine.
3
float
A single-precision floating point value.
4
double
A double-precision floating point value.
5
void
Represents the absence of type.
D programming language also allows to define various other types of variables such as Enumeration, Pointer, Array, Structure, Union, etc., which we will cover in subsequent chapters. For this chapter, let us study only basic variable types.

Variable Definition in D

A variable definition tells the compiler where and how much space to create for the variable. A variable definition specifies a data type and contains a list of one or more variables of that type as follows −
type variable_list;
Here, type must be a valid D data type including char, wchar, int, float, double, bool, or any user-defined object, etc., and variable_list may consist of one or more identifier names separated by commas. Some valid declarations are shown here −
int    i, j, k; 
char   c, ch; 
float  f, salary; 
double d;
The line int i, j, k; both declares and defines the variables i, j and k; which instructs the compiler to create variables named i, j, and k of type int.
Variables can be initialized (assigned an initial value) in their declaration. The initializer consists of an equal sign followed by a constant expression as follows −
type variable_name = value;

Examples

extern int d = 3, f = 5;    // declaration of d and f.  
int d = 3, f = 5;           // definition and initializing d and f.  
byte z = 22;                // definition and initializes z.  
char x = 'x';               // the variable x has the value 'x'.
When a variable is declared in D, it is always set to its 'default initializer', which can be manually accessed as T.init where T is the type (ex. int.init). The default initializer for integer types is 0, for Booleans false, and for floating-point numbers NaN.

Variable Declaration in D

A variable declaration provides assurance to the compiler that there is one variable existing with the given type and name so that compiler proceed for further compilation without needing complete detail about the variable. A variable declaration has its meaning at the time of compilation only, compiler needs actual variable declaration at the time of linking of the program.

Example

Try the following example, where variables have been declared at the start of the program, but are defined and initialized inside the main function −
import std.stdio; 
 
int a = 10, b = 10; 
int c;
float f;  

int main () { 
   writeln("Value of a is : ", a); 
   
   /* variable re definition: */ 
   int a, b; 
   int c; 
   float f;
   
   /* Initialization */ 
   a = 30; 
   b = 40; 
   writeln("Value of a is : ", a); 
   
   c = a + b; 
   writeln("Value of c is : ", c);  
   
   f = 70.0/3.0; 
   writeln("Value of f is : ", f); 
   return 0; 
}
When the above code is compiled and executed, it produces the following result −
Value of a is : 10 
Value of a is : 30 
Value of c is : 70 
Value of f is : 23.3333

Lvalues and Rvalues in D

There are two kinds of expressions in D −
  • lvalue − An expression that is an lvalue may appear as either the left-hand or right-hand side of an assignment.
  • rvalue − An expression that is an rvalue may appear on the right- but not left-hand side of an assignment.
Variables are lvalues and so may appear on the left-hand side of an assignment. Numeric literals are rvalues and so may not be assigned and cannot appear on the left-hand side. The following statement is valid −
int g = 20;
But the following is not a valid statement and would generate a compile-time error −
10 = 20;

D Programming - Data Types

In the D programming language, data types refer to an extensive system used for declaring variables or functions of different types. The type of a variable determines how much space it occupies in storage and how the stored bit pattern is interpreted.
The types in D can be classified as follows −
Sr.No.Types and Description
1
Basic Types −
They are arithmetic types and consist of the three types: (a) integer, (b) floating-point, and (c) character.
2
Enumerated types −
They are again arithmetic types. They are used to define variables that can only be assigned certain discrete integer values throughout the program.
3
The type void −
The type specifier void indicates that no value is available.
4
Derived types −
They include (a) Pointer types, (b) Array types, (c) Structure types, (d) Union types, and (e) Function types.
The array types and structure types are referred to collectively as the aggregate types. The type of a function specifies the type of the function's return value. We will see basic types in the following section whereas other types will be covered in the upcoming chapters.

Integer Types

The following table gives lists standard integer types with their storage sizes and value ranges −
TypeStorage sizeValue range
bool1 bytefalse or true
byte1 byte-128 to 127
ubyte1 byte0 to 255
int4 bytes-2,147,483,648 to 2,147,483,647
uint4 bytes0 to 4,294,967,295
short2 bytes-32,768 to 32,767
ushort2 bytes0 to 65,535
long8 bytes-9223372036854775808 to 9223372036854775807
ulong8 bytes0 to 18446744073709551615
To get the exact size of a type or a variable, you can use the sizeof operator. The expression type.(sizeof) yields the storage size of the object or type in bytes. The following example gets the size of int type on any machine −
import std.stdio; 
 
int main() { 
   writeln("Length in bytes: ", ulong.sizeof); 

   return 0; 
}
When you compile and execute the above program, it produces the following result −
Length in bytes: 8 

Floating-Point Types

The following table mentions standard float-point types with storage sizes, value ranges, and their purpose −
TypeStorage sizeValue rangePurpose
float4 bytes1.17549e-38 to 3.40282e+386 decimal places
double8 bytes2.22507e-308 to 1.79769e+30815 decimal places
real10 bytes3.3621e-4932 to 1.18973e+4932either the largest floating point type that the hardware supports, or double; whichever is larger
ifloat4 bytes1.17549e-38i to 3.40282e+38iimaginary value type of float
idouble8 bytes2.22507e-308i to 1.79769e+308iimaginary value type of double
ireal10 bytes3.3621e-4932 to 1.18973e+4932imaginary value type of real
cfloat8 bytes1.17549e-38+1.17549e-38i to 3.40282e+38+3.40282e+38icomplex number type made of two floats
cdouble16 bytes2.22507e-308+2.22507e-308i to 1.79769e+308+1.79769e+308icomplex number type made of two doubles
creal20 bytes3.3621e-4932+3.3621e-4932i to 1.18973e+4932+1.18973e+4932icomplex number type made of two reals
The following example prints storage space taken by a float type and its range values −
import std.stdio;

int main() { 
   writeln("Length in bytes: ", float.sizeof); 

   return 0; 
}
When you compile and execute the above program, it produces the following result on Linux −
Length in bytes: 4

Character Types

The following table lists standard character types with storage sizes and its purpose.
TypeStorage sizePurpose
char1 byteUTF-8 code unit
wchar2 bytesUTF-16 code unit
dchar4 bytesUTF-32 code unit and Unicode code point
The following example prints storage space taken by a char type.
import std.stdio;

int main() {
   writeln("Length in bytes: ", char.sizeof);
   
   return 0;
}
When you compile and execute the above program, it produces the following result −
Length in bytes: 1

The void Type

The void type specifies that no value is available. It is used in two kinds of situations −
Sr.No.Types and Description
1
Function returns as void
There are various functions in D which do not return value or you can say they return void. A function with no return value has the return type as void. For example, void exit (int status);
2
Function arguments as void
There are various functions in D which do not accept any parameter. A function with no parameter can accept as a void. For example, int rand(void);
The void type may not be understood to you at this point, so let us proceed and we will cover these concepts in upcoming chapters.

D Programming - Enums

An enumeration is used for defining named constant values. An enumerated type is declared using the enum keyword.

The enum Syntax

The simplest form of an enum definition is the following −
enum enum_name {  
   enumeration list 
}
Where,
  • The enum_name specifies the enumeration type name.
  • The enumeration list is a comma-separated list of identifiers.
Each of the symbols in the enumeration list stands for an integer value, one greater than the symbol that precedes it. By default, the value of the first enumeration symbol is 0. For example −
enum Days { sun, mon, tue, wed, thu, fri, sat };

Example

The following example demonstrates the use of enum variable −
import std.stdio;

enum Days { sun, mon, tue, wed, thu, fri, sat };

int main(string[] args) {
   Days day;

   day = Days.mon;
   writefln("Current Day: %d", day); 
   writefln("Friday : %d", Days.fri); 
   return 0;
}
When the above code is compiled and executed, it produces the following result −
Current Day: 1 
Friday : 5
In the above program, we can see how an enumeration can be used. Initially, we create a variable named day of our user defined enumeration Days. Then we set it to mon using the dot operator. We need to use the writefln method to print the value of mon that is been stored. You also need specify the type. It is of the type integer, hence we use %d for printing.

Named Enums Properties

The above example uses a name Days for the enumeration and is called named enums. These named enums have the following properties −
  • Init − It initializes the first value in the enumeration.
  • min − It returns the smallest value of enumeration.
  • max − It returns the largest value of enumeration.
  • sizeof − It returns the size of storage for enumeration.
Let us modify the previous example to make use of the properties.
import std.stdio;

// Initialized sun with value 1 
enum Days { sun = 1, mon, tue, wed, thu, fri, sat };

int main(string[] args) { 
   writefln("Min : %d", Days.min); 
   writefln("Max : %d", Days.max);
   writefln("Size of: %d", Days.sizeof); 
   return 0; 
}
When the above code is compiled and executed, it produces the following result −
Min : 3
Max : 9
Size of: 4

Anonymous Enum

Enumeration without name is called anonymous enum. An example foranonymous enum is given below.
import std.stdio; 
 
// Initialized sun with value 1 
enum { sun , mon, tue, wed, thu, fri, sat }; 
 
int main(string[] args) { 
   writefln("Sunday : %d", sun); 
   writefln("Monday : %d", mon); 
   return 0; 
}
When the above code is compiled and executed, it produces the following result −
Sunday : 0
Monday : 1
Anonymous enums work pretty much the same way as named enums but they do not have the max, min, and sizeof properties.

Enum with Base Type Syntax

The syntax for enumeration with base type is shown below.
enum :baseType {  
   enumeration list 
}
Some of the base types includes long, int, and string. An example using long is shown below.
import std.stdio;
  
enum : string { 
   A = "hello", 
   B = "world", 
} 
  
int main(string[] args) { 
   writefln("A : %s", A); 
   writefln("B : %s", B); 
   
   return 0; 
}
When the above code is compiled and executed, it produces the following result −
A : hello
B : world

More Features

Enumeration in D provides features like initialization of multiple values in an enumeration with multiple types. An example is shown below.
import std.stdio;
  
enum { 
   A = 1.2f,  // A is 1.2f of type float 
   B,         // B is 2.2f of type float 
   int C = 3, // C is 3 of type int 
   D          // D is 4 of type int 
}
  
int main(string[] args) { 
   writefln("A : %f", A); 
   writefln("B : %f", B); 
   writefln("C : %d", C); 
   writefln("D : %d", D);  
   return 0; 
}
When the above code is compiled and executed, it produces the following result −
A : 1.200000
B : 2.200000
C : 3
D : 4

D Programming - Literals

Constant values that are typed in the program as a part of the source code are called literals.
Literals can be of any of the basic data types and can be divided into Integer Numerals, Floating-Point Numerals, Characters, Strings, and Boolean Values.
Again, literals are treated just like regular variables except that their values cannot be modified after their definition.

Integer Literals

An integer literal can be a of the following types −
  • Decimal uses the normal number represention with the first digit cannot be 0 as that digit is reserved for indicating the octal system.This does not include 0 on its own: 0 is zero.
  • Octal uses 0 as prefix to number.
  • Binary uses 0b or 0B as prefix.
  • Hexadecimal uses 0x or 0X as prefix.
An integer literal can also have a suffix that is a combination of U and L, for unsigned and long, respectively. The suffix can be uppercase or lowercase and can be in any order.
When you don’t use a suffix, the compiler itself chooses between int, uint, long, and ulong based on the magnitude of the value.
Here are some examples of integer literals −
212         // Legal 
215u        // Legal 
0xFeeL      // Legal 
078         // Illegal: 8 is not an octal digit 
032UU       // Illegal: cannot repeat a suffix 
Following are other examples of various types of integer literals −
85         // decimal 
0213       // octal
0x4b       // hexadecimal 
30         // int 
30u        // unsigned int 
30l        // long 
30ul       // unsigned long 
0b001      // binary

Floating Point Literals

The floating point literals can be specified in either the decimal system as in 1.568 or in the hexadecimal system as in 0x91.bc.
In the decimal system, an exponent can be represented by adding the character e or E and a number after that. For example, 2.3e4 means "2.3 times 10 to the power of 4". A “+” character may be specified before the value of the exponent, but it has no effect. For example 2.3e4 and 2.3e + 4 are the same.
The “-” character added before the value of the exponent changes the meaning to be "divided by 10 to the power of". For example, 2.3e-2 means "2.3 divided by 10 to the power of 2".
In the hexadecimal system, the value starts with either 0x or 0X. The exponent is specified by p or P instead of e or E. The exponent does not mean "10 to the power of", but "2 to the power of". For example, the P4 in 0xabc.defP4 means "abc.de times 2 to the power of 4".
Here are some examples of floating-point literals −
3.14159       // Legal 
314159E-5L    // Legal 
510E          // Illegal: incomplete exponent 
210f          // Illegal: no decimal or exponent 
.e55          // Illegal: missing integer or fraction 
0xabc.defP4   // Legal Hexa decimal with exponent 
0xabc.defe4   // Legal Hexa decimal without exponent.
By default, the type of a floating point literal is double. The f and F mean float, and the L specifier means real.

Boolean Literals

There are two Boolean literals and they are part of standard D keywords −
  • A value of true representing true.
  • A value of false representing false.
You should not consider the value of true equal to 1 and value of false equal to 0.

Character Literals

Character literals are enclosed in single quotes.
A character literal can be a plain character (e.g., 'x'), an escape sequence (e.g., '\t'), ASCII character (e.g., '\x21'), Unicode character (e.g., '\u011e') or as named character (e.g. '\©','\♥', '\€' ).
There are certain characters in D when they are preceded by a backslash they will have special meaning and they are used to represent like newline (\n) or tab (\t). Here, you have a list of some of such escape sequence codes −
Escape sequenceMeaning
\\\ character
\'' character
\"" character
\?? character
\aAlert or bell
\bBackspace
\fForm feed
\nNewline
\rCarriage return
\tHorizontal tab
\vVertical tab
The following example shows few escape sequence characters −
import std.stdio;
  
int main(string[] args) { 
   writefln("Hello\tWorld%c\n",'\x21'); 
   writefln("Have a good day%c",'\x21'); 
   return 0; 
}
When the above code is compiled and executed, it produces the following result −
Hello   World!

Have a good day!

String Literals

String literals are enclosed in double quotes. A string contains characters that are similar to character literals: plain characters, escape sequences, and universal characters.
You can break a long line into multiple lines using string literals and separate them using whitespaces.
Here are some examples of string literals −
import std.stdio;

int main(string[] args) {
   writeln(q"MY_DELIMITER
      Hello World
      Have a good day
      MY_DELIMITER");

   writefln("Have a good day%c",'\x21'); 
   auto str = q{int value = 20; ++value;}; 
   writeln(str); 
}
In the above example, you can find the use of q"MY_DELIMITER MY_DELIMITER" to represent multi line characters. Also, you can see q{} to represent an D language statement itself.

D Programming - Operators

An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations. D language is rich in built-in operators and provides the following types of operators −
  • Arithmetic Operators
  • Relational Operators
  • Logical Operators
  • Bitwise Operators
  • Assignment Operators
  • Misc Operators
This chapter explains arithmetic, relational, logical, bitwise, assignment, and other operators one by one.

Arithmetic Operators

The following table shows all arithmetic operators supported by D language. Assume variable A holds 10 and variable B holds 20 then −
OperatorDescriptionExample
+It adds two operands.A + B gives 30
-It subtracts second operand from the first.A - B gives -10
*It multiplies both operands.A * B gives 200
/It divides numerator by denumerator.B / A gives 2
%It returns remainder of an integer division.B % A gives 0
++The increment operator increases integer value by one.A++ gives 11
--The decrements operator decreases integer value by one.A-- gives 9

Relational Operators

The following table shows all the relational operators supported by D language. Assume variable A holds 10 and variable B holds 20, then −
OperatorDescriptionExample
==Checks if the values of two operands are equal or not, if yes then condition becomes true.(A == B) is not true.
!=Checks if the values of two operands are equal or not, if values are not equal then condition becomes true.(A != B) is true.
>Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true.(A > B) is not true.
<Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true.(A < B) is true.
>=Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true.(A >= B) is not true.
<=Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true.(A <= B) is true.

Logical Operators

The following table shows all the logical operators supported by D language. Assume variable A holds 1 and variable B holds 0, then −
OperatorDescriptionExample
&&It is called Logical AND operator. If both the operands are non-zero, then condition becomes true.(A && B) is false.
||It is called Logical OR Operator. If any of the two operands is non-zero, then condition becomes true.(A || B) is true.
!It is called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false.!(A && B) is true.

Bitwise Operators

Bitwise operators works on bits and perform bit-by-bit operation. The truth tables for &, |, and ^ are as follows −
pqp & qp | qp ^ q
00000
01011
11110
10011
Assume if A = 60; and B = 13. In the binary format they will be as follows −
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~A  = 1100 0011
The Bitwise operators supported by D language are listed in the following table. Assume variable A holds 60 and variable B holds 13, then −
OperatorDescriptionExample
&Binary AND Operator copies a bit to the result if it exists in both operands.(A & B) will give 12, Means 0000 1100.
|Binary OR Operator copies a bit if it exists in either operand.(A | B) gives 61. Means 0011 1101.
^Binary XOR Operator copies the bit if it is set in one operand but not both.(A ^ B) gives 49. Means 0011 0001
~Binary Ones Complement Operator is unary and has the effect of 'flipping' bits.(~A ) gives -61. Means 1100 0011 in 2's complement form.
<<Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand.A << 2 give 240. Means 1111 0000
>>Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand.A >> 2 give 15. Means 0000 1111.

Assignment Operators

The following assignment operators are supported by D language −
OperatorDescriptionExample
=It is simple assignment operator. It assigns values from right side operands to left side operandC = A + B assigns value of A + B into C
+=It is add AND assignment operator. It adds right operand to the left operand and assign the result to left operandC += A is equivalent to C = C + A
-=It is subtract AND assignment operator. It subtracts right operand from the left operand and assign the result to left operand.C -= A is equivalent to C = C - A
*=It is multiply AND assignment operator. It multiplies right operand with the left operand and assigns the result to left operand.C *= A is equivalent to C = C * A
/=It is divide AND assignment operator. It divides left operand with the right operand and assign the result to left operand.C /= A is equivalent to C = C / A
%=It is modulus AND assignment operator. It takes modulus using two operands and assign the result to left operand.C %= A is equivalent to C = C % A
<<=It is Left shift AND assignment operator.C <<= 2 is same as C = C << 2
>>=It is Right shift AND assignment operator.C >>= 2 is same as C = C >> 2
&=It is bitwise AND assignment operator.C &= 2 is same as C = C & 2
^=It is bitwise exclusive OR and assignment operator.C ^= 2 is same as C = C ^ 2
|=It is bitwise inclusive OR and assignment operatorC |= 2 is same as C = C | 2

Miscillaneous Operators − Sizeof and Ternary

There are few other important operators including sizeof and ? : supported by D Language.
OperatorDescriptionExample
sizeof()Returns the size of an variable.sizeof(a), where a is integer, returns 4.
&Returns the address of a variable.&a; gives actual address of the variable.
*Pointer to a variable.*a; gives pointer to a variable.
? :Conditional ExpressionIf condition is true then value X: Otherwise value Y.

Operators Precedence in D

Operator precedence determines the grouping of terms in an expression. This affects how an expression is evaluated. Certain operators are given precedence over others.
For example, the multiplication operator has higher precedence than the addition operator.
Let us consider an expression
x = 7 + 3 * 2.
Here, x is assigned 13, not 20. The simple reason is, the operator * has higher precedence than +, hence 3*2 is calculated first and then the result is added into 7.
Here, operators with the highest precedence appear at the top of the table, those with the lowest appear at the bottom. Within an expression, higher precedence operators are evaluated first.
CategoryOperatorAssociativity
Postfix() [] -> . ++ - -Left to right
Unary+ - ! ~ ++ - - (type)* & sizeofRight to left
Multiplicative* / %Left to right
Additive+ -Left to right
Shift<< >>Left to right
Relational< <= > >=Left to right
Equality== !=Left to right
Bitwise AND&Left to right
Bitwise XOR^Left to right
Bitwise OR|Left to right
Logical AND&&Left to right
Logical OR||Left to right
Conditional?:Right to left
Assignment= += -= *= /= %=>>= <<= &= ^= |=Right to left
Comma,Left to right

D Programming - Loops

There may be a situation, when you need to execute a block of code several number of times. In general, statements are executed sequentially: The first statement in a function is executed first, followed by the second, and so on.
Programming languages provide various control structures that allow more complicated execution paths.
A loop statement executes a statement or group of statements multiple times. The following general form of a loop statement in mostly used in the programming languages −
Loop Architecture
D programming language provides the following types of loop to handle looping requirements. Click the following links to check their detail.
Sr.No.Loop Type & Description
1while loop
It repeats a statement or group of statements while a given condition is true. It tests the condition before executing the loop body.
2for loop
It executes a sequence of statements multiple times and abbreviates the code that manages the loop variable.
3do...while loop
Like a while statement, except that it tests the condition at the end of the loop body.
4nested loops
You can use one or more loop inside any another while, for, or do..while loop.

Loop Control Statements

Loop control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.
D supports the following control statements −
Sr.No.Control Statement & Description
1break statement
Terminates the loop or switch statement and transfers execution to the statement immediately following the loop or switch.
2continue statement
Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating.

The Infinite Loop

A loop becomes infinite loop if a condition never becomes false. The for loop is traditionally used for this purpose. Since none of the three expressions that form the for loop are required, you can make an endless loop by leaving the conditional expression empty.
import std.stdio;

int main () {

   for( ; ; ) {
      writefln("This loop will run forever.");
   }
   return 0;
}
When the conditional expression is absent, it is assumed to be true. You may have an initialization and increment expression, but D programmers more commonly use the for(;;) construct to signify an infinite loop.
NOTE − You can terminate an infinite loop by pressing Ctrl + C keys.

D Programming - Decisions

The decision making structures contain condition to be evaluated along with the two sets of statements to be executed. One set of statements is executed if the condition it true and another set of statements is executed if the condition is false.
The following is the general form of a typical decision making structure found in most of the programming languages −
Decision making statements in D
D programming language assumes any non-zero and non-null values astrue, and if it is either zero or null, then it is assumed as false value.
D programming language provides the following types of decision making statements.
Sr.No.Statement & Description
1if statement
An if statement consists of a boolean expression followed by one or more statements.
2if...else statement
An if statement can be followed by an optional else statement, which executes when the boolean expression is false.
3nested if statements
You can use one if or else if statement inside another if or else ifstatement(s).
4switch statement
switch statement allows a variable to be tested for equality against a list of values.
5nested switch statements
You can use one switch statement inside another switchstatement(s).

The ? : Operator in D

We have covered conditional operator ? : in previous chapter which can be used to replace if...else statements. It has the following general form
Exp1 ? Exp2 : Exp3;
Where Exp1, Exp2, and Exp3 are expressions. Notice the use and placement of the colon.
The value of a ? expression is determined as follows −
  • Exp1 is evaluated. If it is true, then Exp2 is evaluated and becomes the value of the entire ? expression.
  • If Exp1 is false, then Exp3 is evaluated and its value becomes the value of the expression.

D Programming - Functions

This chapter describes the functions used in D programming.

Function Definition in D

A basic function definition consists of a function header and a function body.

Syntax

return_type function_name( parameter list ) { 
   body of the function 
}
Here are all the parts of a function −
  • Return Type − A function may return a value. The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void.
  • Function Name − This is the actual name of the function. The function name and the parameter list together constitute the function signature.
  • Parameters − A parameter is like a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as actual parameter or argument. The parameter list refers to the type, order, and number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters.
  • Function Body − The function body contains a collection of statements that define what the function does.

Calling a Function

You can a call a function as follows −
function_name(parameter_values)

Function Types in D

D programming supports a wide range of functions and they are listed below.
  • Pure Functions
  • Nothrow Functions
  • Ref Functions
  • Auto Functions
  • Variadic Functions
  • Inout Functions
  • Property Functions
The various functions are explained below.

Pure Functions

Pure functions are functions which cannot access global or static, mutable state save through their arguments. This can enable optimizations based on the fact that a pure function is guaranteed to mutate nothing which is not passed to it, and in cases where the compiler can guarantee that a pure function cannot alter its arguments, it can enable full, functional purity, that is, the guarantee that the function will always return the same result for the same arguments).
import std.stdio; 

int x = 10; 
immutable int y = 30; 
const int* p;  

pure int purefunc(int i,const char* q,immutable int* s) { 
   //writeln("Simple print"); //cannot call impure function 'writeln'
   
   debug writeln("in foo()"); // ok, impure code allowed in debug statement 
   // x = i;  // error, modifying global state 
   // i = x;  // error, reading mutable global state 
   // i = *p; // error, reading const global state
   i = y;     // ok, reading immutable global state 
   auto myvar = new int;     // Can use the new expression: 
   return i; 
}

void main() { 
   writeln("Value returned from pure function : ",purefunc(x,null,null)); 
}
When the above code is compiled and executed, it produces the following result −
Value returned from pure function : 30 

Nothrow Functions

Nothrow functions do not throw any exceptions derived from class Exception. Nothrow functions are covariant with throwing ones.
Nothrow guarantees that a function does not emit any exception.
import std.stdio; 

int add(int a, int b) nothrow { 
   //writeln("adding"); This will fail because writeln may throw 
   int result; 
   
   try { 
      writeln("adding"); // compiles 
      result = a + b; 
   } catch (Exception error) { // catches all exceptions 
   }

   return result; 
} 
 
void main() { 
   writeln("Added value is ", add(10,20)); 
}
When the above code is compiled and executed, it produces the following result −
adding 
Added value is 30 

Ref Functions

Ref functions allow functions to return by reference. This is analogous to ref function parameters.
import std.stdio;

ref int greater(ref int first, ref int second) { 
   return (first > second) ? first : second; 
} 
 
void main() {
   int a = 1; 
   int b = 2;  
   
   greater(a, b) += 10;   
   writefln("a: %s, b: %s", a, b);   
}
When the above code is compiled and executed, it produces the following result −
a: 1, b: 12

Auto Functions

Auto functions can return value of any type. There is no restriction on what type to be returned. A simple example for auto type function is given below.
import std.stdio;

auto add(int first, double second) { 
   double result = first + second; 
   return result; 
} 

void main() { 
   int a = 1; 
   double b = 2.5; 
   
   writeln("add(a,b) = ", add(a, b)); 
}
When the above code is compiled and executed, it produces the following result −
add(a,b) = 3.5

Variadic Functions

Variadiac functions are those functions in which the number of parameters for a function is determined in runtime. In C, there is a limitation of having atleast one parameter. But in D programming, there is no such limitation. A simple example is shown below.
import std.stdio;
import core.vararg;

void printargs(int x, ...) {  
   for (int i = 0; i < _arguments.length; i++) {  
      write(_arguments[i]);  
   
      if (_arguments[i] == typeid(int)) { 
         int j = va_arg!(int)(_argptr); 
         writefln("\t%d", j); 
      } else if (_arguments[i] == typeid(long)) { 
         long j = va_arg!(long)(_argptr); 
         writefln("\t%d", j); 
      } else if (_arguments[i] == typeid(double)) { 
         double d = va_arg!(double)(_argptr); 
         writefln("\t%g", d); 
      } 
   } 
}
  
void main() { 
   printargs(1, 2, 3L, 4.5); 
}
When the above code is compiled and executed, it produces the following result −
int 2 
long 3 
double 4.5

Inout Functions

The inout can be used both for parameter and return types of functions. It is like a template for mutable, const, and immutable. The mutability attribute is deduced from the parameter. Means, inout transfers the deduced mutability attribute to the return type. A simple example showing how mutability gets changed is shown below.
import std.stdio;

inout(char)[] qoutedWord(inout(char)[] phrase) { 
   return '"' ~ phrase ~ '"';
}

void main() { 
   char[] a = "test a".dup; 

   a = qoutedWord(a); 
   writeln(typeof(qoutedWord(a)).stringof," ", a);  

   const(char)[] b = "test b"; 
   b = qoutedWord(b); 
   writeln(typeof(qoutedWord(b)).stringof," ", b); 

   immutable(char)[] c = "test c"; 
   c = qoutedWord(c); 
   writeln(typeof(qoutedWord(c)).stringof," ", c); 
} 
When the above code is compiled and executed, it produces the following result −
char[] "test a" 
const(char)[] "test b" 
string "test c"

No comments

Powered by Blogger.