Intro to Functional Programming Workshop (code4lib)

99
var λ; Introduction to Functional Programming with JavaScript (and a little Haskell) Will Kurt Will Kurt, Creative Commons Attribution- ShareAlike 3.0

Transcript of Intro to Functional Programming Workshop (code4lib)

Page 1: Intro to Functional Programming Workshop (code4lib)

var λ;Introduction to Functional Programming 

with JavaScript(and a little Haskell)

Will Kurt

Will Kurt, Creative Commons Attribution-ShareAlike 3.0

Page 2: Intro to Functional Programming Workshop (code4lib)

"A language that doesn't effect how you think about

programming is not worth learning"

--Alan Perlis

Page 3: Intro to Functional Programming Workshop (code4lib)

So what is Functional Programming?

http://www.flickr.com/photos/foundphotoslj/466713478/

Page 4: Intro to Functional Programming Workshop (code4lib)

What does this mean?

http://www.flickr.com/photos/61417318@N00/4908148942/

Page 5: Intro to Functional Programming Workshop (code4lib)

No Side Effects!

http://www.flickr.com/photos/rka/1733453/

Page 6: Intro to Functional Programming Workshop (code4lib)

http://www.flickr.com/photos/23912576@N05/3056871500/

Page 7: Intro to Functional Programming Workshop (code4lib)

Haskell!

http://www.flickr.com/photos/micurs/4870514382/

Page 8: Intro to Functional Programming Workshop (code4lib)

JavaScript!!!

http://www.flickr.com/photos/jurvetson/96972777/

Page 9: Intro to Functional Programming Workshop (code4lib)

Rules for Today

λ

Page 10: Intro to Functional Programming Workshop (code4lib)

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]

Page 11: Intro to Functional Programming Workshop (code4lib)

Recursion!

"If you already know what recursion is, just remember the answer. Otherwise, find someone who is standing closer to Douglas Hofstadter than you are; then ask him or her what recursion is."

-- Andrew Plotkin

Page 12: Intro to Functional Programming Workshop (code4lib)

Exercise set 1a

10 minutes

Page 13: Intro to Functional Programming Workshop (code4lib)

Answers to set 1a

Page 14: Intro to Functional Programming Workshop (code4lib)

problem 1

var fact = function(x) {    return(       (x===1) ? 1 :       x*fact(x-1)       );}

function fact (x) {     if(x==1){            return 1;      } else {        return x*fact2(x-1);      }}

Page 15: Intro to Functional Programming Workshop (code4lib)

problem 2

var fib = function(x){    return(          (x==0) ? 0 :          (x==1) ? 1 :          fib(x-1)+fib(x-2)    );

}

Page 16: Intro to Functional Programming Workshop (code4lib)

problem 2 continued...

var fib_answers = []fib_answers[0] = 0;fib_answers[1] = 1;var fibm = function (x) {     return fib_mem(x,fib_answer);}

var fib_mem = function(x,m){    if(m[x] != undefined){         return m[x];    } else {         m[x] = fib_mem(x-1,m)+fib_mem(x-2,m);         return m[x];    }}

Page 17: Intro to Functional Programming Workshop (code4lib)

problem 2 last one I swear (also very functional)...

var fib3wrapper = function(c){    return fib3(c,1,0);}

var fib3 = function(c,last1,last2){     return(            (c==2) ? last1+last2:            fib3(c-1,last1+last2,last1)     );}

Page 18: Intro to Functional Programming Workshop (code4lib)

Exercise set 1b

10 minutes

Page 19: Intro to Functional Programming Workshop (code4lib)

Answers to set 1b

Page 20: Intro to Functional Programming Workshop (code4lib)

problem 1

var length = function (xs) {     return(          empty(xs) ? 0 :          1 + length(rest(xs))     );};

Page 21: Intro to Functional Programming Workshop (code4lib)

problem 2

var nth = function(n,xs){    return(         empty(xs) ? [] :         (n == 0) ? first(xs) :         nth(n-1, rest(xs))    );

};

Page 22: Intro to Functional Programming Workshop (code4lib)

problem 3

