SlideShare a Scribd company logo
1 of 283
Download to read offline
Functional JavaScript,
Why or Why Not?
JSDC 2014
bit.ly/jsdc2014-funjs
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Hi, I'm Greg Weng
From Mozilla Taiwan
@GregWeng
about.me/snowmantw
Motivation
Outline
This talk is about
Concepts
Features
Trade-Off
Libraries
Frameworks
This talk is NOT about
20 mins to write a blog (you had enough of it, right?)
42 Tools for your toolbox (although I do recommend to use some libraries)
Hammer on your hand and everything looks like a nail
Brainwash believe whatever you want; so, hacking, not blaming
Lambda Calculus ...wait, or should we put it in slides?
Premise
No Compiler
(No magic!)
Concepts
Functional Programming?
Which one is better?
Which one is better?
more useful?
OOP FP
Functional Programming is about
Purity
Context
Evaluation
Composition
Transformation
It would bring you
Re-thinking about programming
Patterns efficiently make your works done
Fun -citons
Features of Functional Programmings
First-class function | Closure
High-order functions | Function composition
Purity | Managed side-effects | Laziness
Recursion | Tail-recursion optimization | (Type)
Features of Functional Programmings
First-class function | Closure
High-order functions | Function composition
Purity | Managed side-effects | Laziness
Recursion | Tail-recursion optimization | (Type)
JavaScript Ready
Need some hard works
Impossible if runtime
doesn't support it (well)
Discuss it later...
function() {}
is everything
function() {}
is everything
Or () => { } if you're
a lucky bastard
Use Firefox to embrace () => 'the power of ES6!'
(Fat Arrow Functions)
65535 -- Number (*yes, it's a function)
65535 + 1 -- Number β†’ Number β†’ Number
[1] -- Array Number
[1].push(2) -- Array Number β†’ Number β†’
Array Number
[1, 2, 3].length -- Array Number β†’ Number
[1, 2, 3].map((x) => `${ x }`) -- Array Number β†’ (Number β†’ String)
β†’ Array String
Use FirefoxNightly to embrace `the ${power} of ES6!`
(Quasi-Literals)
About the signature
Array Number β†’ (Number β†’ String) β†’ Array String
[a] β†’ (a β†’ b) β†’ [b]
"return value"function as argumentargument
a, b: type variables
var arr = [1, 2, 3]
arr.push(4)
But what about...
var arr = [1, 2, 3]
arr.push(4)
But what about...
=== return a completely new Array: arr β†’ arr'
=== Array Number β†’ Number β†’
Array Number
Immutable Data Structure
Immutable Data Structure
But in JavaScript we can 'pretend' we have it
when we're playing with FP. Would discuss it later
Immutable Data Structure
But in JavaScript we can 'pretend' we have it
when we're playing with FP. Would discuss it later
Facebook has an 'immutable-js' library
https://github.com/facebook/immutable-js
So now we have the Transformation
65535 -- Number (*yes, it's a function)
65535 + 1 -- Number β†’ Number
[1] -- Array Number
[1].push(2) -- Array Number β†’ Number β†’
Array Number
[1, 2, 3].length -- Array Number β†’ Number
[1, 2, 3].map((x) => `${ x }`) -- Array Number β†’ (Number β†’ String)
β†’
Array String
So now we have the Transformation
So now we have the Transformation
ba
But we need to Compose
them together
Part One.
High-Order Functions
[1,2,3].map((x) => `${ x }`)
[1,2,3].map((x) => `${ x }`)
Array Number β†’ (Number β†’ String) β†’ Array String
Receive functions as arguments
High-Order Functions is useful
map:: [a] β†’ (a β†’ b) β†’ [b]
reduce:: [a] β†’ (a β†’ b β†’ b) β†’ [a] β†’ b
High-Order Functions is useful
map:: [a] β†’ (a β†’ b) β†’ [b]
reduce:: [a] β†’ (a β†’ b β†’ b) β†’ [a] β†’ b
-- Note: these are *NOT* correct signatures in Haskell
-- but in JavaScript, we can treat [1,2,3].map as map::[a]...
-- which makes the code matches the type better
No more looping & ijk tricks
var result = [];
for (var i = 0; i < selectors.length; i++) {
var selector = selectors[i];
result.push(document.querySelector(selector));
}
var result = selectors.map(
(selector) => document.querySelector(selector));
It's not only about SLOC
for (var r = 0; r < records.length; r += 1) {
var record = records[r];
var typeStr = NfcUtils.toUTF8(record.type);
if (NfcUtils.equalArrays(record.type, NDEF.RTD_TEXT)) {
poster.text = poster.text || {};
var textData = NDEF.payload.decodeText(record.payload);
if (poster.text[textData.language]) {
// According to NFCForum-SmartPoster_RTD_1.0 3.3.2,
// there MUST NOT be two or more records with
// the same language identifier.
return null;
// to be continue...
reduce:: [a] β†’ b
reduce:: [a] β†’ b
~= build things in this case
return records.reduce((poster, record) => {
var typeStr = NfcUtils.toUTF8(record.type);
if (NfcUtils.equalArrays(record.type, NDEF.RTD_TEXT)) {
poster.text = poster.text || {};
var textData = NDEF.payload.decodeText(record.payload);
if (poster.text[textData.language]) {
// According to NFCForum-SmartPoster_RTD_1.0 3.3.2,
// there MUST NOT be two or more records with
// the same language identifier.
return null;
// to be continue...
return records.reduce((poster, record) => {
var typeStr = NfcUtils.toUTF8(record.type);
if (NfcUtils.equalArrays(record.type, NDEF.RTD_TEXT)) {
poster.text = poster.text || {};
var textData = NDEF.payload.decodeText(record.payload);
if (poster.text[textData.language]) {
// According to NFCForum-SmartPoster_RTD_1.0 3.3.2,
// there MUST NOT be two or more records with
// the same language identifier.
return null;
// to be continue...
A real case in Gaia project: Bug 1039245
People know what are you doing when
they saw the 'map' and 'reduce'
People know what are you doing when
they saw the 'map' and 'reduce'
If there is no or only few side-effects
It can be more powerful if you play
with the type
map:: [a] β†’ (a β†’ b) β†’ [b]
map:: [a] β†’ (a β†’ b) β†’ [b]
while a/URL, b/IO
urls.map((url) => Http.get(url)
.filter((response) => response.status !== 404 )
.map((response) => Parser.comment(response))
.map((comment) => UI.renderComment(comment))
.execute()
urls.map((url) => Http.get(url) // map (URL -> IO) to [ URL ]
.filter((response) => response.status !== 404 )
.map((response) => Parser.comment(response))
.map((comment) => UI.renderComment(comment))
.execute()
// If we have lazy IO & async mixed Monad
// Transformer...will discuss it later
urls.map((url) => Http.get(url) // map (URL -> IO) to [ URL ]
.filter((response) => response.status !== 404 )
.map((response) => Parser.comment(response))
.map((comment) => UI.renderComment(comment))
.execute()
// If we have lazy IO & async mixed Monad
// Transformer...will discuss it later
[URL] β†’ [IO a] β†’ [Parsed b] β†’ [DOM c]
Not only handle data
Some advanced High-Order
Functions of list
forEach:: [a] β†’ (a β†’ SideEffect; will discuss it later)
filter:: [a] β†’ (a β†’ Bool) β†’ [a] * the type is similar with map
groupBy:: [a] β†’ (a β†’ a β†’ Bool) β†’ [[a]] * lo-dash has it
zipWith: [a] β†’[b] β†’ (a β†’ b β†’ c) β†’ [c] * worth to implement
forEach:: [a] β†’ (a β†’ SideEffect; will discuss it later)
filter:: [a] β†’ (a β†’ Bool) β†’ [a] * the type is similar with map
groupBy:: [a] β†’ (a β†’ a β†’ Bool) β†’ [[a]] * lo-dash has it
zipWith: [a] β†’[b] β†’ (a β†’ b β†’ c) β†’ [c] * worth to implement
Recommends to use lo-dash library to acquire these
functions
And reducing is even more basic
var map = (xs, fn) => {
return xs.reduce((acc, x) => {
return acc.concat([ fn(x) ]);
}, []); };
Recommends to use and get understand the 'transducer.js'
Summary: High-Order Functions is
useful, especially for list
Do map & reduce whenever
it's possible
With type in mind we can do lots of
things, not only handling data
With type in mind we can do lots of
things, not only handling data
We'll see more cases soon
And the best thing is major browsers
support map & reduce already
Part Two.
Function Composition
In Functional Programming we don't
like to define new function
Instead, we compose them
when we need it
map (not.odd) [1,2,3]
map (not.odd) [1,2,3]
(.):: (b β†’ c) β†’ (a β†’ b) β†’ (a β†’ c)
Is much better than
map (x -> !odd x) [1,2,3]
let notOdd x = not(odd x);
map notOdd [1,2,3]
This is important because
Safety if small functions are safe, the larger one is safe, too
Reusability no need to create new functions
Flexibility compose anything you want at anytime
Composition is good for you
Unfortunately in JavaScript we don't
have such nice syntax support
map (not.odd.read) ["1","2","3"]
[1,2,3].map(compose(not, odd, read))
Recommends to use lo-dash library to acquire the
compose functions
map (not.odd.read) ["1","2","3"]
[1,2,3].map(compose(not, odd, read))
...?
Function composition is actually the
most important idea we need to know
However in daily works we may fail to
use it unless we sugar the syntax...
with the only one 'operator' we have
$(a, b, c)
Although it's almost abused?
Part Three.
Context & Functor
['1','2','3'].map( $(not, odd, read) )
[a] β†’ (a β†’ b) β†’ [b]
[a] β†’ (a β†’ b) β†’ [b]
['1','2','3'].map( $(not, odd, read) )
m a β†’ (a β†’ b) β†’ m b
['1','2','3'].map( $(not, odd, read) )
m a β†’ (a β†’ b) β†’ m b
IO a β†’ (a β†’ b) β†’ IO b
getString.map( $(not, odd, read) )
IO String
m a β†’ (a β†’ b) β†’ m b
IO a β†’ (a β†’ b) β†’ IO b
[] a β†’ (a β†’ b) β†’ [] b
['1','2','3'].map( $(not, odd, read) )
[ ] Number
m a β†’ (a β†’ b) β†’ m b
IO a β†’ (a β†’ b) β†’ IO b
[] a β†’ (a β†’ b) β†’ [] b
HTTP a β†’ (a β†’ b) β†’ HTTP b
HTTPServer.map( $(not, odd, read) )
HTTP Request
m a β†’ (a β†’ b) β†’ m b
IO a β†’ (a β†’ b) β†’ IO b
[] a β†’ (a β†’ b) β†’ [] b
HTTP a β†’ (a β†’ b) β†’ HTTP b
Maybe a β†’ (a β†’ b) β†’ Maybe b
maybeRead.map( $(not, odd, read) )
Maybe a
m a β†’ (a β†’ b) β†’ m b
IO a β†’ (a β†’ b) β†’ IO b
[] a β†’ (a β†’ b) β†’ [] b
HTTP a β†’ (a β†’ b) β†’ HTTP b
Maybe a β†’ (a β†’ b) β†’ Maybe b
Now we have a same map & function
for the different contexts
m a β†’ (a β†’ b) β†’ m b
IO a β†’ (a β†’ b) β†’ IO b
[] a β†’ (a β†’ b) β†’ [] b
HTTP a β†’ (a β†’ b) β†’ HTTP b
Maybe a β†’ (a β†’ b) β†’ Maybe b
Now we have a same map & function
for the different contexts
In fact this general map called 'fmap'
List apply the function to every element ([1,2,3])
HTTP receive request and response with the handled content
Maybe if previous one is Nothing, do not apply the function
Same fmap; different meaning
The fmap is a common interface
that all contexts are agreed with
Type classes with fmap called
Functor
Functor can lift a function
onto the context
m
a
m
b
( a β†’ b)
fmap
The function keep knowing nothing
about the Context
m
a
m
b
( a β†’ b)
$(not, odd, read)
fmap
It only need to care how to
transform the value from a to b
How to apply context-relevant rules
is encapsulated by fmap
$(not, odd, read)
List
a
List
b
( a β†’ b)
List#fmap
apply the function on every element of the list
fmap
$(not, odd, read)
HTTP
a
HTTP
b
( a β†’ b)
HTTP#fmap
receive the request 'a' and response 'b' to client
fmap
$(not, odd, read)
Maybe
a
Maybe
b
( a β†’ b)
fmap
Maybe#fmap
If there is no 'a' (Nothing), do nothing
This is powerful because we can
keep functions simple
And apply them into different
context to do different things
HTTP
Request
HTTP
Response
( Request β†’Response)
Needn't know how to do IO,
networking, etc.
List
Request
List
Response
( Request β†’ Response)
Needn't know how to apply on every
element (iterate) within the list
Contexts could even be stockpiled
to do complex computations
Contexts could even be stockpiled
to do complex computations
Although stockpiling is beyond Functor.
See Appendix: Monad Transformer
HTTP
Request
HTTP
Response
List List
( Request β†’Response)
Needn't know how to do IO,
networking, etc.
Needn't know how to map
it to all requests.
And the stockpiling order
is very important
HTTP
Request
HTTP
Response
List List
( Request β†’Response)
Needn't know how to do IO,
networking, etc.
Needn't know how to map
it to all requests.
[HTTP Request] (buffering?)
HTTP [Request] (SPDY?)
List
Request
List
Response
HTTP HTTP
( Request β†’Response)
Needn't know how to do IO,
networking, etc.
Needn't know how to map
it to all requests.
So, Functor is an useful concept to
separate context and pure function
But we still need more powerful
structure to do the computation
Part Four.
Monad
"When you gaze long into a Monad
the Monad also gazes into you"
Monad, monad, everywhere, nor any
drop to understand
Monad is a solution for
composing Context-ed actions
In Functor we can only transform
pure data to pure data
HTTP
Request
HTTP
Response
( Request β†’Response)
( a β†’ b )
We may have different sub-
contexts for HTTP
HTTP::200
HTTP::301
HTTP::403
HTTP::500
We can't instance different sub-
contexts with only Functor
HTTP
Request
HTTP::200
Response
( Request β†’Response)
( a β†’ b )
HTTP
Request
HTTP::200
Response
( Request β†’Response)
( a β†’ b )
The 'fmap' only allow (a β†’ b), not (a β†’ m b)
So we can't control which sub-context should be instanced
HTTP
Request
HTTP::404
Response
( Request β†’Response)
( a β†’ b )
The 'fmap' only allow (a β†’ b), not (a β†’ m b)
So we can't control which sub-context should be instanced
Monad allows you to do that with
its 'bind' function
(>>=):: m a β†’ ( a β†’ m b ) β†’ m b
(>>=):: m a β†’ ( a β†’ m b ) β†’ m b
a β†’ m bm a
>>=m a β†’ a a β†’ b; b β†’ m b
unwrap wrap
Allow inject ( a β†’ m b ) means allow
we control the way to wrap the value
HTTPServer
>>= (req -> login)
>>= (authReq -> case (doAuth authReq) of
True -> content
False -> authError))
HTTPServer
>>= (req -> login)
>>= (authReq -> case (doAuth authReq) of
True -> content
False -> authError))
the 'bind' function, infix
HTTP::403
HTTP::200
let content response = HTTP200 response
let authError response = HTTP403 response
(authReq -> case (doAuth authReq) of
True -> content
False -> authError)
( a β†’ m b )
How 'bind' works?
(req -> login) (authReq -> doAuth...)>>= (......)>>=
Client ClientHTTP Monad
HTTPServer
>>= (req -> login)
>>= (authReq -> case (doAuth authReq) of
True -> content
False -> authError))
The bound function stil don't need know
how to open IO, networking, etc.
(a β†’ m b)
We still keep the same interface,
different implementations feature
(req -> login) (authReq -> doAuth...)>>= (......)>>=
Client ClientHTTP Monad
(req -> login) (authReq -> doAuth...)>>= (......)>>=
Map to all
elements
Map to all
elements
List Monad
And the Monadic actions can be
chained as function composition
a β†’ m c
a -> m b b -> m c>>=
a β†’ m c
a -> m b b -> m c>>=
actionFoo = actionA >>= actionB
actionBar = actionFoo >>= actionC
(and so on...)
It's just like Function Composition
But now we can handle Contexts
h = g 。f
h = f >>= g
a β†’ m c = a β†’ m b >>= b β†’ m c
a β†’ c = b β†’ c 。 a β†’ b
And Monad could save us from
unexpected side-effects
And Monad could save us from
unexpected side-effects
if all methods with side-effects
are wrapped
getString
forkIO
openFile
readTVar
+, -, *...
compress
tail
par
writeArray
a β†’ m b
while m /IO, HTTP, UI, ...
a β†’ b
getString
forkIO
openFile
readTVar
+, -, *...
compress
tail
par
writeArray
a β†’ m b
while m /IO, HTTP, UI, ...
a β†’ b
Embed them rationally
with the 'bind' function
So we can combine these functions
and Contexts rationally
from Gaia/System/notifications.js (v2.0)
line: 290 ~ 490 (200 lines)
from Gaia/System/notifications.js (v2.0)
line: 290 ~ 490 (200 lines)
- Create notification
- Detecting gesture
- Append notification
- Play sound
- Color one container
- Scroll container to top
...
from Gaia/System/notifications.js (v2.0)
line: 290 ~ 490 (200 lines)
There are so many
requests
from so many different
contexts
from Gaia/System/notifications.js (v2.0)
line: 290 ~ 490 (200 lines)
It's possible to use FP ideas,
to response these requests
with individual logic units is
trivial & reasonable
DOM
Create notification
Change container's style
UI
Append notification
Scroll container to top
Gesture
Detect gesture on notification
Sound
Play sound
Asynchronous
Manage asynchronous operations
Conditional Statements
If...else to do or not to do things
I/O
Get/write data and control device
...
Functor
Monad
Monad Transformer
High-order Function
Partial Application
Curry
...
This is important because no one
like surprises
Another reason that Monad could
encapsulate side-effects...
X
a β†’ m b β†’ m m c β†’ m d β†’ e
X
a β†’ m b β†’ m m c β†’ m d β†’ e
There is no way allow
a Context-ed value to escape
There is no way allow
a Context-ed value to escape
Yes, I know Comonad and unsafe-
can do that, but...
So once your value get tainted, you
can't use it outside the Monad
Instead, you embed your function
into the tainted context
HTTPServer
>>= (req -> login)
>>= (authReq -> case (doAuth authReq) of
True -> content
False -> authError))
Can only access the value when you're in the context
HTTPServer
>>= (req -> login)
>>= (authReq -> case (doAuth authReq) of
True -> content
False -> authError))
let HTTPValue =
doSomething HTTPValue ...
No way to do that!
extract
The similar case in JavaScript is
the Promised actions
Promise(() => {...})
.then((a) => {...})
.then((b) => {...})
.then((c) => {...})
.then((d) => {...}).extract();
var promisedValue =
No way to do that!
doSomething(promisedValue); ...
In fact what we could learn from
Monad is not only the type & rules
But the idea to control different
computations in different Contexts
Promise(() => {...})
.then((a) => {...})
.then((b) => {...})
.then((c) => {...})
.then((d) => {...});
Context: Ensure the following
step executes only after the
previous one get done.
$('some-selector')
.each(...)
.animate(...)
.append(...)
Context: Select, manipulate and
check the DOM element(s)
_.chain(someValue)
.filter(...)
.groupBy(...)
.map(...)
.reduce(...)
Context: Guarantee the value
would be transformed by lo-dash
functions
ensure()
.frame()
.element(...)
.actions()
.pulls(0, 400)
.perform()
.must(...)
Context: Ensure the integration
test only do what user can do,
instead of magic manipulations
These computations focus on the
transforming within the contexts
Just like what Monads
do in Haskell
Promise(() => {...})
.then((a) => {...})
.then((b) => {...})
.then((c) => {...})
.then((d) => {...});
$('some-selector')
.each(...)
.animate(...)
.append(...)
_.chain(someValue)
.filter(...)
.groupBy(...)
.map(...)
.reduce(...)
DOM _Async
threeCoins = do
a <- randomSt
b <- randomSt
c <- randomSt
return (a,b,c)
main = do
a <- ask "Name?"
b <- ask "Age?"
return ()
IO
add mx my = do
x <- mx
y <- my
return (x + y)
MaybeState
threeCoins = do
a <- randomSt
b <- randomSt
c <- randomSt
return (a,b,c)
main = do
a <- ask "Name?"
b <- ask "Age?"
return ()
IO
add mx my = do
x <- mx
y <- my
return (x + y)
MaybeState
the 'do' notification
So the question is not "why we
need Monad in JavaScript"
But "is it worth to implement the
fluent interface more Monadic"?
How to make
JavaScript
More Monadic?
Lazy vs eager: sometimes it's reasonable to be lazy
Flow control for asynchronous operations is important
Type in some critical places we still need the information
Laws is it possible to follow the Monad Laws?
Requirements to get closer with real Monads
It's easy to make our 'Monad'
lazy with some type supporting
var action = (new Maybe()).Just(3)
.then((v) => {
return (new Maybe()).Just(v+99); })
.then((v) => {
return (new Maybe()).Just(v-12); })
.then((v) => {
return (new Maybe()).Nothing(); })
.then((v) => {
return (new Maybe()).Just(v+12); })
// Execute it with `action.done()`.
action = (Just 3)
>>= v -> return (v + 99)
>>= v -> return (v - 12)
>>= v -> Nothing
>>= v -> return (v + 12)
https://github.com/snowmantw/
warmfuzzything.js/blob/master/maybe.js
var action = (new Maybe()).Just(3)
.then((v) => {
return (new Maybe()).Just(v+99); })
.then((v) => {
return (new Maybe()).Just(v-12); })
.then((v) => {
return (new Maybe()).Nothing(); })
.then((v) => {
return (new Maybe()).Just(v+12); })
// Execute it with `action.done()`.
action = (Just 3)
>>= v -> return (v + 99)
>>= v -> return (v - 12)
>>= v -> Nothing
>>= v -> return (v + 12)
https://github.com/snowmantw/
warmfuzzything.js/blob/master/maybe.js
...?
But things become crazy when the
'Monad' need to mix with Promise
(to support async operations natively)
action = (Just 3)
>>= v -> return (v + 99)
>>= v -> return (v - 12)
>>= v -> Nothing
>>= v -> return (v + 12)
https://github.com/snowmantw/
warmfuzzything.js/blob/master/promise_maybe.js
var action = (new PromiseMaybe()).Just(3)
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Just(v+99)); })
.then((mSelf, v) => {
setTimeout(function() { // Only for test. Meaningless.
mSelf.returns((new PromiseMaybe).Just(v-12));
}, 3000); })
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Nothing()); })
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Just(v+12)); });
action = (Just 3)
>>= v -> return (v + 99)
>>= v -> return (v - 12)
>>= v -> Nothing
>>= v -> return (v + 12)
https://github.com/snowmantw/
warmfuzzything.js/blob/master/promise_maybe.js
var action = (new PromiseMaybe()).Just(3)
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Just(v+99)); })
.then((mSelf, v) => {
setTimeout(function() { // Only for test. Meaningless.
mSelf.returns((new PromiseMaybe).Just(v-12));
}, 3000); })
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Nothing()); })
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Just(v+12)); });
action = (Just 3)
>>= v -> return (v + 99)
>>= v -> return (v - 12)
>>= v -> Nothing
>>= v -> return (v + 12)
https://github.com/snowmantw/
warmfuzzything.js/blob/master/promise_maybe.js
var action = (new PromiseMaybe()).Just(3)
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Just(v+99)); })
.then((mSelf, v) => {
setTimeout(function() { // Only for test. Meaningless.
mSelf.returns((new PromiseMaybe).Just(v-12));
}, 3000); })
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Nothing()); })
.then((mSelf, v) => {
mSelf.returns((new PromiseMaybe).Just(v+12)); });
It can be better, but the real
problem is it's implementation
is very tricky
But the most important things is
it works!
But the most important things is
it works!
When I see a bird that walks like a Monad and swims
like a Monad and quacks like a Monad, I call that bird a Monad
But the most important things is
it works!
(although it doesn't follow the laws)
(although it doesn't follow the laws)
Yes we're still writing
JavaScript!
Summary: Monad light the way to
isolate side-effects in JavaScript
But how much we gain depends on
how much we paid
But how much we gain depends on
how much we paid
(or someone must pay it for us)
But how much we gain depends on
how much we paid
In my experience the 'simple' fluent interface
would be not enough soon
"不小心造出個 lexer ηš„ monad δΊ†οΌŒδ½†ε•ι‘Œζ˜―ζˆ‘
在 javascript 阿阿阿" @banacorn
The Missing Part
How to stockpile different Contexts?
The missing part: how to stockpile different Contexts?
List
Request
List
Response
HTTP HTTP
( Request β†’Response)
The missing part: how to stockpile different Contexts?
List
Request
List
Response
HTTP HTTP
( Request β†’Response)
(See Appendix. Yes, we have a 200+ slides...)
Part Five.
Functional Reactive Programming
TL;DR
React & Flux
So far we discussed how to
compose computations rationally
So far we discussed how to
compose computations rationally
"But 80% of my work is
for UI changes"
Behavior trigger event
Data changed
View redraw
Let's think about what is an GUI program...
Behavior trigger event
Data changed
View redraw
Let's think about what is an GUI program...
It's so simple, right?
Behavior trigger event
Data changed
View redraw
Let's think about what is an GUI program...
Behavior trigger event
Data changed
View redraw
Let's think about what is an GUI program...
Can be done purely, while
IO is relatively simple than drawing
Lots of side-effects and
trolling data anytime
With React we only care
about data changes
And 'create' a new view
every time it get changed
React.renderComponent(
React.DOM.h1(null, "Hello, world!"),
document.getElementById('example'););
And 'create' a new view
every time it get changed
and efficiency is what React should care about
This is like how to manipulate the
immutable data structure in FP...
ys = insert ("e", xs)
This is like how to manipulate the
immutable data structure in FP...
view' = render(..)
And Flux looks like...
And Flux looks like...
And Flux looks like...
Yampa - a Functional Reactive Programming
framework in Haskell
So React & Flux is really close to FP...
It's great because we can build a full
Functional Programming stack on it
It's great because we can build a full
Functional Programming stack on it
with Function Composition, Monad, Partial Application, Curry,
Monad Transformer, and other useful features in JavaScript
Conclusion
We could learn lots from Functional
Programming but no need to bet on it
Since we're still with a language
not so Functional
ex: Composing everything ensures
safety, reusability and flexibility
But the lack of syntax supporting
make bitter to be used
High-Order functions is useful, use
them whenever it's available
And for list manipulation,
native support is ready
Moreover, list transformations are not
only for data processing
Functor & Monad is not so terrible:
they're just for contexts
And isolate pure & impure
computations is good for us
In JavaScript, fluent interface is
very close to Monad
But in current status we don't have a
total Monad solution yet
Although when it grows, more and
more Monadic features are required
So if your fluent interface code get
into troubles of Contexts...
Consider what Monad have and pick
up some concepts to implement
Finally, if you want to construct a
FP-flavour GUI program
FRP is your friend
React & Flux is your friend
Tools & References
- lo-dash is your friend
- transducer in JavaScript is a good way to understand
reducing deeply
- immutable-js make your code purer
- React & Flux bring you a whole new FRP world
- jQuery is a Monad (no, not really, see the comments)
- Learn You a Haskell a good way to learn about Monad
- Typeclassopedia classical article about Typeclasses
- Foldr Foldl Foldl' detailed article about reducing
- CSP and transducers about Transducer in JavaScript
Help and Need Help
How to contribute to FirefoxOS
Q&A
Appendix
How to stockpiling different
Monads
a -> m n b
CSE230 Wi14 - Monad Transformers
When you have many Monads
When you have many Monads
HTTP
Request
HTTP
Response
Logger Logger
( Request β†’Response)
When you have many Monads
HTTP
Request
HTTP
Response
Logger Logger
( Request β†’Response)
We want to process HTTP as usual
Meanwhile we want every request-response
been logged
When you have many Monads
HTTP
Request
HTTP
Response
Database Database
( Request β†’Response)
We want to process HTTP as usual
Meanwhile we may perform some
database R/W at the same time
When you have many Monads
HTTP
Request
HTTP
Response
Error Error
( Request β†’Response)
We want to process HTTP as usual
Meanwhile we want to capture every
step's error and handle it
Monad Transformer
HTTP
Request
HTTP
Response
m m
>>=
Perform m first (ex: Logger)
Then perform the target Monad (HTTP)
It's somewhat of the AOP concept
HTTPTransformer
HTTP
Logger
Request
HTTPT (Transformer)
>>=
How Monad Transformer Works
HTTP
Logger m
The transformer only know the inner one
is the target Monad it can handle with
ex: (MaybeT β†’ Maybe, HTTPT β†’ HTTP)
Request
HTTPT (Transformer)
>>=
How Monad Transformer Works
HTTP
Logger m
The transformer only know the inner one
is the target Monad it can handle with
ex: (MaybeT β†’ Maybe, HTTPT β†’ HTTP)
Request
HTTPT ( "T"ransformer ) would not
care what the outer monad is
HTTPT (Transformer)
>>=
How Monad Transformer Works
HTTP
Logger m#bind
First transformer would call the outer
one's bind function to apply the rule on
the inner monadic value, and dig into the
second layer (inner monad)Request
apply m#bind on the
HTTP monadic value
HTTPT doesn't know
what the 'm' is
How Monad Transformer Works
HTTP
Logger m#bind
First transformer would call the outer
one's bind function to apply the rule on
the inner monadic value
Request
apply m#bind on the
HTTP monadic value
HTTPT doesn't know
what the 'm' is
How Monad Transformer Works
For this example, it means to perform the logging
HTTP
Logger m#bind
And then dig into the second layer
(inner monad)
Request
apply m#bind on the
HTTP monadic value
HTTPT doesn't know
what the 'm' is
How Monad Transformer Works
Now we're in the inner monad context
HTTP
Logger m
Then transformer apply the specific
Monad's binding rules on the inner
monadic value, including to call the
embedded function, just like what the
ordinary Monad does, but now we get
(m n b) rather than (m b)
Request Request
HTTP
Response
>>=
Logger m
http://en.wikibooks.
org/wiki/Haskell/Monad_transformers#A_simple_mon( a β†’ m n b )
How Monad Transformer Works
Step by Step
Outer 'Bind' applied on the monadic value
m (n a) β†’ m (n a)'
Inner 'Bind' applied on the monadic value
m (n a)' β†’ m (n b)
Wrap It Back while it still doesn't know what the m is
m (n a)' β†’ m (n b)
A not so successful try to implement
it in JavaScript
PromiseMaybeT
Now it can stockpile arbitrary PromiseMonad on one
PromiseMaybe monadic action
https://github.com/snowmantw/
warmfuzzything.js/blob/master/maybet.js
PromiseMaybeT
Now it can stockpile arbitrary PromiseMonad on one
PromiseMaybe monadic action
But since our basic 'Monad' is tricky, the transformer, is tricky, too
https://github.com/snowmantw/
warmfuzzything.js/blob/master/maybet.js

More Related Content

What's hot

Deep dive to PostgreSQL Indexes
Deep dive to PostgreSQL IndexesDeep dive to PostgreSQL Indexes
Deep dive to PostgreSQL IndexesIbrar Ahmed
Β 
ggplot2 extensions-ggtree.
ggplot2 extensions-ggtree.ggplot2 extensions-ggtree.
ggplot2 extensions-ggtree.Dr. Volkan OBAN
Β 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorialkizzx2
Β 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanWei-Yuan Chang
Β 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs偉格 高
Β 
The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181Mahmoud Samir Fayed
Β 
JAVA 8 : Migration et enjeux stratΓ©giques en entreprise
JAVA 8 : Migration et enjeux stratΓ©giques en entrepriseJAVA 8 : Migration et enjeux stratΓ©giques en entreprise
JAVA 8 : Migration et enjeux stratΓ©giques en entrepriseSOAT
Β 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: DeanonymizingDavid Evans
Β 
Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwoEishay Smith
Β 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern偉格 高
Β 
Advanced Data Visualization in R- Somes Examples.
Advanced Data Visualization in R- Somes Examples.Advanced Data Visualization in R- Somes Examples.
Advanced Data Visualization in R- Somes Examples.Dr. Volkan OBAN
Β 
Functional Javascript, CVjs
Functional Javascript, CVjsFunctional Javascript, CVjs
Functional Javascript, CVjskaw2
Β 
The Aggregation Framework
The Aggregation FrameworkThe Aggregation Framework
The Aggregation FrameworkMongoDB
Β 
Scalding: Reaching Efficient MapReduce
Scalding: Reaching Efficient MapReduceScalding: Reaching Efficient MapReduce
Scalding: Reaching Efficient MapReduceLivePerson
Β 
Some Examples in R- [Data Visualization--R graphics]
 Some Examples in R- [Data Visualization--R graphics] Some Examples in R- [Data Visualization--R graphics]
Some Examples in R- [Data Visualization--R graphics]Dr. Volkan OBAN
Β 
"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко
"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко
"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнкоFwdays
Β 
ClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei MilovidovClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei MilovidovAltinity Ltd
Β 
Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018
Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018
Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018DevOpsDays Tel Aviv
Β 

What's hot (20)

Deep dive to PostgreSQL Indexes
Deep dive to PostgreSQL IndexesDeep dive to PostgreSQL Indexes
Deep dive to PostgreSQL Indexes
Β 
ggplot2 extensions-ggtree.
ggplot2 extensions-ggtree.ggplot2 extensions-ggtree.
ggplot2 extensions-ggtree.
Β 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorial
Β 
Python fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuanPython fundamentals - basic | WeiYuan
Python fundamentals - basic | WeiYuan
Β 
Functional programming using underscorejs
Functional programming using underscorejsFunctional programming using underscorejs
Functional programming using underscorejs
Β 
The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181The Ring programming language version 1.5.2 book - Part 45 of 181
The Ring programming language version 1.5.2 book - Part 45 of 181
Β 
JAVA 8 : Migration et enjeux stratΓ©giques en entreprise
JAVA 8 : Migration et enjeux stratΓ©giques en entrepriseJAVA 8 : Migration et enjeux stratΓ©giques en entreprise
JAVA 8 : Migration et enjeux stratΓ©giques en entreprise
Β 
Lekcja stylu
Lekcja styluLekcja stylu
Lekcja stylu
Β 
this
thisthis
this
Β 
Class 31: Deanonymizing
Class 31: DeanonymizingClass 31: Deanonymizing
Class 31: Deanonymizing
Β 
Using Scala Slick at FortyTwo
Using Scala Slick at FortyTwoUsing Scala Slick at FortyTwo
Using Scala Slick at FortyTwo
Β 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern
Β 
Advanced Data Visualization in R- Somes Examples.
Advanced Data Visualization in R- Somes Examples.Advanced Data Visualization in R- Somes Examples.
Advanced Data Visualization in R- Somes Examples.
Β 
Functional Javascript, CVjs
Functional Javascript, CVjsFunctional Javascript, CVjs
Functional Javascript, CVjs
Β 
The Aggregation Framework
The Aggregation FrameworkThe Aggregation Framework
The Aggregation Framework
Β 
Scalding: Reaching Efficient MapReduce
Scalding: Reaching Efficient MapReduceScalding: Reaching Efficient MapReduce
Scalding: Reaching Efficient MapReduce
Β 
Some Examples in R- [Data Visualization--R graphics]
 Some Examples in R- [Data Visualization--R graphics] Some Examples in R- [Data Visualization--R graphics]
Some Examples in R- [Data Visualization--R graphics]
Β 
"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко
"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко
"НСмного ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² JavaScript" АлСксСй КовалСнко
Β 
ClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei MilovidovClickHouse Features for Advanced Users, by Aleksei Milovidov
ClickHouse Features for Advanced Users, by Aleksei Milovidov
Β 
Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018
Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018
Wat.tf - Nati Cohen - DevOpsDays Tel Aviv 2018
Β 

Similar to JSDC 2014 - functional java script, why or why not

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
Β 
Groovy
GroovyGroovy
GroovyZen Urban
Β 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskellujihisa
Β 
Π‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай Мозговой
Π‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай ΠœΠΎΠ·Π³ΠΎΠ²ΠΎΠΉΠ‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай Мозговой
Π‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай МозговойSigma Software
Β 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
Β 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course OutlineBaishampayan Ghose
Β 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptCaridy Patino
Β 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Konrad Malawski
Β 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Workhorse Computing
Β 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsFrançois Garillot
Β 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScriptChengHui Weng
Β 
Monads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevMonads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevJavaDayUA
Β 
Functional programming in javascript
Functional programming in javascriptFunctional programming in javascript
Functional programming in javascriptBoris Burdiliak
Β 
Functional perl
Functional perlFunctional perl
Functional perlErrorific
Β 
Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1Nagavarunkumar Kolla
Β 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Raffi Krikorian
Β 
Using Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneUsing Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneCarl Brown
Β 

Similar to JSDC 2014 - functional java script, why or why not (20)

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Β 
Groovy
GroovyGroovy
Groovy
Β 
From Javascript To Haskell
From Javascript To HaskellFrom Javascript To Haskell
From Javascript To Haskell
Β 
Π‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай Мозговой
Π‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай ΠœΠΎΠ·Π³ΠΎΠ²ΠΎΠΉΠ‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай Мозговой
Π‘Ρ‚ΠΎΠ»ΠΏΡ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ программирования для Π°Π΄Π΅ΠΏΡ‚ΠΎΠ² ООП, Николай Мозговой
Β 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
Β 
Pune Clojure Course Outline
Pune Clojure Course OutlinePune Clojure Course Outline
Pune Clojure Course Outline
Β 
MiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScriptMiamiJS - The Future of JavaScript
MiamiJS - The Future of JavaScript
Β 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014
Β 
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Neatly Hashing a Tree: FP tree-fold in Perl5 & Perl6
Β 
Scala Collections : Java 8 on Steroids
Scala Collections : Java 8 on SteroidsScala Collections : Java 8 on Steroids
Scala Collections : Java 8 on Steroids
Β 
Things about Functional JavaScript
Things about Functional JavaScriptThings about Functional JavaScript
Things about Functional JavaScript
Β 
Monads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevMonads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy Dyagilev
Β 
Functional programming in javascript
Functional programming in javascriptFunctional programming in javascript
Functional programming in javascript
Β 
Groovy
GroovyGroovy
Groovy
Β 
Functional perl
Functional perlFunctional perl
Functional perl
Β 
Spark_Documentation_Template1
Spark_Documentation_Template1Spark_Documentation_Template1
Spark_Documentation_Template1
Β 
Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....Scala + WattzOn, sitting in a tree....
Scala + WattzOn, sitting in a tree....
Β 
Using Regular Expressions and Staying Sane
Using Regular Expressions and Staying SaneUsing Regular Expressions and Staying Sane
Using Regular Expressions and Staying Sane
Β 
Fancy talk
Fancy talkFancy talk
Fancy talk
Β 
Internal workshop es6_2015
Internal workshop es6_2015Internal workshop es6_2015
Internal workshop es6_2015
Β 

More from ChengHui Weng

Rust + python: lessons learnt from building a toy filesystem
Rust + python: lessons learnt from building a toy filesystemRust + python: lessons learnt from building a toy filesystem
Rust + python: lessons learnt from building a toy filesystemChengHui Weng
Β 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS EngineChengHui Weng
Β 
Gatekeeper: API gateway
Gatekeeper: API gatewayGatekeeper: API gateway
Gatekeeper: API gatewayChengHui Weng
Β 
Catch a spider monkey
Catch a spider monkeyCatch a spider monkey
Catch a spider monkeyChengHui Weng
Β 
Even more java script best practices
Even more java script best practicesEven more java script best practices
Even more java script best practicesChengHui Weng
Β 
JavaScript Best Pratices
JavaScript Best PraticesJavaScript Best Pratices
JavaScript Best PraticesChengHui Weng
Β 
Yampa AFRP Introduction
Yampa AFRP IntroductionYampa AFRP Introduction
Yampa AFRP IntroductionChengHui Weng
Β 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)ChengHui Weng
Β 

More from ChengHui Weng (8)

Rust + python: lessons learnt from building a toy filesystem
Rust + python: lessons learnt from building a toy filesystemRust + python: lessons learnt from building a toy filesystem
Rust + python: lessons learnt from building a toy filesystem
Β 
12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine12 Monkeys Inside JS Engine
12 Monkeys Inside JS Engine
Β 
Gatekeeper: API gateway
Gatekeeper: API gatewayGatekeeper: API gateway
Gatekeeper: API gateway
Β 
Catch a spider monkey
Catch a spider monkeyCatch a spider monkey
Catch a spider monkey
Β 
Even more java script best practices
Even more java script best practicesEven more java script best practices
Even more java script best practices
Β 
JavaScript Best Pratices
JavaScript Best PraticesJavaScript Best Pratices
JavaScript Best Pratices
Β 
Yampa AFRP Introduction
Yampa AFRP IntroductionYampa AFRP Introduction
Yampa AFRP Introduction
Β 
Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)Introduction to Basic Haskell Components (In Chinese)
Introduction to Basic Haskell Components (In Chinese)
Β 

