fuel up javascript with functional programming
TRANSCRIPT
Fuel Up JavaScript (with)Functional ProgrammingFAYA:80
About Me
A passionate programmer finding my way around Functional Programming…
Work at UST Global
I occasionally blog at http://stoi.wordpress.com
Author of YieldJS & SlangJS
I recently co-authored a book with my colleague, friend and mentor called “.NET Design Patterns” by PACKT Publishing
History
Logic
ComputationCategory
Theory
David
Hilbert
Kurt
GodelGentzen
Alonzo
Church
Alan
Turing
Haskell
Curry
William
Howard
Leap ( A projectile at 90 degrees)
Computing Paradigm
<Functional>
Imperative Paradigms with OOP
Domain Driven Design
Design Patterns
Object Functional
Reactive Programming
<Functional> Reactive
Computing Platform
Single Core
Multi-core
Many-core
Clusters/Load-Balancers
Hypervisors
Virtual Machines
Cloud 100 Years
JS Evolution (A snap-shot)
Client Side DHTML/Dom Manipulation
XMLHTTP/AJAX
jQuery (John Resig)
Web Frameworks
YUI, JQuery UI, Backbone, Knockout, Angular, Bootstrap etc.
Libraries
RxJs, Underscore, Prototype, Immutable, Redux, Lodash, Ramda etc.
Trans-compilers
Coffescript, Typescript, Flow etc.
Mobile Application Platforms
Hybrid – Sencha/Cordova based
Server Side
Node.js (Ryan Dahl)
Node Modules
JS Libraries
Being Functional
Algorithm composition to be dealt on the same lines
as mathematical function evaluations Referential Transparency
Predictable
Transparent
Declarative
Composable
Modular
Lambda (λ) calculus
Alonzo Church Definition
Lambda calculus (also written as λ-calculus) is aformal system in mathematical logic for expressingcomputation based on function abstraction andapplication using variable binding and substitution
var AddOperation = (x, y) => x + y;
Lambda Abstraction : λx.x+y [f(x,y) = x + y]
Variables : x & y
Lambda Term : x + y
Simplifications
1. Anonymous functions
2. Uses functions of a single input
Lambda (λ) calculus - Continued
The following three rules give an inductive definition that can be applied to build all syntactically valid lambda terms:
A variable x, is itself a valid lambda term
If t is a lambda term, and x is a variable, then (λx.t) is a lambda term (called a
lambda abstraction);
if t and s are lambda terms, then (ts) is a lambda term (called an application)
Lambda (λ) calculus - Consequences
λ
Referential
Transparency
Anonymous
Functions
First-Class
Functions
Higher-Order
Functions
Closures
Currying &
Partial
Application
Recursion
Memoization
Referential Transparency
Code Motivation
Now since state of i is not guaranteed mutation-free
AddOneRO (x) <> AddOneRO (y)
if x = y, this further implies
AddOneRO (x) - AddOneRO (x) <> 0
thus invalidating the fundamental mathematical
identity
x – x = 0
Closures
Code Motivation
Now since state of i is not guaranteed mutation-free
AddOneRO (x) <> AddOneRO (y)
if x = y, this further implies
AddOneRO (x) - AddOneRO (x) <> 0
thus invalidating the fundamental mathematical
identity
x – x = 0
Currying Concept
Transforms a function that takes
multiple arguments into a
chain of functions each with a
single argument. af (a,b,c)
a
b
c
Currying Implementation – ES5
Augmenting Types Closures Apply Invocation
Currying Implementation – ES6
Closures Apply Invocation
Partial Application – ES6
Transforms a function that take multiple
arguments into a function that accepts a
fixed number of arguments,
which in turn yields yet anotherfunction that accepts the
remaining arguments.
Recursion
Recursions are leveraged in functional programming to accomplish iteration/looping.
Recursive functions invoke themselves, performing an operation repeatedly till the base case is reached
Recursion typically involves adding stack frames to the call stack, thus growing the stack
You can run out of stack space during deep recursions
Tail-Call Optimization
In this case, no state, except for the calling function's address, needs to be saved either on the stack or on the heap
Call stack frame for fIterator is reused for storage of the intermediate results.
Another thing to note is the addition of an accumulator argument (productin this case)
Monads
Monad is a design pattern used to describe computations as a series of steps.
Monads wrap types giving them additional behavior like the automatic propagation of empty value (Maybe monad) or simplifying asynchronous code (Continuation monad).
Identity Monad
Wraps Itself
Maybe Monad
It can represent the absence of any value
List Monad
Represents a lazily computed list of values
Continuation monad
Binds the context
JS Language Features That Aid Functional Programming
ES5
First-class functions
Function objects
Lexical scoping
Function scope
Closures
Prototypal Inheritance
Augmenting Types
Function Invocation
Controlling context (with Apply & Call)
Array Methods
map, reduce, filter
ES6
Arrow Functions
function*
yield, yield* expressions
Map object
Scenario1
How do you add Exception Handling to your code-base without
extensive code-change?
Scenario2
You tend to write algorithms that operate more often on a sequence of items than on a single item.
More likely, you’ll perform several transformations between the source collection and the ultimate result.
Scenario2 – Solution A
Iterating the collection once for every transformation (n iterations for n transformations)
Increases the execution time for algorithms with many transformations
Increases the application’s memory footprint as it creates interim collections for very transformation
END
Output List -> Interim List2
Transformation2 (Square)
Interim List2 -> [1, 9, 25]
Transformation1 (Filter Odds)
Interim List1 -> [1, 3, 5]
START
Input List -> [1, 2, 3, 4, 5]
Scenario2 – Solution B
Create one method that processes every transformation (1 iteration for n transformations)
Final Collection is produced in one iteration. This improves performance
Lowers the application’s memory footprint as it doesn’t create interim collections for every transformation
Sacrifices Reusability (of individual transformations)
END
Output List -> Interim List1
Transformation1 (Filter Odds + Square)
Interim List1 -> [1, 9, 25]
START
Input List -> [1, 2, 3, 4, 5]
Scenario2 – Solution C
Iterators
Enables you to create methods that operate on a sequence
Iterator methods do not need to allocate storage for the entire sequence of elements
Process and return each element as it is requested (Deferred Execution)
Step in
A JavaScript library for creating Iterators, Generators and Continuation methods for Arrays.
The Iterator would be a method getIterator() that augments the Array data type and would have the following interfaces:
moveNext (method)
current (property)
reset (method)
ITERATOR
• Input List [1,2,3,4,5]
MoveNEXT
• 1 <- Square(FilterODD(1))-> OutputList [1]
MoveNEXT
• 2 <- FilterODD(2)-> MoveNEXT
• 3 <- Square(FilterODD(3))-> OutputList [1,9]
MoveNEXT
• 4 <- FilterODD(4)-> MoveNEXT
• 5 <- Square(FilterODD(5))-> OutputList [1,9,25]
ES6 – Generators & Iterators
function*
The function* declaration (function keyword followed by an asterisk) defines a generator function, which returns a Generator object.
Generator Object
The Generator object is returned by a generator function and it conforms to both the iterable protocol and the iterator protocol.
Generators are functions which can be exited and later re-entered. Their context (variable bindings) will be saved across re-entrances.
Concluding
The proof is in the pudding!!!