var removeAll = function (x, xs) {    return(        empty(xs) ? [ ] :        (x == first(xs)) ? removeAll(x,                                    rest(xs)) :        build(first(xs),               removeAll(x,rest(xs)))

    );};

Page 23: Intro to Functional Programming Workshop (code4lib)

First class functions

http://www.flickr.com/photos/richardmoross/2211308689/

Page 24: Intro to Functional Programming Workshop (code4lib)

First Class Functions (Haskell)add2 x = 2 + xadd3 x = 3 + x

> add2 57

> add3 58

Page 25: Intro to Functional Programming Workshop (code4lib)

First Class Functions (Haskell)argIs2 func = (func) 2argIs3 func = (func) 3

> argIs2(add2)4> argIs2(add3)5> argIs3(add2)5> argIs3(add3)6

Page 26: Intro to Functional Programming Workshop (code4lib)

Lambda Functions

http://www.flickr.com/photos/jeremymates/2362399109/

Page 27: Intro to Functional Programming Workshop (code4lib)

Lambda Function (Haskell)

add4 = (\x -> 4+x)

>argIs2((\x -> 4+x))6

Page 28: Intro to Functional Programming Workshop (code4lib)

Lambda Function (JavaScript)

$.ajax({ url: "test.html", context: document.body, success: function(){        $(this).addClass("done");      }});

$("#exec").click(function(){  $("#results").prepend("<li>Normal Handler</li>");});

Page 29: Intro to Functional Programming Workshop (code4lib)

Exercise set 2

10 minutes

Page 30: Intro to Functional Programming Workshop (code4lib)

Answers to set 2

Page 31: Intro to Functional Programming Workshop (code4lib)

problem 1

var argIs2 = function(func) {    return func(2);}

Page 32: Intro to Functional Programming Workshop (code4lib)

problem 2

argIs2(function(x){ add(2,x);} );

Page 33: Intro to Functional Programming Workshop (code4lib)

problem 3

var flip = function (func) {       return(                 function(x,y){                         func(y,x);                 }       );};

Page 34: Intro to Functional Programming Workshop (code4lib)

Break!

5 minutes

Page 35: Intro to Functional Programming Workshop (code4lib)

Closures

http://www.flickr.com/photos/theredproject/3431459572/

Page 36: Intro to Functional Programming Workshop (code4lib)

Closures (Haskell)

add5 = (+5)makeAdder val = (+val)makeAdderWithLambda val = (\x->x+val)

add6 = makeAdder 6add7 = makeAdderWithLambda 7

> add5 510> add6 511> add7 512

Page 37: Intro to Functional Programming Workshop (code4lib)

Exercise set 3

5 minutes

Page 38: Intro to Functional Programming Workshop (code4lib)

Answers to set 3

Page 39: Intro to Functional Programming Workshop (code4lib)

problem 1

var makeAdder = function (x) {    return(        function(y) {                  return add(x,y);              }    );};

Page 40: Intro to Functional Programming Workshop (code4lib)

problem 2

var apiClosure = function(apiKey){    return(        function(x){             return apiSearch(apiKey,x);        }    );};

Page 41: Intro to Functional Programming Workshop (code4lib)

problem 3

var compose = function (f1,f2) {    return(         function(x){             f1(f2(x));         }    );};

Page 42: Intro to Functional Programming Workshop (code4lib)

Higher Order Functions

http://www.flickr.com/photos/73416633@N00/2425022159/

Page 43: Intro to Functional Programming Workshop (code4lib)

Map

http://www.flickr.com/photos/rosenkranz/3052214847/

Page 44: Intro to Functional Programming Workshop (code4lib)

Map (Haskell)

doubleAll xs = map (*2) xssquareAll xs = map (^2) xssquareAndAdd xs = map (\x->x*x+x) xsupperCase 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"

Page 45: Intro to Functional Programming Workshop (code4lib)

Map (Haskell)

doubleAllv2 = map (*2)squareAllv2 = map (^2)squareAndAddv2 = map (\x->x*x+x)

Page 46: Intro to Functional Programming Workshop (code4lib)

Exercise set 4a

5 minutes

Page 47: Intro to Functional Programming Workshop (code4lib)