Recently uploaded

CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...
CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...
CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...henrik385807
Β 
Open Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdf
Open Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdfOpen Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdf
Open Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdfhenrik385807
Β 
Simulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with AerialistSimulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with AerialistSebastiano Panichella
Β 
CTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdf
CTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdfCTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdf
CTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdfhenrik385807
Β 
NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)
NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)
NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)Basil Achie
Β 
Philippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.pptPhilippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.pptssuser319dad
Β 
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...Pooja Nehwal
Β 
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxGenesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxFamilyWorshipCenterD
Β 
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...NETWAYS
Β 
Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...
Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...
Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...NETWAYS
Β 
The 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software EngineeringThe 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software EngineeringSebastiano Panichella
Β 
call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@vikas rana
Β 
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...NETWAYS
Β 
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...NETWAYS
Β 
WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )
WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )
WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )Pooja Nehwal
Β 
SBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation TrackSBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation TrackSebastiano Panichella
Β 
Microsoft Copilot AI for Everyone - created by AI
Microsoft Copilot AI for Everyone - created by AIMicrosoft Copilot AI for Everyone - created by AI
Microsoft Copilot AI for Everyone - created by AITatiana Gurgel
Β 
LANDMARKS AND MONUMENTS IN NIGERIA.pptx
LANDMARKS  AND MONUMENTS IN NIGERIA.pptxLANDMARKS  AND MONUMENTS IN NIGERIA.pptx
LANDMARKS AND MONUMENTS IN NIGERIA.pptxBasil Achie
Β 
Russian Call Girls in Kolkata Vaishnavi 🀌 8250192130 πŸš€ Vip Call Girls Kolkata
Russian Call Girls in Kolkata Vaishnavi 🀌  8250192130 πŸš€ Vip Call Girls KolkataRussian Call Girls in Kolkata Vaishnavi 🀌  8250192130 πŸš€ Vip Call Girls Kolkata
Russian Call Girls in Kolkata Vaishnavi 🀌 8250192130 πŸš€ Vip Call Girls Kolkataanamikaraghav4
Β 
Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...
Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...
Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...Salam Al-Karadaghi
Β 

