Introduction to Functional Programming with Haskell and JavaScript

5,230 views

Published on

Presentation give to NNSDG on 8/26/2010

Functional programming is often seen as either difficult and academic. Languages such as Haskell, while incredible powerful, don't do much to dismiss this claim. However anyone that's used JavaScript has written a lambda function, and a pretty impressive amount of purely functional code can be implemented in JavaScript. Using these to languages this presentation introduces the fundamentals of functional programming.

Published in: Technology
  • Be the first to comment

Introduction to Functional Programming with Haskell and JavaScript

  1. 1. Introduction to Functional Programming with Haskell and JavaScript Will Kurt Will Kurt, Creative Commons Attribution-ShareAlike 3.0
  2. 2. "A language that doesn't effect how you think about programming is not worth learning" --Alan Perlis
  3. 3. So what is Functional Programming? http://www.flickr.com/photos/foundphotoslj/466713478/
  4. 4. What does this mean? http://www.flickr.com/photos/61417318@N00/4908148942/
  5. 5. No Side Effects! http://www.flickr.com/photos/rka/1733453/
  6. 6. http://www.flickr.com/photos/23912576@N05/3056871500/
  7. 7. Haskell! http://www.flickr.com/photos/micurs/4870514382/
  8. 8. JavaScript!!! http://www.flickr.com/photos/jurvetson/96972777/
  9. 9. Lists!!! first [1,2,3,4] -> 1 (aka: car, head) rest [1,2,3,4] -> [2,3,4] (aka: cdr, tail) empty [1,2,3,4] -> false (aka: null?, nil? empty?,[]) empty [] -> true build 1 , [2,3,4] -> [1,2,3,4] (aka: cons, ':' ) build [1] , [2,3,4] -> [[1],2,3,4]
  10. 10. First class functions http://www.flickr.com/photos/richardmoross/2211308689/
  11. 11. First Class Functions (Haskell) add2 x = 2 + x add3 x = 3 + x > add2 5 7 > add3 5 8
  12. 12. First Class Functions (Haskell) argIs2 func = (func) 2 argIs3 func = (func) 3 > argIs2(add2) 4 > argIs2(add3) 5 > argIs3(add2) 5 > argIs3(add3) 6
  13. 13. First Class Functions (JavaScript) function argIs2(func){ return func(2); } function argIs3(func){ return func(3); }
  14. 14. Lambda Functions http://www.flickr.com/photos/jeremymates/2362399109/
  15. 15. Lambda Function (Haskell) add4 = (x -> 4+x) >argIs2((x -> 4+x)) 6
  16. 16. Lambda Function (JavaScript) var add4 = function(x){ return x+2; } var example = argIs2(function(x){return x+2}); var exampple2 = argIs2(function(x){return x+1000});
  17. 17. Lambda Function (JavaScript) $.ajax({ url: "test.html", context: document.body, success: function() { $(this).addClass("done"); }}); $("#exec").click(function(){ $("#results").prepend("<li>Normal Handler</li>"); });
  18. 18. Closures http://www.flickr.com/photos/theredproject/3431459572/
  19. 19. Closures (Haskell) add5 = (+5) makeAdder val = (+val) makeAdderWithLambda val = (x->x+val) add6 = makeAdder 6 add7 = makeAdderWithLambda 7 > add5 5 10 > add6 5 11 > add7 5 12
  20. 20. Closures (JavaScript) var makeAdder = function(val){ return( function(x){ return val+x; } ); }; >var add6 = makeAdder(6); >add6(5); 11 >add6(8); 14
  21. 21. Higher Order Functions http://www.flickr.com/photos/73416633@N00/2425022159/
  22. 22. Map http://www.flickr.com/photos/rosenkranz/3052214847/
  23. 23. Map (Haskell) doubleAll xs = map (*2) xs squareAll xs = map (^2) xs squareAndAdd xs = map (x->x*x+x) xs upperCase s = map toUpper s > doubleAll [1,2,3,4] [2,4,6,8] > squareAll [1,2,3,4] [1,4,9,16] > squareAndAdd [1,2,3,4] [2,6,12,20] > upperCase "doggie" "DOGGIE"
  24. 24. Map (Haskell) doubleAllv2 = map (*2) squareAllv2 = map (^2) squareAndAddv2 = map (x->x*x+x)
  25. 25. Map (JavaScript) 'The Spolsky Map' function spolsky_map(fn, a) { for (i = 0; i < a.length; i++) { a[i] = fn(a[i]); } } note the side effects
  26. 26. Map (JavaScript) Purely functional version var map = function (func,xs) { return ( empty(xs) ? [] : build(func(first(xs)), map(func,rest(xs)))); }; note: xs and the returned list are distinct
  27. 27. Filter
  28. 28. Filter (Haskell) evenList xs = filter even xs mod17list xs = filter (== (`mod` 17) 0) xs doubleEvens xs = (doubleAll . evenList) xs > evenList [1,2,3,4,5,6] [2,4,6] > mod17list [1..100] [17,34,51,68,85] > doubleEvens [0,3..27] [0,12,24,36,48]
  29. 29. Filter (JavaScript) var filter = function (test,xs) { return ( empty(xs) ? []: test(first(xs)) ? build(first(xs), filter(test,rest(xs))) : filter(test,rest(xs))); };
  30. 30. Foldl (Reduce) http://en.wikipedia.org/wiki/File:Sermon_in_the_Deer_Park_depicted_at_Wat_Chedi_Liem-KayEss-1.jpeg
  31. 31. Foldl (Haskell) mySum xs = foldl (+) 0 xs myReverse xs = foldl (x y -> y:x) [] xs sumOfSquares xs = foldl (+) 0 (map (^2) xs) sumOfSquaresv2 = (mySum . squareAll) > mySum [1..2000000] 2000001000000 > myReverse [4,16..200] [196,184,172,160,148,136,124,112, 100,88,76,64,52,40,28,16,4] > sumOfSquares [1..10] 385 > sumOfSquaresv2 [1..10] 385
  32. 32. Foldl (Haskell) myReverse xs = foldl (x y -> y:x) [] xs myReverse [1,2,3] foldl (x y -> y:x) [] [1,2,3] .. ([] 1 -> 1:[]) .. => [1] foldl (x y -> y:x) [1] [2,3] .. ([1] 2 -> 2:[1]) .. => [2,1]
  33. 33. The Spolsky Reduce (foldl) function spolsky_reduce(fn, a, init) { var s = init; for (i = 0; i < a.length; i++) s = fn( s, a[i] ); return s; }
  34. 34. Foldl (JavaScript) Purely Functional var foldl = function (fn, init, xs) { return( empty(xs) ? init: foldl(fn, fn(init, first(xs)), rest(xs)) ); };
  35. 35. Function Currying
  36. 36. Currying (Haskell) myAdd x y = x + y add8 = myAdd 8 add9 = (+9) > myAdd 8 9 17 > add8 9 17 > add9 8 17
  37. 37. Currying (JavaScript) var curry = function (f,a) { return( function(){ var args = Array.prototype.slice.call(arguments); args.unshift(a); return f.apply(this, args); } ); };
  38. 38. Currying (JavaScript) purely functional var curry = function (f,a) { return( function(){ return( (function(args){ return f.apply(this, build(a,args)); }) (Array.prototype.slice.call(arguments)) ); } ); };
  39. 39. Currying (JavaScript) var add_three = function(a,b,c){ return a+b+c; }; >f1 = curry(add_three,1); >f1(2,3) 6 >f2 = curry(curry(add_three,1),2); >f2(3) 6
  40. 40. Standard Deviation 1. calculate the arithmetic mean of the list 2. subtract the mean from all the numbers in the list 3. square the number in that list 4. calculate the sum of the list 5. divide the sum by length of list by 1 6. get the square root of this number
  41. 41. Standard Deviation 1. calculate the arithmetic mean of the list mean xs = sum xs / fromIntegral(length xs) 2. subtract the mean from all the numbers in the list deviations xs = map (x -> x - m ) xs where m = mean xs 3. square the numbers in that list squareDeviations xs = map(^2) devs where devs = deviations xs 4. calculate the sum of the list sumSquareDeviations xs = (sum . squareDeviations) xs 5. divide the sum by length of list by 1 6. get the square root of this number sd xs = sqrt $ sumSqDev / lsub1 where sumSqDev = sumSquareDeviations xs lsub1 = fromIntegral $ ((-1+) . length)xs
  42. 42. Standard Deviation (JavaScript) var mean = function (xs){ return(sum(xs)/flength(xs)); }; var deviations = function (xs) { var m = mean(xs);//we can remove this return map(function(x){return x-m;},xs); }; var squareDeviations = function(xs){ return map(square,deviations(xs)); };
  43. 43. Standard Deviation (JavaScript) var sumSqDeviations = compose(sum,squareDeviations); var sd = function(xs){ return Math.sqrt( (sumSqDeviations(xs)/(flength(xs)-1))); };
  44. 44. Standard Deviation Haskell > sd [1,4,5,9,2,10] 3.65604522218567 JavaScript > sd([1,4,5,9,2,10]); 3.65604522218567
  45. 45. Who actually uses this stuff? http://cufp.org/
  46. 46. Ocaml
  47. 47. more @ http://www.scala-lang.org/node/1658
  48. 48. Haskell
  49. 49. ... continued more @ http://haskell.org/haskellwiki/Haskell_in_industry
  50. 50. Questions? email: wkurt@unr.edu twitter: willkurt

×