SlideShare a Scribd company logo
1 of 83
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 worldDebasish Ghosh
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional PatternsDebasish Ghosh
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingDebasish Ghosh
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalazoxbow_lakes
 
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 automationJSFestUA
 
Deriving Scalaz
Deriving ScalazDeriving Scalaz
Deriving Scalaznkpart
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basicsVu Tran Lam
 
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 ReviewMark 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 Gostrikr .
 
C sharp part 001
C sharp part 001C sharp part 001
C sharp part 001Ralph Weber
 
Writing DSL with Applicative Functors
Writing DSL with Applicative FunctorsWriting DSL with Applicative Functors
Writing DSL with Applicative FunctorsDavid 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 (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
 
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 210Mahmoud Samir Fayed
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java DevelopersYakov Fain
 
Example Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialExample Cosmos SDK Application Tutorial
Example Cosmos SDK Application TutorialJim 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 codePeter Lawrey
 
Introduction To Groovy 2005
Introduction To Groovy 2005Introduction To Groovy 2005
Introduction To Groovy 2005Tugdual Grall
 
AD215 - Practical Magic with DXL
AD215 - Practical Magic with DXLAD215 - Practical Magic with DXL
AD215 - Practical Magic with DXLStephan 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 languagesArthur Xavier
 
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 FrameworkDaniel Spector
 
Phoenix for Rails Devs
Phoenix for Rails DevsPhoenix for Rails Devs
Phoenix for Rails DevsDiacode
 
Generation_XSD_Article - Part 3.pdf
Generation_XSD_Article - Part 3.pdfGeneration_XSD_Article - Part 3.pdf
Generation_XSD_Article - Part 3.pdfDavid Harrison
 
On Scala Slides - OSDC 2009
On Scala Slides - OSDC 2009On Scala Slides - OSDC 2009
On Scala Slides - OSDC 2009Michael 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 WayDebasish 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 ModelsDebasish Ghosh
 
Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsDebasish 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 rulesDebasish 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 ageDebasish Ghosh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish 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

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 

Recently uploaded (20)

08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 

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.