d programming language
TRANSCRIPT
THE D PROGRAMMINGLANGUAGE
Jordan Open Source Association - TechTalks 19th of September, 2015 Slides prepared by Yazan Dabain (github.com/yazd)
WHAT IS D?A statically typed, compiled language with C-like syntax.
A languages that provides productivity and modelling power at the same time ashigh performance and efficiency.
“D demonstrates that it is possible to build a powerful programming language that is both easy to use and generates fast code.”
WALTER BRIGHTCreator of the D programming language.Developer of multiple C and C++ compilers:Zorland C, Zortech C++, Digital Mars C++, ...Aware of the problems in the existing languages,he decided to write his own language.And so, D started out in 1999.
ANDREI ALEXANDRESCUCo-designer of the D programming language.Joined in 2006.Renowned author/co-author of:
Modern C++ Design: Generic Programming and Design Patterns Applied [2001]
C++ Coding Standards: 101 Rules, Guidelines,and Best Practices [2004]
The D Programming Language [2009]
TIMELINE OF PROGRAMMING LANGUAGES
1970 1975 1980 1985 1990 1995 2000 2005 2010 2015
D2.068.1
C C++
Objective-C
Perl
Erlang
Bash
Haskell
Python
Visual Basic
Lua
PHP
Java
JavaScript
Ruby
D1
Python 2
C#
Scala D2
Python 3
Go
C++11
Java 7
C++14
Swift
Java 8
QUICK LOOK AT D SYNTAXimport std.stdio;
void main() writeln("Hello JOSA!");
/** * Returns the sum of elements. * * Params: * elements = array of integers to sum */int sum(int[] elements) int sum = 0; foreach (element; elements) sum += element; return sum;
/** * Writes each argument and its length * to stdout. */void main(string[] args) import std.stdio;
foreach (arg; args[1 .. $]) writefln("%s: %s", arg, arg.length);
» ./main Welcome to JOSA TechTalksWelcome: 7to: 2JOSA: 4TechTalks: 9
QUICK LOOK AT D SYNTAX - BASIC TYPES,ARRAYS AND ASSOCIATIVE ARRAYS
// logical data type:bool// integral data types:byte, short, int, long, centubyte, ushort, uint, ulong, ucent// floating data types:float, double, real// character data typeschar, wchar, dchar
// defining arrays:int[] nums = [1, 2, 3, 4];// accessing arrays:int sum = nums[0] + nums[$ 1];// slicing arrays:int[] slice = nums[0 .. $ / 2];
// defining an associative array:int[string] wordCount;
// setting a value:wordCount["hello"] = 1;
// check if key exists:bool exists = "hello" in wordCount;
// reading a value:int count = wordCount["hello"];
// reading a value with a default:int count = wordCount.get("hello", 0);
QUICK LOOK AT D SYNTAX - TYPE INFERENCE// without type inferenceint num = 0;string str = "D rocks!";DateTime time = DateTime(2015, 9, 16);
// with automatic type inferenceauto num = 0;auto str = "D rocks!";auto time = DateTime(2015, 9, 16);
QUICK LOOK AT D SYNTAX - LAMBDAS// function declarationint square(int x) return x * x;
// in lambda formauto summation = (int x, int y) => x + y;auto multiplication = (int x, int y) => x * y;auto subtraction = (int x, int y) => x y;
// usage like a normal functionauto result = summation(5, 10);
QUICK LOOK AT D SYNTAX - UNIFORM FUNCTIONCALL SYNTAX
auto withLastName(string firstName, string lastName) return firstName ~ " " ~ lastName;
// can be used as:auto fullName = "Yazan".withLastName("Dabain");
import std.datetime;auto duration = 5.days + 12.hours;// vsauto duration = days(5) + hours(12);
QUICK LOOK AT D SYNTAX// Example:// find all words which are 4 letters or more// ps. no need to be picky about punctuationimport std.algorithm;auto quote = "I would love to change the world, " "but they won't give me the source code.";
// without UFCSauto result = filter!(word => word.length >= 4)(splitter(quote));
// with UFCSauto result = quote.splitter().filter!(word => word.length >= 4)();
CODE COMPARISONDauto celsius = [31.0, 34.2, 33.1, 29.8];
auto fahrenheit = celsius.map!(c => 9.0 * c / 5.0 + 32.0);writeln(fahrenheit);
Pythoncelsius = [31.0, 34.2, 33.1, 29.8]fahrenheit = [9.0 * c / 5.0 + 32.0 for c in celsius]print(fahrenheit)
Java 7double[] celsius = 31.0, 34.2, 33.1, 29.8;double[] fahrenheit = new double[celsius.length];for (int i = 0; i < celsius.length; i++) fahrenheit[i] = 9.0 * celsius[i] / 5.0 + 32.0;
for (double f : fahrenheit) System.out.println(f);
JSvar celsius = [31.0, 34.2, 33.1, 29.8];var fahrenheit = celsius.map(function (v) return 9.0 * v / 5.0 + 32;);console.log(fahrenheit.join(", "));
CODE DUPLICATION AND VERBOSITYint add(int a, int b) return a + b;
float add(float a, float b) return a + b;
// what we want is something similar to:
Type add(Type a, Type b) return a + b;
TEMPLATES// Template functionType add(Type)(Type a, Type b) return a + b;
auto result = add!(int)(10, 12);auto result = add!int(10, 12);auto result = add(10, 12);
// Template functionauto add(T, U)(T a, U b) return a + b;
auto result = add(1, 12.5); // result is of type double
TEMPLATESstruct Tree int value; Tree[] children;
// Template structstruct Tree(T) T value; Tree!T[] children;
// Templates are not limited to types!auto squaredNumbers = [1, 2, 3, 4].map!(e => e * e)(); // 1, 4, 9, 16
// Due to the power of templates, strings need not be special types.// Strings are character arrays, just as [1, 2, 3] is an integer array.auto splitString = "one two three".splitter(' '); // ["one", "two", "three"]auto splitNumbers = [1, 2, 3, 0, 4, 5, 6].splitter(0); // [[1, 2, 3], [4, 5, 6]]
assert("hello world".startsWith("hello"));assert([1, 2, 3, 4, 5, 6, 7, 8].startsWith([1, 2, 3]));
TYPES ARE DIMENSIONSauto numberOfApples = 5;auto numberOfOranges = 20;
// What would your math teacher say?auto result = numberOfApples + numberOfOranges;
// Find the bug ὁvoid addToCart(int userId, int productId) auto shoppingCart = getUserShoppingCart(userId); shoppingCart.add(productId);
void buy(int userId, int[] products) foreach (product; products) addToCart(product, userId);
TYPES ARE DIMENSIONSimport std.typecons;
// create a new type (dimension) containing user ids / product idsalias UserID = Typedef!(long, long.init, "userId");alias ProductID = Typedef!(long, long.init, "productId");
void addToCart(UserID userId, ProductID productId) auto shoppingCart = getUserShoppingCart(userId); shoppingCart.add(productId);
void buy(UserID userId, ProductID[] products) foreach (product; products) addToCart(product, userId); // Compilation error
CONSTRAINTS ARE USEFUL// Library from https://github.com/biozic/quantitiesimport quantities;
auto distance = 384_400 * kilo(meter);auto speed = 299_792_458 * meter/second;
Time time = distance / speed;Time time = speed / distance; // compilation error
// from quantities.si;enum meter = unit!(Numeric, "L");enum second = unit!(Numeric, "T");
alias Length = typeof(meter);alias Time = typeof(second);alias Speed = typeof(meter/second);
DYNAMIC TYPES ARE A SUBSETimport std.variant;
Variant anything = 12;anything = "hello";anything = File("readme.txt");
import vibe.data.json;
auto book = Json.emptyObject;book.title = "D Web Development";book.author = "Kai Nacke";book.price = 19.20;writeln(book.toPrettyString());
COMPILE TIME FUNCTION EVALUATION (CTFE)“Compile-time function evaluation is the ability of a compiler, that would
normally compile a function to machine code and execute it at run time, toexecute the function at compile time.”
COMPILE TIME FUNCTION EVALUATION (CTFE)auto fromRoman(string roman) auto flat = roman .replace("IV", "IIII") .replace("IX", "VIIII") .replace("XL", "XXXX") .replace("XC", "LXXXX");
auto value = flat.count('I') + flat.count('V') * 5 + flat.count('X') * 10 + flat.count('L') * 50 + flat.count('C') * 100;
return value;
struct Roman enum opDispatch(string name) = fromRoman(name);
void main() writeln(Roman.XV); writeln(Roman.IIX); writeln(Roman.VXCII);
0000000000432708 <_Dmain>: push %rbp mov %rsp,%rbp mov $0xf,%edi callq 4334a0 <std.stdio.writeln> mov $0xa,%edi callq 4334a0 <std.stdio.writeln> mov $0x61,%edi callq 4334a0 <std.stdio.writeln> xor %eax,%eax pop %rbp retq xchg %ax,%ax
REFLECTION“Reflection is the ability of a computer program to examine and modify its own
structure and behavior (specifically the values, meta-data, properties andfunctions).”
COMPILE-TIME REFLECTION IN Dstruct Person int id; string username; DateTime birthdate;
// we can use the compiler to tell us// what members Person struct contain[__traits(allMembers, Person)].writeln();// prints ["id", "username", "birthdate"]
// or if Person has some specific memberif (__traits(hasMember, Person, "fname")) writeln("Yes, Person has a firstname");
void create(string title, float price) …
// we can also retrieve function parameter// names, default values, ...assert( [ParameterIdentifierTuple!create] == ["title", "price"]);
COMPILE-TIME REFLECTION AND CODEGENERATION
auto smaller(T)(T a, T b) foreach (member; __traits(allMembers, T)) if (__traits(getMember, a, member) < __traits(getMember, b, member)) return true; else if (__traits(getMember, a, member) > __traits(getMember, b, member)) return false; return false; // equal
struct Person string username; DateTime birthdate;
auto one = Person("joe", DateTime(1990, 1, 1));auto two = Person("john", DateTime(1980, 1, 1));writeln(smaller(one, two));
POWERFUL COMBINATION OF FEATURESimport pegged.grammar;
/// Numbersmixin(grammar(Number: Scientific <~ Floating ( ('e' / 'E' ) Integer )? Floating <~ Integer ('.' Unsigned )? Unsigned <~ [09]+ Integer <~ Sign? Unsigned Hexa <~ [09afAF]+ Sign < '' / '+'));
auto tree = Number("25.12e+21");// use the parse tree
POWERFUL COMBINATION OF FEATURESimport vibe.data.json;
struct Foo int number; string str;
auto f = Foo(12, "hello");string json = serializeToJsonString(f);assert(json == "number":12,"str":"hello");
f = deserializeJson!Foo("number": 42, "str": "the answer");assert(f.number == 42);assert(f.str == "the answer");
SIMPLE WEB SERVERimport vibe.d;
shared static this() auto settings = new HTTPServerSettings; settings.port = 8080;
listenHTTP(settings, &handleRequest);
void handleRequest(HTTPServerRequest req, HTTPServerResponse res) if (req.path == "/") res.writeBody("Hello, World!", "text/plain");
ROUTINGvoid userInfo(HTTPServerRequest req, HTTPServerResponse res) auto username = req.params["user"]; … render!("userinfo.dt", username)(res);
void addUser(HTTPServerRequest req, HTTPServerResponse res) enforceHTTP("user" in req.form, HTTPStatus.badRequest, "Missing user field."); … res.redirect("/users/" ~ req.form["user"]);
shared static this() auto router = new URLRouter();
router .get("/users/:user", &userInfo) .post("/adduser", &addUser) .get("*", serveStaticFiles("./public/"));
listenHTTP(new HTTPServerSettings, router);
REST INTERFACEstruct Weather string status; double temperature; // °C
interface WeatherAPI Weather getWeather(); @property void location(string location); @property string location();
REST INTERFACE - SERVERclass WeatherProvider : WeatherAPI private string m_location;
Weather getWeather() return Weather("sunny", 25); @property void location(string location) m_location = location; @property string location() return m_location;
shared static this() auto router = new URLRouter(); router.registerRestInterface(new WeatherProvider());
auto settings = new HTTPServerSettings; settings.port = 8080; listenHTTP(settings, router);
REST INTERFACE - REMOTE CLIENTauto client = new RestInterfaceClient!WeatherAPI("http://127.0.0.1:8080/");auto weather = client.getWeather();logInfo("Weather: %s, %s °C", weather.status, weather.temperature);client.location = "Paris";logInfo("Location: %s", client.location);
REST INTERFACE - JS CLIENTshared static this() auto restSettings = new RestInterfaceSettings(); restSettings.baseURL = URL("http://127.0.0.1:8080/");
auto router = new URLRouter(); router.registerRestInterface(new WeatherProvider(), restSettings); router.get("/weather.js", serveRestJSClient!WeatherAPI(restSettings));
auto settings = new HTTPServerSettings; settings.port = 8080; listenHTTP(settings, router);
<! in javascript ><script src="weather.js"></script>var weather = WeatherAPI.getWeather();console.log(weather.status);console.log(weather.temperature);
LINKS AND RESOURCESD Programming Language dlang.org
D forums forum.dlang.org
Programming in D - Ali Çehreli ddili.org/ders/d.en/
TDPL - Andrei AlexanderscuD Templates - Philippe Sigaud github.com/PhilippeSigaud/D-templates-tutorial
Rosetta Code (various tasks solved in D) rosettacode.org/wiki/Category:D
IRC channel #d on freenode.org
Dub package manager code.dlang.org