D programming language


Presenter : 鄧仕榆、賴柏瑜
王議偉、陳殿善

Introduction

    Walter Bright

  • 編譯專家,開發許多C++編譯器
  • 創立D語言
  • 實做D語言編譯器

Generics

							
							template Foo (T)
								if(is(T == int)) // constraint
							{
							    T number;
							}
							
						

Generative

							
							struct A{
								int a;
								mixin(bitfields!(
									unit, "x", 2,
									int, "y", 3,
									uint, "z", 2,
									bool, "flag", 1));
							}
	
							A obj;
							obj.x = 2;
							obj.z = obj.x;
							
						

Contract

							
							in
							{
								... contract preconditions ...
							}
							out (result)
							{
								... contract postconditions ...
							}
							do
							{
								... code ...
							}
							
						

Associative Arrays

							
								int[string] aa = ["hello":3, "world":4];

								aa["hello"] = 5;  // set value associated with key "hello" to 5
								int value = aa["hello"];  // lookup value from a key
								assert(value == 5);
							
						

Static Typing With Inference

							
								void main(){
									// type:double[]
									auto arr = [1, 2, 3.14, 5.1, 6];
									// type:int[string]
									auto dictionary = ["one": 1, "two": 2, "three": 3];
									
									auto x = min(arr[0], dictionary["two"]);
								}
								
								auto min(T1, T2)(T1 lhs, T2 rhs){
									return rhs < lhs ? rhs : lhs;
								}
							
						

Resource Management

							
								import std.stdio, core.stdc.stdlib
								class Widget{    }
								
								void main(){
									auto w = new Widget;    //automatic
									
									//Code is executed in any case upon scope exit
									scope(exit){ writeln("Exiting main"); }
									
									auto p = malloc(10);    //explicit C style
									if(p)free(p);
								}
							
						

Slices

							
							auto filename = "etc/c/zip d"
							auto path = filename[0..6];    //"etc/c/"
							auto name = filename[6..9];    //"zip"
							auto ext = filename[10..11];    //"d"
							
						

Feature

Inline Assembler


						asm{
							assembler language
						}
						

Assert


						assert(expression);
						

Contract Programming

								
								in
								{
									contract preconditions
								}
								out(result)
								{
									contract postconditions
								}
								do
								{
									code
								}
								
							

Invariant

specify characteristics of a class or struct that must always be true

						invariant
						{
							assert(expr1);
							assert(expr2);
							...
						}
						

Invariant Example


							class Date
							{
								int day;
								int hour;
								this (int d, int h){
									day = d;
									hour = h;
								}
								invariant
								{
									assert(1 <= day && day <=31);
									assert(0 <= hour && hour < 24);
								}
							}
						

UFCS Example


						writeln(evens(divide(multiply(values, 10), 3)));
						
						values.multiply(10).divide(3).evens.writeln;
						

Thread Local Storage (TLS)

Thread Local Storage (TLS)

Thread Local Storage (TLS)

							
							in main thread : temp = 1, temp address is 7F7E4E79C740
							in sub  thread : temp = 2, temp address is 7F7E4D68A580
							in main thread : temp = 1, temp address is 7F7E4E79C740
							in sub  thread : temp = 2, temp address is 7F7E4D68A580
							in main thread : temp = 1, temp address is 7F7E4E79C740
							
						

Mutex

							
								mtx.lock_nothrow();

								counter += 1;

								mtx.unlock_nothrow();
					
							
						

Message Passing

Message Passing in C/C++

								
								int main(int argc , char *argv[]) //server
								{
									//socket的建立
									char inputBuffer[256] = {};
									char message[] = {"Hi,this is server.\n"};
									int sockfd = 0,forClientSockfd = 0;
									sockfd = socket(AF_INET , SOCK_STREAM , 0);
								
									if (sockfd == -1){
										printf("Fail to create a socket.");
									}
								
									//socket的連線
									struct sockaddr_in serverInfo,clientInfo;
									int addrlen = sizeof(clientInfo);
									bzero(&serverInfo,sizeof(serverInfo));
								
									serverInfo.sin_family = PF_INET;
									serverInfo.sin_addr.s_addr = INADDR_ANY;
									serverInfo.sin_port = htons(8700);
									bind(sockfd,(struct sockaddr *)&serverInfo,sizeof(serverInfo));
									listen(sockfd,5);
								
									while(1){
										forClientSockfd = accept(sockfd,(struct sockaddr*) &clientInfo, &addrlen);
										send(forClientSockfd,message,sizeof(message),0);
										recv(forClientSockfd,inputBuffer,sizeof(inputBuffer),0);
										printf("Get:%s\n",inputBuffer);
									}
									return 0;
								}
								
							
								
								int main(int argc , char *argv[]) //client
								{		
									//socket的建立
									int sockfd = 0;
									sockfd = socket(AF_INET, SOCK_STREAM , 0);
									
									if (sockfd == -1){
										printf("Fail to create a socket.");
									}
								
									//socket的連線							
									struct sockaddr_in info;
									bzero(&info,sizeof(info));
									info.sin_family = PF_INET;
								
									//localhost test
									info.sin_addr.s_addr = inet_addr("127.0.0.1");
									info.sin_port = htons(8700);
															
									int err = connect(sockfd,(struct sockaddr *)&info,sizeof(info));
									if(err==-1){
										printf("Connection error");
									}						
								
									//Send a message to server
									char message[] = {"Hi there"};
									char receiveMessage[100] = {};
									send(sockfd,message,sizeof(message),0);
									recv(sockfd,receiveMessage,sizeof(receiveMessage),0);
								
									printf("%s",receiveMessage);
									printf("close Socket\n");
									close(sockfd);
									return 0;
								}
								
							

