Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Pure Kevin Edelmann “Fun” facts • Functional programming language • Syntactically similar to Haskell • Successor to the Q programming language • Dynamically typed No Monads! • Ironically, this makes Pure less “purely” functional • Then again, Scala allows “direct” printing as well • But it’s also easier to read and use! using system; puts "Hello, world!"; Rewriting • A Pure program is a collection of equations. • Equations are used to symbolically reduce expressions to normal form (no other equations can be applied). • Expressions are evaluated in a leftmost-innermost fashion • Equations are considered from the top-down when matching expressions • Similar to Prolog Simple Rewriting Example • Simple equations look like normal function definitions. • Bottom row shows rewriting steps as applied by Pure. >square x = x*x; >square(5+8); 169 square (5+8) => square 13 => 13*13 => 169 Pattern Matching • Functions can be defined via pattern matching • (As well as in other ways, but nothing we haven’t seen elsewhere) > sum [] = 0; > sum (x:xs) = x+sum xs; > sum (1..30); 465 Pattern Matching with Arbitrary Stuff • Pattern matching can match any sort of data • BST Tree generation example: > nonfix nil; > insert nil y = bin y nil nil; > insert (bin x L R) y = bin x (insert L y) R if y<x; > = bin x L (insert R y) otherwise; > foldl insert nil [7,3,9,18]; bin 7 (bin 3 nil nil) (bin 9 nil (bin 18 nil nil)) Arbitrary Polymorphism • Because Pure is dynamically typed, it supports an arbitrary degree of polymorphism. • Any operation, even those built into Pure, can be extended by equations. > f + g = \x -> f x + g x if nargs f > 0 && nargs g > 0; > f - g = \x -> f x - g x if nargs f > 0 && nargs g > 0; > f x = 2*x+1; g x = x*x; h x = 3; > map (f+g-h) (1..10); [1,6,13,22,33,46,61,78,97,118] > (max-min) 2 5; 3 Symbolic Rewriting • In Pure, attempting to evaluate an expression containing one or more undefined variables returns a symbolic evaluation of the result. • In other languages, the compiler gets angry at you. > square (a+b); (a+b)*(a+b) > sum [a,b,c]; a+(b+(c+0)) > map f [a,b+c,x*y]; [2*a+1,2*(b+c)+1,2*(x*y)+1] More Symbolic Rewriting • In Pure, attempting to set two expressions equal to each other is totally okay; it’s just another rewriting rule. • Arbitrary functions and operators are allowed on the left, just as is so on the right. • In other languages, the compiler gets even angrier than the previous slide. • Example including associative and distributive rules for + and *: > (x+y)*z = x*z+y*z; x*(y+z) = x*y+x*z; > x+(y+z) = (x+y)+z; x*(y*z) = (x*y)*z; > square (a+b); a*a+a*b+b*a+b*b > sum [a,b,c]; a+b+c+0 > map f [a,b+c,x*y]; [2*a+1,2*b+2*c+1,2*x*y+1] One More Symbolic Rewriting example • (Seriously, this is really cool to me) • Converting logical expressions to disjunctive normal form using • de Morgan’s Laws • Distributive Laws • Associative Laws > ~~a = a; > ~(a || b) = ~a && ~b; > ~(a && b) = ~a || ~b; > a && (b || c) = a && b || a && c; > (a || b) && c = a && c || b && c; > (a && b) && c = a && (b && c); > (a || b) || c = a || (b || c); > a || ~(b || (c && ~d)); a||~b&&~c||~b&&d In Summary • Pure can do someone’s Algebra homework for them • More importantly, you can control the flow of how an expression is evaluated by first re-writing the expression • You can also use undefined variables to see how Pure will evaluate an input expression (since it will simply output the symbolic version of what it would otherwise calculate) Further Reading/Source https://bitbucket.org/purelang/pure-lang/wiki/Home ?