SlideShare a Scribd company logo
Domain Specific Languages -   a  user  view and an  implementation  view does expressiveness imply a compromise on the underlying domain model ?
Debasish Ghosh @debasishg on twitter Code @  http://github.com/debasishg   Blog @  Ruminations of a Programmer http:// debasishg.blogspot.com
Open Source Footprints ,[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object]
View Or Syntax  new_trade  'T-12435'   for account  'acc-123'   to buy  100  shares of  'IBM' ,  at UnitPrice =  100 ,  Principal =  12000 , Tax =  500 DSL Model … Semantic model of the domain
view / syntax is derived from model
view / syntax is a veneer of abstraction over model
view / syntax is decoupled thru an interpreter from model
view / syntax can be multiple over the same model
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],idiomatic  Ruby  API
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],add  domain syntax
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],add  domain syntax
domain syntax idiomatic Ruby model interpreter isolation layer between the  model and the view of the DSL
[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object]
… … abstractions of  the core domain model layers of  abstractions
… … abstractions of  the core domain model abstractions that glue model elements layers of  abstractions combinators, façade objects,  bridges & adapters
… … abstractions of  the core domain model abstractions that glue model elements layers of  abstractions combinators, façade objects,  bridges & adapters d omain  s pecific  e mbedded  l anguage
… … abstractions of  the core domain model abstractions that glue model elements layers of  abstractions combinators, façade objects,  bridges & adapters d omain  s pecific  e mbedded  l anguage model view
layers of  abstractions .. ,[object Object],[object Object],[object Object]
withAccount(trade) {  account => { settle(trade using account.getClient .getStandingRules .filter(_.account == account) .first) andThen journalize } } DSL in  Scala  over a  Java  domain model
withAccount( trade ) {  account  => { settle (trade using account.getClient .getStandingRules .filter(_.account == account) .first) andThen journalize } } DSL in  Scala  over a  Java  domain model Java abstractions
withAccount ( trade ) {  account  => { settle (trade  using account.getClient .getStandingRules .filter(_.account == account) .first) andThen  journalize } } DSL in  Scala  over a  Java  domain model Java abstractions Wired through Scala control structures
[object Object]
Our domain – stocks, trades, bulls, bears .. ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Our domain – stocks, trades, bulls, bears .. ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
// The Trade model case class   Trade ( account:  Account ,  instrument:  Instrument ,  referenceNo:  String ,  market:  Market , unitPrice:  BigDecimal ,  quantity:  BigDecimal ,  tradeDate:  Date  =  Calendar .getInstance.getTime,  valueDate:  Option [ Date ] =  None ,  taxFees:  Option [ List [( TaxFeeId ,  BigDecimal )]] =  None ,  netAmount:  Option [ BigDecimal ] =  None )
// various tax/fees to be paid when u do a trade sealed trait   TaxFeeId case object   TradeTax   extends   TaxFeeId case object   Commission   extends   TaxFeeId case object   VAT   extends   TaxFeeId case object   Surcharge   extends   TaxFeeId
// computes value date of a trade val  valueDateProcessor:  Trade  =>  Trade  =  //.. impl // computes tax/fee of a trade val  taxFeeProcessor:  Trade  =>  Trade  =  //.. Impl // computes the net cash value of a trade val  netAmountProcessor:  Trade  =>  Trade  =  //.. impl
val  trades =  //.. list of security trades // get a list of value dates for all trades   val  valueDates = trades map (_.valueDate) // enrich a trade passing it thru multiple processors   val  richTrade = (valueDateProcessor map  taxFeeProcessor map  netAmountProcessor)  apply  trade  // pass a trade thru one specific processor val  t = some(trade) map valueDateProcessor
val trades = //.. list of security trades // get a list of value dates for all trades  val valueDates =   trades   map (_. valueDate ) // enrich a trade passing it thru multiple processors   val richTrade = ( valueDateProcessor   map   taxFeeProcessor   map   netAmountProcessor )  apply trade  // pass a trade thru one specific processor val t =   some( trade ) map   valueDateProcessor
val trades = //.. list of security trades // get a list of value dates for all trades  val valueDates = trades   map   (_.valueDate) // enrich a trade passing it thru multiple processors  val richTrade = (valueDateProcessor   map   taxFeeProcessor   map   netAmountProcessor) apply trade  // pass a trade thru one specific processor val t = some(trade)   map   valueDateProcessor
val  trades =  //.. list of security trades // map across the list functor val  valueDates = trades map (_.valueDate) // map across the Function1 functor   val  richTrade = (valueDateProcessor map  taxFeeProcessor map  netAmountProcessor) apply trade  // map across an Option functor val  t = some(trade) map valueDateProcessor
[object Object],[object Object]
[object Object],[object Object]
[object Object],[object Object]
sealed trait   MA [ M [_],  A ]  extends   PimpedType [ M [ A ]] { def  map[ B ](f:  A  =>  B )( implicit  t:  Functor [ M ]):  M [ B ] = t.fmap(value, f) source: scalaz :  https://github.com/scalaz/scalaz   a type class a pimp
trait  Functor[ F [ _ ]]  extends   InvariantFunctor [ F ] {    def  fmap[ A ,  B ](r:  F [ A ], f:  A  =>  B ):  F [ B ] } source: scalaz :  https://github.com/scalaz/scalaz
a  functor  is .. a type class for all things that can be mapped over
// map across the Function1 functor   val  richTrade = (valueDateProcessor map  taxFeeProcessor map  netAmountProcessor) apply trade   Function1[] implicit def Function1Functor[R] =  new Functor //..
the idea is to  generalize  abstractions .. .. and by generalizing  map  over functors we get a  combinator that can glue a large set of our domain abstractions .. and this gives a feeling of uniformity in the DSL syntax
semantic model + combinators = DSL
[object Object],[object Object],[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object]
so, a domain model also has to be .. designed for compositionality Image source: Mathematical art of M. C. Escher  ( http://im-possible.info/english/articles/escher_math/escher_math.html )
domain  rule .. ,[object Object],[object Object],[object Object],[object Object]
the  DSL  .. val  enrich =  for  { // get the tax/fee ids for a trade    taxFeeIds <- forTrade // calculate tax fee values    taxFeeValues <- taxFeeCalculate // enrich trade with net cash amount    netAmount <- enrichTradeWith } yield ((taxFeeIds map taxFeeValues) map netAmount) // enriching a trade trade map enrich should equal(…)
the  DSL  .. val enrich =  for { // get the tax/fee ids for a trade    taxFeeIds <-   forTrade // calculate tax fee values    taxFeeValues <-   taxFeeCalculate // enrich trade with net cash amount    netAmount <-   enrichTradeWith } yield((taxFeeIds map taxFeeValues) map netAmount) // enriching a trade trade   map enrich should equal(…) Model elements that can be composed using the for-comprehension
reiterating .. a  combinator  acts .. as a glue combining model elements But ..
there is a  prerequisite  .. model elements should be composable we call this the  compositionality  of the model
Q : How to design your model  so that it's  compositional  ? A : choose the right  abstractions  .. depending on the programming  paradigm  (FP, OO ..) and the implementation  language  used
domain  rule .. ,[object Object],[object Object],[object Object],[object Object]
the  DSL  .. // type alias for domain vocabulary type   NetAmount   =   BigDecimal type   CashValueCalculationStrategy   =   PartialFunction [ Market ,  Trade  =>  NetAmount ] // declarative business logic val   cashValueComputation :  Trade   =>   NetAmount  =  {   trade  =>     (forHongKong   orElse   forSingapore   orElse   forDefault)(trade.market)(trade) }
the  DSL  .. val   cashValue :  Trade   =>   CashValueCalculationStrategy  =>  NetAmount  =  {   trade  =>  pf  =>     if   (pf.isDefinedAt(trade.market))   pf(trade.market)(trade)     else   cashValueComputation(trade) }
[object Object],[object Object],[object Object],[object Object]
val  forHongKong:  CashValueCalculationStrategy  = {    case  HongKong => { trade => //.. } } val  forSingapore:  CashValueCalculationStrategy  = {    case  Singapore => { trade => //.. } } val  forDefault:  CashValueCalculationStrategy  = {    case  _ => { trade => //.. } }
[object Object],[object Object],[object Object],[object Object],[object Object]
choice of abstractions depends on the  programming language  chosen  for implementation of your DSL always keep an eye on the  paradigms  that your implementation language supports and play to the  idioms  of the language
domain  rule .. A trade needs to be enriched with a set of tax and fees before we calculate its net cash value
the  Java  way   .. // use the decorator pattern new  CommissionDecorator( new  TaxFeeDecorator(new Trade(..))); public class  Trade {  //.. public class  TaxFeeDecorator  extends  Trade { private  Trade trade; //.. } public class  CommissionDecorator  extends  Trade { private  Trade trade; //.. }
the  Java  way   .. ,[object Object],[object Object],[object Object]
the  Ruby  way   .. ## decorator pattern Trade . new (..).with  TaxFee ,  Commission class   Trade attr_accessor  .. def  initialize .. def  with(*args) args.inject(self) {|memo, val| memo. extend  val} end def value @principal end end
the  Ruby  way   .. ## mixins module   TaxFee ## calculate taxfee def   value super   + .. end end ## mixins module   Commission ## calculate commission def   value super   + .. end end
the  Ruby  way   .. ,[object Object],[object Object],[object Object]
if we were to do the same in  Clojure  .. ## decorator pattern (with-tax-fee trade (with-values :tax  12 ) (with-values :commission  23 )) ( defmacro  with-tax-fee &quot;wrap a function in one or more decorators&quot; [func & decorators] `(redef ~func (-> ~func ~@decorators)))
the  Clojure  way   .. ,[object Object],[object Object],[object Object]
[object Object],[object Object],[object Object],[object Object],[object Object]
if you thought DSLs grow through c omposition of abstractions  ..  .. then the final DSL is the  whole  formed from the composition of its  parts  ..
…  and if the final DSL is also an abstraction .. .. there's no reason we can compose it with  another abstraction  (aka another DSL) to form a  bigger whole  ..
trait   TradeDsl  { type   T  <:  Trade def  enrich:  PartialFunction [ T ,  T ] //.. other methods } constrained abstract type abstract method
trait   FixedIncomeTradeDsl   extends   TradeDsl  { type   T  =  FixedIncomeTrade import   FixedIncomeTradingService ._ override def  enrich:  PartialFunction [ T ,  T ] = { case  t => t.cashValue = cashValue(t) t.taxes = taxes(t) t.accruedInterest = accruedInterest(t) t } } object   FixedIncomeTradeDsl   extends   FixedIncomeTradeDsl concrete type for fixed income trade concrete definition for enrichment of  fixed income trade
trait   EquityTradeDsl   extends   TradeDsl  { type   T  =  EquityTrade import   EquityTradingService ._ override def  enrich:  PartialFunction [ T ,  T ] = { case  t => t.cashValue = cashValue(t) t.taxes = taxes(t) t } } object   EquityTradeDsl   extends   EquityTradeDsl concrete type for equity trade concrete definition for enrichment of  equity trade
.. and now a new market rule comes up that needs to be applied to  all  types of trades .. you  don’t want to affect the core logic , since the rule is a temporary and promotional one and is likely to be discontinued after a few days ..
.. design the DSL for the new rule in such a way that you can  plug in  the semantics of  all types of trade  within it ..
and now the rule itself .. “ Any trade on the New York Stock Exchange of principal value > 10,000 USD must have a discount of 10% of the principal on the net cash value.”
trait   MarketRuleDsl   extends   TradeDsl  { val  semantics:  TradeDsl type   T  = semantics. T override def  enrich:  PartialFunction [ T ,  T ] = { case  t => val  tr = semantics.enrich(t) tr  match  { case  x  if  x.market ==  NYSE  &&  x.principal >  1000  => tr.cashValue = tr.cashValue - tr.principal *  0.1 tr case  x => x } } }
trait MarketRuleDsl extends TradeDsl { val   semantics :  TradeDsl type T = semantics.T override def enrich: PartialFunction[T, T] = { case t => val tr = semantics.enrich(t) tr  match  { case  x  if  x.market ==  NYSE  &&  x.principal >  1000  => tr.cashValue = tr.cashValue - tr.principal *  0.1 tr case  x => x } } } polymorphic  embedding new business rule that acts on top of the enriched trade
object  EquityTradeMarketRuleDsl  extends   MarketRuleDsl  { val  semantics = EquityTradeDsl } object  FixedIncomeTradeMarketRuleDsl  extends   MarketRuleDsl  { val  semantics = FixedIncomeTradeDsl } pluggable composition  of DSLs plug-in the concrete semantics
import  FixedIncomeTradeMarketRuleDsl._ withTrade( 200  discount_bonds  IBM for_client  NOMURA on NYSE at  72 .ccy( USD )) {trade => Mailer(user) mail trade Logger log trade } cashValue a sneak peek at the  fully composed  DSL ..
Summary ,[object Object],[object Object],[object Object],[object Object]
 

More Related Content

What's hot

Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
Debasish Ghosh
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
Debasish Ghosh
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
Debasish Ghosh
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalaz
oxbow_lakes
 
Scalaz
ScalazScalaz
Scalaz
mpilquist
 
Les03
Les03Les03
Les03
Sudharsan S
 
Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...
Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...
Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...
Codemotion
 
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automationJS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JSFestUA
 
Deriving Scalaz
Deriving ScalazDeriving Scalaz
Deriving Scalaz
nkpart
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basicsVu Tran Lam
 
Composite Pattern
Composite PatternComposite Pattern
Composite Pattern
Somenath Mukhopadhyay
 
Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)Vu Tran Lam
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The WildStackMob Inc
 
Mercury: A Functional Review
Mercury: A Functional ReviewMercury: A Functional Review
Mercury: A Functional Review
Mark Cheeseman
 
Introduction to C#
Introduction to C#Introduction to C#
Introduction to C#
ANURAG SINGH
 
Reflection in Go
Reflection in GoReflection in Go
Reflection in Go
strikr .
 
C sharp part 001
C sharp part 001C sharp part 001
C sharp part 001
Ralph Weber
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative Functors
David Galichet
 

What's hot (19)

Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalaz
 
Scalaz
ScalazScalaz
Scalaz
 
Les03
Les03Les03
Les03
 
Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...
Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...
Mauricio Palma - You can’t read this sentence - A11y automation - Codemotion ...
 
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automationJS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
 
Deriving Scalaz
Deriving ScalazDeriving Scalaz
Deriving Scalaz
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basics
 
Composite Pattern
Composite PatternComposite Pattern
Composite Pattern
 
Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)
 
Monad Transformers In The Wild
Monad Transformers In The WildMonad Transformers In The Wild
Monad Transformers In The Wild
 
Mercury: A Functional Review
Mercury: A Functional ReviewMercury: A Functional Review
Mercury: A Functional Review
 
Introduction to C#
Introduction to C#Introduction to C#
Introduction to C#
 
Reflection in Go
Reflection in GoReflection in Go
Reflection in Go
 
C sharp part 001
C sharp part 001C sharp part 001
C sharp part 001
 
Les03
Les03Les03
Les03
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative Functors
 

Viewers also liked

Simplicity 2.0 - Get the power back
Simplicity 2.0 - Get the power backSimplicity 2.0 - Get the power back
Simplicity 2.0 - Get the power back
Rui Carvalho
 
Pimp my gc - Supersonic Scala
Pimp my gc - Supersonic ScalaPimp my gc - Supersonic Scala
Pimp my gc - Supersonic Scala
Pierre Laporte
 
X bar
X barX bar
1.5 form 4 c_center of mass
1.5 form 4 c_center of mass1.5 form 4 c_center of mass
1.5 form 4 c_center of mass
chris lembalemba
 
Syntax - Why so CareMad?
Syntax - Why so CareMad?Syntax - Why so CareMad?
Syntax - Why so CareMad?
Mahesh Paolini-Subramanya
 
X bar theory
X bar theoryX bar theory
X bar theory
Adel Rahimi
 
ENGLISH SYNTAX
ENGLISH SYNTAXENGLISH SYNTAX
ENGLISH SYNTAX
Videoconferencias UTPL
 
Syntax (Part 1)
Syntax (Part 1)Syntax (Part 1)
Syntax (Part 1)zouhirgabsi
 
Adv&adj Phrase
Adv&adj PhraseAdv&adj Phrase
Adv&adj PhraseUt Tram Tran
 
Tree diagram
Tree diagramTree diagram
Tree diagram
Asif Ali Raza
 

Viewers also liked (11)

Simplicity 2.0 - Get the power back
Simplicity 2.0 - Get the power backSimplicity 2.0 - Get the power back
Simplicity 2.0 - Get the power back
 
Pimp my gc - Supersonic Scala
Pimp my gc - Supersonic ScalaPimp my gc - Supersonic Scala
Pimp my gc - Supersonic Scala
 
X bar
X barX bar
X bar
 
1.5 form 4 c_center of mass
1.5 form 4 c_center of mass1.5 form 4 c_center of mass
1.5 form 4 c_center of mass
 
Syntax - Why so CareMad?
Syntax - Why so CareMad?Syntax - Why so CareMad?
Syntax - Why so CareMad?
 
X bar theory
X bar theoryX bar theory
X bar theory
 
ENGLISH SYNTAX
ENGLISH SYNTAXENGLISH SYNTAX
ENGLISH SYNTAX
 
Syntax (Part 1)
Syntax (Part 1)Syntax (Part 1)
Syntax (Part 1)
 
Adv&adj Phrase
Adv&adj PhraseAdv&adj Phrase
Adv&adj Phrase
 
Syntax
SyntaxSyntax
Syntax
 
Tree diagram
Tree diagramTree diagram
Tree diagram
 

Similar to DSL - expressive syntax on top of a clean semantic model

Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
Andreas Dewes
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amfrailsconf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
Tony Hillerson
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
JAXLondon_Conference
 
The Ring programming language version 1.9 book - Part 95 of 210
The Ring programming language version 1.9 book - Part 95 of 210The Ring programming language version 1.9 book - Part 95 of 210
The Ring programming language version 1.9 book - Part 95 of 210
Mahmoud Samir Fayed
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
Yakov Fain
 
Example Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialExample Cosmos SDK Application Tutorial
Example Cosmos SDK Application Tutorial
Jim Yang
 
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
InfluxData
 
Legacy lambda code
Legacy lambda codeLegacy lambda code
Legacy lambda code
Peter Lawrey
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
Tugdual Grall
 
AD215 - Practical Magic with DXL
AD215 - Practical Magic with DXLAD215 - Practical Magic with DXL
AD215 - Practical Magic with DXL
Stephan H. Wissel
 
Advisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScriptAdvisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScriptdominion
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
Arthur Xavier
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack MiddlewareLittleBIGRuby
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
Daniel Spector
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
Diacode
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
Sasha Goldshtein
 
Generation_XSD_Article - Part 3.pdf
Generation_XSD_Article - Part 3.pdfGeneration_XSD_Article - Part 3.pdf
Generation_XSD_Article - Part 3.pdf
David Harrison
 
DSL in scala
DSL in scalaDSL in scala
DSL in scala
Xuân Thu Nguyễn
 
On Scala Slides - OSDC 2009
On Scala Slides - OSDC 2009On Scala Slides - OSDC 2009
On Scala Slides - OSDC 2009
Michael Neale
 

Similar to DSL - expressive syntax on top of a clean semantic model (20)

Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...Code is not text! How graph technologies can help us to understand our code b...
Code is not text! How graph technologies can help us to understand our code b...
 
Integrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby AmfIntegrating Flex And Rails With Ruby Amf
Integrating Flex And Rails With Ruby Amf
 
Flex With Rubyamf
Flex With RubyamfFlex With Rubyamf
Flex With Rubyamf
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
The Ring programming language version 1.9 book - Part 95 of 210
The Ring programming language version 1.9 book - Part 95 of 210The Ring programming language version 1.9 book - Part 95 of 210
The Ring programming language version 1.9 book - Part 95 of 210
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
Example Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialExample Cosmos SDK Application Tutorial
Example Cosmos SDK Application Tutorial
 
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
Anais Dotis-Georgiou & Faith Chikwekwe [InfluxData] | Top 10 Hurdles for Flux...
 
Legacy lambda code
Legacy lambda codeLegacy lambda code
Legacy lambda code
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005
 
AD215 - Practical Magic with DXL
AD215 - Practical Magic with DXLAD215 - Practical Magic with DXL
AD215 - Practical Magic with DXL
 
Advisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScriptAdvisor Jumpstart: JavaScript
Advisor Jumpstart: JavaScript
 
Type safe embedded domain-specific languages
Type safe embedded domain-specific languagesType safe embedded domain-specific languages
Type safe embedded domain-specific languages
 
Rack Middleware
Rack MiddlewareRack Middleware
Rack Middleware
 
Crossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end FrameworkCrossing the Bridge: Connecting Rails and your Front-end Framework
Crossing the Bridge: Connecting Rails and your Front-end Framework
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails Devs
 
The Style of C++ 11
The Style of C++ 11The Style of C++ 11
The Style of C++ 11
 
Generation_XSD_Article - Part 3.pdf
Generation_XSD_Article - Part 3.pdfGeneration_XSD_Article - Part 3.pdf
Generation_XSD_Article - Part 3.pdf
 
DSL in scala
DSL in scalaDSL in scala
DSL in scala
 
On Scala Slides - OSDC 2009
On Scala Slides - OSDC 2009On Scala Slides - OSDC 2009
On Scala Slides - OSDC 2009
 

More from Debasish Ghosh

Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
Debasish Ghosh
 
Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming Applications
Debasish Ghosh
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
Debasish Ghosh
 
Big Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageBig Data - architectural concerns for the new age
Big Data - architectural concerns for the new age
Debasish Ghosh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
Debasish Ghosh
 

More from Debasish Ghosh (6)

Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
 
Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming Applications
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
 
Big Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageBig Data - architectural concerns for the new age
Big Data - architectural concerns for the new age
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 

Recently uploaded

Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 

Recently uploaded (20)

Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 

DSL - expressive syntax on top of a clean semantic model

  • 1. Domain Specific Languages - a user view and an implementation view does expressiveness imply a compromise on the underlying domain model ?
  • 2. Debasish Ghosh @debasishg on twitter Code @ http://github.com/debasishg Blog @ Ruminations of a Programmer http:// debasishg.blogspot.com
  • 3.
  • 4.
  • 5.
  • 6. View Or Syntax new_trade 'T-12435' for account 'acc-123' to buy 100 shares of 'IBM' , at UnitPrice = 100 , Principal = 12000 , Tax = 500 DSL Model … Semantic model of the domain
  • 7. view / syntax is derived from model
  • 8. view / syntax is a veneer of abstraction over model
  • 9. view / syntax is decoupled thru an interpreter from model
  • 10. view / syntax can be multiple over the same model
  • 11.
  • 12.
  • 13.
  • 14. domain syntax idiomatic Ruby model interpreter isolation layer between the model and the view of the DSL
  • 15.
  • 16.
  • 17.
  • 18. … … abstractions of the core domain model layers of abstractions
  • 19. … … abstractions of the core domain model abstractions that glue model elements layers of abstractions combinators, façade objects, bridges & adapters
  • 20. … … abstractions of the core domain model abstractions that glue model elements layers of abstractions combinators, façade objects, bridges & adapters d omain s pecific e mbedded l anguage
  • 21. … … abstractions of the core domain model abstractions that glue model elements layers of abstractions combinators, façade objects, bridges & adapters d omain s pecific e mbedded l anguage model view
  • 22.
  • 23. withAccount(trade) { account => { settle(trade using account.getClient .getStandingRules .filter(_.account == account) .first) andThen journalize } } DSL in Scala over a Java domain model
  • 24. withAccount( trade ) { account => { settle (trade using account.getClient .getStandingRules .filter(_.account == account) .first) andThen journalize } } DSL in Scala over a Java domain model Java abstractions
  • 25. withAccount ( trade ) { account => { settle (trade using account.getClient .getStandingRules .filter(_.account == account) .first) andThen journalize } } DSL in Scala over a Java domain model Java abstractions Wired through Scala control structures
  • 26.
  • 27.
  • 28.
  • 29. // The Trade model case class Trade ( account: Account , instrument: Instrument , referenceNo: String , market: Market , unitPrice: BigDecimal , quantity: BigDecimal , tradeDate: Date = Calendar .getInstance.getTime, valueDate: Option [ Date ] = None , taxFees: Option [ List [( TaxFeeId , BigDecimal )]] = None , netAmount: Option [ BigDecimal ] = None )
  • 30. // various tax/fees to be paid when u do a trade sealed trait TaxFeeId case object TradeTax extends TaxFeeId case object Commission extends TaxFeeId case object VAT extends TaxFeeId case object Surcharge extends TaxFeeId
  • 31. // computes value date of a trade val valueDateProcessor: Trade => Trade = //.. impl // computes tax/fee of a trade val taxFeeProcessor: Trade => Trade = //.. Impl // computes the net cash value of a trade val netAmountProcessor: Trade => Trade = //.. impl
  • 32. val trades = //.. list of security trades // get a list of value dates for all trades val valueDates = trades map (_.valueDate) // enrich a trade passing it thru multiple processors val richTrade = (valueDateProcessor map taxFeeProcessor map netAmountProcessor) apply trade // pass a trade thru one specific processor val t = some(trade) map valueDateProcessor
  • 33. val trades = //.. list of security trades // get a list of value dates for all trades val valueDates = trades map (_. valueDate ) // enrich a trade passing it thru multiple processors val richTrade = ( valueDateProcessor map taxFeeProcessor map netAmountProcessor ) apply trade // pass a trade thru one specific processor val t = some( trade ) map valueDateProcessor
  • 34. val trades = //.. list of security trades // get a list of value dates for all trades val valueDates = trades map (_.valueDate) // enrich a trade passing it thru multiple processors val richTrade = (valueDateProcessor map taxFeeProcessor map netAmountProcessor) apply trade // pass a trade thru one specific processor val t = some(trade) map valueDateProcessor
  • 35. val trades = //.. list of security trades // map across the list functor val valueDates = trades map (_.valueDate) // map across the Function1 functor val richTrade = (valueDateProcessor map taxFeeProcessor map netAmountProcessor) apply trade // map across an Option functor val t = some(trade) map valueDateProcessor
  • 36.
  • 37.
  • 38.
  • 39. sealed trait MA [ M [_], A ] extends PimpedType [ M [ A ]] { def map[ B ](f: A => B )( implicit t: Functor [ M ]): M [ B ] = t.fmap(value, f) source: scalaz : https://github.com/scalaz/scalaz a type class a pimp
  • 40. trait Functor[ F [ _ ]] extends InvariantFunctor [ F ] {    def fmap[ A , B ](r: F [ A ], f: A => B ): F [ B ] } source: scalaz : https://github.com/scalaz/scalaz
  • 41. a functor is .. a type class for all things that can be mapped over
  • 42. // map across the Function1 functor val richTrade = (valueDateProcessor map taxFeeProcessor map netAmountProcessor) apply trade Function1[] implicit def Function1Functor[R] = new Functor //..
  • 43. the idea is to generalize abstractions .. .. and by generalizing map over functors we get a combinator that can glue a large set of our domain abstractions .. and this gives a feeling of uniformity in the DSL syntax
  • 44. semantic model + combinators = DSL
  • 45.
  • 46.
  • 47. so, a domain model also has to be .. designed for compositionality Image source: Mathematical art of M. C. Escher ( http://im-possible.info/english/articles/escher_math/escher_math.html )
  • 48.
  • 49. the DSL .. val enrich = for { // get the tax/fee ids for a trade    taxFeeIds <- forTrade // calculate tax fee values    taxFeeValues <- taxFeeCalculate // enrich trade with net cash amount    netAmount <- enrichTradeWith } yield ((taxFeeIds map taxFeeValues) map netAmount) // enriching a trade trade map enrich should equal(…)
  • 50. the DSL .. val enrich = for { // get the tax/fee ids for a trade    taxFeeIds <- forTrade // calculate tax fee values    taxFeeValues <- taxFeeCalculate // enrich trade with net cash amount    netAmount <- enrichTradeWith } yield((taxFeeIds map taxFeeValues) map netAmount) // enriching a trade trade map enrich should equal(…) Model elements that can be composed using the for-comprehension
  • 51. reiterating .. a combinator acts .. as a glue combining model elements But ..
  • 52. there is a prerequisite .. model elements should be composable we call this the compositionality of the model
  • 53. Q : How to design your model so that it's compositional ? A : choose the right abstractions .. depending on the programming paradigm (FP, OO ..) and the implementation language used
  • 54.
  • 55. the DSL .. // type alias for domain vocabulary type NetAmount = BigDecimal type CashValueCalculationStrategy = PartialFunction [ Market , Trade => NetAmount ] // declarative business logic val cashValueComputation : Trade => NetAmount = { trade =>    (forHongKong orElse forSingapore orElse forDefault)(trade.market)(trade) }
  • 56. the DSL .. val cashValue : Trade => CashValueCalculationStrategy => NetAmount = { trade => pf =>    if (pf.isDefinedAt(trade.market)) pf(trade.market)(trade)    else cashValueComputation(trade) }
  • 57.
  • 58. val forHongKong: CashValueCalculationStrategy = {    case HongKong => { trade => //.. } } val forSingapore: CashValueCalculationStrategy = {    case Singapore => { trade => //.. } } val forDefault: CashValueCalculationStrategy = {    case _ => { trade => //.. } }
  • 59.
  • 60. choice of abstractions depends on the programming language chosen for implementation of your DSL always keep an eye on the paradigms that your implementation language supports and play to the idioms of the language
  • 61. domain rule .. A trade needs to be enriched with a set of tax and fees before we calculate its net cash value
  • 62. the Java way .. // use the decorator pattern new CommissionDecorator( new TaxFeeDecorator(new Trade(..))); public class Trade { //.. public class TaxFeeDecorator extends Trade { private Trade trade; //.. } public class CommissionDecorator extends Trade { private Trade trade; //.. }
  • 63.
  • 64. the Ruby way .. ## decorator pattern Trade . new (..).with TaxFee , Commission class Trade attr_accessor .. def initialize .. def with(*args) args.inject(self) {|memo, val| memo. extend val} end def value @principal end end
  • 65. the Ruby way .. ## mixins module TaxFee ## calculate taxfee def value super + .. end end ## mixins module Commission ## calculate commission def value super + .. end end
  • 66.
  • 67. if we were to do the same in Clojure .. ## decorator pattern (with-tax-fee trade (with-values :tax 12 ) (with-values :commission 23 )) ( defmacro with-tax-fee &quot;wrap a function in one or more decorators&quot; [func & decorators] `(redef ~func (-> ~func ~@decorators)))
  • 68.
  • 69.
  • 70. if you thought DSLs grow through c omposition of abstractions .. .. then the final DSL is the whole formed from the composition of its parts ..
  • 71. … and if the final DSL is also an abstraction .. .. there's no reason we can compose it with another abstraction (aka another DSL) to form a bigger whole ..
  • 72. trait TradeDsl { type T <: Trade def enrich: PartialFunction [ T , T ] //.. other methods } constrained abstract type abstract method
  • 73. trait FixedIncomeTradeDsl extends TradeDsl { type T = FixedIncomeTrade import FixedIncomeTradingService ._ override def enrich: PartialFunction [ T , T ] = { case t => t.cashValue = cashValue(t) t.taxes = taxes(t) t.accruedInterest = accruedInterest(t) t } } object FixedIncomeTradeDsl extends FixedIncomeTradeDsl concrete type for fixed income trade concrete definition for enrichment of fixed income trade
  • 74. trait EquityTradeDsl extends TradeDsl { type T = EquityTrade import EquityTradingService ._ override def enrich: PartialFunction [ T , T ] = { case t => t.cashValue = cashValue(t) t.taxes = taxes(t) t } } object EquityTradeDsl extends EquityTradeDsl concrete type for equity trade concrete definition for enrichment of equity trade
  • 75. .. and now a new market rule comes up that needs to be applied to all types of trades .. you don’t want to affect the core logic , since the rule is a temporary and promotional one and is likely to be discontinued after a few days ..
  • 76. .. design the DSL for the new rule in such a way that you can plug in the semantics of all types of trade within it ..
  • 77. and now the rule itself .. “ Any trade on the New York Stock Exchange of principal value > 10,000 USD must have a discount of 10% of the principal on the net cash value.”
  • 78. trait MarketRuleDsl extends TradeDsl { val semantics: TradeDsl type T = semantics. T override def enrich: PartialFunction [ T , T ] = { case t => val tr = semantics.enrich(t) tr match { case x if x.market == NYSE && x.principal > 1000 => tr.cashValue = tr.cashValue - tr.principal * 0.1 tr case x => x } } }
  • 79. trait MarketRuleDsl extends TradeDsl { val semantics : TradeDsl type T = semantics.T override def enrich: PartialFunction[T, T] = { case t => val tr = semantics.enrich(t) tr match { case x if x.market == NYSE && x.principal > 1000 => tr.cashValue = tr.cashValue - tr.principal * 0.1 tr case x => x } } } polymorphic embedding new business rule that acts on top of the enriched trade
  • 80. object EquityTradeMarketRuleDsl extends MarketRuleDsl { val semantics = EquityTradeDsl } object FixedIncomeTradeMarketRuleDsl extends MarketRuleDsl { val semantics = FixedIncomeTradeDsl } pluggable composition of DSLs plug-in the concrete semantics
  • 81. import FixedIncomeTradeMarketRuleDsl._ withTrade( 200 discount_bonds IBM for_client NOMURA on NYSE at 72 .ccy( USD )) {trade => Mailer(user) mail trade Logger log trade } cashValue a sneak peek at the fully composed DSL ..
  • 82.
  • 83. Â