the d programming language cs 4450. what is d? a system programming language conceived in 1996 as a...

Post on 16-Jan-2016

217 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

The D Programming The D Programming LanguageLanguageCS 4450

What is D?What is D?A system programming language

conceived in 1996 as a C++ replacement

Combines the power of C++ with the usability of languages like Java, C# and Python

If something works in C++, C# or Java, it probably works pretty much the same in D

“Often, programming teams will resort to a hybrid approach, where they will mix Python and C++, trying to get the productivity of Python and the performance of C++. The frequency of this approach indicates that there is a large unmet need in the programming language department.”

“D intends to fill that need. It combines the ability to do low-level manipulation of the machine with the latest technologies in building reliable, maintainable, portable, high-level code. D has moved well ahead of any other language in its abilities to support and integrate multiple paradigms like imperative, OOP, and generic programming.”

— Walter Bright, Co-designer of D

D is like C++D is like C++It supports static local variablesIt supports pointers

◦but you almost never need them (we won’t)It has templates

◦but they’re easier and more flexible than in C++

◦ it supports compile-time executionIt’s fast

◦compiles to native codeIt supports operator overloading

D is Like Java and C#D is Like Java and C#It supports garbage collection

◦the default, but you can opt-outIt supports explicit, user-defined

interfaces◦uses “:” for inheritance, like C#

It has inner classes, like Java and C#It has delegates

◦but more powerful than in C#It distinguishes reference and value

typesIt supports properties

D is Like Python and FP D is Like Python and FP LanguagesLanguagesIt has modules and packages

◦like Python’sIt supports nested functions and

closures◦including anonymous functions

It has a pure FP subset◦and the usual higher-order functions

reduce, map, filter, compose

◦supports lazy evaluation of function parameters

D is for Real ProgrammersD is for Real ProgrammersIt has software engineering support:

◦unit testing◦contract programming

invariants, preconditions, postconditions◦built-in constructs for exception-safe

transactions Supports concurrent programming

◦with thread-local storage◦both lock and lockless programming

Can interoperate with C and C++

D'iving InD'iving In

// hello.dimport std.stdio;

void main(string[] args) { if (args.length > 1) foreach (a; args[1..$]) writeln("Hello " ~ a); else writeln("Hello, Modern World");}

Chuck-Allisons-iMac-4:CCSC chuck$ dmd hello.dChuck-Allisons-iMac-4:CCSC chuck$ ./helloHello, Modern WorldChuck-Allisons-iMac-4:CCSC chuck$ ./hello John JaneHello JohnHello Jane

Primitive Data TypesPrimitive Data TypesType Meaning Default (.init)void no value n/abool Boolean value falsebyte signed 8 bits 0ubyte unsigned 8 bits 0short signed 16 bits 0ushort unsigned 16 bits 0int signed 32 bits 0uint unsigned 32 bits 0long signed 64 bits 0ulong unsigned 64 bits 0float 32-bit floating-point float. nandouble 64-bit floating-point double. nanreal largest in hardware real. nanchar unsigned 8-bit UTF-8 0xFFwchar unsigned 16-bit UTF-16 0xFFFFdchar unsigned 32-bit UTF-32 0x0000FFFF

Literals and Type Literals and Type InferenceInferenceUses the same suffixes as C/C++

◦f, l, u, etc.Uses the same prefixes

◦0123, 0x1CF◦Adds binary: 0b01001

Type inference with auto:auto targetSalary = 15_000_000;auto sq = (double x) { return x*x; };

ArraysArraysStatic arrays

◦Similar to arrays in C/C++◦int a[3];◦int[3] a; // Same thing

Dynamic Arrays◦Similar to vectors, ArrayLists, etc.

See staticarray.dInitialization:

◦int[3] a = [1:2, 3]; // [0,2,3]

Selected Array OperationsSelected Array OperationsIndexing with [ ]Concatenation with ~Copying with a.dupAssignment with =Length with .length

◦$ = .length in index expressions (a[2..$])◦m..n is an array slice (excludes n)◦can assign to .length to resize dynamic

arraysArray-wise operations (mathematical

vector operations)See mergesort.d, vector.d

StringsStringsStrings are dynamic arrays of