Recently uploaded (20)

CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...
CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...
CTAC 2024 Valencia - Sven Zoelle - Most Crucial Invest to Digitalisation_slid...
Β 
Open Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdf
Open Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdfOpen Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdf
Open Source Strategy in Logistics 2015_Henrik Hankedvz-d-nl-log-conference.pdf
Β 
Simulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with AerialistSimulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Simulation-based Testing of Unmanned Aerial Vehicles with Aerialist
Β 
CTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdf
CTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdfCTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdf
CTAC 2024 Valencia - Henrik Hanke - Reduce to the max - slideshare.pdf
Β 
NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)
NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)
NATIONAL ANTHEMS OF AFRICA (National Anthems of Africa)
Β 
Philippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.pptPhilippine History cavite Mutiny Report.ppt
Philippine History cavite Mutiny Report.ppt
Β 
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Navi Mumbai Call Girls Service Pooja 9892124323 Real Russian Girls Looking Mo...
Β 
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptxGenesis part 2 Isaiah Scudder 04-24-2024.pptx
Genesis part 2 Isaiah Scudder 04-24-2024.pptx
Β 
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...
OSCamp Kubernetes 2024 | Zero-Touch OS-Infrastruktur fΓΌr Container und Kubern...
Β 
Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...
Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...
Open Source Camp Kubernetes 2024 | Monitoring Kubernetes With Icinga by Eric ...
Β 
The 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software EngineeringThe 3rd Intl. Workshop on NL-based Software Engineering
The 3rd Intl. Workshop on NL-based Software Engineering
Β 
call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@call girls in delhi malviya nagar @9811711561@
call girls in delhi malviya nagar @9811711561@
Β 
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
OSCamp Kubernetes 2024 | A Tester's Guide to CI_CD as an Automated Quality Co...
Β 
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Open Source Camp Kubernetes 2024 | Running WebAssembly on Kubernetes by Alex ...
Β 
WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )
WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )
WhatsApp πŸ“ž 9892124323 βœ…Call Girls In Juhu ( Mumbai )
Β 
SBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation TrackSBFT Tool Competition 2024 -- Python Test Case Generation Track
SBFT Tool Competition 2024 -- Python Test Case Generation Track
Β 
Microsoft Copilot AI for Everyone - created by AI
Microsoft Copilot AI for Everyone - created by AIMicrosoft Copilot AI for Everyone - created by AI
Microsoft Copilot AI for Everyone - created by AI
Β 
LANDMARKS AND MONUMENTS IN NIGERIA.pptx
LANDMARKS  AND MONUMENTS IN NIGERIA.pptxLANDMARKS  AND MONUMENTS IN NIGERIA.pptx
LANDMARKS AND MONUMENTS IN NIGERIA.pptx
Β 
Russian Call Girls in Kolkata Vaishnavi 🀌 8250192130 πŸš€ Vip Call Girls Kolkata
Russian Call Girls in Kolkata Vaishnavi 🀌  8250192130 πŸš€ Vip Call Girls KolkataRussian Call Girls in Kolkata Vaishnavi 🀌  8250192130 πŸš€ Vip Call Girls Kolkata
Russian Call Girls in Kolkata Vaishnavi 🀌 8250192130 πŸš€ Vip Call Girls Kolkata
Β 
Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...
Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...
Exploring protein-protein interactions by Weak Affinity Chromatography (WAC) ...
Β 