Answers to set 4a

Page 48: Intro to Functional Programming Workshop (code4lib)

problem 1

var map = function (func, xs) {    return(        empty(xs) ? [ ] :        build( func(first(xs)),                  map (func, rest (xs))));    );};

Page 49: Intro to Functional Programming Workshop (code4lib)

problem 2

map(function(x){                return x*x},         xs);

Page 50: Intro to Functional Programming Workshop (code4lib)

Filter

Page 51: Intro to Functional Programming Workshop (code4lib)

Filter (Haskell)

evenList xs = filter even xsmod17list xs = filter (== (`mod` 17) 0) xsdoubleEvens 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]

Page 52: Intro to Functional Programming Workshop (code4lib)

Exercise set 4b

10 minutes

Page 53: Intro to Functional Programming Workshop (code4lib)

Answers to set 4b

Page 54: Intro to Functional Programming Workshop (code4lib)

problem 1

var filter = function (test,xs){    return(         empty(xs) ? [ ] :         test(first(xs)) ? filter(test, rest(xs)) :         build(first(xs),filter(test,rest(xs)))    );};

Page 55: Intro to Functional Programming Workshop (code4lib)

problem 2

var removeAll = function(x,xs){    return(        filter(function(y){                          return y == x},                 xs)    );

};

Page 56: Intro to Functional Programming Workshop (code4lib)

Foldl (Reduce)

http://en.wikipedia.org/wiki/File:Sermon_in_the_Deer_Park_depicted_at_Wat_Chedi_Liem-KayEss-1.jpeg

Page 57: Intro to Functional Programming Workshop (code4lib)

Foldl (Haskell)

mySum xs = foldl (+) 0 xssumOfSquares xs = foldl (+) 0 (map (^2) xs)sumOfSquaresv2 = (mySum . squareAll)

> mySum [1..2000000]2000001000000> sumOfSquares [1..10]385> sumOfSquaresv2 [1..10]385

Page 58: Intro to Functional Programming Workshop (code4lib)

Foldl (Haskell)

myReverse xs = foldl (\x y -> y:x) [] xsmyReverse [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]

Page 59: Intro to Functional Programming Workshop (code4lib)

Exercise set 4c

5 minutes

Page 60: Intro to Functional Programming Workshop (code4lib)

Answers to set 4c

Page 61: Intro to Functional Programming Workshop (code4lib)

problem 1

var foldl = function (step, init, xs) {    return(         empty(xs) ? init  :        foldl(step,                step(init,first(xs)),                rest(xs)

    );};

Page 62: Intro to Functional Programming Workshop (code4lib)

problem 2

var sum = function(xs) {    return foldl(add,0,xs);};

Page 63: Intro to Functional Programming Workshop (code4lib)

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

Page 64: Intro to Functional Programming Workshop (code4lib)

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;    }

Page 65: Intro to Functional Programming Workshop (code4lib)

Break

5 minutes

Page 66: Intro to Functional Programming Workshop (code4lib)

Exercise 5a

5 minutes

Page 67: Intro to Functional Programming Workshop (code4lib)

Answers to set 5a

Page 68: Intro to Functional Programming Workshop (code4lib)

problem 1

var last = compose(first,reverse);

Page 69: Intro to Functional Programming Workshop (code4lib)

problem 2

var reverse = function (xs) {    return foldl(flip(build),[ ],xs);};

Page 70: Intro to Functional Programming Workshop (code4lib)

Standard Deviation

1. calculate the arithmetic mean of the list2. subtract the mean from all the numbers in the list3. square the number in that list4. calculate the sum of the list5. divide the sum by length of list by 16. get the square root of this number 

Page 71: Intro to Functional Programming Workshop (code4lib)

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 xs3. square the numbers in that list

squareDeviations xs = map(^2) devs                      where devs = deviations xs4. calculate the sum of the list

sumSquareDeviations xs = (sum .squareDeviations) xs5. divide the sum by length of list minus 16. get the square root of this number 

sd xs = sqrt $ sumSqDev / lsub1 where sumSqDev = sumSquareDeviations xs       lsub1 = fromIntegral $ ((-1+) . length)xs