immutable characters◦ alias immutable(char)[] string;

◦string char (UTF-8)◦wstring wchar (UTF-16)◦dstring dchar (UTF-32)

foreach visits each character:◦ foreach (c; s) …

Associative ArraysAssociative ArraysA map (aka “dictionary”, “hash”, etc.)

◦Except it’s a built-in type (like dict in Python)

Uses array syntax:

void main() {int[string] mymap = ["one":1, "two":2];mymap["three"] = 3;foreach (k,v; mymap) writef("%s:%s ",k,v);

}

/* Output:three:3 one:1 two:2 */

Word Count Program Word Count Program OutputOutput/* Abbreviated output from the Gettysburg Address:But,: 1Four: 1…who: 3will: 1work: 1world: 1years: 1*/

A Word Count ProgramA Word Count Programimport std.stdio, std.array, std.file;

void wc(string filename) { string[] words = split(cast(string) read(filename)); int[string] counts; foreach (word; words) ++counts[word]; foreach (w; counts.keys.sort) writefln("%s: %d", w, counts[w]);}

void main(string[] args) { if (args.length == 2) wc(args[1]);}

TuplesTuplesDefined in std.typeconsTuple!(type1,type2,..)Helper function:

◦tuple(val1,val2,…)Can use 0-based position numbers

Can also use field namesSee tuple.d

Data QualifiersData QualifiersFor function parameters:

◦in | out | inout◦ref◦lazy

General declaration qualifiers:◦const◦immutable

Lazy ParametersLazy Parametersimport std.stdio;

void f(bool b, lazy void g) { if (b) { g(); }}

void main() { f(false, writeln("executing g")); f(true, writeln("executing g"));}

/* Output:executing g*/

ClosuresClosuresNested functions are returned as

(dynamic) closures◦aka “delegates” (a code-environment pair)◦The referencing environment could be a

function, class, or object◦Escaped activation records are moved

from the stack to the garbage-collected heap

Plain function pointers also supported:◦ int function(int) f; (vs. “int (*f)(int);” in C)

20

Plain Function PointersPlain Function Pointersint f1(int n) {return n+1;}int f2(int n) {return n+2;}int f3(int n) {return n+3;}

void main() { auto funs = [&f1, &f2, &f3]; foreach (f; funs) writeln(f(1));}

/* Output:234*/

Higher-Level Functions and Higher-Level Functions and ClosuresClosures

import std.stdio;

bool delegate(int) gtn(int n) { bool execute(int m) { return m > n; } return &execute;}

