The D Programming Language http://www.digitalmars.com/d The D Programming Language O que é? • Linguagem nascida em 1999, da autoria de Walter Bright, com o intuito de criar “um C++ melhor”. • Repensar e refazer os pontos fracos do C++. • Incorporando features modernas que têm surgido noutras linguagens (Java, C# e não só). Mantêm como objectivo: • Performance elevada. • Acesso baixo nível (memória, hardware, sistema operativo, etc.) The D Programming Language Linguagem compilada (para código nativo). Sintaxe: Linguagem da família do C. Código fonte não é compativel com C++ ou C. Possui compatibilidade binária com C (C ABI compatible). • Linka com ficheiros obj compilados em C. Existem 2 compiladores em desenvolvimento (DMD e GDC) usáveis. • …mas poucas ferramentas de desenvolvimento (IDEs e debuggers). The D Programming Language Exemplo Hello World: import std.stdio; int main(char[][] args) { writefln("Hello World"); return 0; } Aspectos alterados (1) Unidade de compilação é um só ficheiro, o módulo. Não há ficheiros header (.h’s). • Módulos estruturados em packages, acedidos com import. • Logo, namespace estruturado hierárquico. Não são necessárias forward declarations. Os nomes definidos à frente estão imediatamente acessíveis. Tipos primitivos com tamanho e sinal definido. • byte, char: 8 bits; short: 16 bits; int: 32 bits; long: 64 bits; • byte, ubyte; short, ushort; int, uint; Default initializers. • int i; // i inicializado a int.init (zero) • float f; // f inicializado a float.init (NAN) Tipo bool (e literais true e false). Aspectos alterados (2) Tipos agregados (struct, union) e enum. • Declaração uniforme, não há namespace separado. struct Point { int x, y, z; } Point mypoint; • Agora com directivas de alinhamento. Atributos de protecção (public, private, package, protected, export) para qualquer entidade. Name(entity) aliasing: • alias uint Ano; • alias char[] string; Não há pré-processador. • Considerado mau, substituído por outras features. Compilação condicional (antigo #ifdef’s ) . • version (DemoEdition) { ... } Inline assembler estandardizado. Novas Features (1) Debug e Release builds. foreach statement. • foreach(string name; nameList) { ... } • foreach(int i, string name; nameList) { ... } Exception Handling (try, catch e *finally*) Suporte a Unicode, tanto nos identificadores como nas strings da linguagem. • void writeOláPessoalEmJaponês() { writefln("はじめまして、みんな。"); } Comments de documentação. Novas Features (2) Static constructors. Scope guards. 80 bit floating point (extended precision). IEEE Standard 754 fully-compliant floats. Numeros complexos e imaginários. • cdouble cp = 6 + 7i; Inferência de tipos. • ArrayList!(string) names = new ArrayList!(string)(); • auto names = new ArrayList!(string)(); Ponteiros e Arrays (1) Prefix Array Declarations. • int*[5][8] p; //array de 8 arrays de 5 ptrs para int Array bounds checking (em debug builds). Arrays dinâmicas: char[] str1 = "World"; str1 = “Hello " ~ str1; char[] str2; str2 []= str1; str2.length = 10; • Strings implementadas como char[] alias char[] string; Ponteiros e Arrays (2) Array literals • writefln([1, 4, 9, 16]); • nums = [1, 2, 3] ~ [4, 5, 6]; Array slicing • writefln("hello world"[6..11]); Associative Arrays (aka Dictionaries, Maps): int[string] idades; idades["Luis"] = 22; idades.remove("Luis"); OOP e Classes (1) Classes com herança simples e interfaces. Classe Object no topo da hierarquia. Constructores e destructores. Dynamic class Info. Mas sem reflexão (ainda) nem dynamic class loading. Classes são reference types. OOP e Classes (2) Exemplo: class FooBar : Bar { int x; this() { x = 42; } void xpto() { writefln(x); } } ... FooBar foobar = new FooBar(); foobar.xpto(); OOP e Classes (3) Todos os métodos virtuais por omissão. (o compilador é livre de optimizar) Keywords override, final, static, abstract. Covariant return types. Class properties. ( :-/ ) Operator overload (com sintaxe melhorada). Operadores para testar identidade e igualdade. • if(foobar is null) { ... • if(foobar == foobar2) { ... Nested & Inner Classes. Anonymous Classes: • func(new class() BaseObj { int x, y; }); Memory Management (1) Garbage Collection. O GC é controlável, (fullCollect(), genCollect(), disable(), enable() ). Possível alocar blocos unmanaged (malloc, free). GC disponível em simultâneo com gestão manual. (é possível invocar deletes). Para maximizar o potencial do GC, o spec da linguagem define algumas restrições ao uso de ponteiros. • (não guardar ponteiros no disco ou em variaveis nãoponteiro, não usar lower bits, etc.) Memory Management (2) RAII (desalocação automática) • Liga o ciclo de vida de um objecto ao seu scope. • Idioma popular em C++. (Em Java e C# usa-se finally.) void func() { auto Foo foo = new Foo(); foo.xpto(); ... } // foo.~this() chamado à saida do bloco, // seja com return, goto, excepção, etc. Funções (1) Function overload e default parameter values. Parâmetros in, out, inout : • void add(int a, inout int b, out int result) {...} Variadic Functions com Type Info: • writefln("Nome: ", name, " Idade:", age); Delegates e function pointers: • void delegate(int,int) drawdg = &foobar.draw; drawdg(80, 120); • string str = "AbCdEf"; str.select(&isuppercase); // returns "ACE" Funções (2) Nested Functions (e closures). int delegate(int) genAccum(int c) { int accum(int n) { return c += n; } return &accum; } Function e Delegate literals (aka lambdas): • "AbCdEf".select( delegate bool(char c) { return c >= 65 && c >= 90; } ); Short syntax: • "AbCdEf".select( (char c) { return c >= 65 && c >= 90; } ); • return (int n) { return c += n; } ; • button.onDoubleClick( { displayWarning("OH NOES!"); } ); Lazy parameters shortCircuitAnd(bool b1, lazy bool b2) { if(b1) return b2(); else return false; } Threading Suporte a Threading: Thread tr = new Thread(&threadFunc); tr.start(); tr.wait(); // espera que tr termine (join). Synchronize Statement: synchronized(objectFoo) { ... // só uma thread para blocos objectFoo } Conditional Variables para vir? synchronized(objectFoo) { objectFoo.wait(); } Contracts (1) Assert expression. • assert(memptr != null); Pre-conditions, Post-conditions: long square_root(long x) in { assert(x >= 0); } out (result) { assert((result * result) == x); } body { return math.sqrt(x); } Contracts (2) Class Invariants. class Date { int day; int hour; // verif. antes e depois de métodos públicos invariant { assert(1 <= day && day <= 31); assert(0 <= hour && hour < 24); } } Unit Testing Blocos de Unit Testing em classes e módulos: class Sum { int add(int x, int y) { return x + y; } unittest { Sum sum = new Sum(); assert(sum.add(3,4) == 7); assert(sum.add(-2,0) == -2); } } Compilada e verificada com uma opção do compilador. Generic Programming (1) Tipos genéricos (templates): class HashMap(KEY, VALUE) { void insert(KEY key, VALUE value) { ... } VALUE get(KEY key) { ... } ... } ... auto map = new HashMap!(string, Foobar)(); Generic Programming (2) Parâmetros do template podem ser tipos, literais (de int, float, string), ou mesmo identificadores: struct Vector(int SIZE, ELEMTYPE) { ELEMTYPE[SIZE] vec; Vector crossProduct(Vector vec){ ... } Vector Normalize() { ... } ELEMTYPE dotProduct(Vector vec){ ... } } ... alias Vector!(3, float) Vector3f; Generic Programming (3) Na realidade, os templates são de qualquer bloco de código (conjunto de declarações): template AccumFunc(int value) { int inc = value; int func(int num) { return num + inc; } } ... AccumFunc!(10).func(100); // devolve 110 AccumFunc!(10).inc = 20; AccumFunc!(10).func(100); // devolve 120 Generic Programming (4) E ainda: typeof() e is() expressions. static if, static assert. Mixins (adicionam código onde instanciadas, tipo copy&paste). IFTI (Implicit Function Template Instantiation). Template template parameters. Showcases http://www.tiobe.com/tpci.htm http://shootout.alioth.debian.org/debian/benchm ark.php?test=all&lang=all http://wwwusers.mat.uni.torun.pl/~h3r3tic/ctrace/ http://www.dsource.org/projects/ddl http://www.asahi-net.or.jp/~cs8k-cyu/ http://www.shorthike.com/ #!shdmd.sh module direxpand; import shscript; int main(char[][] args) { string DIRSEP = "-"; if(args.length == 2) DIRSEP = args[1]; string[] files = normalizedFileNames(listdir(".", "*")); foreach(file; files) { string newfile = file.dup; newfile = std.string.replace(newfile,"/", DIRSEP); if(!newfile.exists()) { writefln("copy to: ", newfile); copy(file, newfile); } else { writefln("WARNING: file exists: ", newfile); } } return 0; } The D Programming Language http://www.digitalmars.com/d Take the red pill...