Functional Programming for OO Programmers (part 1)
-
Upload
calvin-cheng -
Category
Software
-
view
768 -
download
0
Transcript of Functional Programming for OO Programmers (part 1)
WHY
• Different implementation paradigms for different parts of your program (or system) to produce high quality software with minimal bugs
• Leverage on immutability - shared mutable state is the root of all evil (data race conditions, program complexity etc)
functional programming?
WHYfunctional programming?
• Function purity gives you these benefits
1. testable
2. portable
3. memoizable
4. parallelizable
WHYfunctional programming?
• Real world software
1. Clojure in Akamai
2. Scala in Twitter
3. Haskell in AT&T and in Standard Chartered
4. Reactjs' immutable state and virtual dom in FB
A COMPARISONprocedural vs OO vs functional
• Programming paradigms are world views
1. most languages are on a sliding scale
2. we can apply the different paradigms on any given turing-complete language
A COMPARISONprocedural (“imperative”)
• Code is organised into “small procedures” that use and change our data
A COMPARISONobject-oriented
• Code is organised as ‘templates’ and instantiated with objects with data, that changes
A COMPARISONfunctional
• Code is organised as composable functions and given a particular input data, will always return the same output data
A COMPARISONprocedural vs OO vs functional
• Testableprocedural globally shared data makes it hard to
test.
OO requires mock libraries which adds complexity to testing.
functionalpure functions always return an expected value given a particular input. So testing becomes trivial.
A COMPARISONprocedural vs OO vs functional
• Portableprocedural procedures are often one-off.
OOportability is good but complex inheritance chains result in unexpected behaviors.
functional pure functions are completely portable.
A COMPARISONprocedural vs OO vs functional
• Memoizableprocedural Not memoizable.
OO Not memoizable.
functional pure functions are completely memoizable.
A COMPARISONprocedural vs OO vs functional
• Parallelizableprocedural Rarely parallelizable.
OO Rarely parallelizable due to shared mutable state.
functional pure functions are always parallelizable.
WHAT
• First-class functions
• Functions can return functions
• Lexical closures
• Pure functions
• Safe recursion
• No mutating state
makes a language functional?
FIRST-CLASSvar f = function(a, b) {
return a + b;
};
var callFunctionAndArgs = function(f, a, b) {
return f(a, b);
};
callFunctionAndArgs(f, 1, 2);
functions
FUNCTIONSvar f = function(a, b) {
return a + b;
};
var applyFirst = function (f, a) {
return function(b) {
return f(a, b);
};
};
// applyFirst returns a function that has not been evaluated
// this is applicable for `currying` in functional paradigm
can return functions
LEXICAL SCOPEfunction add(x) {
console.log('x is ' + x);
return function(y) {
return x + y;
};
}
var add10 = add(10);
console.log(add10);
// console.log('x is ' + x); x is not defined in outside of the `add` function
console.log(add10(20));
free variables belong to parent scope
belongs to parent scopereturns [Function]
returns 30
PURE FUNCTIONS
• Functions that don’t change anything out-of-scope and don’t depend on anything out-of-scope are called “pure”
• A pure function always gives the same result given the same parameters; independent of program/system state
with no side effects
SAFE RECURSION
function factorial(n, accumulator) {
if (n === 0) {
return accumulator;
}
return factorial(n -‐ 1, n * accumulator);
}
// recursively call itself from 5 to 0, breaking at n === 0
factorial(5, 1)
tail call
with proper tail call
SAFE RECURSION
• Proper tail call is mechanism by which language compiler/interpreter recognises tail calls and reuses call frames so call stack does not grow
• JavaScript does not use proper tail call (so use with care for recurse depth of no more than 10,000)
• ES6 JavaScript does
with proper tail call
NO MUTATING STATE
• Using pure functions to compose your program result in a program that does not have shared mutable state.
• JavaScript - writing pure functions or programs with no shared mutation state is possible; but not guaranteed.
so everything is predictable