240 likes | 397 Views
Language Oriented Programming in F#. Robert Pickering, Chance Coble, Roger Castillo. Languages are Logic. Programming languages provide a way to express logic in a symbolic notation Combinators give us a way to express logic
E N D
Language Oriented Programming in F# Robert Pickering, Chance Coble, Roger Castillo
Languages are Logic • Programming languages provide a way to express logic in a symbolic notation • Combinators give us a way to express logic • Using this approach we can create a few atoms, many rewrite rules and presto… New Language
Combinators true-fn(x, y) = x false-fn(x, y) = y or-fn(x, y) = x(true-fn, y) and-fn(x, y) = x(y, false-fn)
Combinators true-fn(x, y) = x false-fn(x, y) = y or-fn(x, y) = x(true-fn, y) and-fn(x, y) = x(y, false-fn) not-fn (a(x,y)) = a(y,x) equals-fn x y = x(y, (not-fn y)) Implication-fn x y = or((not-fn x), y)
Combinators and-fn(x, y) = not-fn (or-fn ((not-fn x), (not-fn y)) = not-fn ((not-fn x)(true-fn, (not-fn y))) = not-fn (x (false-fn, y)) = x(y, false-fn) true-fn(x, y) = x false-fn(x, y) = y or-fn(x, y) = x(true-fn, y) and-fn(x, y) = x(y, false-fn) not-fn( a (x, y)) = a(y, x) equals-fn(x, y) = x(y, (not-fn y)) implication-fn(x, y) = or((not-fn x), y)
While Statement while (true) { if (1!=1) Console.WriteLine(“CosmicDeath Ray Detected”); }
Statement Grammer while (true) { if (1!=1) Console.WriteLine(“Cosmic Death Ray Detected”); } if statement list Boolean expression
Statements and Expressions while (true) { if (1!=1) Console.WriteLine(“Cosmic Death Ray Detected”); } while if statement list Boolean expression statement list Boolean expression
Syntax Tree while (true) { if (1!=1) Console.WriteLine(“Cosmic Death Ray Detected”); } while if Boolean expression (true) statement list Boolean expression (1!=1)
Abstract Syntax Tree This language is a list of statements The statements must follow a grammar that can be represented by a tree while if Boolean expression statement list Boolean expression
Abstract Syntax Trees and Grammars This language is a list of statements The statements must follow a grammar that can be represented by BNF statement ::= ‘while’ ‘(‘expression’)’ statement-list | ‘if’ ‘(‘expression’)’ statement-list | ... | ...
Direct Translation From Grammar statement ::= ‘while’ ‘(‘expression’)’ statement-list | ‘if’ ‘(‘expression’)’ statement-list | ... | ... // F# Discriminated Union type Statement = | While of boolexpression * Statement list | If of boolexpression * Statement list
Abstract Syntax Tree Tuple Syntax (X,Y) type Statement = | While of bool expression * Statement list | If of bool expression * Statement list
Union Types – The Option Type // The pre-defined option type type Option<'a> = | Some of 'a | None // constructing options let someValue = Some 1 let noValue = None // pattern matching over options let convert value = match value with | Some x -> Printf.sprintf"Value: %i" x | None -> "No value"
Union Types - Trees // a binary tree definition type BinaryTree<'a> = | Node of BinaryTree<'a> * BinaryTree<'a> | Leaf of 'a // walk the tree collection values let reccollectValues acc tree = match tree with | Node(ltree, rtree) -> // recursively walk the left tree let acc = collectValues acc ltree // recursively walk the right tree collectValues acc rtree | Leaf value -> value :: acc // add value to accumulator
Using the Tree // define a tree let tree = Node( Node(Leaf 1, Leaf 2), Node(Leaf 3, Leaf 4)) // recover all values from the leaves let values = collectValues [] tree
Union Types – Multiple Patterns // balance the left side of the tree letbalanceLeft tree = matchtree with | RedTree (y, yv, RedTree(x, xv, a, b), c) -> RedTree(y, yv, BlackTree(x, xv, a, b), c) | RedTree (x, xv, a, RedTree(y, yv, b, c)) -> // none matched, just make a tree RedTree(y, yv, BlackTree(x, xv, a, b), BlackTree(z, zv, c, d)) | _ ->mkTree(isBlack, z, zv, l, d) // none matched, just make a tree
Can we do this using other constructs? Functional Operations • Enum • Inheritance OO Types
3D Visualization DSL type Prop = | Line of Point list * (TimedIndex->Point) * MaterialColor | Surface of Origin * SurfaceProperties * (TimedPoint->float) | Triangle of (int->TriangleFace) | TextAnnotationof (int->RectangleFace * string) | Sphere ofSphereProperties | Cylinder ofCylinderProperties type Scene = | AnimatedSceneof Prop list * Scene * SceneSpeed | StillSceneof Prop list * Scene | Empty
Evaluating the Language let receval model = function | AnimatedScene(ps,scene,speed) -> // … skipping some timer code let model' = fold evalProp model ps // … eval model' scene | Empty -> model
Production Rules letevalPropenv prop = match prop with | Line(points,updateFunction,thickness,color) -> let l = evalLine points updateFunction thickness color env.View.Children.Add(l) env | Triangle(f) -> evalTriangle f env | TextAnnotation(rectUpdate,opacity) -> evalAnnotation rectUpdate opacity env | Sphere props ->env.View.Children.Add (evalSphere props) env | Cylinder props ->env.View.Children.Add (evalCylinder props) env
Wrap up • Combinator libraries offer compositional thinking • Increased modularity in operations (as opposed to objects) • Reasoning by substitution