Message Passing in D

							
							void workerFunc(Tid tid) { 
								int value = 0;  
								while (value >= 0) { 
									value = receiveOnly!int();
									auto result = to!int(value) * 5;
									tid.send(result);
								}
							} 
							
							void main() { 
								Tid worker = spawn(&workerFunc,thisTid); 
								
								foreach (value; 5 .. 10) {
									worker.send(value);
									auto result = receiveOnly!int();
									writefln("main sent: %s, received: %s", value, result); // value = 5 ,result = 30 ...
								}
								
								worker.send(-1); 
							} 
							
						

Message Passing in D

								
								void workerFunc(Tid tid)
								{
								   Thread.sleep(dur!("secs")( 5 ),);
								   tid.send("hello");
								}
		
								void main()
								{
									spawn(&workerFunc,thisTid);
													
									writeln("Waiting for a message");
									bool received = false;		
									while (!received)
									{
										received = receiveTimeout(dur!("secs")( 1 ),
										(string message){
											writeln("received: ", message);
										});
									
										if (!received)	writeln("... no message yet");
									}
								}
								
							
								
								Waiting for a message
								... no message yet
								... no message yet
								... no message yet
								... no message yet
								received: hello
								
							

Fiber

							
							import std.stdio;
							import core.thread : Fiber;
	
							void foo() {
								writeln("Hello");
								Fiber.yield();
								writeln("World");
							}
	
							int main(){
								
								auto f = new Fiber(&foo);
								f.call(); // prints Hello
								f.call(); // prints World
							
								return 0;
							}
							
						

Parallel

														
								import std.stdio;
								import core.thread;
								import std.parallelism;
								
								struct Student {
									int number;
								
									void sleepOperation() {
										Thread.sleep(1.seconds);
										writefln("The work on student %s has ended", number);
									}
								}

								void main() {
									auto students =
										[ Student(1), Student(2), Student(3), Student(4) ];
								
									foreach (student; parallel(students)) {	//	parallelism
										student.sleepOperation();
									}
								}
								
							

Garbage Collection

							
							void main() {
								import core.memory;
								import std.stdio;
							
								GC.disable;
								writeln("Goodbye, GC!");
							}
							
						

Class Template

C++

							
							template < class T>
							class Foo{
								T x;
								Foo(T init){ this.x = init; }
							};
							
						

D

							
								class Foo(T){
									T x;
									this(T init){ this.x = init; }
								}
							
						

Function Template

C++

							
							template < class T > 
							T Foo(T t){
								return t;
							};
							
						

D

							
							T Foo(T)(T t){
								return t;
							}
							
						

Grouping templates with the same parameters

C++

							
							template< class T, class U>
							class Foo_Bar { ... };
							
							template< class T, class U>
							T Foo_foo(T t, U u) { ... };
							
						

D

							
						template Foo(T, U)
						{
							class Bar { ... }
							T foo(T t, U u) { ... }
						}
							
						

Readability

C++

							
							template< class T>
							struct Alloc { };
							
							template< class T>
							using Vec = vector< T, Alloc< T > >;
							// since C++14
							
							Vec v;
							
						

InputRange

							
							interface InputRange(E)
							{
								bool empty();
								E front();
								void popFront();
							}
							
						

Fibonacci

							
							struct FibonacciRange {
								int first = 1, second = 1;
							
								//The fibonacci range never ends
								enum empty = false; 
							
								int front() const @property{
									return first;
								}
							
								void popFront(){
									auto t = first;
									first = second;
									second = t + second;
								}
							}
							
						
							
							FibonacciRange fib;

							fib.take(10).writeln; 
							// [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
							
						
							
							FibonacciRange fib;

							fib.take(10).writeln; 
							// [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
							
						

Demo