30
Creating Domain Specific Languages in F# PhD student @ University of Cambridge [email protected] Tomas Petricek @tomaspetricek Conspirator behind http://fsharp.org

Creating Domain Specific Languages in F#

Embed Size (px)

DESCRIPTION

When designing software, we often need to solve numerous instances of the same problem. When designing user-interfaces, we need to describe the layout and interaction. When financial systems, we need to describe a wide range of financial contracts or, for example, recognize different patterns in price change. Domain Specific Languages (DSLs) give us a way to solve such repeating problems. By designing a composable functional library, we can build an expressive language for describing our problems. Using the flexible F# syntax, we can get code that even non-programmers can understand. In this practically oriented talk, we'll develop a number of sample DSLs, ending with realistic examples. We'll cover both basic principles of DSL design as well as advanced tricks, such as using the F# 3.0 query syntax.

Citation preview

Page 1: 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

Page 2: Creating Domain Specific Languages in F#

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

Page 3: Creating Domain Specific Languages in F#

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

Page 4: Creating Domain Specific Languages in F#

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

Page 5: Creating Domain Specific Languages in F#

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

Page 6: Creating Domain Specific Languages in F#

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

Page 7: Creating Domain Specific Languages in F#

Building a DSL for:Option Pricing

Page 8: Creating Domain Specific Languages in F#

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

Page 9: Creating Domain Specific Languages in F#

Composed options

Page 10: Creating Domain Specific Languages in F#

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

Page 11: Creating Domain Specific Languages in F#

Demo: Building & using the DSL

Make it more convenientCustom operatorsDerived primitives

Use it for its purposeDrawing pay-off diagramsEvaluating option price

Page 12: Creating Domain Specific Languages in F#

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

Page 13: Creating Domain Specific Languages in F#

Internal DSL: Building Blocks

Vanilla .NET Method chainingEnumerationsClassesOperator OverloadingAttributesIterators & LINQExtension methods

F# SpecificPipeliningDiscriminated UnionsRecordsCustom OperatorsQuotationsComputation ExpressionsFunctions

Page 14: Creating Domain Specific Languages in F#

Building a DSL for: Detecting Price Patterns

Page 15: Creating Domain Specific Languages in F#

Declining pattern

Page 16: Creating Domain Specific Languages in F#

Rounding top pattern

Page 17: Creating Domain Specific Languages in F#

Multiple bottom pattern

Page 18: Creating Domain Specific Languages in F#

Doman-specific language approach

Primitive classifiersDeclining priceRising price

Combinators for classifiersAverage using regressionSequence multiple patternsCheck patterns at the same time

Page 19: Creating Domain Specific Languages in F#

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))

Page 20: Creating Domain Specific Languages in F#

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)

Page 21: Creating Domain Specific Languages in F#

Demo: Detecting more patterns

Double bottom patternChange over regressionDown–Up two times

Declining fast patternDeclining over regression(Max – Min) > 3 USD

Page 22: Creating Domain Specific Languages in F#

Advanced Techniquesfor Embedded DSLs

Page 23: Creating Domain Specific Languages in F#

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

Page 24: Creating Domain Specific Languages in F#

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>

Page 25: Creating Domain Specific Languages in F#

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) }

Page 26: Creating Domain Specific Languages in F#

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) }

Page 27: Creating Domain Specific Languages in F#

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)) -> (...)| _ -> (...)

Page 28: Creating Domain Specific Languages in F#

Summary

Page 29: Creating Domain Specific Languages in F#

How To: Building your own DSL

❶ Understand Primitives and Combinators

❷ Model the language using Discriminated Unions

❸ Add convenient Syntax

Page 30: Creating Domain Specific Languages in F#

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]