Page 72: Intro to Functional Programming Workshop (code4lib)

Exercise 5b

10 minutes

Page 73: Intro to Functional Programming Workshop (code4lib)

Answers to set 5b

Page 74: Intro to Functional Programming Workshop (code4lib)

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));};

Page 75: Intro to Functional Programming Workshop (code4lib)

Standard Deviation (JavaScript)

var sumSqDeviations = compose(sum,squareDeviations);

var sd = function(xs){    return  Math.sqrt(     (sumSqDeviations(xs)/(length(xs)-1)));};

Page 76: Intro to Functional Programming Workshop (code4lib)

Standard Deviation

Haskell> sd [1,4,5,9,2,10]3.65604522218567

JavaScript> sd([1,4,5,9,2,10]);3.65604522218567

Page 77: Intro to Functional Programming Workshop (code4lib)

Function Currying

Page 78: Intro to Functional Programming Workshop (code4lib)

Currying (Haskell)

myAdd x y = x + yadd8 = myAdd 8add9  = (+9)

> myAdd 8 917> add8 917> add9 817

Page 79: Intro to Functional Programming Workshop (code4lib)

Currying (JavaScript)

var curry = function (f,a) {    return(function(){    var args = Array.prototype.slice.call(arguments);     args.unshift(a);    return f.apply(this, args);}    );};

Page 80: Intro to Functional Programming Workshop (code4lib)

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))   );}    );};

Page 81: Intro to Functional Programming Workshop (code4lib)

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

Page 82: Intro to Functional Programming Workshop (code4lib)

Exercise 6

10 minutes

Page 83: Intro to Functional Programming Workshop (code4lib)

Answers to set 6

Page 84: Intro to Functional Programming Workshop (code4lib)

problem 1

var makeAdder = curry(add,x);

var apiClosure = curry(apiSearch,apiKey);

Page 85: Intro to Functional Programming Workshop (code4lib)

problem 2

var unrealisticFunction = function (a, b){    (function(c){        return((function(d){                                if(c<d){                                           return c+d;                                           }else{                                           return c*d;                                          }                    };)(c+a)        );    })(a*b)};

Page 86: Intro to Functional Programming Workshop (code4lib)

Thanks!

email: [email protected]

twitter: willkurt

Page 87: Intro to Functional Programming Workshop (code4lib)

Still have time?

awesome!

Page 88: Intro to Functional Programming Workshop (code4lib)

Haskell vs JavaScript

Page 89: Intro to Functional Programming Workshop (code4lib)

Types!!!

areaOfTrapezoid :: Float -> Float -> Float -> FloatareaOfTrapezoid h b1 b2 = 0.5*h*(b1+b2)

evenList :: (Integral a) => [a] -> [a]evenList xs  = filter even xs

Page 90: Intro to Functional Programming Workshop (code4lib)

Lazy Evaluation!!!

 [2,4..] !! 108> 218

Page 91: Intro to Functional Programming Workshop (code4lib)

Pattern MatchingpatternMatch [a,b,c] = b ++ c ++ apatternMatch [a,b] = a ++ bpatternMatch [] = "no list"patternMatch as = "a larger list"

Page 92: Intro to Functional Programming Workshop (code4lib)

Pattern MatchingpatternMatch ["a","b","c"]>"bca"patternMatch ["a","b"]>"ab"patternMatch [ ]>"no list"patternMatch ["a","b","c","d"]>"a larger list"

Page 93: Intro to Functional Programming Workshop (code4lib)

Who actually uses this stuff?

http://cufp.org/

Page 94: Intro to Functional Programming Workshop (code4lib)

Ocaml

Page 95: Intro to Functional Programming Workshop (code4lib)
Page 96: Intro to Functional Programming Workshop (code4lib)
Page 97: Intro to Functional Programming Workshop (code4lib)

more @ http://www.scala-lang.org/node/1658

Page 98: Intro to Functional Programming Workshop (code4lib)

Haskell

Page 99: Intro to Functional Programming Workshop (code4lib)

... continued

more @ http://haskell.org/haskellwiki/Haskell_in_industry