TI1220 Lecture 14: Domain-Specific Languages

1,849 views

Published on

Published in: Technology
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,849
On SlideShare
0
From Embeds
0
Number of Embeds
556
Actions
Shares
0
Downloads
17
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

TI1220 Lecture 14: Domain-Specific Languages

  1. 1. TI1220 2012-2013Concepts of Programming LanguagesEelco Visser / TU DelftLecture 14: Domain-Specific Languages
  2. 2. Syntax and SemanticsNames, Bindings, and ScopesStorageData TypesFunctional ProgrammingFirst-class FunctionsPolymorphismType ParameterizationParsing and InterpretationData Abstraction / Modular ProgrammingFunctional Programming ReduxConcurrencyConcurrent ProgrammingDomain-Specific LanguagesQuarter 3Quarter 4Basics ofScalaJavaScriptC
  3. 3. Linguistic AbstractionFormalizing Design Patterns
  4. 4. ProblemDomainSolutionDomainimplementvalidateSoftware Engineering
  5. 5. Software Reuse: Don’t RepeatYourselfsoftware reuse patterns• copy and paste• libraries• frameworks• service APIs• design patterns
  6. 6. Linguistic Abstractionidentify patternuse new abstractionlanguage A language Bdesign abstraction
  7. 7. From Instructions to Expressionsmov &a, &cadd &b, &cmov &a, &t1sub &b, &t1and &t1,&cSource: http://sites.google.com/site/arch1utep/home/course_outline/translating-complex-expressions-into-assembly-language-using-expression-treesc = ac += bt1 = at1 -= bc &= t1c = (a + b) & (a - b)
  8. 8. From Calling Conventions to Procedurescalc:push eBP ; save old frame pointermov eBP,eSP ; get new frame pointersub eSP,localsize ; reserve place for locals.. ; perform calculations, leave result in AX.mov eSP,eBP ; free space for localspop eBP ; restore old frame pointerret paramsize ; free parameter space and returnf(e1,e2,...,en)push eAX ; pass some register resultpush byte[eBP+20] ; pass some memory variable (FASM/TASM syntax)push 3 ; pass some constantcall calc ; the returned result is now in eAXf(x) { ... }http://en.wikipedia.org/wiki/Calling_convention
  9. 9. A structure is a collection of one or more variables, possibly of different types,grouped together under a single name for convenient handling. (Structures arecalled ``records in some languages, notably Pascal.)struct point { int x; int y;};memberstructure tagStructures in C:Abstract from Memory Layout
  10. 10. Malloc/Free to Automatic Memory Management/* Allocate space for an array with ten elements of type int. */int *ptr = (int*)malloc(10 * sizeof (int));if (ptr == NULL) {/* Memory could not be allocated, the programshould handle the error here as appropriate. */} else {/* Allocation succeeded. Do something. */free(ptr); /* We are done with the int objects,and free the associated pointer. */ptr = NULL; /* The pointer must not be used again,unless re-assigned to using malloc again. */}http://en.wikipedia.org/wiki/Mallocint [] = new int[10];/* use it; gc will clean up (hopefully) */
  11. 11. typedef struct Base {void* (**vtable)();int x;} Base;void (*Base_Vtable[])() = { &Base_print };Base* newBase(int v) {Base* obj = (Base*)malloc(sizeof(Base));obj->vtable = Base_Vtable;obj->x = v;return obj;}void print(Base* obj) {obj->vtable[0](obj);}class Base {Integer x;public Base(Integer v) {x = v;}public void print() {System.out.println("Base: " + x);}}class Child extends Base {Integer y;public Child(Integer v1, Integer v2) {super(v1);y = v2;}public void print() {System.out.println("Child: (" + x + "," + y + ")");}}Dynamic Dispatch
  12. 12. Polymorphic Higher-Order Functionsdef map[A,B](f: A => B, xs: List[A]): List[B] = {xs match{case Nil() => Nil()case Cons(y, ys) => Cons(f(y), map(f, ys))}}def incList(xs: IntList): IntList =xs match {case Nil() => Nil()case Cons(y, ys) => Cons(y + 1, incList(ys))}
  13. 13. Abstractions in Programming Languages❖ Structured control-flow★ if-then-else, while❖ Procedural abstraction★ procedures, first-class functions (closures)❖ Memory management★ garbage collection❖ Data abstraction★ abstract data types, objects❖ Modules★ inheritance, traits, mixins
  14. 14. “A programming language is low level when itsprograms require attention to the irrelevant”Alan J. Perlis. Epigrams on Programming. SIGPLAN Notices, 17(9):7-13, 1982.
  15. 15. Do HLLs eliminate all irrelevant details?What about❖ data persistence❖ data services❖ concurrency❖ distribution❖ access control❖ data invariants❖ workflow❖ ...
  16. 16. Do HLLs eliminate all irrelevant details?What about❖ data persistence❖ data services❖ concurrency❖ distribution❖ access control❖ data invariants❖ workflow❖ ...many of theseconcerns requireprogrammaticencodings
  17. 17. What is the Next Level ofAbstraction?ProblemDomainHLL Machine
  18. 18. Domain-Specific LanguagesProblemDomainHLL MachineDSL
  19. 19. Example: Encoding Unitscompilercomputerinputinput distance : Float;input duration : Float;output speed : Float := duration / distance;output
  20. 20. Example: Encoding Unitscompilercomputerinputinput distance : Float;input duration : Float;output speed : Float := duration / distance;errorwrong output
  21. 21. Impact of Software ErrorscompilercomputererrorMars Climate OrbiterUnit mismatch: Orbitervariables in Newtons,Ground control software inPound-force.Damage: ~350 M$input distance : Float;input duration : Float;output speed : Float := duration / distance;wrong output
  22. 22. Example: Explicit Representation of Unitscomputerinput distance : Meter;input duration : Second;output speed : Meter/Second := duration / distance;compilerformalize knowledge of application area (domain) in languageerror
  23. 23. DSLs Provide Domain-Specific ...Abstractions★ directly represent domain conceptsConcrete syntax★ natural notationOptimization★ based on domain assumptionsError checking★ report errors in terms of domain conceptsTool support★ interpreter, compiler, code generator, IDE
  24. 24. Internal DSLLibrary in HLL★ Haskell, Scala, Ruby, ...★ API is language★ language features for ‘linguistic abstraction’Advantages★ host language = implementation languageDisadvantages★ host language = implementation language (encoding)★ no portability★ no domain-specific errors, analysis, optimization
  25. 25. External DSLDedicated language★ independent of host/target language (portable)★ implementation with interpreter or compilerAdvantages★ language tuned to domain★ domain-specific errors, analysis, optimizationsDisadvantages★ cost of learning new language★ cost of maintaining language
  26. 26. Example DSLs (1)Spreadsheet★ formulas, macrosQuerying★ SQL, XQuery, XPathGraph layout★ GraphVizWeb★ HTML, CSS, RSS, XML, XSLT★ Ruby/Rails, JSP, ASP, JSF, WebDSL
  27. 27. Example DSLs (2)Games★ Lua, UnrealScriptModeling★ UML, OCL, QVTLanguage engineering★ YACC, LEX, RegExp, ANTLR, SDF★ TXL, ASF+SDF, Stratego
  28. 28. Example: Linguistic Integration inWebDSL
  29. 29. browser server databaseweb appWeb Programming
  30. 30. browser server databaseJava SQLHTML,JS, CSSWeb Programming = Distributed Programming
  31. 31. Concerns in WebProgrammingData PersistenceAccess ControlInjection AttacksSearchXSSDataValidationData BindingRouting... ...
  32. 32. Zef Hemel, Danny M. Groenewegen, Lennart C. L. Kats, EelcoVisser.Static consistency checking of web applications withWebDSL. Journal of Symbolic Computation, 46(2):150-182, 2011.Late Failure Detection in Web Applications
  33. 33. Complexity in Web Programming:Multiple Languages x Multiple ConcernsConsistency not statically checked
  34. 34. EelcoVisser. WebDSL: A Case Study in Domain-Specific Language Engineering. InRalf Lämmel, JoostVisser, João Saraiva, editors, Generative and Transformational Techniques inSoftware Engineering II, International Summer School, GTTSE 2007.Volume 5235 of Lecture Notesin Computer Science, pages 291-373, Springer, Braga, Portugal, 2007.Separation of Concerns & Linguistic Integration
  35. 35. Formalizing Navigation Logic
  36. 36. http://eelcovisser.org/blog/post/42/dsl-engineering“http://”+ “eelcovisser.org” // host domain+ “blog” // application name+ “post” // page+ “42” // identity+ “dsl-engineering” // title
  37. 37. page blog(b: Blog, index: Int) {main(b){for(p: Post in b.recentPosts(index,5)) {section{header{ navigate post(p) { output(p.title) } }par{ output(p.content) }par{ output(p.created.format("MMMM d, yyyy")) }}}}page post(p: Post) { ... }Statically checked navigation
  38. 38. entity Blog {key :: String (id)title :: String (name)posts -> Set<Post> (inverse=Post.blog)function recentPosts(index: Int, n: Int): List<Post> {var i := max(1,index) - 1;return [p | p: Post in postsorder by p.created desclimit n offset i*n].list();}}entity Post {key :: String (id)title :: String (name, searchable)content :: WikiText (searchable)blog -> Blog}Persistent Data ModelsGeneration of queries: no injection attacks
  39. 39. entity Assignment {key :: String (id)title :: String (name, searchable)shortTitle :: Stringdescription :: WikiText (searchable)course -> CourseEdition (searchable)weight :: Float (default=1.0)deadline :: DateTime (default=null)// ...}page assignment(assign: Assignment, tab: String) {main{progress(assign, tab)pageHeader{output(assign.title)breadcrumbs(assign)}// ...}}Persistent variables in WebDSLhttp://department.st.ewi.tudelft.nl/weblab/assignment/752objects are automatically persisted in database123
  40. 40. page post(p: Post) { ... }page editpost(p: Post) {action save() { return blog(p); }main(p.blog){form{formEntry("Title"){input(p.title) }formEntry("Content") {input(p.content) }formEntry("Posted") {input(p.created) }submit save() { "Save" }}}}Forms & Data BindingNo separate controller!
  41. 41. access control rulesprincipal is Userwith credentials username, passwordrule page blog(b: Blog, index: Int) {true}rule page post(p: Post) {p.public || p.author == principal}rule page editpost(p: Post) {principal == p.author}extend entity User {password :: Secret}extend entity Blog {owner -> User}extend entity Post {public :: Bool}Declarative Access Control Rules
  42. 42. Linguistically IntegratedPersistent data modelLogicTemplates (UI, Email, Service)Data bindingAccess controlData validationFaceted searchCollaborative filtering
  43. 43. DSL Summarysoftware reuse through linguistic abstraction• capture understanding of design patterns in language concepts• abstract from accidental complexity• program in terms of domain concepts• automatically generate implementation
  44. 44. When to Use/Create DSLs?Hierarchy of abstractions• first understand how to program it• make variations by copy, paste, adapt• (avoid over-engineering)• make library of frequently used patterns• find existing (internal) DSLs for the domainTime for a DSL?• large class of applications using same design patterns• design patterns cannot be captured in PL• lack of checking / optimization for DSL abstractions
  45. 45. Language Engineering
  46. 46. object ExpParser extends JavaTokenParsers with PackratParsers {lazy val exp: PackratParser[Exp] =(exp <~ "+") ~ exp1 ^^ { case lhs~rhs => Add(lhs, rhs) } |exp1lazy val exp1: PackratParser[Exp] =(exp1 ~ exp0) ^^ { case lhs~rhs => App(lhs, rhs) } |exp0lazy val exp0: PackratParser[Exp] =number | identifier | function | letBinding |"(" ~> exp <~ ")"// ...def parse(text: String) = parseAll(exp, text)}syntax through parsers
  47. 47. sealed abstract class Valuecase class numV(n: Int) extends Valuecase class closureV(param: Symbol, body: Exp, env: Env)extends Valuedef eval(exp: Exp, env: Env): Value = exp match {case Num(v) => numV(v)case Add(l, r) => plus(eval(l, env), eval(r, env))case Id(name) => lookup(name, env)case Let(name, e1, e2) =>eval(e2, bind(name, eval(e1, env), env))case Fun(name, body) => closureV(name, body, env)case App(fun, arg) => eval(fun, env) match {case closureV(name, body, env2) =>eval(body, bind(name, eval(arg, env), env2))case _ => sys.error("Closure expected")}}semantics through interpreter
  48. 48. Traditional Compilers
  49. 49. Traditional CompilerslsCourse.java
  50. 50. Traditional CompilerslsCourse.javajavac -verbose Course.java[parsing started Course.java][parsing completed 8ms][loading java/lang/Object.class(java/lang:Object.class)][checking university.Course][wrote Course.class][total 411ms]
  51. 51. Traditional CompilerslsCourse.javajavac -verbose Course.java[parsing started Course.java][parsing completed 8ms][loading java/lang/Object.class(java/lang:Object.class)][checking university.Course][wrote Course.class][total 411ms]lsCourse.class Course.java
  52. 52. Language Processorssyntax analysis• parsing• AST constructionstatic analysis• name analysis• type analysissemantics• generation• interpretation
  53. 53. Integrated Development Environments (IDE)
  54. 54. Modern Compilers in IDEssyntactic editor services• syntax checking• syntax highlighting• outline view• code folding• bracket matchingsemantic editor services• error checking• reference resolving• hover help• content completion• refactoring
  55. 55. Eclipse Platformruntime platform• composition• integrationdevelopment platform• complex APIs• abstractions for Eclipse IDEs• concepts: editors, views, label provider, label providerfactory, …• tedious, boring, frustrating
  56. 56. Spoofax Language Workbenchdeclarative meta-languages• syntax definition• editor services• term rewritingimplementation• generic integration into Eclipse and IMP• compilation & interpretation of language definitionsagile• Spoofax & IDE under development in same Eclipse instance• support for test-driven development
  57. 57. A Taste of Language Engineeringwith Spoofax• abstract syntax trees• declarative syntax definition• name binding and scope• transformation by term rewriting
  58. 58. EnFun: Entities with Functionsmodule blogentity String {function plus(that:String): String}entity Bool { }entity Set<T> {function add(x: T)function remove(x: T)function member(x: T): Bool}entity Blog {posts : Set<Post>function newPost(): Post {var p : Post := Post.new();posts.add(p);}}entity Post {title : String}
  59. 59. Structure:Abstract Syntax
  60. 60. Signature & TermsconstructorsModule : ID * List(Definition) -> ModuleImports : ID -> DefinitionModule("application", [Imports("library"),Imports("users"),Imports("frontend")])
  61. 61. Entities & PropertiesconstructorsEntity : ID * List(Property) -> DefinitionType : ID -> TypeNew : Type -> ExpconstructorsProperty : ID * Type -> PropertyThis : ExpPropAccess : Exp * ID -> ExpModule("users", [ Imports("library"), Entity("User", [ Property("email", Type("String")), Property("password", Type("String")), Property("isAdmin", Type("Bool"))])])
  62. 62. Parsing: From Text to Structure
  63. 63. Declarative Syntax DefinitionEntity("User", [Property("first", Type("String")),Property("last", Type("String"))])signatureconstructorsEntity : ID * List(Property) -> DefinitionType : ID -> TypeProperty : ID * Type -> Property
  64. 64. Declarative Syntax Definitionentity User {first : Stringlast : String}Entity("User", [Property("first", Type("String")),Property("last", Type("String"))])signatureconstructorsEntity : ID * List(Property) -> DefinitionType : ID -> TypeProperty : ID * Type -> Property
  65. 65. Declarative Syntax Definitionentity User {first : Stringlast : String}Entity("User", [Property("first", Type("String")),Property("last", Type("String"))])signatureconstructorsEntity : ID * List(Property) -> DefinitionType : ID -> TypeProperty : ID * Type -> Propertycontext-free syntax"entity" ID "{" Property* "}" -> Definition {"Entity"}ID -> Type {"Type"}ID ":" Type -> Property {"Property"}
  66. 66. Prototyping Syntax Definition
  67. 67. Context-free SyntaxconstructorsTrue : ExpFalse : ExpNot : Exp -> ExpAnd : Exp * Exp -> ExpOr : Exp * Exp -> Expcontext-free syntax"true" -> Exp {"True"}"false" -> Exp {"False"}"!" Exp -> Exp {"Not"}Exp "&&" Exp -> Exp {"And"}Exp "||" Exp -> Exp {"Or"}
  68. 68. Lexical SyntaxconstructorsTrue : ExpFalse : ExpNot : Exp -> ExpAnd : Exp * Exp -> ExpOr : Exp * Exp -> Expcontext-free syntax"true" -> Exp {"True"}"false" -> Exp {"False"}"!" Exp -> Exp {"Not"}Exp "&&" Exp -> Exp {"And"}Exp "||" Exp -> Exp {"Or"}lexical syntax[a-zA-Z][a-zA-Z0-9]* -> ID"-"? [0-9]+ -> INT[ tnr] -> LAYOUTconstructors: String -> ID: String -> INTscannerless generalized (LR) parsingform of tokens (words, lexemes)
  69. 69. AmbiguityconstructorsTrue : ExpFalse : ExpNot : Exp -> ExpAnd : Exp * Exp -> ExpOr : Exp * Exp -> Expcontext-free syntax"true" -> Exp {"True"}"false" -> Exp {"False"}"!" Exp -> Exp {"Not"}Exp "&&" Exp -> Exp {"And"}Exp "||" Exp -> Exp {"Or"}isPublic || isDraft && (author == principal())
  70. 70. AmbiguityconstructorsTrue : ExpFalse : ExpNot : Exp -> ExpAnd : Exp * Exp -> ExpOr : Exp * Exp -> Expcontext-free syntax"true" -> Exp {"True"}"false" -> Exp {"False"}"!" Exp -> Exp {"Not"}Exp "&&" Exp -> Exp {"And"}Exp "||" Exp -> Exp {"Or"}isPublic || isDraft && (author == principal())amb([And(Or(Var("isPublic"), Var("isDraft")),Eq(Var("author"), ThisCall("principal", []))),Or(Var("isPublic"),And(Var("isDraft"), Eq(Var("author"), ThisCall("principal", []))))])
  71. 71. Disambiguation by Encoding PrecedenceconstructorsTrue : ExpFalse : ExpNot : Exp -> ExpAnd : Exp * Exp -> ExpOr : Exp * Exp -> Expcontext-free syntax"true" -> Exp {"True"}"false" -> Exp {"False"}"!" Exp -> Exp {"Not"}Exp "&&" Exp -> Exp {"And"}Exp "||" Exp -> Exp {"Or"}context-free syntax"(" Exp ")" -> Exp0 {bracket}"true" -> Exp0 {"True"}"false" -> Exp0 {"False"}Exp0 -> Exp1"!" Exp0 -> Exp1 {"Not"}Exp1 -> Exp2Exp1 "&&" Exp2 -> Exp2 {"And"}Exp2 -> Exp3Exp2 "||" Exp3 -> Exp3 {"Or"}
  72. 72. Declarative Disambiguationcontext-free syntax"true" -> Exp {"True"}"false" -> Exp {"False"}"!" Exp -> Exp {"Not"}Exp "&&" Exp -> Exp {"And", left}Exp "||" Exp -> Exp {"Or", left}"(" Exp ")" -> Exp {bracket}context-free priorities{left: Exp.Not} >{left: Exp.Mul} >{left: Exp.Plus Exp.Minus} >{left: Exp.And} >{non-assoc: Exp.Eq Exp.Lt Exp.Gt Exp.Leq Exp.Geq}isPublic || isDraft && (author == principal())Or(Var("isPublic"),And(Var("isDraft"),Eq(Var("author"), ThisCall("principal", []))))
  73. 73. Analysis: Name Resolution+
  74. 74. Definitions and Referencesmodule testentity String { }entity User {first : Stringlast : String}definitionreference
  75. 75. Name Binding in IDE
  76. 76. From Tree to GraphModule("test", [ Entity("String", []), Entity("User", [ Property("first", ), Property("last", )])])
  77. 77. NaBL: Name Binding Languagemodule namesimportsinclude/Camnamespaces Type Property Function VariablerulesEntity(name, None(), None(), _):defines Type name of type Type(name, [])scopes Type, Function, Property, VariableType(name, _):refers to Type name
  78. 78. Transformation
  79. 79. Transformation by Strategic Rewritingrulesdesugar:Plus(e1, e2) -> MethCall(e1, "plus", [e2])desugar:Or(e1, e2) -> MethCall(e1, "or", [e2])desugar :VarDeclInit(x, t, e) ->Seq([VarDecl(x, t),Assign(Var(x), e)])strategiesdesugar-all = topdown(repeat(desugar))
  80. 80. Return-Lifting Appliedfunction fact(n: Int): Int {var res: Int;if(n == 0) {res := 1;} else {res := this * fact(n - 1);}return res;}function fact(n: Int): Int {if(n == 0) {return 1;} else {return this * fact(n - 1);}}
  81. 81. Return-Lifting Rulesruleslift-return-all =alltd(lift-return; normalize-all)lift-return :FunDef(x, arg*, Some(t), stat1*) ->FunDef(x, arg*, Some(t), Seq([VarDecl(y, t),Seq(stat2*),Return(Var(y))]))where y := <new>;stat2* := <alltd(replace-return(|y))> stat1*replace-return(|y) :Return(e) -> Assign(y, e)
  82. 82. Language Engineering Summaryapply linguistic abstraction to language engineering• declarative languages for language definition• automatic derivation of efficient compilers• automatic derivation of IDEs
  83. 83. Research Agenda
  84. 84. Example: Explicit Representation of Unitscomputerinput distance : Meter;input duration : Second;output speed : Meter/Second := duration / distance;compilerformalize knowledge of application area (domain) in languageerror
  85. 85. errorProblem: Correctness of Language DefinitionscomputercompilerCan wetrust thecompiler?wrong outputinputprogramtype soundness: well-typed programs don’t go wrong
  86. 86. compilererrorChallenge:AutomaticVerification of Correctnesscomputercompilerwrong outputprogramtype soundness: well-typed programs don’t go wrongtypecheckercodegeneratorinput
  87. 87. CorrectnessProofLanguage WorkbenchState-of-the-Art: Language EngineeringSyntaxCheckerNameResolverTypeCheckerCodeGeneratorfocus on implementation; not suitable for verificationCompilerEditor(IDE)Tests
  88. 88. Formal Language SpecificationState-of-the-Art: Semantics EngineeringAbstractSyntaxTypeSystemDynamicSemanticsTransformsfocus on (only semi-automatic) verification; not suitable for implementationCorrectnessProofTestsCompilerEditor(IDE)
  89. 89. Declarative Language DefinitionMy Approach: Multi-Purpose Language DefinitionsSyntaxDefinitionNameBindingTypeSystemDynamicSemanticsTransformsCompilerEditor(IDE)CorrectnessProofTestsbridging the gap between language engineering and semantics engineering
  90. 90. Software Development on the Webrevisiting the architecture of the IDE
  91. 91. Exam
  92. 92. Syntax and SemanticsNames, Bindings, and ScopesStorageData TypesFunctional ProgrammingFirst-class FunctionsPolymorphismType ParameterizationParsing and InterpretationData Abstraction / Modular ProgrammingFunctional Programming ReduxConcurrencyConcurrent ProgrammingDomain-Specific LanguagesQuarter 3Quarter 4Basics ofScalaJavaScriptC
  93. 93. Material for examSlides from lecturesTutorial exercisesGraded assignmentsSebesta: Chapters 1-13, 15Programming in Scala: Chapters 1, 4-16, 19, 32-33K&R C: Chapters 1-6JavaScript Good Parts: Chapters 1-4
  94. 94. Content of exam10% multiple choice questionsabout concepts50% Scala programming(functional programming)20% C programming(structures and pointers)20% JavaScript programming(objects and prototypes)
  95. 95. Registration for Exam is Requiredhttp://department.st.ewi.tudelft.nl/weblab/assignment/761 -> your submission
  96. 96. Good Luck!

×