JSDC 2014 - functional java script, why or why not

  • 1. Functional JavaScript, Why or Why Not? JSDC 2014 bit.ly/jsdc2014-funjs
  • 2. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 3. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 4. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 5. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 6. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 7. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 8. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 9. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 10. Hi, I'm Greg Weng From Mozilla Taiwan @GregWeng about.me/snowmantw
  • 12.
  • 14. This talk is about Concepts Features Trade-Off Libraries Frameworks
  • 15. This talk is NOT about 20 mins to write a blog (you had enough of it, right?) 42 Tools for your toolbox (although I do recommend to use some libraries) Hammer on your hand and everything looks like a nail Brainwash believe whatever you want; so, hacking, not blaming Lambda Calculus ...wait, or should we put it in slides?
  • 19. Which one is better?
  • 20. Which one is better? more useful? OOP FP
  • 21. Functional Programming is about Purity Context Evaluation Composition Transformation
  • 22. It would bring you Re-thinking about programming Patterns efficiently make your works done Fun -citons
  • 23. Features of Functional Programmings First-class function | Closure High-order functions | Function composition Purity | Managed side-effects | Laziness Recursion | Tail-recursion optimization | (Type)
  • 24. Features of Functional Programmings First-class function | Closure High-order functions | Function composition Purity | Managed side-effects | Laziness Recursion | Tail-recursion optimization | (Type) JavaScript Ready Need some hard works Impossible if runtime doesn't support it (well) Discuss it later...
  • 26. function() {} is everything Or () => { } if you're a lucky bastard Use Firefox to embrace () => 'the power of ES6!' (Fat Arrow Functions)
  • 27. 65535 -- Number (*yes, it's a function) 65535 + 1 -- Number β†’ Number β†’ Number [1] -- Array Number [1].push(2) -- Array Number β†’ Number β†’ Array Number [1, 2, 3].length -- Array Number β†’ Number [1, 2, 3].map((x) => `${ x }`) -- Array Number β†’ (Number β†’ String) β†’ Array String Use FirefoxNightly to embrace `the ${power} of ES6!` (Quasi-Literals)
  • 28. About the signature Array Number β†’ (Number β†’ String) β†’ Array String [a] β†’ (a β†’ b) β†’ [b] "return value"function as argumentargument a, b: type variables
  • 29. var arr = [1, 2, 3] arr.push(4) But what about...
  • 30. var arr = [1, 2, 3] arr.push(4) But what about... === return a completely new Array: arr β†’ arr' === Array Number β†’ Number β†’ Array Number
  • 32. Immutable Data Structure But in JavaScript we can 'pretend' we have it when we're playing with FP. Would discuss it later
  • 33. Immutable Data Structure But in JavaScript we can 'pretend' we have it when we're playing with FP. Would discuss it later Facebook has an 'immutable-js' library https://github.com/facebook/immutable-js
  • 34. So now we have the Transformation
  • 35. 65535 -- Number (*yes, it's a function) 65535 + 1 -- Number β†’ Number [1] -- Array Number [1].push(2) -- Array Number β†’ Number β†’ Array Number [1, 2, 3].length -- Array Number β†’ Number [1, 2, 3].map((x) => `${ x }`) -- Array Number β†’ (Number β†’ String) β†’ Array String So now we have the Transformation
  • 36. So now we have the Transformation ba
  • 37. But we need to Compose them together
  • 40. [1,2,3].map((x) => `${ x }`) Array Number β†’ (Number β†’ String) β†’ Array String
  • 41. Receive functions as arguments
  • 42. High-Order Functions is useful map:: [a] β†’ (a β†’ b) β†’ [b] reduce:: [a] β†’ (a β†’ b β†’ b) β†’ [a] β†’ b
  • 43. High-Order Functions is useful map:: [a] β†’ (a β†’ b) β†’ [b] reduce:: [a] β†’ (a β†’ b β†’ b) β†’ [a] β†’ b -- Note: these are *NOT* correct signatures in Haskell -- but in JavaScript, we can treat [1,2,3].map as map::[a]... -- which makes the code matches the type better
  • 44. No more looping & ijk tricks
  • 45. var result = []; for (var i = 0; i < selectors.length; i++) { var selector = selectors[i]; result.push(document.querySelector(selector)); }
  • 46. var result = selectors.map( (selector) => document.querySelector(selector));
  • 47. It's not only about SLOC
  • 48. for (var r = 0; r < records.length; r += 1) { var record = records[r]; var typeStr = NfcUtils.toUTF8(record.type); if (NfcUtils.equalArrays(record.type, NDEF.RTD_TEXT)) { poster.text = poster.text || {}; var textData = NDEF.payload.decodeText(record.payload); if (poster.text[textData.language]) { // According to NFCForum-SmartPoster_RTD_1.0 3.3.2, // there MUST NOT be two or more records with // the same language identifier. return null; // to be continue...
  • 50. reduce:: [a] β†’ b ~= build things in this case
  • 51. return records.reduce((poster, record) => { var typeStr = NfcUtils.toUTF8(record.type); if (NfcUtils.equalArrays(record.type, NDEF.RTD_TEXT)) { poster.text = poster.text || {}; var textData = NDEF.payload.decodeText(record.payload); if (poster.text[textData.language]) { // According to NFCForum-SmartPoster_RTD_1.0 3.3.2, // there MUST NOT be two or more records with // the same language identifier. return null; // to be continue...
  • 52. return records.reduce((poster, record) => { var typeStr = NfcUtils.toUTF8(record.type); if (NfcUtils.equalArrays(record.type, NDEF.RTD_TEXT)) { poster.text = poster.text || {}; var textData = NDEF.payload.decodeText(record.payload); if (poster.text[textData.language]) { // According to NFCForum-SmartPoster_RTD_1.0 3.3.2, // there MUST NOT be two or more records with // the same language identifier. return null; // to be continue... A real case in Gaia project: Bug 1039245
  • 53. People know what are you doing when they saw the 'map' and 'reduce'
  • 54. People know what are you doing when they saw the 'map' and 'reduce' If there is no or only few side-effects
  • 55. It can be more powerful if you play with the type
  • 56. map:: [a] β†’ (a β†’ b) β†’ [b]
  • 57. map:: [a] β†’ (a β†’ b) β†’ [b] while a/URL, b/IO
  • 58. urls.map((url) => Http.get(url) .filter((response) => response.status !== 404 ) .map((response) => Parser.comment(response)) .map((comment) => UI.renderComment(comment)) .execute()
  • 59. urls.map((url) => Http.get(url) // map (URL -> IO) to [ URL ] .filter((response) => response.status !== 404 ) .map((response) => Parser.comment(response)) .map((comment) => UI.renderComment(comment)) .execute() // If we have lazy IO & async mixed Monad // Transformer...will discuss it later
  • 60. urls.map((url) => Http.get(url) // map (URL -> IO) to [ URL ] .filter((response) => response.status !== 404 ) .map((response) => Parser.comment(response)) .map((comment) => UI.renderComment(comment)) .execute() // If we have lazy IO & async mixed Monad // Transformer...will discuss it later [URL] β†’ [IO a] β†’ [Parsed b] β†’ [DOM c]
  • 63. forEach:: [a] β†’ (a β†’ SideEffect; will discuss it later) filter:: [a] β†’ (a β†’ Bool) β†’ [a] * the type is similar with map groupBy:: [a] β†’ (a β†’ a β†’ Bool) β†’ [[a]] * lo-dash has it zipWith: [a] β†’[b] β†’ (a β†’ b β†’ c) β†’ [c] * worth to implement
  • 64. forEach:: [a] β†’ (a β†’ SideEffect; will discuss it later) filter:: [a] β†’ (a β†’ Bool) β†’ [a] * the type is similar with map groupBy:: [a] β†’ (a β†’ a β†’ Bool) β†’ [[a]] * lo-dash has it zipWith: [a] β†’[b] β†’ (a β†’ b β†’ c) β†’ [c] * worth to implement Recommends to use lo-dash library to acquire these functions
  • 65. And reducing is even more basic
  • 66. var map = (xs, fn) => { return xs.reduce((acc, x) => { return acc.concat([ fn(x) ]); }, []); }; Recommends to use and get understand the 'transducer.js'
  • 67. Summary: High-Order Functions is useful, especially for list
  • 68. Do map & reduce whenever it's possible
  • 69. With type in mind we can do lots of things, not only handling data
  • 70. With type in mind we can do lots of things, not only handling data We'll see more cases soon
  • 71. And the best thing is major browsers support map & reduce already
  • 73. In Functional Programming we don't like to define new function
  • 74. Instead, we compose them when we need it
  • 76. map (not.odd) [1,2,3] (.):: (b β†’ c) β†’ (a β†’ b) β†’ (a β†’ c)
  • 78. map (x -> !odd x) [1,2,3]
  • 79. let notOdd x = not(odd x); map notOdd [1,2,3]
  • 80. This is important because
  • 81. Safety if small functions are safe, the larger one is safe, too Reusability no need to create new functions Flexibility compose anything you want at anytime Composition is good for you
  • 82. Unfortunately in JavaScript we don't have such nice syntax support
  • 83. map (not.odd.read) ["1","2","3"] [1,2,3].map(compose(not, odd, read)) Recommends to use lo-dash library to acquire the compose functions
  • 85. Function composition is actually the most important idea we need to know
  • 86. However in daily works we may fail to use it unless we sugar the syntax...
  • 87. with the only one 'operator' we have $(a, b, c) Although it's almost abused?
  • 89. ['1','2','3'].map( $(not, odd, read) ) [a] β†’ (a β†’ b) β†’ [b]
  • 90. [a] β†’ (a β†’ b) β†’ [b] ['1','2','3'].map( $(not, odd, read) )
  • 91. m a β†’ (a β†’ b) β†’ m b ['1','2','3'].map( $(not, odd, read) )
  • 92. m a β†’ (a β†’ b) β†’ m b IO a β†’ (a β†’ b) β†’ IO b getString.map( $(not, odd, read) ) IO String
  • 93. m a β†’ (a β†’ b) β†’ m b IO a β†’ (a β†’ b) β†’ IO b [] a β†’ (a β†’ b) β†’ [] b ['1','2','3'].map( $(not, odd, read) ) [ ] Number
  • 94. m a β†’ (a β†’ b) β†’ m b IO a β†’ (a β†’ b) β†’ IO b [] a β†’ (a β†’ b) β†’ [] b HTTP a β†’ (a β†’ b) β†’ HTTP b HTTPServer.map( $(not, odd, read) ) HTTP Request
  • 95. m a β†’ (a β†’ b) β†’ m b IO a β†’ (a β†’ b) β†’ IO b [] a β†’ (a β†’ b) β†’ [] b HTTP a β†’ (a β†’ b) β†’ HTTP b Maybe a β†’ (a β†’ b) β†’ Maybe b maybeRead.map( $(not, odd, read) ) Maybe a
  • 96. m a β†’ (a β†’ b) β†’ m b IO a β†’ (a β†’ b) β†’ IO b [] a β†’ (a β†’ b) β†’ [] b HTTP a β†’ (a β†’ b) β†’ HTTP b Maybe a β†’ (a β†’ b) β†’ Maybe b Now we have a same map & function for the different contexts
  • 97. m a β†’ (a β†’ b) β†’ m b IO a β†’ (a β†’ b) β†’ IO b [] a β†’ (a β†’ b) β†’ [] b HTTP a β†’ (a β†’ b) β†’ HTTP b Maybe a β†’ (a β†’ b) β†’ Maybe b Now we have a same map & function for the different contexts In fact this general map called 'fmap'
  • 98. List apply the function to every element ([1,2,3]) HTTP receive request and response with the handled content Maybe if previous one is Nothing, do not apply the function Same fmap; different meaning
  • 99. The fmap is a common interface that all contexts are agreed with
  • 100. Type classes with fmap called Functor
  • 101. Functor can lift a function onto the context
  • 102. m a m b ( a β†’ b) fmap
  • 103. The function keep knowing nothing about the Context
  • 104. m a m b ( a β†’ b) $(not, odd, read) fmap
  • 105. It only need to care how to transform the value from a to b
  • 106. How to apply context-relevant rules is encapsulated by fmap
  • 107. $(not, odd, read) List a List b ( a β†’ b) List#fmap apply the function on every element of the list fmap
  • 108. $(not, odd, read) HTTP a HTTP b ( a β†’ b) HTTP#fmap receive the request 'a' and response 'b' to client fmap
  • 109. $(not, odd, read) Maybe a Maybe b ( a β†’ b) fmap Maybe#fmap If there is no 'a' (Nothing), do nothing
  • 110. This is powerful because we can keep functions simple
  • 111. And apply them into different context to do different things
  • 112. HTTP Request HTTP Response ( Request β†’Response) Needn't know how to do IO, networking, etc.
  • 113. List Request List Response ( Request β†’ Response) Needn't know how to apply on every element (iterate) within the list
  • 114. Contexts could even be stockpiled to do complex computations
  • 115. Contexts could even be stockpiled to do complex computations Although stockpiling is beyond Functor. See Appendix: Monad Transformer
  • 116. HTTP Request HTTP Response List List ( Request β†’Response) Needn't know how to do IO, networking, etc. Needn't know how to map it to all requests.
  • 117. And the stockpiling order is very important
  • 118. HTTP Request HTTP Response List List ( Request β†’Response) Needn't know how to do IO, networking, etc. Needn't know how to map it to all requests. [HTTP Request] (buffering?)
  • 119. HTTP [Request] (SPDY?) List Request List Response HTTP HTTP ( Request β†’Response) Needn't know how to do IO, networking, etc. Needn't know how to map it to all requests.
  • 120. So, Functor is an useful concept to separate context and pure function
  • 121. But we still need more powerful structure to do the computation
  • 123. "When you gaze long into a Monad the Monad also gazes into you"
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130. Monad, monad, everywhere, nor any drop to understand
  • 131. Monad is a solution for composing Context-ed actions
  • 132. In Functor we can only transform pure data to pure data
  • 134. We may have different sub- contexts for HTTP
  • 136. We can't instance different sub- contexts with only Functor
  • 138. HTTP Request HTTP::200 Response ( Request β†’Response) ( a β†’ b ) The 'fmap' only allow (a β†’ b), not (a β†’ m b) So we can't control which sub-context should be instanced
  • 139. HTTP Request HTTP::404 Response ( Request β†’Response) ( a β†’ b ) The 'fmap' only allow (a β†’ b), not (a β†’ m b) So we can't control which sub-context should be instanced
  • 140. Monad allows you to do that with its 'bind' function
  • 141. (>>=):: m a β†’ ( a β†’ m b ) β†’ m b
  • 142. (>>=):: m a β†’ ( a β†’ m b ) β†’ m b a β†’ m bm a >>=m a β†’ a a β†’ b; b β†’ m b unwrap wrap
  • 143. Allow inject ( a β†’ m b ) means allow we control the way to wrap the value
  • 144. HTTPServer >>= (req -> login) >>= (authReq -> case (doAuth authReq) of True -> content False -> authError))
  • 145. HTTPServer >>= (req -> login) >>= (authReq -> case (doAuth authReq) of True -> content False -> authError)) the 'bind' function, infix HTTP::403 HTTP::200
  • 146. let content response = HTTP200 response let authError response = HTTP403 response (authReq -> case (doAuth authReq) of True -> content False -> authError) ( a β†’ m b )
  • 148. (req -> login) (authReq -> doAuth...)>>= (......)>>= Client ClientHTTP Monad
  • 149. HTTPServer >>= (req -> login) >>= (authReq -> case (doAuth authReq) of True -> content False -> authError)) The bound function stil don't need know how to open IO, networking, etc. (a β†’ m b)
  • 150. We still keep the same interface, different implementations feature
  • 151. (req -> login) (authReq -> doAuth...)>>= (......)>>= Client ClientHTTP Monad
  • 152. (req -> login) (authReq -> doAuth...)>>= (......)>>= Map to all elements Map to all elements List Monad
  • 153. And the Monadic actions can be chained as function composition
  • 154. a β†’ m c a -> m b b -> m c>>=
  • 155. a β†’ m c a -> m b b -> m c>>= actionFoo = actionA >>= actionB actionBar = actionFoo >>= actionC (and so on...)
  • 156. It's just like Function Composition But now we can handle Contexts
  • 157. h = g 。f h = f >>= g a β†’ m c = a β†’ m b >>= b β†’ m c a β†’ c = b β†’ c 。 a β†’ b
  • 158. And Monad could save us from unexpected side-effects
  • 159. And Monad could save us from unexpected side-effects if all methods with side-effects are wrapped
  • 160. getString forkIO openFile readTVar +, -, *... compress tail par writeArray a β†’ m b while m /IO, HTTP, UI, ... a β†’ b
  • 161. getString forkIO openFile readTVar +, -, *... compress tail par writeArray a β†’ m b while m /IO, HTTP, UI, ... a β†’ b Embed them rationally with the 'bind' function
  • 162. So we can combine these functions and Contexts rationally
  • 164. from Gaia/System/notifications.js (v2.0) line: 290 ~ 490 (200 lines) - Create notification - Detecting gesture - Append notification - Play sound - Color one container - Scroll container to top ...
  • 165. from Gaia/System/notifications.js (v2.0) line: 290 ~ 490 (200 lines) There are so many requests from so many different contexts
  • 166. from Gaia/System/notifications.js (v2.0) line: 290 ~ 490 (200 lines) It's possible to use FP ideas, to response these requests with individual logic units is trivial & reasonable
  • 167. DOM Create notification Change container's style UI Append notification Scroll container to top Gesture Detect gesture on notification Sound Play sound Asynchronous Manage asynchronous operations Conditional Statements If...else to do or not to do things I/O Get/write data and control device ... Functor Monad Monad Transformer High-order Function Partial Application Curry ...
  • 168. This is important because no one like surprises
  • 169.
  • 170. Another reason that Monad could encapsulate side-effects...
  • 171. X a β†’ m b β†’ m m c β†’ m d β†’ e
  • 172. X a β†’ m b β†’ m m c β†’ m d β†’ e
  • 173. There is no way allow a Context-ed value to escape
  • 174. There is no way allow a Context-ed value to escape Yes, I know Comonad and unsafe- can do that, but...
  • 175. So once your value get tainted, you can't use it outside the Monad
  • 176.
  • 177. Instead, you embed your function into the tainted context
  • 178. HTTPServer >>= (req -> login) >>= (authReq -> case (doAuth authReq) of True -> content False -> authError)) Can only access the value when you're in the context
  • 179. HTTPServer >>= (req -> login) >>= (authReq -> case (doAuth authReq) of True -> content False -> authError)) let HTTPValue = doSomething HTTPValue ... No way to do that! extract
  • 180. The similar case in JavaScript is the Promised actions
  • 181. Promise(() => {...}) .then((a) => {...}) .then((b) => {...}) .then((c) => {...}) .then((d) => {...}).extract(); var promisedValue = No way to do that! doSomething(promisedValue); ...
  • 182. In fact what we could learn from Monad is not only the type & rules
  • 183. But the idea to control different computations in different Contexts
  • 184. Promise(() => {...}) .then((a) => {...}) .then((b) => {...}) .then((c) => {...}) .then((d) => {...}); Context: Ensure the following step executes only after the previous one get done.
  • 187. ensure() .frame() .element(...) .actions() .pulls(0, 400) .perform() .must(...) Context: Ensure the integration test only do what user can do, instead of magic manipulations
  • 188. These computations focus on the transforming within the contexts
  • 189. Just like what Monads do in Haskell
  • 190. Promise(() => {...}) .then((a) => {...}) .then((b) => {...}) .then((c) => {...}) .then((d) => {...}); $('some-selector') .each(...) .animate(...) .append(...) _.chain(someValue) .filter(...) .groupBy(...) .map(...) .reduce(...) DOM _Async
  • 191. threeCoins = do a <- randomSt b <- randomSt c <- randomSt return (a,b,c) main = do a <- ask "Name?" b <- ask "Age?" return () IO add mx my = do x <- mx y <- my return (x + y) MaybeState
  • 192. threeCoins = do a <- randomSt b <- randomSt c <- randomSt return (a,b,c) main = do a <- ask "Name?" b <- ask "Age?" return () IO add mx my = do x <- mx y <- my return (x + y) MaybeState the 'do' notification
  • 193. So the question is not "why we need Monad in JavaScript"
  • 194. But "is it worth to implement the fluent interface more Monadic"?
  • 196. Lazy vs eager: sometimes it's reasonable to be lazy Flow control for asynchronous operations is important Type in some critical places we still need the information Laws is it possible to follow the Monad Laws? Requirements to get closer with real Monads
  • 197. It's easy to make our 'Monad' lazy with some type supporting
  • 198. var action = (new Maybe()).Just(3) .then((v) => { return (new Maybe()).Just(v+99); }) .then((v) => { return (new Maybe()).Just(v-12); }) .then((v) => { return (new Maybe()).Nothing(); }) .then((v) => { return (new Maybe()).Just(v+12); }) // Execute it with `action.done()`. action = (Just 3) >>= v -> return (v + 99) >>= v -> return (v - 12) >>= v -> Nothing >>= v -> return (v + 12) https://github.com/snowmantw/ warmfuzzything.js/blob/master/maybe.js
  • 199. var action = (new Maybe()).Just(3) .then((v) => { return (new Maybe()).Just(v+99); }) .then((v) => { return (new Maybe()).Just(v-12); }) .then((v) => { return (new Maybe()).Nothing(); }) .then((v) => { return (new Maybe()).Just(v+12); }) // Execute it with `action.done()`. action = (Just 3) >>= v -> return (v + 99) >>= v -> return (v - 12) >>= v -> Nothing >>= v -> return (v + 12) https://github.com/snowmantw/ warmfuzzything.js/blob/master/maybe.js ...?
  • 200. But things become crazy when the 'Monad' need to mix with Promise (to support async operations natively)
  • 201. action = (Just 3) >>= v -> return (v + 99) >>= v -> return (v - 12) >>= v -> Nothing >>= v -> return (v + 12) https://github.com/snowmantw/ warmfuzzything.js/blob/master/promise_maybe.js var action = (new PromiseMaybe()).Just(3) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Just(v+99)); }) .then((mSelf, v) => { setTimeout(function() { // Only for test. Meaningless. mSelf.returns((new PromiseMaybe).Just(v-12)); }, 3000); }) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Nothing()); }) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Just(v+12)); });
  • 202. action = (Just 3) >>= v -> return (v + 99) >>= v -> return (v - 12) >>= v -> Nothing >>= v -> return (v + 12) https://github.com/snowmantw/ warmfuzzything.js/blob/master/promise_maybe.js var action = (new PromiseMaybe()).Just(3) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Just(v+99)); }) .then((mSelf, v) => { setTimeout(function() { // Only for test. Meaningless. mSelf.returns((new PromiseMaybe).Just(v-12)); }, 3000); }) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Nothing()); }) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Just(v+12)); });
  • 203. action = (Just 3) >>= v -> return (v + 99) >>= v -> return (v - 12) >>= v -> Nothing >>= v -> return (v + 12) https://github.com/snowmantw/ warmfuzzything.js/blob/master/promise_maybe.js var action = (new PromiseMaybe()).Just(3) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Just(v+99)); }) .then((mSelf, v) => { setTimeout(function() { // Only for test. Meaningless. mSelf.returns((new PromiseMaybe).Just(v-12)); }, 3000); }) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Nothing()); }) .then((mSelf, v) => { mSelf.returns((new PromiseMaybe).Just(v+12)); }); It can be better, but the real problem is it's implementation is very tricky
  • 204. But the most important things is it works!
  • 205. But the most important things is it works! When I see a bird that walks like a Monad and swims like a Monad and quacks like a Monad, I call that bird a Monad
  • 206. But the most important things is it works! (although it doesn't follow the laws)
  • 207. (although it doesn't follow the laws)
  • 208. Yes we're still writing JavaScript!
  • 209. Summary: Monad light the way to isolate side-effects in JavaScript
  • 210. But how much we gain depends on how much we paid
  • 211. But how much we gain depends on how much we paid (or someone must pay it for us)
  • 212. But how much we gain depends on how much we paid In my experience the 'simple' fluent interface would be not enough soon
  • 213. "不小心造出個 lexer ηš„ monad δΊ†οΌŒδ½†ε•ι‘Œζ˜―ζˆ‘ 在 javascript 阿阿阿" @banacorn
  • 215. How to stockpile different Contexts?
  • 216. The missing part: how to stockpile different Contexts? List Request List Response HTTP HTTP ( Request β†’Response)
  • 217. The missing part: how to stockpile different Contexts? List Request List Response HTTP HTTP ( Request β†’Response) (See Appendix. Yes, we have a 200+ slides...)
  • 220. So far we discussed how to compose computations rationally
  • 221. So far we discussed how to compose computations rationally
  • 222. "But 80% of my work is for UI changes"
  • 223. Behavior trigger event Data changed View redraw Let's think about what is an GUI program...
  • 224. Behavior trigger event Data changed View redraw Let's think about what is an GUI program... It's so simple, right?
  • 225. Behavior trigger event Data changed View redraw Let's think about what is an GUI program...
  • 226. Behavior trigger event Data changed View redraw Let's think about what is an GUI program... Can be done purely, while IO is relatively simple than drawing Lots of side-effects and trolling data anytime
  • 227. With React we only care about data changes
  • 228. And 'create' a new view every time it get changed
  • 230. And 'create' a new view every time it get changed and efficiency is what React should care about
  • 231. This is like how to manipulate the immutable data structure in FP... ys = insert ("e", xs)
  • 232. This is like how to manipulate the immutable data structure in FP... view' = render(..)
  • 233. And Flux looks like...
  • 234. And Flux looks like...
  • 235. And Flux looks like... Yampa - a Functional Reactive Programming framework in Haskell
  • 236. So React & Flux is really close to FP...
  • 237. It's great because we can build a full Functional Programming stack on it
  • 238.
  • 239. It's great because we can build a full Functional Programming stack on it with Function Composition, Monad, Partial Application, Curry, Monad Transformer, and other useful features in JavaScript
  • 241. We could learn lots from Functional Programming but no need to bet on it
  • 242. Since we're still with a language not so Functional
  • 243. ex: Composing everything ensures safety, reusability and flexibility
  • 244. But the lack of syntax supporting make bitter to be used
  • 245. High-Order functions is useful, use them whenever it's available
  • 246. And for list manipulation, native support is ready
  • 247. Moreover, list transformations are not only for data processing
  • 248. Functor & Monad is not so terrible: they're just for contexts
  • 249. And isolate pure & impure computations is good for us
  • 250. In JavaScript, fluent interface is very close to Monad
  • 251. But in current status we don't have a total Monad solution yet
  • 252. Although when it grows, more and more Monadic features are required
  • 253. So if your fluent interface code get into troubles of Contexts...
  • 254. Consider what Monad have and pick up some concepts to implement
  • 255. Finally, if you want to construct a FP-flavour GUI program
  • 256. FRP is your friend
  • 257. React & Flux is your friend
  • 259. - lo-dash is your friend - transducer in JavaScript is a good way to understand reducing deeply - immutable-js make your code purer - React & Flux bring you a whole new FRP world
  • 260. - jQuery is a Monad (no, not really, see the comments) - Learn You a Haskell a good way to learn about Monad - Typeclassopedia classical article about Typeclasses - Foldr Foldl Foldl' detailed article about reducing - CSP and transducers about Transducer in JavaScript
  • 261. Help and Need Help
  • 262.
  • 263. How to contribute to FirefoxOS
  • 264. Q&A
  • 266. How to stockpiling different Monads
  • 267. a -> m n b CSE230 Wi14 - Monad Transformers When you have many Monads
  • 268. When you have many Monads HTTP Request HTTP Response Logger Logger ( Request β†’Response)
  • 269. When you have many Monads HTTP Request HTTP Response Logger Logger ( Request β†’Response) We want to process HTTP as usual Meanwhile we want every request-response been logged
  • 270. When you have many Monads HTTP Request HTTP Response Database Database ( Request β†’Response) We want to process HTTP as usual Meanwhile we may perform some database R/W at the same time
  • 271. When you have many Monads HTTP Request HTTP Response Error Error ( Request β†’Response) We want to process HTTP as usual Meanwhile we want to capture every step's error and handle it
  • 272. Monad Transformer HTTP Request HTTP Response m m >>= Perform m first (ex: Logger) Then perform the target Monad (HTTP) It's somewhat of the AOP concept HTTPTransformer
  • 274. HTTP Logger m The transformer only know the inner one is the target Monad it can handle with ex: (MaybeT β†’ Maybe, HTTPT β†’ HTTP) Request HTTPT (Transformer) >>= How Monad Transformer Works
  • 275. HTTP Logger m The transformer only know the inner one is the target Monad it can handle with ex: (MaybeT β†’ Maybe, HTTPT β†’ HTTP) Request HTTPT ( "T"ransformer ) would not care what the outer monad is HTTPT (Transformer) >>= How Monad Transformer Works
  • 276. HTTP Logger m#bind First transformer would call the outer one's bind function to apply the rule on the inner monadic value, and dig into the second layer (inner monad)Request apply m#bind on the HTTP monadic value HTTPT doesn't know what the 'm' is How Monad Transformer Works
  • 277. HTTP Logger m#bind First transformer would call the outer one's bind function to apply the rule on the inner monadic value Request apply m#bind on the HTTP monadic value HTTPT doesn't know what the 'm' is How Monad Transformer Works For this example, it means to perform the logging
  • 278. HTTP Logger m#bind And then dig into the second layer (inner monad) Request apply m#bind on the HTTP monadic value HTTPT doesn't know what the 'm' is How Monad Transformer Works Now we're in the inner monad context
  • 279. HTTP Logger m Then transformer apply the specific Monad's binding rules on the inner monadic value, including to call the embedded function, just like what the ordinary Monad does, but now we get (m n b) rather than (m b) Request Request HTTP Response >>= Logger m http://en.wikibooks. org/wiki/Haskell/Monad_transformers#A_simple_mon( a β†’ m n b ) How Monad Transformer Works
  • 280. Step by Step Outer 'Bind' applied on the monadic value m (n a) β†’ m (n a)' Inner 'Bind' applied on the monadic value m (n a)' β†’ m (n b) Wrap It Back while it still doesn't know what the m is m (n a)' β†’ m (n b)
  • 281. A not so successful try to implement it in JavaScript
  • 282. PromiseMaybeT Now it can stockpile arbitrary PromiseMonad on one PromiseMaybe monadic action https://github.com/snowmantw/ warmfuzzything.js/blob/master/maybet.js
  • 283. PromiseMaybeT Now it can stockpile arbitrary PromiseMonad on one PromiseMaybe monadic action But since our basic 'Monad' is tricky, the transformer, is tricky, too https://github.com/snowmantw/ warmfuzzything.js/blob/master/maybet.js