Creating Domain Specific Languages in F#


Published on

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.

  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Prefer internal DSLs
  • Creating Domain Specific Languages in F#

    1. 1. Creating Domain Specific Languages in F# PhD student @ University of Tomas Petricek @tomaspetricek Conspirator behind
    2. 2. Real World Functional Programming tutorials F# and C# monads functional concepts practical examples industry experts F# Deep Dives . domain modeling financial & insurance web & data actor model concurrency social gamingF# Trainings & Consultingtesting London async & concurrent New York DSLsdata processing
    3. 3. software stacks trainings teaching F# user groups snippetsmac and linux cross-platform books and tutorials F# Software Foundation F# community open-source MonoDevelop contributions research support consultancy mailing list
    4. 4. Domain-specific languagesWe have a class of problems Create a language for the class Use language to solve themDSLs and functional languages Internal DSLs are just library External DSLs are easier to build
    5. 5. Domain-specific languagesLanguage for solving specific problems Fun.cylinder |> Fun.translate (0, 0, 1) |> Fun.color Color.Gold $ Fun.cone |> Fun.color Color.DarkRedContrast with general purpose languages
    6. 6. Demo: Building a castleDomain Specific Language Defines a few simple primitives Extensible by compositionSingle-purpose or general-purpose? Most code is single-purpose Can use general-purpose if neededSee also FAKE: the F# Make
    7. 7. Building a DSL for: Option Pricing
    8. 8. Demo: Modeling Euro optionsWhat is the language? Primitive values Composition operationsHow do we use the model? Drawing a pay-off diagram Calculating option price Checking for execution
    9. 9. Composed options
    10. 10. Building the modelPrimitives of the language type OptionKind = Call | Put type Option = | European of OptionKind * floatComposition combinators | Combine of Option * Option | Times of float * Option
    11. 11. Demo: Building & using the DSLMake it more convenient Custom operators Derived primitivesUse it for its purpose Drawing pay-off diagrams Evaluating option price
    12. 12. Domain-specific languagesAdvantages DisadvantagesReadability Additional abstraction Greater for External DSL Smaller for Internal DSLMaintainability Time to implement Hides the implementation Easier for Internal DSL Internals can be changed Time to learnDomain Focus Avoid crazy operators Non-experts can read it Make it familiar
    13. 13. Internal DSL: Building BlocksVanilla .NET F# SpecificMethod chaining PipeliningEnumerations Discriminated UnionsClasses RecordsOperator Overloading Custom OperatorsAttributes QuotationsIterators & LINQ Computation ExpressionsExtension methods Functions
    14. 14. Building a DSL for:Detecting Price Patterns
    15. 15. Declining pattern
    16. 16. Rounding top pattern
    17. 17. Multiple bottom pattern
    18. 18. Doman-specific language approachPrimitive classifiers Declining price Rising priceCombinators for classifiers Average using regression Sequence multiple patterns Check patterns at the same time
    19. 19. Demo: Detecting price patternsBuilding complex from simple Check multiple conditions let bothAnd a b = both a b |> map (fun (a, b) -> a && b) Calculate minimum value let minimum = reduce min |> map (fun v -> Math.Round(v, 2)) All values are in a range let inRange min max = bothAnd (atLeast min) (atMost max)
    20. 20. How does it work?What is a classifier? type Classifier<T> = ClassifyFunc of ((DateTime * float)[] -> T)A function value! Given data, calculate the result Generic – can produce any value Abstract – representation is hidden
    21. 21. Demo: Detecting more patternsDouble bottom pattern Change over regression Down–Up two timesDeclining fast pattern Declining over regression (Max – Min) > 3 USD
    22. 22. Advanced Techniques for Embedded DSLs
    23. 23. Advanced Embedded DSLsComputation expressions Reinterpret expression composition Add constructs with F# 3.0 queriesMeta-programming with quotations Reinterpret F# expressionsActive patterns More expressive pattern language Implementing external DSLs
    24. 24. Repeating patterns in DSLsRepeating functions in DSLs Map: transform the produced value (T -> R) -> Clsif<T> -> Clsif<R> Bind & return: composition of computations (T -> Clsif<R>) -> Clsif<T> -> Clsif<R> T -> Clsif<T>Simplify using them? With language syntax?
    25. 25. F# computation expressionsSyntax for computations For types with certain operations Aka monads in HaskellDeclining fast pattern classify { let! max = P.maximum let! min = P.minimum let! upwards = P.regression P.rising return upwards & (abs (min - max) > 3.0) }
    26. 26. F# query expressionsCustomize the meaning of a query 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) }Query for event processing Custom operators e.g. iter, select, pairwise Transformations, joins, merging and more Full power to be explored!
    27. 27. F# active patternsExtending the pattern language match input with | Bracketed * * (body, rest) -> (...) | Bracketed [ ] (body, Bracketed ( ) (link, rest)) -> (...) | _ -> (...)Parsing Markdown format Detecting character patterns Detecting multi-line patterns See more at
    28. 28. Summary
    29. 29. How To: Building your own DSL ❶ Understand Primitives and Combinators ❷ Model the language using Discriminated Unions ❸ Add convenient Syntax
    30. 30. For more information…Learn and explore F# Read tutorials at http://tryfsharp.orgJoin & help with F# Foundation Visit and for on GitHub!New York F# Trainings & Tutorials in May Check out: Contact me directly: