Creating Domain Specific Languages in F#

Post on 10-May-2015

3155 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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.

Transcript

Creating Domain Specific

Languages in F#

PhD student @ University of Cambridge

tomas@tomasp.net 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: tomas@tomasp.net

top related