Functional Programming in Javascript - 1 day course notes

These are my notes from a 1 day training by Brian Lonsdorf given in San Francisco. A cool guy who's really into functional programming and is eager to share that with his fellow developers (thank you man!).
Brian Lansdorf   brian@looprecur.com
Course Overview

Brians recommendations

- play with haskell
- osteele.com functional javascript http://osteele.com/sources/javascript/functional/
- see iotope11.com  quickly learn you a haskell http://isotope11.com/blog/tags/haskell
- type classes on loop-recur on Github curry as well. Production ready.
- steps to use day to day: 1. loops to map/reduce with underscore etc. 2. use compose
- hoogle search: http://www.haskell.org/hoogle/

Bob Martin endorsed functional programming.er...wow!

pasing a dynamic function as a callback is often unnecessary, could just pass fn

"nobody should be writing loops any more"
- use map instead
- map is a higher order function (a function whihc takes a function)

result = map(fnToCallPerItem, array)
results = filter
results = reduce (fn, accumulator, sourceList)

// reduce looks kinda like this
function reduce(callback, accumulator, sourceList)
   for (i in sourceList) {
       accumulator = callback(accululator, list);
   }
   return accumulator;
}


Imperative vs Declarative
- in traditonal style you encode the series of steps baked in, like writing a loop (Imperative)
- in declarative you use functions like map

cata morphisms
para morphisms


types are really important part of functional programming
e.g.
the following means pluck returns c and takes a and b....a, b and c are different types
//+ pluck :: a -> b -> c

the following means a function (cos ()) takes a and b, returns b
//+ map:: (a -> b) -> [a] -> [b]

take an array of a nd return one a
//+ last :: [a] -> a

//+ sort :: (a -> a -> Number) -> [a] -> [a]


Haskell has a search tool to find fns: http://www.haskell.org/hoogle/


Purity
Whats Pure? - fn always return same result every time given same arg..no side effects
You want to write pure functions

Whats Impure? you want to avoid impure fns
- mutations are impure e.g. splice which mutates an array OR push
- references to outside your fn
- side effects such as logging inside, db updates,


Curry (from Haskell Curry...his name)
A function which returns a fn until it gets all its args
Curry allows you to take you data out of your functions to make them more reusable
Can be very powerful

You can call the result of a call to curried fn. Each call freezes a param in place
So you can use curry to partial fns and remix them...but make the fns take data last
When you partially apply a curry fn you only give it some of its arguments

wu.js has an autoCurry fn to correct deficiency




Compose
make functions from other functions
output of 1 fn is input to next
evaluated from right to left, so put 1st call fn on the right
but expects 1 argument per (functions with multiple arguments is tricky)
Denis, this feels really powerful!

// consider you write a fn wordCount as follows. You could could rewrite it using compose as shown
//  just below it

var wordCount = function(st) {
    var words = split(' ', str);
    return length(words);
}
var len = wordCount("have a great morning tea")

var length = compose(length, words);  // where length and words are functions
var len = length("have a great morning tea")

//
var render = compose(displayPage, compose(getRoute, parselUrl));




Category Theory
"The mathematical theory of transforming values"
Which is what programs are!


res = f(x)
g = g(res)

...same...as:

g = g(f(x))





Types
look at types as contaners which add behavior

OurType = Constructor(funtion(x) {
   this.val = x;
});
OurType(3)
OurType("33")
OurType([1, 2])



Functors
- anything which iterates over fmap
- if you have an object which implements an fmap then you have a functor
- fmap will return a new object (type) with update of fn

Think of it as defining behaviors as types, because there's only 1 fmap per prototype.
You objects could just be literals...which are wrapped in fmaps

map(plus1, [3])            same as: [plus1(3)]

map(plus1, MyObject(3))    same as: MyObject(plus1(3))
=> MyObject(4)


Rename map to fmap
fmap(plus1, MyObject(3))    same as: MyObject(plus1(3))


Try to stay out of habit of defining variables e.g.  var my fn = map(aFn)
....just use map when you call it



Monads
A side effect of functors is lots of nested Maybes. If you see your functors nesting then use Monads
Monad implements 3 functions
mjoin : flattens 1 level; evey time gets too nested then mjoin; used a great deal
mbind : basically a flipped fmap, but you have to close it up explicitly. This is very useful for nested calls. mbind is not ready in js per the instructor
mresult :

mcompose : a compose which calls mjoins every step automatically


Install training exercises
  sudo npm install jasmine-node -g
  git clone git@github.com:loop-recur/fp101.git     // exercises repo

Functionaljs library
Brians Functionaljs library: http://github.com/loop-recur/FunctionalJS
It's a fork of osteele's functional lib, but we ignores some of it.
Additional Resources


Note: ''avoids state and mutable data"
Slideshare   (to slide 19, slide 49-end)
Languages etc (slides 25 - 31)



"it’s almost certainly true that functional programming is the next big thing"
Soundbite "Functional programming is programming without assignment statements."
Bobs point is that machines with multi-core processors require languages which  support programming in such an environment. fp with no side effects and more may be an idea whose time has come.

Comments

Popular posts from this blog

deep dive into Material UI TextField built by mui

angular js protractor e2e cheatsheet

react-router v6.4+ loaders, actions, forms and more