void main() { auto g5 = gtn(5); // Returns a ">5" delegate writeln(g5(1)); // false writeln(g5(6)); // true}

Lambda ExpressionsLambda Expressions

auto gtn(int n) { return delegate bool(int m) {return m > n;};}

// Preferred:auto gtn(int n) { return (int m) {return m > n;};}

An Object Calling An Object Calling EnvironmentEnvironment

void main() {    class A { int fun() { return 42; } }    A a = new A;    auto dg = &a.fun; // A “bound method”    writeln(dg()); // 42}

Parametric PolymorphismParametric PolymorphismCompile-time ParametersCompile-time Parameters

auto gtn(T)(T n) { return (T m) {return m > n;};}

void main() { auto g5 = gtn(5); writeln(g5(1)); writeln(g5(6));

auto g5s = gtn("baz"); writeln(g5s("bar")); writeln(g5s("foo"));}

Compile-Time ConstraintsCompile-Time Constraintsimport std.stdio, std.traits;

auto gtn(T)(T n) if (isNumeric!T) { return (T m) {return m > n;};}

void main() { auto g5 = gtn!int(5); writeln(g5(1)); writeln(g5(6));

auto g5s = gtn!string("baz"); // Error writeln(g5s("bar")); writeln(g5s("foo"));}

Compile-Time Function Compile-Time Function EvaluationEvaluation

// ctfe.d: Compile-time function executionimport std.stdio, std.conv; int square(int i) { return i * i; } void main() { static int n = square(3); // compile time writefln(text(n)); writefln(text(square(4))); // runtime}

Pure FunctionsPure FunctionsFor Referential TransparencyFor Referential Transparency

import std.stdio;import std.conv;

pure ulong fib(uint n) { if (n == 0 || n == 1) return n; ulong a = 1, b = 1; foreach (i; 2..n) { auto t = b; b += a; a = t; } return b;}

void main(string[] args) { if (args.length > 1) writeln(fib(to!(uint)(args[1])));}

Selected Higher-Level Selected Higher-Level FunctionsFunctionsint[] nums = [1,2,3,4,5];

auto squarelist(int[] list) { // 1 4 9 16 25 return map!("a*a")(list);}

auto sqsum2(int[] list) { // 55 return reduce!("a + b*b")(0,list); // (list)}

auto evens(int[] list) { // 2 4 return filter!("a % 2 == 0")(list);}

alias compose!("a/3.0","a*a","a+1.0") comp;writeln(comp(2.0)); // 3 = (2+1)^2 / 3alias pipe!(div3,sq,pls1) pip; // fns in scopewriteln(pip(2.0)); // 1.4444 = (2/3)^2+1

std.functional.memoizestd.functional.memoizeMemoization is a technique

where a cache of input-output pairs is kept for function calls

Avoids recomputing function values

See fib.d

Variable-length Argument Variable-length Argument ListsListsUse “…” in the parameter definitionHomogeneous

◦use “…” in the runtime parameter list◦passes a dynamic array

Heterogeneous◦use “…” in the compile-time parameter

list◦passes a tuple

See varargs.d

An Unsafe FunctionAn Unsafe Function

void g() { risky_op1(); // May acquire resources… risky_op2(); risky_op3(); writeln("g succeeded");}

Assume further that these functions must run to completion or not at all.

An Unsavory SolutionAn Unsavory Solutionvoid g() { risky_op1(); try { risky_op2(); } catch (Exception x) { undo_risky_op1(); // Back-out op1 throw x; // Rethrow exception } try { risky_op3(); writeln("g succeeded"); } catch (Exception x) { // Back-out op1 and op2 in reverse order undo_risky_op2(); undo_risky_op1(); throw x; }}

DD ’’s s scopescope Statement StatementOptions: Options: exitexit | | successsuccess | | failurefailure

void g() { risky_op1(); scope(failure) undo_risky_op1(); risky_op2(); scope(failure) undo_risky_op2(); risky_op3(); writeln("g succeeded");}

Contract Programming Contract Programming ExampleExampleAlso illustrates value types, operator overloading, Also illustrates value types, operator overloading, and unit testingand unit testingimport std.math; // For abs()

struct Rational { private int num = 0; private int den = 1; // Local helper function static int gcd(int m, int n) { return n == 0 ? abs(m) : gcd(abs(n), abs(m)%abs(n)); } // Class invariant invariant() { assert(den > 0 && gcd(num, den) == 1); }

Contract Programming Contract Programming ExampleExample(continued)(continued)

// Constructor this(int n, int d = 1) // Constructor precondition in { assert(d != 0); } body { num = n; den = d; auto div = gcd(num, den); if (den < 0) div = -div; num /= div; den /= div; }

Contract Programming Contract Programming ExampleExample(concluded)(concluded) // ("if" form evaluated at compile time) Rational opBinary(string op)(Rational r) if (op == "+”) { return Rational(num*r.den + den*r.num, den*r.den); }}

unittest { // Compile with –unittest option auto r1 = Rational(1,2), r2 = Rational(3,4), r3 = r1 + r2; assert(r3.num == 5 && r3.den == 4);}

void main(){}

Variant TypesVariant TypesSometimes you want to hold any type

◦hopefully not too often!Variant can hold any typeYou can only get out what was last

put in◦see variant.d

Bounded, discriminated unions with Algebraic◦like ML unions◦see variant2.d

ThreadsThreadsA thread is a path of execution

inside a running program (process)

A thread is launched on a function basis

Using the std.concurrency.spawn

See concur1.d

Message PassingMessage Passing

A paradigm for thread-to-thread communication

Threads send/receive data to/from each other

Less problematic (and less flexible) than sharing data via mutexesSee concur1,2,3.d

Infinite Streams in DInfinite Streams in DThreads and Message Passing

naturally support streams

See stream.d

top related