Week 8: Building internal DSMLs
Goals for today
Today we will look beyond building standalone external DSMLs
Copyright By PowCoder代写 加微信 powcoder
– How can we quickly build a DSML with the tools available “on board” an existing GPL? – What are the benefits / drawbacks of doing so?
– When do we need external DSMLs? When do we not need them?
06/03/2020 (c) King’s College London 2
DSMLs on a spectrum
Domain-Specific Languages and Language Oriented Programming
Programming is theory-building1
– We build and layer abstractions to handle the complexity of a domain – May turn into libraries and frameworks
– May later turn into DSMLs
– A set of abstractions for describing a particular concern in a system is a language! – Should consider it as such
– Where does a library end and a DSML begin?
1Naur, P. (1986). Programming as Theory Building. Microprocessing and Microprogramming, 15, 253–261. 06/03/2020 (c) King’s College London 4
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315…………………… x10301MRP220050329………………………… x50214..7050329………………………….
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
06/03/2020 (c) King’s College London 5
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315…………………… x10301MRP220050329………………………… x50214..7050329………………………….
Type of record
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
06/03/2020 (c) King’s College London 5
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCL USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315…………………… x10301MRP220050329………………………… x50214..7050329………………………….
Customer Name
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
06/03/2020 (c) King’s College London 5
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315…………………… x10301MRP220050329………………………… x50214..7050329………………………….
ReaderStrategy
typeCode: String targetClass: Class
FieldExtractor
begin: int
end: int propertyName: String
06/03/2020
(c) King’s College London 5
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
An example (kudos to )
public void Configure(Reader target) {
target.AddStrategy(ConfigureUsage()); S0120050313…………………….
} X0320050315……………………
RP220050329………………………… private ReaderStrategy ConfigureServiceCall() {
.7050329………………………….
ReaderStrategy result = new ReaderStrategy(“SVCL”, typeof (ServiceCall));
result.AddFieldExtractor(4, 18, “CustomerName”); result.AddFieldExtractor(19, 23, “CustomerID”); result.AddFieldExtractor(24, 27, “CallTypeCode”); result.AddFieldExtractor(28, 35, “DateOfCallString”); return result;
private ReaderStrategy ConfigureUsage() {
ReaderStrategy result = new ReaderStrategy(“USGE”, typeof (Usage)); result.AddFieldExtractor(4, 8, “CustomerID”); result.AddFieldExtractor(9, 22, “CustomerName”); result.AddFieldExtractor(30, 30, “Cycle”); result.AddFieldExtractor(31, 36, “ReadDate”);
return result;
#123456789012345678901234
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10201D x10301M x50214.
ReaderStrategy
typeCode: String targetClass: Class
FieldExtractor
begin: int
end: int propertyName: String
06/03/2020
(c) King’s College London 5
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
An example (kudos to )
public void Configure(Reader target) {
target.AddStrategy(ConfigureUsage()); S0120050313…………………….
} X0320050315……………………
RP220050329………………………… private ReaderStrategy ConfigureServiceCall() {
.7050329………………………….
ReaderStrategy result = new ReaderStrategy(“SVCL”, typeof (ServiceCall));
result.AddFieldExtractor(4, 18, “CustomerName”); result.AddFieldExtractor(19, 23, “CustomerID”); result.AddFieldExtractor(24, 27, “CallTypeCode”); result.AddFieldExtractor(28, 35, “DateOfCallString”); return result;
private ReaderStrategy ConfigureUsage() {
ReaderStrategy result = new ReaderStrategy(“USGE”, typeof (Usage)); result.AddFieldExtractor(4, 8, “CustomerID”); result.AddFieldExtractor(9, 22, “CustomerName”); result.AddFieldExtractor(30, 30, “Cycle”); result.AddFieldExtractor(31, 36, “ReadDate”);
return result;
#123456789012345678901234
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10201D x10301M x50214.
ReaderStrategy
typeCode: String targetClass: Class
FieldExtractor
begin: int
end: int propertyName: String
06/03/2020
(c) King’s College London 5
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315……………………
x50214..7050329………………………….
ReaderStrategy
typeCode: String targetClass: Class
FieldExtractor
begin: int
end: int propertyName: String
06/03/2020
(c) King’s College London 5
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315…………………… x10301MRP220050329………………………… x50214..7050329………………………….
mapping SVCL dsl.ServiceCall 4-18: CustomerName
19-23: CustomerID
24-27: CallTypeCode 28-35: DateOfCallString
mapping USGE dsl.Usage
4-8: CustomerID
9-22: CustomerName
30-30: Cycle
31-36: ReadDate
ReaderStrategy
typeCode: String targetClass: Class
FieldExtractor
begin: int
end: int propertyName: String
06/03/2020
(c) King’s College London 5
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
An example (kudos to )
#123456789012345678901234567890123456789012345678901234567890
SVCLFOWLER SVCLHOHPE SVCLTWO USGE10301TWO
10101MS0120050313…………………….
10201DX0320050315……………………
x10301MRP220050329………………………… mapping(‘SVCL’, ServiceCall) do
x50214..7050329…………………………. extract 4..18, ‘customer_name’
extract 19..23, ‘customer_ID’ extract 24..27, ‘call_type_code’ extract 28..35, ‘date_of_call_string’
mapping(‘USGE’, Usage) do
extract 9..22, ‘customer_name’ extract 4..8, ‘customer_ID’ extract 30..30, ‘cycle’ extract 31..36, ‘read_date’
ReaderStrategy
typeCode: String targetClass: Class
FieldExtractor
begin: int
end: int propertyName: String
06/03/2020
(c) King’s College London 5
Fowler, M. (2005). Language Workbenches : The Killer-App for Domain Specific Languages? Retrieved November 1, 2018, from http://www.martinfowler.com/articles/languageWorkbench.html
A language spectrum
Named things (variables, …)
Libraries (reuse by instantiation)
Encapsulation (functions, classes)
Frameworks (reuse by configuration)
Generic Language Domain-Specific Language
06/03/2020 (c) King’s College London 6
Internal DSMLs (Framework/Library with concrete syntax)
External DSMLs (Separate from host language)
An example
In your pairs
– Pull the maze game example repository from KEATS and explore it – Check out the Main class
– What does it do?
– Is it correct?
– How easy is it to understand?
– How easy would it be to extend?
– Prepare for a plenary discussion You have 10 minutes
06/03/2020 (c) King’s College London 8
The Builder design pattern
06/03/2020 (c) King’s College London 10
The Builder design pattern
Builder is useful for incrementally constructing complex objects
– Maintains state of currently constructed object
– Different buildPart() calls incrementally add to the constructed object – Final getResult() call obtains the final object
– Means we can encode logic of construction in builder
– Various buildPart() methods form ‘language’ of what can be said about the target object
06/03/2020 (c) King’s College London 11
In your pairs
– Create a MazeBuilder class and define methods that allow incremental creation of maze games – Make a copy of the Main class in your own project
– Change it to use your MazeBuilder to construct the same maze
– Can you make sure some constraints are enforced? You have 10 minutes
06/03/2020 (c) King’s College London 12
Fluent interfaces
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
06/03/2020 (c) King’s College London 15
Fluent interfaces
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
private ObjectToBuild product;
public MyBuilder withColour(Colour c) { product.colour = c;
return this;
public ObjectToBuild produce() {
return product;
createObject().withColour(Colour.BLACK) .produce();
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
06/03/2020 (c) King’s College London 15
Fluent interfaces
Static method serves as starting point.
Can be used directly based on statically importing MyBuilder.
class MyBuilder {
return new MyBuilder();
private ObjectToBuild product;
public MyBuilder withColour(Colour c) { product.colour = c;
return this;
public ObjectToBuild produce() {
return product;
createObject().withColour(Colour.BLACK) .produce();
public static MyBuilder createObject()
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
06/03/2020 (c) King’s College London 15
Fluent interfaces
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
public MyBuilder withColour(Colour c) { product.colour = c;
return this;
public ObjectToBuild produce() {
return product;
createObject().withColour(Colour.BLACK) .produce();
private ObjectToBuild product;
Builder is already a language
– But not a very good one
– Code is cumbersome to write and readKeep a reference
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
to the object we are constructing.
06/03/2020 (c) King’s College London
Fluent interfaces
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
private ObjectToBuild product;
product.colour = c;
return this; }
public ObjectToBuild produce() {
return product;
createObject().withColour(Colour.BLACK) .produce();
06/03/2020 (c) King’s College London
Method names chosen to make chained invocations read more naturally.
public MyBuilder withColour(Colour c) {
Fluent interfaces
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
private ObjectToBuild product;
Always return the builder so that method calls can be chained.
public MyBuilder withColour(Colour c) {
product.colour = c;
return this;
public ObjectToBuild produce() {
return product;
createObject().withColour(Colour.BLACK) .produce();
06/03/2020 (c) King’s College London 15
Fluent interfaces
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
private ObjectToBuild product;
object to be extracted.
public MyBuilder withColour(Colour c) {
product.colour = c;
Finally, enable constructed
return this;
public ObjectToBuild produce() {
return product;
… createObject().withColour(Colour.BLACK)
.produce();
06/03/2020 (c) King’s College London 15
Fluent interfaces
Builder is already a language
– But not a very good one
– Code is cumbersome to write and read
Fluent interfaces to the rescue
– A builder where
– There is a static start method
– Can be called directly using a static import
– Each method returns the builder itself
– Allowing method chaining
– Methods are named so as to make the code
read as if it was its own language
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
private ObjectToBuild product;
public MyBuilder withColour(Colour c) { product.colour = c;
return this;
public ObjectToBuild produce() {
return product;
Method chaining and method naming
combine for readability of code.
createObject().withColour(Colour.BLACK) .produce();
06/03/2020 (c) King’s College London 15
In your pairs
– Improve your MazeBuilder class by using fluent interfaces – Change your Main class to use your fluent language
You have 10 minutes
Download last step as tag maze_game_builder from the MazeGame repository linked from KEATS
06/03/2020 (c) King’s College London 16
Validation in internal DSMLs
Where have we got to?
Can cover syntax and semantics
– Syntax provided by available fluent operations and their signatures – Within bounds of host language
– Semantics provided by implementation of those operations
– Translational semantics: generates a new object from its “specification”
What about model validity?
– Static checks?
– Using the host-language compiler
– Dynamic checks?
– Throwing exceptions for invalid constructions
06/03/2020 (c) King’s College London 19
Compiler-based validation in internal DSMLs
Host-language compiler only sees standard classes and objects
– Can only check based on host-language rules
– Need to use rules to encode constraints of DSML
– Define internal scopes
– Separate builder classes used in specific contexts
– By returning a sub-builder from a builder method – Can lead to complex and long method chains
– By passing a sub-builder to a closure provided as a parameter
– Nice nesting
– Syntax can become cluttered (Java, but see Ruby for a good example)
– By asking for a complex object / a builder as a parameter – Allows to break method chains
06/03/2020 (c) King’s College London 20
Compiler-based validation: returning sub-builders
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
private ObjectToBuild product;
public SubBuilder withSubObject() {
return new SubBuilder();
public SubBuilder withColour(Color c) { subObject.color = c;
return this;
public MyBuilder end() {
return MyBuilder.this;
public class SubBuilder { private SubObject subObject;
public SubBuilder() {
subObject = new SubObject(); product.subObjects.add(subObject);
createObject().withSubObject() .withColour(Colour.BLACK)
.produce();
06/03/2020 (c) King’s College London 21
Compiler-based validation: returning sub-builders
class MyBuilder {
public static MyBuilder createObject() {
return new MyBuilder();
public SubBuilder withColour(Color c) { subObject.color = c;
return this;
public MyBuilder end() {
return MyBuilder.this;
private ObjectToBuild product;
Return a sub-builder. From here on, only the terms defined in the sub-builder’s language are available.
public SubBuilder withSubObject()
return new SubBuilder(); }}
public class SubBuilder { private SubObject subObject;
public SubBuilder() {
subObject = new SubObject(); product.subObjects.add(subObject);
createObject().withSubObject() .withColour(Colour.BLACK)
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com