introduction to functional programming with haskell and javascript

Post on 06-May-2015

4.502 Views

Category:

Technology

2 Downloads

Preview:

Click to see full reader

DESCRIPTION

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.

TRANSCRIPT

Introduction to Functional Programming

with Haskell and JavaScriptWill Kurt

Will Kurt, Creative Commons Attribution-ShareAlike 3.0

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

programming is not worth learning"

--Alan Perlis

So what is Functional Programming?

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

What does this mean?

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

No Side Effects!

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

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

Haskell!

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

JavaScript!!!

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

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]

First class functions

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

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

> add2 57

> add3 58

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

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

First Class Functions (JavaScript)

function argIs2(func){ return func(2);}function argIs3(func){ return func(3);}

Lambda Functions

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

Lambda Function (Haskell)

add4 = (\x -> 4+x)

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

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

Lambda Function (JavaScript)

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

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

Closures

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

Closures (Haskell)

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

add6 = makeAdder 6add7 = makeAdderWithLambda 7

> add5 510> add6 511> add7 512

Closures (JavaScript)

var makeAdder = function(val){ return(function(x){ return val+x; } );};

>var add6 = makeAdder(6);>add6(5);11>add6(8);14

Higher Order Functions

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

Map

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

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"

Map (Haskell)

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

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

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

Filter

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]

Filter (JavaScript)

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

Foldl (Reduce)

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

Foldl (Haskell)

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

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]

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

Foldl (JavaScript) Purely Functional

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

Function Currying

Currying (Haskell)

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

> myAdd 8 917> add8 917> add9 817

Currying (JavaScript)

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

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

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

Standard Deviation

1. calculate the arithmetic mean of the list

2. 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

Standard Deviation1. calculate the arithmetic mean of the listmean xs = sum xs / fromIntegral(length xs)2. subtract the mean from all the numbers in the listdeviations xs = map (\x -> x - m ) xs where m = mean xs3. square the numbers in that listsquareDeviations xs = map(^2) devs where devs = deviations xs4. calculate the sum of the listsumSquareDeviations xs = (sum .squareDeviations) xs5. divide the sum by length of list by 16. get the square root of this number sd xs = sqrt $ sumSqDev / lsub1 where sumSqDev = sumSquareDeviations xs lsub1 = fromIntegral $ ((-1+) . length)xs

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

Standard Deviation (JavaScript)

var sumSqDeviations = compose(sum,squareDeviations);

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

Standard Deviation

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

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

Who actually uses this stuff?

http://cufp.org/

Ocaml

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

Haskell

... continued

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

Questions?

email: wkurt@unr.edu

twitter: willkurt

top related