D Programming Language: the Sudden

D Programming Language: the Sudden

D Programming Language: The Sudden Andrei Alexandrescu, Ph.D. Research Scientist, Facebook [email protected] YOW 2014 c 2014– Andrei Alexandrescu. 1/44 Introduction c 2014– Andrei Alexandrescu. 2/44 Introduction c 2014– Andrei Alexandrescu. 3/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice • Airburn Infantry c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice • Airburn Infantry Sequel to BoB and Operation Flamethrower c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice • Airburn Infantry Sequel to BoB and Operation Flamethrower • Newburn c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice • Airburn Infantry Sequel to BoB and Operation Flamethrower • Newburn Sequel to Chucky and Spontaneous Combustion c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice • Airburn Infantry Sequel to BoB and Operation Flamethrower • Newburn Sequel to Chucky and Spontaneous Combustion • The Dark Knight Rises c 2014– Andrei Alexandrescu. 4/44 Sudden Sequels • Pronouncing “Melbourne” and “Brisbane” • Burn Identity Sequel to Bourne Identity and Burn Notice • Airburn Infantry Sequel to BoB and Operation Flamethrower • Newburn Sequel to Chucky and Spontaneous Combustion • The Dark Knight Rises Batman vs. Bun c 2014– Andrei Alexandrescu. 4/44 Motivation • Systems-level programming a necessity • Several application categories • Faster is better—no “good enough” limit • Ever-growing modeling needs • No room below, no escape: all in same language ◦ Runtime support ◦ Machine, device interface ◦ Base library • This is (literally) where the buck stops c 2014– Andrei Alexandrescu. 7/44 D Design Principles • Leave no room below ◦ share memory model with C ◦ statically typed • Multi-paradigm; balanced • Practical • Principled • Avoid arcana c 2014– Andrei Alexandrescu. 8/44 Why? • Party line ◦ convenience ◦ modeling power ◦ efficiency • Actual reasons ◦ Produces fast binaries, fast ◦ Easier to get into than alternatives ◦ Fun c 2014– Andrei Alexandrescu. 9/44 Why not? • Party line ◦ • Actual reasons ◦ Poor on formal specification ◦ Little corporate pickup, support ◦ Dearth of libraries ◦ Large c 2014– Andrei Alexandrescu. 10 / 44 The “Meh” #!/usr/bin/rdmd import std.stdio; void main() { writeln("Hello, world!"); } • Why the std.std stutter? • Why import stuff for everything? • Why no code at top level? • However: ◦ Simple ◦ Correct ◦ Scriptable c 2014– Andrei Alexandrescu. 11 / 44 The Innocently Plausible void main() { import std.stdio; writeln("Hello, world!"); } • Doesn’t work in Java, C# • Career-limiting move in Python, C, C++ • In D, most everything can be scoped everywhere ◦ Functions ◦ Types (Voldermort types) ◦ Even generics ◦ Better modularity, reasoning c 2014– Andrei Alexandrescu. 12 / 44 The Unexpected Emergent void log(T)(T stuff) { import std.datetime, std.stdio; writeln(Clock.currTime(), ’ ’, stuff); } void main() { log("hello"); } • If not instantiated, no import • imports cached once realized • Generics faster to build, import • Less pressure on linker c 2014– Andrei Alexandrescu. 13 / 44 Heck, add variadics too void log(T...)(T stuff) { import std.datetime, std.stdio; writeln(Clock.currTime(), ’ ’, stuff); } void main() { log("Reached Nirvana level: ", 9); } c 2014– Andrei Alexandrescu. 14 / 44 Suddenly Natural lexical scoping leads to faster builds c 2014– Andrei Alexandrescu. 15 / 44 Approach to Purity c 2014– Andrei Alexandrescu. 16 / 44 Thesis • Writing entire programs in pure style challenging • Writing fragments of programs in pure style easy, useful • + Easier to verify useful properties, debug • + Better code generation • − Challenge: interfacing pure and impure code c 2014– Andrei Alexandrescu. 17 / 44 Functional Factorial (yawn) ulong factorial(uint n) { return n <= 1 ? 1 : n * factorial(n - 1); } • It’s PSPACE! • Somebody should do hard time for this c 2014– Andrei Alexandrescu. 18 / 44 However, it’s pure pure ulong factorial(uint n) { return n <= 1 ? 1 : n * factorial(n - 1); } • Pure is good c 2014– Andrei Alexandrescu. 19 / 44 Functional Factorial, Fixed pure ulong factorial(uint n) { ulong crutch(uint n, ulong result) { return n <= 1 ? result : crutch(n - 1, n * result); } return crutch(n, 1); } • Threads state through as parameters • You know what? I don’t care for it c 2014– Andrei Alexandrescu. 20 / 44 Honest Factorial ulong factorial(uint n) { ulong result = 1; foreach (uint i = 2; i <= n; ++i) { result *= i; } return result; } • But no longer pure! • Well allow me to retort c 2014– Andrei Alexandrescu. 21 / 44 Pure is as pure does • “Pure functions always return the same result for the same arguments” • No reading and writing of global variables ◦ (Global constants okay) • No calling of impure functions • Who said anything about local, transient state inside the function? c 2014– Andrei Alexandrescu. 23 / 44 Transitive State pure void reverse(T)(T[] a) { foreach (i; 0 .. a.length / 2) { swap(a[i], a[$ - i - 1]); } } • Possibility: disallow • More useful: relaxed rule • Operate with transitive closure of state reachable through parameter • Not functional pure, but an interesting superset • No need for another annotation, it’s all in the signature! c 2014– Andrei Alexandrescu. 24 / 44 User-defined types pure BigInt factorial(uint n) { BigInt result = 1; for (; n > 1; --n) { result *= n; } return result; } • Better yet: purity deduced for generics and lambdas c 2014– Andrei Alexandrescu. 25 / 44 Aftermath • If parameters reach mutable state: ◦ Relaxed pure—no globals, no I/O, no impure calls • If parameters can’t reach mutable state: ◦ “Haskell-grade” observed purity ◦ Yet imperative implementation possible ◦ As long as it’s local only c 2014– Andrei Alexandrescu. 26 / 44 Suddenly Combining purity with mutability improves both c 2014– Andrei Alexandrescu. 27 / 44 The Generative Connection c 2014– Andrei Alexandrescu. 28 / 44 Generative programming • In brief: code that generates code • Generic programming often requires algorithm specialization • Specification often present in a DSL c 2014– Andrei Alexandrescu. 29 / 44 Embedded DSLs Force into host language’s syntax? c 2014– Andrei Alexandrescu. 30 / 44 Embedded DSLs • Formatted printing? c 2014– Andrei Alexandrescu. 31 / 44 Embedded DSLs • Formatted printing? • Regular expressions? c 2014– Andrei Alexandrescu. 31 / 44 Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? c 2014– Andrei Alexandrescu. 31 / 44 Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? • PEG? c 2014– Andrei Alexandrescu. 31 / 44 Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? • PEG? • SQL? c 2014– Andrei Alexandrescu. 31 / 44 Embedded DSLs • Formatted printing? • Regular expressions? • EBNF? • PEG? • SQL? • . Pasta for everyone! c 2014– Andrei Alexandrescu. 31 / 44 Embedded DSLs Here: use with native grammar Process during compilation Generate D code accordingly c 2014– Andrei Alexandrescu. 32 / 44 Compile-Time Evaluation • A large subset of D available for compile-time evaluation ulong factorial(uint n) { ulong result = 1; for (; n > 1; --n) result *= n; return result; } ... auto f1 = factorial(10); // run-time static f2 = factorial(10); // compile-time c 2014– Andrei Alexandrescu. 33 / 44 Code injection with mixin mixin("writeln(\"hello, world\");"); mixin(generateSomeCode()); • Not as glamorous as AST manipulation but darn effective • Easy to understand and debug • Now we have compile-time evaluation AND mixin. c 2014– Andrei Alexandrescu. 34 / 44 Wait a minute! c 2014– Andrei Alexandrescu. 35 / 44 Example: bitfields in library struct A { int a; mixin(bitfields!( uint,"x", 2, int, "y", 3, uint,"z", 2, bool, "flag", 1)); } A obj; obj.x = 2; obj.z = obj.x; c 2014– Andrei Alexandrescu. 36 / 44 Parser import pegged.grammar; // by Philippe Sigaud mixin(grammar(" Expr < Factor AddExpr* AddExpr < (’+’/’-’) Factor Factor < Primary MulExpr* MulExpr < (’*’/’/’) Primary Primary < Parens / Number / Variable / ’-’ Primary Parens < ’(’ Expr ’)’ Number <~ [0-9]+ Variable <- Identifier ")); c 2014– Andrei Alexandrescu. 37 / 44 Usage // Parsing at compile-time: static parseTree1 = Expr.parse( "1 + 2 - (3*x-5)*6"); pragma(msg, parseTree1.capture); // Parsing at run-time: auto parseTree2 = Expr.parse(readln()); writeln(parseTree2.capture); c 2014– Andrei Alexandrescu. 38 / 44 Scaling up 1000 lines of D grammar → 3000 lines D parser c 2014– Andrei Alexandrescu. 39 / 44 Highly integrated lex+yacc c 2014– Andrei Alexandrescu. 40 / 44 What about regexen? c 2014– Andrei Alexandrescu. 41 / 44 Compile-time regular expressions • GSoC project by Dmitry Olshansky, merged into std • Fully UTF capable, no special casing for ASCII • Two modes sharing the same backend: auto r1 = regex("^.*/([^/]+)/?$"); static r2 = ctRegex!("^.*/([^/]+)/?$"); • Run-time version uses intrinsics in a few places • Static version generates specialized automaton, then compiles it c 2014– Andrei Alexandrescu. 42 / 44 Summary • Modularity + scoping • Purity + sinning • Compile-time evaluation + mixing code in c 2014– Andrei Alexandrescu. 44 / 44.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    57 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us