Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Creating Domain Specific Languages in F#

6,404 views

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.

Creating Domain Specific Languages in F#

  1. 1. Creating Domain Specific Languages in F# PhD student @ University of Cambridgetomas@tomasp.net Tomas Petricek @tomaspetricek Conspirator behind http://fsharp.org
  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 http://functional-programming.net
  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 http://www.fsharp.org 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 http://manning.com/petricek2
  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 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

×