Xbase - Implementing Domain-Specific Languages for Java

3,484 views
3,263 views

Published on

As presented at the GPCE 2012 Conference.

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,484
On SlideShare
0
From Embeds
0
Number of Embeds
37
Actions
Shares
0
Downloads
62
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Xbase - Implementing Domain-Specific Languages for Java

    1. 1. Implementing Domain-Specific Languages for Java Sven Efftinge Wilhelm Hasselbring Moritz Eysholdt Robert von Massow Jan Köhnlein Michael HanusSebastian Zarnekow
    2. 2. Agenda• What is Xtext?• Motivation• Xbase Architecture•A Reusable language - What is the Interface?• Real World Applications
    3. 3. grammar org.example.domainmodel.DomainModel with org.eclipse.xtext.common.Terminals generate domainmodel "http://www.example.org/domainmodel/Domainmodel" example DSL Domainmodel :    elements += Type*;    Type:  DataType |  datatype String  Entity; entity Person {    name : String DataType:  givenName : String  datatype name = ID; address : Address} Entity:entity Address { entity name = ID street : String (extends superType = [Entity])? { zip : String features += Feature* city : String };} Feature: objectinstance name = ID : type = [Type]; grammar
    4. 4. Adaptability• grammar (reuse by choice)• tool chain (customize Xtext’s editor-generator)• runtime (subclass + exchange via dependency injection)
    5. 5. Motivation How to add behavior to your DSL?• Old: Generation Gap Pattern • Better: Make DSL more Powerful • generate abstract class • designing expression languages • handwrite concrete subclass is hard • expression grammar • type system • compiler • expressions are very similar across DSLs
    6. 6. Xbase A reusable Expression LanguageGrammar (Parser, Lexer) Operator Overloading Lambda Expressions Extension MethodsLinker Control Structures Arithmetic, Logic Java Callout / -inType SystemInterpreter / CompilerAdvanced EditorEclipse Workbench IntegrationDebugger Parser Serializer Advanced EditorEclipse Platform EMF Antlr
    7. 7. Xbase is fun (this is Xbase embedded into Xtend)class Movies { @Test def void sumOfVotesOfTop2() { val movies = movies.sortBy[-rating].take(2).map[numberOfVotes].reduce[a, b| a + b] assertEquals(47_229, movies) } val movies = new FileReader(data.csv).readLines.map[ line | val segments = line.split( ).iterator return new Movie( segments.next, Double::parseDouble(segments.next), Long::parseLong(segments.next), ) ]} 1. Read file into List<Movie>@Data class Movie { String title double rating } long numberOfVotes 2. Filter/Map/Reduce Listdata.csvA Few Good Men 7.6 68236Empire Records 6.4 20780"Rome" 9.2 21278Witness for the Prosecution 8.4 20202
    8. 8. Xbase is fun (this is Xbase embedded into Xtend)class Movies { @Test def void sumOfVotesOfTop2() { val movies = movies.sortBy[-rating].take(2).map[numberOfVotes].reduce[a, b| a + b] Method } assertEquals(47_229, movies) Body val movies = new FileReader(data.csv).readLines.map[ line | val segments = line.split( ).iterator return new Movie( Field segments.next, Double::parseDouble(segments.next), Initialization Long::parseLong(segments.next), ) ]}@Data class Movie { String title double rating long numberOfVotes}data.csvA Few Good Men 7.6 68236Empire Records 6.4 20780"Rome" 9.2 21278Witness for the Prosecution 8.4 20202
    9. 9. Xbase is fun (this is Xbase embedded into Xtend)class Movies { @Test def void sumOfVotesOfTop2() { val movies = movies.sortBy[-rating].take(2).map[numberOfVotes].reduce[a, b| a + b] assertEquals(47_229, movies) } val movies = new FileReader(data.csv).readLines.map[ line | val segments = line.split( ).iterator return new Movie( segments.next, Double::parseDouble(segments.next), Long::parseLong(segments.next), ) ]}@Data class Movie { String title double rating long numberOfVotes Extension Methods}data.csvA Few Good Men 7.6 68236Empire Records 6.4 20780"Rome" 9.2 21278Witness for the Prosecution 8.4 20202
    10. 10. Xbase is fun (this is Xbase embedded into Xtend)class Movies { @Test def void sumOfVotesOfTop2() { val movies = movies.sortBy[-rating].take(2).map[numberOfVotes].reduce[a, b| a + b] assertEquals(47_229, movies) } val movies = new FileReader(data.csv).readLines.map[ line | val segments = line.split( ).iterator return new Movie( segments.next, Double::parseDouble(segments.next), Long::parseLong(segments.next), ) ]}@Data class Movie { String title double rating long numberOfVotes Lambda Expressions}data.csvA Few Good Men 7.6 68236Empire Records 6.4 20780"Rome" 9.2 21278Witness for the Prosecution 8.4 20202
    11. 11. Xbase is fun (this is Xbase embedded into Xtend)class Movies { @Test def void sumOfVotesOfTop2() { val movies = movies.sortBy[-rating].take(2).map[numberOfVotes].reduce[a, b| a + b] assertEquals(47_229, movies) } val movies = new FileReader(data.csv).readLines.map[ line | val segments = line.split( ).iterator return new Movie( segments.next, Double::parseDouble(segments.next), Long::parseLong(segments.next), ) ]}@Data class Movie { String title double rating long numberOfVotes Type Inference}data.csvA Few Good Men 7.6 68236Empire Records 6.4 20780"Rome" 9.2 21278Witness for the Prosecution 8.4 20202
    12. 12. REUSE A LANGUAGE?? How to integrate it? What is the interface? Grammar (Parser, Lexer) Linker Type SystemMyLanguage Interpreter / Compiler Advanced Editor Eclipse Workbench Integration Debugger bad, since this is not an abstraction:it doesn’t hide complexity from the client
    13. 13. REUSE A LANGUAGE?? How to integrate it? What is the interface? grammar inheritance Grammar (Parser, Lexer) Linker Type System JvmModelMyLanguage Interpreter / Compiler Advanced Editor Eclipse Integration Debugger JvmModelInferrer (M2M transformation)
    14. 14. Grammar Inheritance grammar org.eclipse.xtext.example.domainmodel.Domainmodel with org.eclipse.xtext.xbase.Xbase MyLanguage Grammar generate domainmodel "http://www.xtext.org/example/Domainmodel" DomainModel: elements+=AbstractElement*; My Language Grammar AbstractElement: PackageDeclaration | Entity | Import; Import: import importedNamespace=QualifiedNameWithWildCard; PackageDeclaration: package name=QualifiedName { elements+=AbstractElement* }; Entity: entity name=ValidID (extends superType=JvmParameterizedTypeReference)? { features+=Feature* }; Feature: Property | Operation; Property: name=ValidID : type=JvmTypeReference; Operation: op name=ValidID ( (params+=FullJvmFormalParameter (, params+=FullJvmFormalParameter)*)? ) : type=JvmTypeReference body=XBlockExpression; QualifiedNameWithWildCard : QualifiedName (. *)?;
    15. 15. JvmModel Inference (M2M transformation with trace) MyLanguage Instance MyLanguage JvmModel (serialized) package my.social.network;package my.social.network { (imports) import java.util.List public class Person { private String firstName; private String lastName; entity Person { private List<Person> friends; firstName : String (getter, setter) lastName : String public String getFullName() { friends : List<Person> String _plus = (this.firstName + " "); return (_plus + this.lastName); op getFullName() : String { } return firstName + " " + lastName public List<Person> getSortedFriends() { } final Function1<Person,String> _function = new Function1<Person,String>() { public String apply(final Person it) { op getSortedFriends() : List<Person> { String _fullName = it.getFullName(); return _fullName; return friends.sortBy[fullName] } } }; return IterableExtensions.<Person, String> } sortBy(this.friends, _function);} } } Syntax, inherited from Xbase Xbase compiler output
    16. 16. JvmModel Inference MyLanguage JvmModel (serialized) package my.social.network;Embedding Xbase (imports) public class Person { expressions private String firstName; private String lastName; private List<Person> friends;into Java methods (getter, setter) gives them a public String getFullName() { String _plus = (this.firstName + " "); context! return (_plus + this.lastName); } public List<Person> getSortedFriends() { final Function1<Person,String> _function = new Function1<Person,String>() { public String apply(final Person it) { String _fullName = it.getFullName(); return _fullName; } }; return IterableExtensions.<Person, String> sortBy(this.friends, _function); } }
    17. 17. the last slide was really important, let us go back one more time.
    18. 18. JvmModel Inference MyLanguage JvmModel (serialized) package my.social.network;Embedding Xbase (imports) public class Person { expressions private String firstName; private String lastName; private List<Person> friends;into Java methods (getter, setter) gives them a public String getFullName() { String _plus = (this.firstName + " "); context! return (_plus + this.lastName); } public List<Person> getSortedFriends() { final Function1<Person,String> _function = new Function1<Person,String>() { public String apply(final Person it) { String _fullName = it.getFullName(); return _fullName; } }; return IterableExtensions.<Person, String> sortBy(this.friends, _function); } }
    19. 19. JvmModel Inference MyLanguage JvmModel (serialized) package my.social.network; (imports) public class Person { private String firstName; context! private String lastName; private List<Person> friends; (getter, setter) ...for linking public String getFullName() { String _plus = (this.firstName + " "); return (_plus + this.lastName); (as implemented by scoping) }•names of method parameters public List<Person> getSortedFriends() { final Function1<Person,String> _function =•names of member fields new Function1<Person,String>() { public String apply(final Person it) {•names of member methods String _fullName = it.getFullName(); return _fullName;•names of visible types }; } return IterableExtensions.<Person, String> sortBy(this.friends, _function); } }
    20. 20. JvmModel Inference MyLanguage JvmModel (serialized) package my.social.network; (imports) context! public class Person { private String firstName; private String lastName; private List<Person> friends; ...for the Type System (getter, setter) public String getFullName() { String _plus = (this.firstName + " "); return (_plus + this.lastName);• a method’s return type is the } expected type of an expression public List<Person> getSortedFriends() { final Function1<Person,String> _function =• fields, variables and parameters new Function1<Person,String>() { public String apply(final Person it) { String _fullName = it.getFullName(); have types return _fullName; }• generated java classes are }; return IterableExtensions.<Person, String> available as new types sortBy(this.friends, _function); } }
    21. 21. JvmModel Inference MyLanguage JvmModel (serialized) package my.social.network; (imports) public class Person { private String firstName; private String lastName; context! private List<Person> friends; (getter, setter) public String getFullName() { String _plus = (this.firstName + " "); ...for the Compiler } return (_plus + this.lastName); public List<Person> getSortedFriends() { final Function1<Person,String> _function =• actually, the serialized JvmModel new Function1<Person,String>() { public String apply(final Person it) { String _fullName = it.getFullName(); is the compiler output :) return _fullName; } }; return IterableExtensions.<Person, String> sortBy(this.friends, _function); } }
    22. 22. Real World Applications• Learning By Example: 7 Languages For The JVM - http://www.eclipse.org/Xtext/7languages.html • Build Language • DSL for Guice • Template Language • Scripting Language • DSL for MongoDB • HTTP routing language • Little Tortoise• Xtend - Java-like GPL that also supports functional programming and has powerful type inference • http://www.eclipse.org/xtend/• DESAGN - textually define 3D models of cutting tools (physical tools) • http://www.eclipsecon.org/europe2012/sessions/desagn-xtext-cutting-edge• openHAB - open Home Automation Bus - Program the behavior of your house! • http://code.google.com/p/openhab/• spray - Generate graphical Eclipse editors for the Graphiti framework • http://eclipselabs.org/p/spray/• Jnario - Executable Specifications for Java (Behavior Driven Development, BDD) • http://jnario.org

    ×