Pure and functional JavaScript
Developer Conference 2013
Jakob Westhoff (@jakobwesthoff)
November 7th, 2013
I am
Jakob Westhoff
I
Senior PHP professional
I
Senior JavaScript professional
I
Open source enthusiast
I
Regular speaker at (inter)national
conferences
We are
Helping people to create high quality web applications.
http://qafoo.com
I
Trainings, Workshops and Consulting
I
Twitter:
@qafoo
We are
Helping people to create high quality web applications.
http://qafoo.com
I
Trainings, Workshops and Consulting
I
Twitter:
@qafoo
We are
Helping people to create high quality web applications.
http://qafoo.com
I
Trainings, Workshops and Consulting
I
Twitter:
@qafoo
We are
Helping people to create high quality web applications.
http://qafoo.com
I
Trainings, Workshops and Consulting
I
Twitter:
@qafoo
Functional Programming
Functional programming
is a programming paradigm [...], that
[...] avoids state and mutable data. Functional programming
emphasizes functions that produce results that depend only on
their inputs and not on the program state - i.e. pure mathematical
functions.
Functional Programming
Functional programming
is a
programming paradigm
[...], that
[...] avoids state and mutable data. Functional programming
emphasizes functions that produce results that depend only on
their inputs and not on the program state - i.e. pure mathematical
functions.
Functional Programming
Functional programming
is a programming paradigm [...], that
[...]
avoids state and mutable data. Functional programming
emphasizes functions that produce results that depend only on
their inputs and not on the program state - i.e. pure mathematical
functions.
Functional Programming
Functional programming
is a programming paradigm [...], that
[...] avoids state and mutable data. Functional programming
emphasizes
functions
that produce results that depend
only on
their inputs
and not on the program state - i.e. pure mathematical
functions.
Functional Programming
Functional programming
is a programming paradigm [...], that
[...] avoids state and mutable data. Functional programming
emphasizes functions that produce results that depend only on
their inputs and not on the program state - i.e.
pure
mathematical
functions.
Functions
A simple function
1
f u n c t i o n
i n c r e m e n t
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
I
Function Declaration
A simple function
1
f u n c t i o n
i n c r e m e n t
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
I
Function
Declaration
A simple function
1
f u n c t i o n
i n c r e m e n t
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
I
Function Declaration
Functions
Functions are special
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
Functions are special
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
Functions are special
1f u n c t i o n
one
( )
{
2f u n c t i o n
two
( )
{
3f u n c t i o n
t h r e e
( )
{
4/ /
. . .
5}
6}
7}
Higher-Order Functions
1
window
.
s e t T i m e o u t
(
f u n c t i o n
( )
{
2a l e r t
(
” A second has passed ”
) ;
3}
, 1000) ;
Higher-Order Functions
1
window
.
s e t T i m e o u t
(
f u n c t i o n
( )
{
2a l e r t
(
” A second has passed ”
) ;
3}
, 1000) ;
Higher-Order Functions
1v a r makeGreeter
=
f u n c t i o n
(
name
)
{
2r e t u r n f u n c t i o n
( )
{
3a l e r t
(
” H e l l o ”
+
name
+
” ! ”
) ;
4}
;
5}
;
Higher-Order Functions
1v a r makeGreeter
=
f u n c t i o n
(
name
)
{
2r e t u r n f u n c t i o n
( )
{
3a l e r t
(
” H e l l o ”
+
name
+
” ! ”
) ;
4}
;
5}
;
Higher-Order Functions
I
Functions which
consume
or
return
other functions are called
What comes next?
Sideeffects
1v a r cou nt
=
f u n c t i o n
(
i t e m s
)
{
2v a r l e n g t h
= 0 ;
3while
(
i t e m s
.
pop
( ) )
{
4l e n g t h
+= 1 ;
5}
6 7r e t u r n
l e n g t h
;
8}
9 10v a r i t e m s
= [ 1 , 2 , 3 ] ;
11a l e r t
(
cou nt
(
i t e m s
) ) ;
/ / 3
Sideeffects
1v a r cou nt
=
f u n c t i o n
(
i t e m s
)
{
2v a r l e n g t h
= 0 ;
3while
(
i t e m s
.
pop
( ) )
{
4l e n g t h
+= 1 ;
5}
6 7r e t u r n
l e n g t h
;
8}
9 10v a r i t e m s
= [ 1 , 2 , 3 ] ;
11a l e r t
(
cou nt
(
i t e m s
) ) ;
/ / 3
Sideeffects
1v a r cou nt
=
f u n c t i o n
(
i t e m s
)
{
2v a r l e n g t h
= 0 ;
3while
(
i t e m s
.
pop
( ) )
{
4l e n g t h
+= 1 ;
5}
6 7r e t u r n
l e n g t h
;
8}
9 10v a r i t e m s
= [ 1 , 2 , 3 ] ;
11a l e r t
(
cou nt
(
i t e m s
) ) ;
/ / 3
IModification of state
Sideeffects
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
Sideeffects
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2a l e r t
(
a
+1) ;
3
}
Pure Functions
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2r e t u r n
a
+ 1 ;
3
}
I
No sideeffects
Pure Functions
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2r e t u r n
a
+ 1 ;
3
}
I
No sideeffects
Pure Functions
1
v a r i n c r e m e n t
=
f u n c t i o n
(
a
)
{
2r e t u r n
a
+ 1 ;
3
}
I
No sideeffects
Pure Functions
I
Functions which are
sideeffect free
are called
Pure Functions
I
No program can consist of
Pure Functions
only
I
It would simply do nothing
Pure Functions
I
No program can consist of
Pure Functions
only
I
It would simply do
nothing
Pure Functions
I
No program can consist of
Pure Functions
only
I
It would simply do
nothing
What comes next?
Functional Loops
I
Loops (
for
,
while
,
...
) are quite common in every program
I
Loops are mostly used to
I
Cause Sideeffects on every element of a set
ITransform or Extract data from a set
Functional Loops
I
Loops (
for
,
while
,
...
) are quite common in every program
I
Loops are mostly used to
I
Cause Sideeffects on every element of a set
I
Transform or Extract data from a set
Functional Loops
I
Loops (
for
,
while
,
...
) are quite common in every program
I
Loops are mostly used to
I
Cause Sideeffects on every element of a set
I
Transform or Extract data from a set
IAggregate or Accumulate data from a set
Functional Loops
I
Loops (
for
,
while
,
...
) are quite common in every program
I
Loops are mostly used to
I
Cause Sideeffects on every element of a set
I
Transform or Extract data from a set
Looping
1v a r s e s s i o n s
= . . . ;
2 3v a r i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5doSomething
(
s e s s i o n s
[
i
] ) ;
6}
I
Loop through data
Looping
1v a r s e s s i o n s
= . . . ;
2 3v a r i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5doSomething
(
s e s s i o n s
[
i
] ) ;
6}
I
Loop through data
Looping
1v a r s e s s i o n s
= . . . ;
2 3v a r i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5doSomething
(
s e s s i o n s
[
i
] ) ;
6}
I
Loop through data
Array.prototype.forEach
1v a r s e s s i o n s
= . . . ;
2 3s e s s i o n s
.
f o r E a c h
(
f u n c t i o n
(
s e s s i o n
)
{
4doSomething
(
s e s s i o n
) ;
5}
) ;
Data extraction
1v a r t i t l e s
= [ ] ;
2 3v a r i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5t i t l e s
.
push
(
s e s s i o n s
[
i
] .
t i t l e
) ;
6}
Data extraction
1v a r t i t l e s
= [ ] ;
2 3v a r i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5t i t l e s
.
push
(
s e s s i o n s
[
i
] .
t i t l e
) ;
6}
Array.prototype.map
1
v a r t i t l e s
=
s e s s i o n s
.
map
(
f u n c t i o n
(
s e s s i o n
)
{
2r e t u r n
s e s s i o n
.
t i t l e
;
3
}
) ;
I
This kind of property extraction is needed quite often
Array.prototype.map
1
v a r t i t l e s
=
s e s s i o n s
.
map
(
f u n c t i o n
(
s e s s i o n
)
{
2r e t u r n
s e s s i o n
.
t i t l e
;
3
}
) ;
I
This kind of
property extraction
is needed quite often
Array.prototype.map
1
v a r t i t l e s
=
s e s s i o n s
.
map
(
f u n c t i o n
(
s e s s i o n
)
{
2r e t u r n
s e s s i o n
.
t i t l e
;
3
}
) ;
I
This kind of
property extraction
is needed quite often
extract
1v a r e x t r a c t
=
f u n c t i o n
(
p r o p e r t y
)
{
2r e t u r n f u n c t i o n
(
o b j e c t
)
{
3r e t u r n
o b j e c t
[
p r o p e r t y
] ;
4}
;
5}
;
1var
t i t l e s = s e s s i o n s . map ( e x t r a c t ( ” t i t l e ” ) ) ;
extract
1v a r e x t r a c t
=
f u n c t i o n
(
p r o p e r t y
)
{
2r e t u r n f u n c t i o n
(
o b j e c t
)
{
3r e t u r n
o b j e c t
[
p r o p e r t y
] ;
4}
;
5}
;
1var
t i t l e s
=
s e s s i o n s
.
map
(
e x t r a c t
(
” t i t l e ”
) ) ;
extract
1v a r e x t r a c t
=
f u n c t i o n
(
p r o p e r t y
)
{
2r e t u r n f u n c t i o n
(
o b j e c t
)
{
3r e t u r n
o b j e c t
[
p r o p e r t y
] ;
4}
;
5}
;
1var
t i t l e s
=
s e s s i o n s
.
map
(
e x t r a c t
(
” t i t l e ”
) ) ;
extract
1v a r e x t r a c t
=
f u n c t i o n
(
p r o p e r t y
)
{
2r e t u r n f u n c t i o n
(
o b j e c t
)
{
3r e t u r n
o b j e c t
[
p r o p e r t y
] ;
4}
;
5}
;
1var
t i t l e s
=
s e s s i o n s
.
map
(
e x t r a c t
(
” t i t l e ”
) ) ;
extract
1v a r e x t r a c t
=
f u n c t i o n
(
p r o p e r t y
)
{
2r e t u r n f u n c t i o n
(
o b j e c t
)
{
3r e t u r n
o b j e c t
[
p r o p e r t y
] ;
4}
;
5}
;
1var
t i t l e s
=
s e s s i o n s
.
map
(
e x t r a c t
(
” t i t l e ”
) ) ;
Data accumulation
1var
s e s s i o n L i s t
=
” ”
;
2 3var
i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5s e s s i o n L i s t
+=
”
<
l i
>
”
+
s e s s i o n s
[
i
] .
t i t l e
+
”
<
/
l i
>
”
;
6}
I
Accumulate information from given data structure
I
Two things are actually done here:
1. Extract each sessions title
Data accumulation
1var
s e s s i o n L i s t
=
” ”
;
2 3var
i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5s e s s i o n L i s t
+=
”
<
l i
>
”
+
s e s s i o n s
[
i
] .
t i t l e
+
”
<
/
l i
>
”
;
6}
I
Accumulate information from given data structure
I
Two things are actually done here:
1. Extract each sessions title
Data accumulation
1var
s e s s i o n L i s t
=
” ”
;
2 3var
i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5s e s s i o n L i s t
+=
”
<
l i
>
”
+
s e s s i o n s
[
i
] .
t i t l e
+
”
<
/
l i
>
”
;
6}
I
Accumulate information from given data structure
I
Two things are actually done here:
1. Extract each sessions title
Array.prototype.reduce
1v a r s e s s i o n L i s t
=
s e s s i o n s
2.
map
(
f u n c t i o n
(
s e s s i o n
)
{
3r e t u r n
s e s s i o n
.
t i t l e
;
4}
)
5.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
6r e t u r n
a c c u m u l a t i o n
+
”
<
l i
>
”
+
n e x t
+
”
<
/ l i
>
”
7}
,
” ”
) ;
Array.prototype.reduce
1v a r s e s s i o n L i s t
=
s e s s i o n s
2.
map
(
f u n c t i o n
(
s e s s i o n
)
{
3r e t u r n
s e s s i o n
.
t i t l e
;
4}
)
5.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
6r e t u r n
a c c u m u l a t i o n
+
”
<
l i
>
”
+
n e x t
+
”
<
/ l i
>
”
7}
,
” ”
) ;
Array.prototype.reduce
1v a r s e s s i o n L i s t
=
s e s s i o n s
2.
map
(
e x t r a c t
(
” t i t l e ”
) )
3.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
4r e t u r n
a c c u m u l a t i o n
+
”
<
l i
>
”
+
n e x t
+
”
<
/ l i
>
”
5}
,
” ”
) ;
Array.prototype.reduce
1v a r s e s s i o n L i s t
=
s e s s i o n s
2.
map
(
e x t r a c t
(
” t i t l e ”
) )
3.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
4r e t u r n
a c c u m u l a t i o n
+
”
<
l i
>
”
+
n e x t
+
”
<
/ l i
>
”
5}
,
” ”
) ;
Array.prototype.reduce
1v a r wrapIn
=
f u n c t i o n
(
element
)
{
2r e t u r n f u n c t i o n
(
i n p u t
)
{
3r e t u r n
”
<
”
+
element
+
”
>
”
+
i n p u t
+
”
<
/ ”
+
element
+
”
>
”
;
4}
;
5}
;
6 7v a r s e s s i o n L i s t
=
s e s s i o n s
8.
map
(
e x t r a c t
(
” t i t l e ”
) )
9.
map
(
wrapIn
(
” l i ”
) )
10.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
11r e t u r n
a c c u m u l a t i o n
+
n e x t
12}
,
” ”
) ;
Array.prototype.reduce
1v a r wrapIn
=
f u n c t i o n
(
element
)
{
2r e t u r n f u n c t i o n
(
i n p u t
)
{
3r e t u r n
”
<
”
+
element
+
”
>
”
+
i n p u t
+
”
<
/ ”
+
element
+
”
>
”
;
4}
;
5}
;
6 7v a r s e s s i o n L i s t
=
s e s s i o n s
8.
map
(
e x t r a c t
(
” t i t l e ”
) )
9.
map
(
wrapIn
(
” l i ”
) )
10.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
11r e t u r n
a c c u m u l a t i o n
+
n e x t
12}
,
” ”
) ;
Array.prototype.reduce
1v a r wrapIn
=
f u n c t i o n
(
element
)
{
2r e t u r n f u n c t i o n
(
i n p u t
)
{
3r e t u r n
”
<
”
+
element
+
”
>
”
+
i n p u t
+
”
<
/ ”
+
element
+
”
>
”
;
4}
;
5}
;
6 7v a r s e s s i o n L i s t
=
s e s s i o n s
8.
map
(
e x t r a c t
(
” t i t l e ”
) )
9.
map
(
wrapIn
(
” l i ”
) )
10.
reduce
(
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
11r e t u r n
a c c u m u l a t i o n
+
n e x t
12}
,
” ”
) ;
Array.prototype.reduce
1v a r c o n c a t e n a t e
=
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
2r e t u r n
a c c u m u l a t i o n
+
n e x t
;
3}
;
4 5v a r s e s s i o n L i s t
=
s e s s i o n s
6.
map
(
e x t r a c t
(
” t i t l e ”
) )
7.
map
(
wrapIn
(
” l i ”
) )
8.
reduce
(
concatenate
,
” ”
) ;
Array.prototype.reduce
1v a r c o n c a t e n a t e
=
f u n c t i o n
(
a c c u m u l a t i o n
,
n e x t
)
{
2r e t u r n
a c c u m u l a t i o n
+
n e x t
;
3}
;
4 5v a r s e s s i o n L i s t
=
s e s s i o n s
6.
map
(
e x t r a c t
(
” t i t l e ”
) )
7.
map
(
wrapIn
(
” l i ”
) )
8.
reduce
(
concatenate
,
” ”
) ;
Array.prototype.reduce
1v a r s e s s i o n L i s t
=
s e s s i o n s
2.
map
(
e x t r a c t
(
” t i t l e ”
) )
3.
map
(
wrapIn
(
” l i ”
) )
4.
reduce
(
concatenate
,
” ”
) ;
VS.
1var
s e s s i o n L i s t = ” ” ;
2 3var
i , l e n ;
4f o r ( i =0 , l e n = s e s s i o n s . l e n g t h ; i
<
l e n ;
i ++)
{
5s e s s i o n L i s t += ”
<
l i
>
” + s e s s i o n s [ i ] . t i t l e + ”
<
/
l i
>
” ;
6}
Array.prototype.reduce
1v a r s e s s i o n L i s t
=
s e s s i o n s
2.
map
(
e x t r a c t
(
” t i t l e ”
) )
3.
map
(
wrapIn
(
” l i ”
) )
4.
reduce
(
concatenate
,
” ”
) ;
VS.
1var
s e s s i o n L i s t
=
” ”
;
2 3var
i
,
l e n
;
4f o r
(
i
=0 ,
l e n
=
s e s s i o n s
.
l e n g t h
;
i
<
l e n
;
i
++)
{
5s e s s i o n L i s t
+=
”
<
l i
>
”
+
s e s s i o n s
[
i
] .
t i t l e
+
”
<
/
l i
>
”
;
6}
A little bit more real
world please!
A little bit more real world
1. Extract
title
,
speaker
and description for display
2. Preprocess the data according to certain rules
I
Uppercase names
I
Highlight certain buzzwords
I
Limit descriptions to a maximal length
A little bit more real world
1. Extract
title
,
speaker
and description for display
2. Preprocess the data according to certain rules
IUppercase names
I
Highlight certain buzzwords
I
Limit descriptions to a maximal length
A little bit more real world
1. Extract
title
,
speaker
and description for display
2. Preprocess the data according to certain rules
I
Uppercase names
I
Highlight certain buzzwords
I
Limit descriptions to a maximal length
A little bit more real world
1. Extract
title
,
speaker
and description for display
2. Preprocess the data according to certain rules
I
Uppercase names
I
Highlight certain buzzwords
I
Limit descriptions to a maximal length
3. Finally accumulate everything as HTML
A little bit more real world
1. Extract
title
,
speaker
and description for display
2. Preprocess the data according to certain rules
I
Uppercase names
I
Highlight certain buzzwords
I
Limit descriptions to a maximal length
A little bit more real world
1 var t i t l e s = s e s s i o n s 2 .map(e x t r a c t(” t i t l e ”) ) 3 .map(wrapIn(” h2 ”) ) ; 1 var speakers = s e s s i o n s 2 . map ( e x t r a c t ( ” speaker ” ) ) 3 . map ( u p p e r c a s e E v e r y F i r s t ( ) ) 4 . map ( p r e f i x ( ” Speaker : ” ) ) 5 . map ( wrapIn ( ” h3 ” ) ) ; 1 var d e s c r i p t i o n s = s e s s i o n s 2 . map ( e x t r a c t ( ” d e s c r i p t i o n ” ) ) 3 . map ( e l l i p s i s ( 1 6 0 ) ) 4 . map ( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) 5 . map ( wrapIn ( ” p ” ) ) ;A little bit more real world
1 var t i t l e s = s e s s i o n s 2 .map(e x t r a c t(” t i t l e ”) ) 3 .map(wrapIn(” h2 ”) ) ; 1 var speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ; 1 var d e s c r i p t i o n s = s e s s i o n s 2 . map ( e x t r a c t ( ” d e s c r i p t i o n ” ) ) 3 . map ( e l l i p s i s ( 1 6 0 ) ) 4 . map ( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) 5 . map ( wrapIn ( ” p ” ) ) ;A little bit more real world
1 var t i t l e s = s e s s i o n s 2 .map(e x t r a c t(” t i t l e ”) ) 3 .map(wrapIn(” h2 ”) ) ; 1 var speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ; 1 var d e s c r i p t i o n s = s e s s i o n s 2 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 3 .map(e l l i p s i s( 1 6 0 ) ) 4 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 5 .map(wrapIn(” p ”) ) ;A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ;A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ;A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ; 1 v a r u p p e r c a s e E v e r y F i r s t = f u n c t i o n( ) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 r e t u r n i n p u t 4 .s p l i t(” ”) 5 .map(u p p e r c a s e F i r s t( ) ) 6 .j o i n(” ”) ; 7 } 8 }A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ; 1 v a r u p p e r c a s e E v e r y F i r s t = f u n c t i o n( ) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 r e t u r n i n p u t 4 .s p l i t(” ”) 5 .map(u p p e r c a s e F i r s t( ) ) 6 .j o i n(” ”) ; 7 } 8 }A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ; 1 v a r u p p e r c a s e E v e r y F i r s t = f u n c t i o n( ) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 r e t u r n i n p u t 4 .s p l i t(” ”) 5 .map(u p p e r c a s e F i r s t( ) ) 6 .j o i n(” ”) ; 7 } 8 } 1 v a r u p p e r c a s e F i r s t = f u n c t i o n( ) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 r e t u r n i n p u t.c h a r A t( 0 ) .toUpperCase( ) 4 + i n p u t.s u b s t r i n g( 1 ) ; 5 } 6 }A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ;A little bit more real world
1 v a r speakers = s e s s i o n s 2 .map(e x t r a c t(” speaker ”) ) 3 .map(u p p e r c a s e E v e r y F i r s t( ) ) 4 .map(p r e f i x(” Speaker : ”) ) 5 .map(wrapIn(” h3 ”) ) ; 1 v a r p r e f i x = f u n c t i o n(p r e f i x) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 r e t u r n p r e f i x + i n p u t; 4 } 5 };A little bit more real world
1 v a r d e s c r i p t i o n s = s e s s i o n s 2 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 3 .map(e l l i p s i s( 1 6 0 ) ) 4 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 5 .map(wrapIn(” p ”) ) ;A little bit more real world
1 v a r d e s c r i p t i o n s = s e s s i o n s 2 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 3 .map(e l l i p s i s( 1 6 0 ) ) 4 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 5 .map(wrapIn(” p ”) ) ;A little bit more real world
1 v a r d e s c r i p t i o n s = s e s s i o n s 2 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 3 .map(e l l i p s i s( 1 6 0 ) ) 4 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 5 .map(wrapIn(” p ”) ) ; 1 v a r e l l i p s i s = f u n c t i o n(maxLength) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 i f (i n p u t.l e n g t h <= maxLength) { 4 r e t u r n i n p u t; 5 } 6 7 r e t u r n i n p u t.s u b s t r i n g( 0 ,maxLength−1) + ”. . .” 8 } 9 }A little bit more real world
1 v a r d e s c r i p t i o n s = s e s s i o n s 2 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 3 .map(e l l i p s i s( 1 6 0 ) ) 4 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 5 .map(wrapIn(” p ”) ) ;A little bit more real world
1 v a r d e s c r i p t i o n s = s e s s i o n s 2 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 3 .map(e l l i p s i s( 1 6 0 ) ) 4 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 5 .map(wrapIn(” p ”) ) ; 1 v a r h i g h l i g h t = f u n c t i o n(/∗ args . . . ∗/) { 2 v a r args = A r r a y.p r o t o t y p e.s l i c e.c a l l(arguments) ; 3 r e t u r n f u n c t i o n(i n p u t) { 4 args.f o r E a c h(f u n c t i o n(replacement) { 5 i n p u t = i n p u t.r e p l a c e(6 new RegExp(”\ \b ” + replacement + ”\ \b ”) ,
7 ”<em>” + replacement + ”</em>” 8 ) ; 9 }) ; 10 11 r e t u r n i n p u t; 12 } 13 }
A little bit more real world
1 v a r t i t l e s = . . . , speakers = . . . , d e s c r i p t i o n s = . . . 1 v a r r e s u l t = weave ( t i t l e s , speakers , d e s c r i p t i o n s ) 2 . map ( j o i n ( ) ) 3 . map ( wrapIn ( ” d i v ” ) ) 4 . reduce ( c o n c a t e n a t e ( ) ) ;A little bit more real world
1 v a r t i t l e s = . . . , speakers = . . . , d e s c r i p t i o n s = . . . 1 v a r r e s u l t = weave(t i t l e s , speakers, d e s c r i p t i o n s) 2 .map(j o i n( ) ) 3 .map(wrapIn(” d i v ”) ) 4 .reduce(c o n c a t e n a t e( ) ) ;A little bit more real world
1 v a r t i t l e s = . . . , speakers = . . . , d e s c r i p t i o n s = . . . 1 v a r r e s u l t = weave(t i t l e s , speakers, d e s c r i p t i o n s) 2 .map(j o i n( ) ) 3 .map(wrapIn(” d i v ”) ) 4 .reduce(c o n c a t e n a t e( ) ) ;A little bit more real world
1 v a r t i t l e s = . . . , speakers = . . . , d e s c r i p t i o n s = . . . 1 v a r r e s u l t = weave(t i t l e s , speakers, d e s c r i p t i o n s) 2 .map(j o i n( ) ) 3 .map(wrapIn(” d i v ”) ) 4 .reduce(c o n c a t e n a t e( ) ) ; 1 [ 1 , 2 , 3 , 4 ] 2 [” a ”,” b ”,” c ”,” d ”] 3 [” ! ”,” ? ”,” $ ”,” = ”] 4 −−−−−−weave−−−−−− 5 [ 6 [ 1 ,” a ”,” ! ”] , 7 [ 2 ,” b ”,” ? ”] , 8 [ 3 ,” c ”,” $ ”] , 9 [ 4 ,” d ”,” = ”] 10 ]A little bit more real world
1 v a r t i t l e s = . . . , speakers = . . . , d e s c r i p t i o n s = . . . 1 v a r r e s u l t = weave(t i t l e s , speakers, d e s c r i p t i o n s) 2 .map(j o i n( ) ) 3 .map(wrapIn(” d i v ”) ) 4 .reduce(c o n c a t e n a t e( ) ) ;A little bit more real world
1 v a r t i t l e s = . . . , speakers = . . . , d e s c r i p t i o n s = . . . 1 v a r r e s u l t = weave(t i t l e s , speakers, d e s c r i p t i o n s) 2 .map(j o i n( ) ) 3 .map(wrapIn(” d i v ”) ) 4 .reduce(c o n c a t e n a t e( ) ) ; 1 v a r j o i n = f u n c t i o n(d e l i m i t e r) { 2 r e t u r n f u n c t i o n(i n p u t) { 3 r e t u r n i n p u t.j o i n(d e l i m i t e r) ; 4 } 5 }A little bit more real world
1 v a r t i t l e s = s e s s i o n s 2 .map(e x t r a c t(” t i t l e ”) ) 3 .map(wrapIn(” h2 ”) ) ; 4 5 v a r speakers = s e s s i o n s 6 .map(e x t r a c t(” speaker ”) ) 7 .map(u p p e r c a s e E v e r y F i r s t( ) ) 8 .map(p r e f i x(” Speaker : ”) ) 9 .map(wrapIn(” h3 ”) ) ; 10 11 v a r d e s c r i p t i o n s = s e s s i o n s 12 .map(e x t r a c t(” d e s c r i p t i o n ”) ) 13 .map(e l l i p s i s( 1 6 0 ) ) 14 .map(h i g h l i g h t(” J a v a S c r i p t ”, ”HTML5”) ) 15 .map(wrapIn(” p ”) ) ; 16 17 v a r r e s u l t = weave(t i t l e s , speakers, d e s c r i p t i o n s) 18 .map(j o i n( ) ) 19 .map(wrapIn(” d i v ”) ) 20 .reduce(c o n c a t e n a t e( ) ) ;What comes next?
JavaScript is
Asynchronous
Asynchronous functional handling
I
JavaScript utilizes
Evented-IO
I
A lot of operations are asynchronous
Asynchronous functional handling
I
JavaScript utilizes
Evented-IO
I
A lot of operations are asynchronous
Asynchronous functional handling
I
JavaScript utilizes
Evented-IO
IA lot of operations are asynchronous
Fetching our
sessions
via XHR
I
Our
sessions
data needs to be retrieved from the server
IIt is devided into multiple chunks by day
1 var u r l s = [ 2 ” / c o n f e r e n c e / s e s s i o n s / day1 ” , 3 ” / c o n f e r e n c e / s e s s i o n s / day2 ” , 4 ” / c o n f e r e n c e / s e s s i o n s / s o c i a l e v e n t ” , 5 ” / c o n f e r e n c e / s e s s i o n s / day3 ” 6 ] ;
Fetching our
sessions
via XHR
I
Our
sessions
data needs to be retrieved from the server
I
It is devided into multiple chunks by day
1 var u r l s = [ 2 ” / c o n f e r e n c e / s e s s i o n s / day1 ” , 3 ” / c o n f e r e n c e / s e s s i o n s / day2 ” , 4 ” / c o n f e r e n c e / s e s s i o n s / s o c i a l e v e n t ” , 5 ” / c o n f e r e n c e / s e s s i o n s / day3 ” 6 ] ;
Fetching our
sessions
via XHR
I
Our
sessions
data needs to be retrieved from the server
I
It is devided into multiple chunks by day
1 var u r l s = [ 2 ” / c o n f e r e n c e / s e s s i o n s / day1 ”, 3 ” / c o n f e r e n c e / s e s s i o n s / day2 ”, 4 ” / c o n f e r e n c e / s e s s i o n s / s o c i a l e v e n t ”, 5 ” / c o n f e r e n c e / s e s s i o n s / day3 ” 6 ] ;
Fetching our
sessions
via XHR
1 v a r f e t c h = f u n c t i o n(u r l s, done) { 2 v a r r e c e i v e d D a t a = [ ] ; 3 v a r i, l e n; 4 5 f o r(i=0 , l e n=u r l s.l e n g t h; i<l e n; i++) { 6 $.a j a x({ 7 u r l: u r l s[i] , 8 success: f u n c t i o n(data) { 9 r e c e i v e d D a t a[i] = data; 10 i f(r e c e i v e d D a t a.l e n g t h == u r l s.l e n g t h) { 11 done(r e c e i v e d D a t a) ; 12 } 13 } 14 }) 15 } 16 };Fetching our
sessions
via XHR
1 v a r f e t c h = f u n c t i o n(u r l s, done) { 2 v a r r e c e i v e d D a t a = [ ] ; 3 v a r i, l e n; 4 5 f o r(i=0 , l e n=u r l s.l e n g t h; i<l e n; i++) { 6 $.a j a x({ 7 u r l: u r l s[i] , 8 success: f u n c t i o n(data) { 9 r e c e i v e d D a t a[i] = data; 10 i f(r e c e i v e d D a t a.l e n g t h == u r l s.l e n g t h) { 11 done(r e c e i v e d D a t a) ; 12 } 13 } 14 }) 15 } 16 };Fetching our
sessions
via XHR
1 v a r f e t c h = f u n c t i o n(u r l s, done) { 2 v a r r e c e i v e d D a t a = [ ] ; 3 v a r i, l e n; 4 5 f o r(i=0 , l e n=u r l s.l e n g t h; i<l e n; i++) { 6 (f u n c t i o n(i) { 7 $.a j a x({ 8 u r l: u r l s[i] , 9 success: f u n c t i o n(data) { 10 r e c e i v e d D a t a[i] = data; 11 i f(r e c e i v e d D a t a.l e n g t h == u r l s.l e n g t h) { 12 done(r e c e i v e d D a t a) ; 13 } 14 } 15 }) 16 }) (i) ; 17 } 18 };Btw: It still does not
work!
Fetching our
sessions
via XHR
1 v a r f e t c h = f u n c t i o n(u r l s, done) { 2 v a r r e c e i v e d D a t a = [ ] ; 3 v a r i, l e n; 4 5 f o r(i=0 , l e n=u r l s.l e n g t h; i<l e n; i++) { 6 (f u n c t i o n(i) { 7 $.a j a x({ 8 u r l: u r l s[i] , 9 success: f u n c t i o n(data) { 10 r e c e i v e d D a t a[i] = data; 11 i f(r e c e i v e d D a t a.l e n g t h == u r l s.l e n g t h) { 12 done(r e c e i v e d D a t a) ; 13 } 14 } 15 }) 16 }) (i) ; 17 } 18 };Fetching our
sessions
via XHR
1 v a r f e t c h = f u n c t i o n(u r l s, done) { 2 v a r r e c e i v e d D a t a = [ ] ; 3 v a r i, l e n; 4 v a r r e c e i v e d C o u n t = 0 ; 5 6 f o r(i=0 , l e n=u r l s.l e n g t h; i<l e n; i++) { 7 (f u n c t i o n(i) { 8 $.a j a x({ 9 u r l: u r l s[i] , 10 success: f u n c t i o n(data) { 11 r e c e i v e d D a t a[i] = data; 12 r e c e i v e d C o u n t += 1 ; 13 i f(r e c e i v e d C o u n t == u r l s.l e n g t h) { 14 done(r e c e i v e d D a t a) ; 15 } 16 } 17 }) 18 }) (i) ; 19 } 20 };Fetching our
sessions
via XHR
1 v a r f e t c h = f u n c t i o n(u r l s, done) { 2 v a r r e c e i v e d D a t a = [ ] ; 3 v a r i, l e n; 4 v a r r e c e i v e d C o u n t = 0 ; 5 6 f o r(i=0 , l e n=u r l s.l e n g t h; i<l e n; i++) { 7 (f u n c t i o n(i) { 8 $.a j a x({ 9 u r l: u r l s[i] , 10 success: f u n c t i o n(data) { 11 r e c e i v e d D a t a[i] = data; 12 r e c e i v e d C o u n t += 1 ; 13 i f(r e c e i v e d C o u n t == u r l s.l e n g t h) { 14 done(r e c e i v e d D a t a) ; 15 } 16 } 17 }) 18 }) (i) ; 19 } 20 };Asynchronous
map
/
reduce
to the
Asynchronous
map/reduce
I
https://github.com/caolan/async
I
Functional style asynchronous handling
Asynchronous
map/reduce
I
https://github.com/caolan/async
I
Functional style asynchronous handling
Asynchronous
map/reduce
I
https://github.com/caolan/async
IFunctional style asynchronous handling
Asynchronous
map/reduce
1 v a r f e t c h = f u n t i o n(u r l s, done) {
2 async.map(u r l s, a j a x, done) ;
Asynchronous
map/reduce
1 v a r f e t c h = f u n t i o n(u r l s, done) {
2 async.map(u r l s, a j a x, done) ;
Asynchronous
map/reduce
1 v a r f e t c h = f u n t i o n(u r l s, done) {
2 async.map(u r l s, a j a x, done) ;
3 }; 1 v a r a j a x = f u n c t i o n(u r l, done) { 2 $.a j a x({ 3 u r l: u r l, 4 success: done 5 }) ; 6 };
What comes next?
Performance considerations
I
”I am writing high performance JS. I can’t use
forEach
,
map
,
reduce
and others.”
IIs this true?
I
Yes. Due to the higher amount of function calls those are
slower.
Performance considerations
I
”I am writing high performance JS. I can’t use
forEach
,
map
,
reduce
and others.”
I
Is this true?
I
Yes. Due to the higher amount of function calls those are
slower.
Performance considerations
I
”I am writing high performance JS. I can’t use
forEach
,
map
,
reduce
and others.”
I
Is this true?
I
Yes. Due to the higher amount of function calls those are
slower.
Performance considerations
I
”I am writing high performance JS. I can’t use
forEach
,
map
,
reduce
and others.”
I
Is this true?
I
Yes. Due to the higher amount of function calls those are
slower.
What comes next?
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many pure functions as possible
IEven if you are doing JavaScript OOP
I
Use JavaScripts functional built-ins
I
Create generic
map
/
reduce
functions
I
Btw: Closures ROCK!
I
Don’t let asynchronous scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
I
Use JavaScripts functional built-ins
I
Create generic
map
/
reduce
functions
I
Btw: Closures ROCK!
I
Don’t let asynchronous scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
IUse JavaScripts functional built-ins
I
Create generic
map
/
reduce
functions
I
Btw: Closures ROCK!
I
Don’t let asynchronous scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
I
Use JavaScripts
functional built-ins
I
Create generic
map
/
reduce
functions
I
Btw: Closures ROCK!
I
Don’t let asynchronous scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
I
Use JavaScripts
functional built-ins
I
Create
generic
map
/
reduce
functions
I
Btw: Closures ROCK!
I
Don’t let asynchronous scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
I
Use JavaScripts
functional built-ins
I
Create
generic
map
/
reduce
functions
I
Btw:
Closures
ROCK!
I
Don’t let asynchronous scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
I
Use JavaScripts
functional built-ins
ICreate
generic
map
/
reduce
functions
I
Btw:
Closures
ROCK!
I
Don’t let
asynchronous
scenarios stop you
Conclusion
I
Functions are
first-level citizens
in JavaScript
I
Try to create as many
pure
functions as possible
I
Even if you are doing JavaScript OOP
I
Use JavaScripts
functional built-ins
ICreate
generic
map
/
reduce
functions
I
Btw:
Closures
ROCK!
I