Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.
Nächste SlideShare
Wird geladen in …5
×

# Combinators, DSLs, HTML and F#

5.564 Aufrufe

Veröffentlicht am

• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here
• Don't miss Wing Beats, an open source DSL for XHTML in F# : http://wingbeats.codeplex.com/

Sind Sie sicher, dass Sie …  Ja  Nein
Ihre Nachricht erscheint hier

### Combinators, DSLs, HTML and F#

1. 1. Combinators, DSLs, HTML and F#<br />Robert Pickering, ALTI<br />
2. 2. About the Presenter<br />2<br /><ul><li>Using F# for about 6 years
3. 3. Oldest F# user outside of Microsoft
4. 4. Written a book about F# </li></ul>(now in its second edition)<br /><ul><li>Spend at least 2 years as a professional functional programmer
5. 5. I have 3 cats</li></ul>Contact me:<br />robert@strangelights.com<br />http://strangelights.com/blog<br />
6. 6. What is a Combinator?<br />A combinator is a higher-order function that uses only function application and earlier defined combinators to define a result from its arguments.<br />Source: Wikipedia, http://en.wikipedia.org/wiki/Combinatory_Logic<br />
7. 7. Combinatory Logic in Computing<br />In computer science, combinatory logic is used as a simplified model of computation, used in computability theory and proof theory. Despite its simplicity, combinatory logic captures many essential features of computation.<br />Source: Wikipedia, http://en.wikipedia.org/wiki/Combinatory_Logic<br />
8. 8. Combinator Library<br />"A combinator library offers functions (the combinators) that combine functions together to make bigger functions"[1]. These kinds of libraries are particularly useful for allowing domain-specific programming languages to be easily embedded into a general purpose language by defining a few primitive functions for the given domain.<br />Souce: Wikipedia http://en.wikipedia.org/wiki/Combinator_library<br />[1] “A History of Haskell” Hudak, Hughes, Peyton Jones, Wadler<br />
9. 9. History of Haskell: Combinator Libraries<br />What is a combinatorlibrary? The reader will search in vain for a definition of this heavily used term, but the key idea is this: a combinator library offers functions (the combinators) that combine functions together to make bigger functions.<br />
10. 10. History of Haskell: Combinator Libraries<br />What is a combinatorlibrary?The reader will search in vain for a definition of this heavily used term, but the key idea is this: a combinator library offers functions (the combinators) that combine functions together to make bigger functions.<br />
11. 11. History of Haskell: Combinator Libraries<br />Another productive way to think of a combinator library is as a domain-specific language (DSL) for describing values of a particular type.<br />
12. 12. What is a Domain Specific Language?<br />A programming language tailored for a particular application domain, which captures precisely the semantics of the application domain -- no more, no less.<br />A DSL allows one to develop software for a particular application domain quickly, and effectively, yielding programs that are easy to understand, reason about, and maintain.<br />Hudak<br />
13. 13. Combinatorsvs DSLs<br />Combinartor libraries are a special case of DSLs<br />Sometimes called DSELs (Domain Specific Embed languages)<br />DSELs have several advantages:<br /><ul><li>Inherit non-domain-specific parts of the design.
14. 14. Inherit compilers and tools.
15. 15. Uniform “look and feel” across many DSLs
16. 16. DSLs integrated with full programming language, and with each other.</li></ul>DSELs one disadvantage:<br /><ul><li>Constrained by host language syntax and type system</li></li></ul><li>What Makes F# a Suitable for DSLs ?<br />Algebraic data types <br />type Option<'a> = Some x | None<br />Lambda functions<br />fun x -> x + 1<br />Define and redefine operators<br />let (++) x = x + 1<br />Define custom numeric literals<br />let x : Expression = 1.0N<br />
17. 17. The Anatomy of a DSL<br />Syntax Tree<br />type Expression =<br /> | Add of Expression * Expression<br /> | Subtract of Expression * Expression<br /> | Multiply of Expression * Expression<br /> | Constant ofint<br /> | Parameter of string<br />with<br />staticmember (+) (x, y) = Add(x, y)<br />staticmember (-) (x, y) = Subtract(x, y)<br />staticmember (*) (x, y) = Multiply(x, y)<br />moduleNumericLiteralN = <br />letFromZero() = Constant 0<br />letFromOne() = Constant 1<br />let FromInt32 = Constant<br />letparam = Parameter<br />Combinators<br />
18. 18. The Anatomy of a DSL<br />letexpr = (1N + 2N) * (5N - 2N)<br />valexpr : Expression =<br /> Multiply (Add (Constant 1,Constant 2),<br /> Subtract (Constant 5,Constant 2))<br />
19. 19. The Anatomy of a DSL<br />Expressions now have an abstract tree like representation:<br /><ul><li>Multiply
21. 21. Constant 1
22. 22. Constant 2
23. 23. Subtract
24. 24. Constant 5
25. 25. Constant 2
26. 26. This can then be evaluated
27. 27. Or we can preform more advanced analysis </li></li></ul><li>The Anatomy of a DSL<br />letevaluateExpression parameters =<br />letrecinnerEval tree =<br />match tree with<br /> | Multiply (x, y) ->innerEval x * innerEval y<br /> | Add (x, y) ->innerEval x + innerEval y<br /> | Subtract (x, y) ->innerEval x - innerEval y<br /> | Constant value -> value<br /> | Parameter key ->Map.find key parameters<br />innerEval<br />let expr = (1N + 2N) * (5N - 2N)<br />evaluateExpressionMap.emptyexpr<br />
28. 28. The Anatomy of a DSL<br />
29. 29. The Anatomy of a DSL<br />letrecsimplifyExpressionexp =<br />let simpIfPoss op exp1 exp2 =<br />letexp' = op (simplifyExpression exp1, <br />simplifyExpressionexp2)<br />ifexp' = expthenexp' elsesimplifyExpressionexp'<br />matchexpwith<br /> | Multiply(Constant 0, Constant _) -> Constant 0<br /> | Multiply(Constant _, Constant 0) -> Constant 0<br /> | Multiply(Constant n1, Constant n2) -> Constant (n1 * n2)<br /> | Add(Constant n1, Constant n2) -> Constant (n1 + n2)<br /> | Subtract(Constant n1, Constant n2) -> Constant (n1 - n2)<br /> | Multiply(exp1, exp2) ->simpIfPoss Multiply exp1 exp2<br /> | Add(exp1, exp2) ->simpIfPoss Add exp1 exp2<br /> | Subtract(exp1, exp2) ->simpIfPoss Add exp1 exp2<br /> | Constant _ | Parameter _ ->exp<br />
30. 30. The Anatomy of a DSL<br />
31. 31. Why a DSL for HTML?<br /><htmlxmlns="http://www.w3.org/1999/xhtml"><br /><head><br /><title></title><br /></head><br /><body><br /><h1>Hello world!</h1><br /><formid="form1"><br /><inputtype="text"name="name"/><br /> </form><br /></body><br /></html><br />
32. 32. Why a DSL for HTML ?<br />HTML has a tree like structure<br />We need be able to generate and manipulate this tree in an abstract, type safe way<br />
33. 33. Why a DSL for HTML?<br /><ul><li>Tag: html
34. 34. Tag: head
35. 35. Tag: title
36. 36. Tag: body
37. 37. Tag: h1
38. 38. Text: Hello world!
39. 39. Tag: form
40. 40. Tag: input
41. 41. Attribute: type :: text
42. 42. Attribute: name :: name</li></li></ul><li>Why a DSL for HTML?<br />At this point any red blooded functional programmer should start foaming at the mouth, yelling “build a combinator library”<br />Source: “Composing contracts: an adventure in financial engineering”<br />Peyton Jones, Eber, Seward<br />http://research.microsoft.com/~simonpj/Papers/financial-contracts/contracts-icfp.htm<br />
43. 43. DSLs for Working with HTML<br />#light – DSL for working with HTML, by SadekDrobi: http://sharplight.codeplex.com/<br />F# Web Tools – Tool kit for Ajax programing, by TomášPetříček: http://www.codeplex.com/fswebtools<br />WebSharper – DSL for HTML with F# to JavaScript translator, by IntelliFactory: http://www.intellifactory.com/products/wsp<br />
44. 44. Hello world<br />Paragraph Element<br /> [<JavaScript>]<br />let Main () =<br />let welcome = P [Text "Welcome"]<br />Div [<br /> welcome<br /> Input [Type "Button"; Value "Click me!"]<br /> |> On Events.Click (fun e -><br />welcome.Text <- "Hello, world!")<br /> ]<br />Input Button Element<br />Client Side Event Handler<br />
45. 45. How Does it Work?<br />At compile time an extra step takes place:<br />Functions & types are translated into JavaScript<br />Compiler attempts to optimize JavaScript code<br />Compiler tries to preserve binding names<br />F# functions are compiled using the F# quotations system<br />
46. 46. Aside: Quotations in F#<br />openMicrosoft.FSharp.Quotations.Patterns<br />openMicrosoft.FSharp.Quotations.DerivedPatterns<br />let quotation = <@ 1 + 1 @><br />// a function to interpret very simple quotations<br />letrecinterpretQuotationexp =<br />matchexpwith<br /> | Value (x, typ) whentyp = typeof<int> ->printfn"%d" (x :?> int)<br /> | SpecificCall <@ (+) @> (_, _, [l;r]) ->interpretQuotation l <br />printfn"+"<br />interpretQuotation r<br /> | _ ->printfn"not supported"<br />// test the function<br />interpretQuotation quotation <br />
47. 47. Formlets– Compositional Forms<br />Text Input Element<br />[<JavaScript>]<br />let input label err =<br />Controls.Input""<br /> |> Validator.IsNotEmpty err<br /> |> Controls.Enhance.WithLabel label<br /> [<JavaScript>]<br />letinputInt label err = <br />Controls.Input""<br /> |> Validator.IsInt err<br /> |> Controls.Enhance.WithLabellabel<br />Add Validation Element<br />Add Label Element<br />
48. 48. Formlets – Compositional Forms<br /> [<JavaScriptType>]<br />typeBasicInfo = { Name : string; Age : int }<br /> [<JavaScript>]<br />letBasicInfoForm () : Formlet<BasicInfo> =<br />Formlet.Yield (fun name age -><br /> { Name = name; <br /> Age = age |> int })<br /> <*> input "Name""Please enter your name"<br /> <*> inputInt"Age""Please enter a valid age"<br />Construct form result<br />Construct and compose input elements<br />
49. 49. Formlets – Compositional Forms<br />Configuration options<br />letconf = <br /> { Render.FormConfiguration.Defaultwith<br /> Header = "Sign up" }<br />Render.FormThenResponse<br />conf<br /> (ContactForms.BasicInfoForm())<br /> (fun info ->Div [ P [ "Thanks " + info.Name ]<br /> P [ "You are " + string info.Age<br /> + " years old" ] ])<br />Form and config<br />Function that constructs result<br />
50. 50. Plotting Graphs Client Side<br />Demo<br />
51. 51. Flowlets – Composing Formlets<br />Flowlet.Flowlet.Do {<br />let! info = ContactForms.BasicInfoForm() <br /> |> Flowlet.OfFormlet conf1<br />let! contact = ContactForms.ContactInfoForm() <br /> |> Flowlet.OfFormlet conf2<br />return info, contact<br /> }<br />
52. 52. Flowlets – Composing Formlets<br />Flowlet.Run (fun (info, contact) -><br /> letresult =<br />matchcontact with<br /> | ContactForms.ContactVia.Address address -><br />"the address: " + address.Street + ", " +<br />address.City + ", " + address.Country<br />| ContactForms.ContactVia.Phone phone -><br />"the phone number: " + phone<br />letresults =<br />FieldSet [<br />Legend [Text "Sign-up summary"]<br />P ["Hi " + info.Name + "!" |> Text]<br />P ["You are " + string info.Age + <br />" years old" |> Text]<br />P ["Your preferred contact method is via "<br /> + result |> Text]<br />]<br /> steps -< [ results ] |> ignore)<br />
53. 53. Wrapping It Up<br />Combinator libraries/DSL are an excellent way of tackling many problems<br />Especially if that problem involves some kind of tree manipulation<br />F# provides the features you need to implement combinator libraries<br />
54. 54. Further F# Info<br />MSDN Center: http://msdn.microsoft.com/fsharp/<br />User’s forums:<br />http://cs.hubfs.net/forums<br />http://stackoverflow.com/tags/F%23<br />Blogs (there are lots of others) : <br />http://blogs.msnd.com/dsyme<br />http://strangelights.com/blog<br />Websites :<br />http://code.msdn.microsoft.com/fsharpsamples<br />http://code.google.com/hosting/search?q=label:fsharp<br />http://codeplex.com/Project/ProjectDirectory.aspx?TagName=F%23<br />
55. 55. Books<br />