Creating Domain Specific Languages in F#
-
Upload
tomas-petricek -
Category
Documents
-
view
3.157 -
download
0
description
Transcript of Creating Domain Specific Languages in F#
Creating Domain Specific
Languages in F#
PhD student @ University of Cambridge
[email protected] Tomas Petricek @tomaspetricek Conspirator behind http://fsharp.org
Real World Functional Programming tutorials F# and C#monads functional concepts practical examples
F# Deep Divesindustry experts .domain modeling financial & insurance web & data
actor model concurrency social gaming
F# Trainings & Consultingtesting London async & concurrent New York DSLs
data processing http://functional-programming.net
F# Software Foundation
http://www.fsharp.org
software stackstrainings teaching F# user groups snippets
mac and linux cross-platform books and tutorials
F# community open-source MonoDevelop
contributions research support consultancy mailing list
Domain-specific languages
We have a class of problemsCreate a language for the classUse language to solve them
DSLs and functional languagesInternal DSLs are just libraryExternal DSLs are easier to build
Domain-specific languages
Language for solving specific problems
Contrast with general purpose languages
Fun.cylinder |> Fun.translate (0, 0, 1) |> Fun.color Color.Gold $Fun.cone |> Fun.color Color.DarkRed
Demo: Building a castle
Domain Specific LanguageDefines a few simple primitivesExtensible by composition
Single-purpose or general-purpose?Most code is single-purposeCan use general-purpose if needed
See also FAKE: the F# Make
Building a DSL for:Option Pricing
Demo: Modeling Euro options
What is the language?Primitive valuesComposition operations
How do we use the model?Drawing a pay-off diagramCalculating option priceChecking for execution
Composed options
Building the model
Primitives of the language
Composition combinators
type OptionKind = Call | Put
type Option = | European of OptionKind * float
| Combine of Option * Option | Times of float * Option
Demo: Building & using the DSL
Make it more convenientCustom operatorsDerived primitives
Use it for its purposeDrawing pay-off diagramsEvaluating option price
Domain-specific languages
Advantages
ReadabilityGreater for External DSL
MaintainabilityHides the implementationInternals can be changed
Domain FocusNon-experts can read it
Disadvantages
Additional abstractionSmaller for Internal DSL
Time to implementEasier for Internal DSL
Time to learnAvoid crazy operatorsMake it familiar
Internal DSL: Building Blocks
Vanilla .NET Method chainingEnumerationsClassesOperator OverloadingAttributesIterators & LINQExtension methods
F# SpecificPipeliningDiscriminated UnionsRecordsCustom OperatorsQuotationsComputation ExpressionsFunctions
Building a DSL for: Detecting Price Patterns
Declining pattern
Rounding top pattern
Multiple bottom pattern
Doman-specific language approach
Primitive classifiersDeclining priceRising price
Combinators for classifiersAverage using regressionSequence multiple patternsCheck patterns at the same time
Demo: Detecting price patterns
Building complex from simpleCheck multiple conditions
Calculate minimum value
All values are in a rangelet inRange min max = bothAnd (atLeast min) (atMost max)
let bothAnd a b = both a b |> map (fun (a, b) -> a && b)
let minimum = reduce min |> map (fun v -> Math.Round(v, 2))
How does it work?
What is a classifier?
A function value!Given data, calculate the resultGeneric – can produce any valueAbstract – representation is hidden
type Classifier<'T> = ClassifyFunc of ((DateTime * float)[] -> 'T)
Demo: Detecting more patterns
Double bottom patternChange over regressionDown–Up two times
Declining fast patternDeclining over regression(Max – Min) > 3 USD
Advanced Techniquesfor Embedded DSLs
Advanced Embedded DSLs
Computation expressionsReinterpret expression compositionAdd constructs with F# 3.0 queries
Meta-programming with quotationsReinterpret F# expressions
Active patternsMore expressive pattern languageImplementing external DSLs
Repeating patterns in DSLs
Repeating functions in DSLsMap: transform the produced value
Bind & return: composition of computations
Simplify using them? With language syntax?
('T -> 'R) -> Clsif<'T> -> Clsif<'R>
('T -> Clsif<'R>) -> Clsif<'T> -> Clsif<'R>
'T -> Clsif<'T>
F# computation expressions
Syntax for computationsFor types with certain operationsAka monads in Haskell
Declining fast pattern
classify { let! max = P.maximum let! min = P.minimum let! upwards = P.regression P.rising return upwards & (abs (min - max) > 3.0) }
F# query expressionsCustomize the meaning of a query
Query for event processingCustom operators e.g. iter, select, pairwiseTransformations, joins, merging and more Full power to be explored!
event { for e in frm.MouseDown do pairwise into (e1, e2) select (e1.X - e2.X, e1.Y - e2.Y) into r iter (printfn "%A" r) }
F# active patternsExtending the pattern language
Parsing Markdown formatDetecting character patterns Detecting multi-line patternsSee more at http://manning.com/petricek2
match input with| Bracketed '*' '*' (body, rest) -> (...)| Bracketed '[' ']' (body, Bracketed '(' ')' (link, rest)) -> (...)| _ -> (...)
Summary
How To: Building your own DSL
❶ Understand Primitives and Combinators
❷ Model the language using Discriminated Unions
❸ Add convenient Syntax
For more information…
Learn and explore F#Read tutorials at http://tryfsharp.org
Join & help with F# FoundationVisit http://fsharp.org and for on GitHub!
New York F# Trainings & Tutorials in May Check out: http://functional-programming.net Contact me directly: [email protected]