7 Nov 2013 ... A simple function. 1 function increment (a) {. 2 alert (a+1) ;. 3. } ▷ Function
Declaration. ▷ Most common way to create a function in JavaScript ...
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
I
Consultant, Trainer and Author
We are
Helping people to create high quality web applications.
http://qafoo.com I
Trainings, Workshops and Consulting
I
Twitter: @qafoo
I
Mail:
[email protected]
We are
Helping people to create high quality web applications.
http://qafoo.com I
Trainings, Workshops and Consulting
I
Twitter: @qafoo
I
Mail:
[email protected]
We are
Helping people to create high quality web applications.
http://qafoo.com I
Trainings, Workshops and Consulting
I
Twitter: @qafoo
I
Mail:
[email protected]
We are
Helping people to create high quality web applications.
http://qafoo.com I
Trainings, Workshops and Consulting
I
Twitter: @qafoo
I
Mail:
[email protected]
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. – Wikipedia
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. – Wikipedia
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. – Wikipedia
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. – Wikipedia
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. – Wikipedia
Functions
JavaScript Functions
A simple function
2
function i n c r e m e n t ( a ) { a l e r t ( a +1) ;
3
}
1
I
Function Declaration
I
Most common way to create a function in JavaScript
A simple function
2
function i n c r e m e n t ( a ) { a l e r t ( a +1) ;
3
}
1
I
Function Declaration
I
Most common way to create a function in JavaScript
A simple function
2
function i n c r e m e n t ( a ) { a l e r t ( a +1) ;
3
}
1
I
Function Declaration
I
Most common way to create a function in JavaScript
Functions
First-Level Citizens
Functions are special
2
v a r i n c r e m e n t = function ( a ) { a l e r t ( a +1) ;
3
}
1
I
Function Expression
Functions are special
2
v a r i n c r e m e n t = function ( a ) { a l e r t ( a +1) ;
3
}
1
I
Function Expression
Functions are special
1 2 3 4
function one ( ) { function two ( ) { function t h r e e ( ) { // ...
}
5
}
6 7
I
}
Functions can be nested
Higher-Order Functions
1 2 3
I
window . setTimeout ( function ( ) { a l e r t ( ”A second has passed ” ) ; } , 1000) ;
Functions can take other functions as arguments
Higher-Order Functions
1 2 3
I
window . setTimeout ( function ( ) { a l e r t ( ”A second has passed ” ) ; } , 1000) ;
Functions can take other functions as arguments
Higher-Order Functions
1 2 3 4 5
I
v a r makeGreeter = function ( name ) { r e t u r n function ( ) { a l e r t ( ” H e l l o ” + name + ” ! ” ) ; }; };
Functions may return other functions
Higher-Order Functions
1 2 3 4 5
I
v a r makeGreeter = function ( name ) { r e t u r n function ( ) { a l e r t ( ” H e l l o ” + name + ” ! ” ) ; }; };
Functions may return other functions
Higher-Order Functions
I
Functions which consume or return other functions are called
Higher-Order Functions
What comes next?
Sideeffects
Sideeffects 1 2 3 4
v a r count = function ( i t e m s ) { var length = 0; while ( i t e m s . pop ( ) ) { l e n g t h += 1 ;
}
5 6
return length ;
7 8
}
9 10 11
I
var items = [ 1 , 2 , 3 ] ; a l e r t ( count ( i t e m s ) ) ; / / 3
Are there any problems with this implementation?
Sideeffects 1 2 3 4
v a r count = function ( i t e m s ) { var length = 0; while ( i t e m s . pop ( ) ) { l e n g t h += 1 ;
}
5 6
return length ;
7 8
}
9 10 11
I
var items = [ 1 , 2 , 3 ] ; a l e r t ( count ( i t e m s ) ) ; / / 3
Are there any problems with this implementation?
Sideeffects 1 2 3 4
v a r count = function ( i t e m s ) { var length = 0; while ( i t e m s . pop ( ) ) { l e n g t h += 1 ;
}
5 6
return length ;
7 8
}
9 10 11
I
var items = [ 1 , 2 , 3 ] ; a l e r t ( count ( i t e m s ) ) ; / / 3
Modification of state
Sideeffects
2
v a r i n c r e m e n t = function ( a ) { a l e r t ( a +1) ;
3
}
1
I
Interaction with the outside world
Sideeffects
2
v a r i n c r e m e n t = function ( a ) { a l e r t ( a +1) ;
3
}
1
I
Interaction with the outside world
Pure Functions
2
v a r i n c r e m e n t = function ( a ) { r e t u r n a +1;
3
}
1
I
No sideeffects
I
Easier to maintain, easier to test
Pure Functions
2
v a r i n c r e m e n t = function ( a ) { r e t u r n a +1;
3
}
1
I
No sideeffects
I
Easier to maintain, easier to test
Pure Functions
2
v a r i n c r e m e n t = function ( a ) { r e t u r n a +1;
3
}
1
I
No sideeffects
I
Easier to maintain, easier to test
Pure Functions
I
Functions which are sideeffect free are called
Pure Functions
Pure Functions
I
No program can consist of Pure Functions only
I
It would simply do nothing
I
Every program needs to have at least one impure function
Pure Functions
I
No program can consist of Pure Functions only
I
It would simply do nothing
I
Every program needs to have at least one impure function
Pure Functions
I
No program can consist of Pure Functions only
I
It would simply do nothing
I
Every program needs to have at least one impure function
What comes next?
Functional Built-Ins
Functional Loops
I
Loops (for, while, ...) are quite common in every program
I
Loops are mostly used to I I I
Cause Sideeffects on every element of a set Transform or Extract data from a set Aggregate 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 I I
Cause Sideeffects on every element of a set Transform or Extract data from a set Aggregate 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 I I
Cause Sideeffects on every element of a set Transform or Extract data from a set Aggregate 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 I I
Cause Sideeffects on every element of a set Transform or Extract data from a set Aggregate or Accumulate data from a set
Looping
1
var sessions = . . . ;
2
5
var i , len ; f 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 ++) { doSomething ( s e s s i o n s [ i ] ) ;
6
}
3 4
I
Loop through data
I
Cause some sideeffect on each data entry
Looping
1
var sessions = . . . ;
2
5
var i , len ; f 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 ++) { doSomething ( s e s s i o n s [ i ] ) ;
6
}
3 4
I
Loop through data
I
Cause some sideeffect on each data entry
Looping
1
var sessions = . . . ;
2
5
var i , len ; f 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 ++) { doSomething ( s e s s i o n s [ i ] ) ;
6
}
3 4
I
Loop through data
I
Cause some sideeffect on each data entry
Array.prototype.forEach
1
var sessions = . . . ;
2 3 4 5
s e s s i o n s . forEach ( function ( s e s s i o n ) { doSomething ( s e s s i o n ) ; }) ;
Data extraction
1
var t i t l e s = [ ] ;
2
5
var i , len ; f 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 ++) { t i t l e s . push ( s e s s i o n s [ i ] . t i t l e ) ;
6
}
3 4
I
Extract certain bits of data from a bigger structure
Data extraction
1
var t i t l e s = [ ] ;
2
5
var i , len ; f 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 ++) { t i t l e s . push ( s e s s i o n s [ i ] . t i t l e ) ;
6
}
3 4
I
Extract certain bits of data from a bigger structure
Array.prototype.map
1 2 3
v a r t i t l e s = s e s s i o n s . map( function ( s e s s i o n ) { return session . t i t l e ; }) ;
I
This kind of property extraction is needed quite often
I
Let’s extract it to its own method
Array.prototype.map
1 2 3
v a r t i t l e s = s e s s i o n s . map( function ( s e s s i o n ) { return session . t i t l e ; }) ;
I
This kind of property extraction is needed quite often
I
Let’s extract it to its own method
Array.prototype.map
1 2 3
v a r t i t l e s = s e s s i o n s . map( function ( s e s s i o n ) { return session . t i t l e ; }) ;
I
This kind of property extraction is needed quite often
I
Let’s extract it to its own method
extract
5
v a r e x t r a c t = function ( p r o p e r t y ) { r e t u r n function ( o b j e c t ) { return o b j e c t [ property ] ; }; };
1
var 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 ” ) ) ;
1 2 3 4
extract
5
v a r e x t r a c t = function ( p r o p e r t y ) { r e t u r n function ( o b j e c t ) { return o b j e c t [ property ] ; }; };
1
var 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 ” ) ) ;
1 2 3 4
extract
5
v a r e x t r a c t = function ( p r o p e r t y ) { r e t u r n function ( o b j e c t ) { return o b j e c t [ property ] ; }; };
1
var 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 ” ) ) ;
1 2 3 4
extract
5
v a r e x t r a c t = function ( p r o p e r t y ) { r e t u r n function ( o b j e c t ) { return o b j e c t [ property ] ; }; };
1
var 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 ” ) ) ;
1 2 3 4
extract
5
v a r e x t r a c t = function ( p r o p e r t y ) { r e t u r n function ( o b j e c t ) { return o b j e c t [ property ] ; }; };
1
var 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 ” ) ) ;
1 2 3 4
Data accumulation 1
var s e s s i o n L i s t = ” ” ;
2 3 4 5
6
var i , l e n ; f 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 ++) { s 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 >” ;
}
I
Accumulate information from given data structure
I
Two things are actually done here: 1. Extract each sessions title 2. Accumulate result into an HTML-List
Data accumulation 1
var s e s s i o n L i s t = ” ” ;
2 3 4 5
6
var i , l e n ; f 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 ++) { s 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 >” ;
}
I
Accumulate information from given data structure
I
Two things are actually done here: 1. Extract each sessions title 2. Accumulate result into an HTML-List
Data accumulation 1
var s e s s i o n L i s t = ” ” ;
2 3 4 5
6
var i , l e n ; f 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 ++) { s 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 >” ;
}
I
Accumulate information from given data structure
I
Two things are actually done here: 1. Extract each sessions title 2. Accumulate result into an HTML-List
Array.prototype.reduce
1 2 3 4 5 6 7
var s e s s i o n L i s t = sessions . map( function ( s e s s i o n ) { return session . t i t l e ; }) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + ” < l i > ” + n e x t + ” < / l i > ” }, ””);
Array.prototype.reduce
1 2 3 4 5 6 7
var s e s s i o n L i s t = sessions . map( function ( s e s s i o n ) { return session . t i t l e ; }) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + ” < l i > ” + n e x t + ” < / l i > ” }, ””);
Array.prototype.reduce
1 2 3 4 5
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + ” < l i > ” + n e x t + ” < / l i > ” }, ””);
Array.prototype.reduce
1 2 3 4 5
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + ” < l i > ” + n e x t + ” < / l i > ” }, ””);
Array.prototype.reduce 1 2 3
4 5
v a r wrapIn = function ( element ) { r e t u r n function ( i n p u t ) { r e t u r n ” < ” + element + ” > ” + i n p u t + ” < / ” + element + ” > ” ; }; };
6 7 8 9 10 11 12
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + n e x t }, ””);
Array.prototype.reduce 1 2 3
4 5
v a r wrapIn = function ( element ) { r e t u r n function ( i n p u t ) { r e t u r n ” < ” + element + ” > ” + i n p u t + ” < / ” + element + ” > ” ; }; };
6 7 8 9 10 11 12
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + n e x t }, ””);
Array.prototype.reduce 1 2 3
4 5
v a r wrapIn = function ( element ) { r e t u r n function ( i n p u t ) { r e t u r n ” < ” + element + ” > ” + i n p u t + ” < / ” + element + ” > ” ; }; };
6 7 8 9 10 11 12
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( function ( accumulation , n e x t ) { r e t u r n a cc u mu l a ti o n + n e x t }, ””);
Array.prototype.reduce
1 2 3
v a r concatenate = function ( accumulation , n e x t ) { r e t u r n a cc u m ul a ti o n + n e x t ; };
4 5 6 7 8
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( concatenate , ” ” ) ;
Array.prototype.reduce
1 2 3
v a r concatenate = function ( accumulation , n e x t ) { r e t u r n a cc u m ul a ti o n + n e x t ; };
4 5 6 7 8
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( concatenate , ” ” ) ;
Array.prototype.reduce 1 2 3 4
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( concatenate , ” ” ) ;
VS.
1
var s e s s i o n L i s t = ” ” ;
2 3 4 5
6
var i , l e n ; f 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 ++) { s 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 >” ;
}
Array.prototype.reduce 1 2 3 4
var s e s s i o n L i s t = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” l i ” ) ) . reduce ( concatenate , ” ” ) ;
VS.
1
var s e s s i o n L i s t = ” ” ;
2 3 4 5
6
var i , l e n ; f 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 ++) { s 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 >” ;
}
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 I I
Uppercase names Highlight certain buzzwords 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 I I
Uppercase names Highlight certain buzzwords 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 I I
Uppercase names Highlight certain buzzwords 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 I I
Uppercase names Highlight certain buzzwords 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 I I
Uppercase names Highlight certain buzzwords Limit descriptions to a maximal length
3. Finally accumulate everything as HTML
A little bit more real world 1 2 3
1 2 3 4 5
1 2 3 4 5
var 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 ” ) ) . map( wrapIn ( ” h2 ” ) ) ;
var speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
var d e s c r i p t i o n s = s e s s i o n s . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
A little bit more real world 1 2 3
1 2 3 4 5
1 2 3 4 5
var 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 ” ) ) . map( wrapIn ( ” h2 ” ) ) ;
var speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
var d e s c r i p t i o n s = s e s s i o n s . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
A little bit more real world 1 2 3
1 2 3 4 5
1 2 3 4 5
var 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 ” ) ) . map( wrapIn ( ” h2 ” ) ) ;
var speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
var d e s c r i p t i o n s = s e s s i o n s . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
A little bit more real world 1 2 3 4 5
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
A little bit more real world 1 2 3 4 5
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
A little bit more real world 1 2 3 4 5
1 2 3 4 5 6
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
v a r u p p e r c a s e E v e r y F i r s t = function ( ) { r e t u r n function ( i n p u t ) { return i n p u t . split ( ” ” ) . map( u p p e r c a s e F i r s t ( ) ) . join ( ” ” ) ;
}
7 8
}
A little bit more real world 1 2 3 4 5
1 2 3 4 5 6
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
v a r u p p e r c a s e E v e r y F i r s t = function ( ) { r e t u r n function ( i n p u t ) { return i n p u t . split ( ” ” ) . map( u p p e r c a s e F i r s t ( ) ) . join ( ” ” ) ;
}
7 8
}
A little bit more real world 1 2 3 4 5
1 2 3 4 5 6
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
v a r u p p e r c a s e E v e r y F i r s t = function ( ) { r e t u r n function ( i n p u t ) { return i n p u t . split ( ” ” ) . map( u p p e r c a s e F i r s t ( ) ) . join ( ” ” ) ;
}
7 8
}
1
v a r u p p e r c a s e F i r s t = function ( ) { r e t u r n function ( i n p u t ) { r e t u r n i n p u t . c h a r A t ( 0 ) . toUpperCase ( ) + input . substring (1) ;
2 3 4
}
5 6
}
A little bit more real world 1 2 3 4 5
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
A little bit more real world 1 2 3 4 5
1 2 3
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
v a r p r e f i x = function ( p r e f i x ) { r e t u r n function ( i n p u t ) { return p r e f i x + i n p u t ;
}
4 5
};
A little bit more real world 1 2 3 4 5
var d e s c r i p t i o n s = sessions . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
A little bit more real world 1 2 3 4 5
var d e s c r i p t i o n s = sessions . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
A little bit more real world 1 2 3 4 5
1 2 3 4
var d e s c r i p t i o n s = sessions . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
v a r e l l i p s i s = function ( maxLength ) { r e t u r n function ( i n p u t ) { i f ( i n p u t . l e n g t h ” ); }) ;
10
return i n p u t ;
11
}
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
2 3 4
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
2 3 4
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
2 3 4
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
2 3 4
1 2 3 4 5 6 7 8 9 10
[ 1, 2, 3, 4 ] [ ”a” , ”b” , ”c” , ”d” ] [ ” ! ” , ”?” , ”$” , ”=” ] −−−−−−weave−−−−−− [ [1 , ”a” , ” ! ” ] , [2 , ”b” , ”?” ] , [3 , ” c ” , ”$” ] , [4 , ”d” , ”=” ] ]
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
2 3 4
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
2 3 4
1 2 3
v a r j o i n = function ( d e l i m i t e r ) { r e t u r n function ( i n p u t ) { return 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 2 3
var t i t l e s = sessions . map( e x t r a c t ( ” t i t l e ” ) ) . map( wrapIn ( ” h2 ” ) ) ;
4 5 6 7 8 9
v a r speakers = s e s s i o n s . map( e x t r a c t ( ” speaker ” ) ) . map( u p p e r c a s e E v e r y F i r s t ( ) ) . map( p r e f i x ( ” Speaker : ” ) ) . map( wrapIn ( ” h3 ” ) ) ;
10 11 12 13 14 15
var d e s c r i p t i o n s = sessions . map( e x t r a c t ( ” d e s c r i p t i o n ” ) ) . map( e l l i p s i s ( 1 6 0 ) ) . map( h i g h l i g h t ( ” J a v a S c r i p t ” , ”HTML5” ) ) . map( wrapIn ( ” p ” ) ) ;
16 17 18 19 20
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 ) . map( j o i n ( ) ) . map( wrapIn ( ” d i v ” ) ) . reduce ( concatenate ( ) ) ;
What comes next?
JavaScript is Asynchronous
Asynchronous functional handling
I
JavaScript utilizes Evented-IO
I
A lot of operations are asynchronous
I
Especially those with the outside world
Asynchronous functional handling
I
JavaScript utilizes Evented-IO
I
A lot of operations are asynchronous
I
Especially those with the outside world
Asynchronous functional handling
I
JavaScript utilizes Evented-IO
I
A lot of operations are asynchronous
I
Especially those with the outside world
Fetching our sessions via XHR
1 2 3 4 5 6
I
Our sessions data needs to be retrieved from the server
I
It is devided into multiple chunks by day var u r l s = [ ” / conference / s e s s i o n s / day1 ” , ” / conference / s e s s i o n s / day2 ” , ” / conference / s e s s i o n s / s o c i a l e v e n t ” , ” / conference / s e s s i o n s / day3 ” ];
Fetching our sessions via XHR
1 2 3 4 5 6
I
Our sessions data needs to be retrieved from the server
I
It is devided into multiple chunks by day var u r l s = [ ” / conference / s e s s i o n s / day1 ” , ” / conference / s e s s i o n s / day2 ” , ” / conference / s e s s i o n s / s o c i a l e v e n t ” , ” / conference / s e s s i o n s / day3 ” ];
Fetching our sessions via XHR
1 2 3 4 5 6
I
Our sessions data needs to be retrieved from the server
I
It is devided into multiple chunks by day var u r l s = [ ” / conference / s e s s i o n s / day1 ” , ” / conference / s e s s i o n s / day2 ” , ” / conference / s e s s i o n s / s o c i a l e v e n t ” , ” / conference / s e s s i o n s / day3 ” ];
Fetching our sessions via XHR 1 2 3
v a r f e t c h = function ( u r l s , done ) { v a r r ec e iv e d Da t a = [ ] ; var i , len ;
4
f o r ( i =0 , l e n = u r l s . l e n g t h ; i < l e n ; i ++) { $ . ajax ( { url : urls [ i ] , success : function ( data ) { r ec e iv e d Da t a [ i ] = data ; i f ( r e ce i ve d Da t a . l e n g t h == u r l s . l e n g t h ) { done ( r e c ei v ed D at a ) ;
5 6 7 8 9 10 11
}
12
}
13
})
14
}
15 16
};
Really?
It doesn’t even work!
Fetching our sessions via XHR 1 2 3
v a r f e t c h = function ( u r l s , done ) { v a r r ec e iv e d Da t a = [ ] ; var i , len ;
4
f o r ( i =0 , l e n = u r l s . l e n g t h ; i < l e n ; i ++) { $ . ajax ( { url : urls [ i ] , success : function ( data ) { r ec e iv e d Da t a [ i ] = data ; i f ( r e ce i ve d Da t a . l e n g t h == u r l s . l e n g t h ) { done ( r e c ei v ed D at a ) ;
5 6 7 8 9 10 11
}
12
}
13
})
14
}
15 16
};
Fetching our sessions via XHR 1 2 3
v a r f e t c h = function ( u r l s , done ) { v a r r ec e iv e d Da t a = [ ] ; var i , len ;
4
f o r ( i =0 , l e n = u r l s . l e n g t h ; i < l e n ; i ++) { ( function ( i ) { $ . ajax ( { url : urls [ i ] , success : function ( data ) { r ec e iv e d Da t a [ i ] = data ; i f ( r e ce i ve d Da t a . l e n g t h == u r l s . l e n g t h ) { done ( r e c ei v ed D at a ) ;
5 6 7 8 9 10 11 12
}
13
}
14
}) }) ( i ) ;
15 16
}
17 18
};
Btw: It still does not work!
Fetching our sessions via XHR 1 2 3
v a r f e t c h = function ( u r l s , done ) { v a r r ec e iv e d Da t a = [ ] ; var i , len ;
4
f o r ( i =0 , l e n = u r l s . l e n g t h ; i < l e n ; i ++) { ( function ( i ) { $ . ajax ( { url : urls [ i ] , success : function ( data ) { r ec e iv e d Da t a [ i ] = data ; i f ( r e ce i ve d Da t a . l e n g t h == u r l s . l e n g t h ) { done ( r e c ei v ed D at a ) ;
5 6 7 8 9 10 11 12
}
13
}
14
}) }) ( i ) ;
15 16
}
17 18
};
Fetching our sessions via XHR 1 2 3 4
v a r f e t c h = function ( u r l s , done ) { v a r r ec e iv e d Da t a = [ ] ; var i , len ; v a r receivedCount = 0 ;
5
f o r ( i =0 , l e n = u r l s . l e n g t h ; i < l e n ; i ++) { ( function ( i ) { $ . ajax ( { url : urls [ i ] , success : function ( data ) { r ec e iv e d Da t a [ i ] = data ; receivedCount += 1 ; i f ( receivedCount == u r l s . l e n g t h ) { done ( r e c ei v ed D at a ) ;
6 7 8 9 10 11 12 13 14
}
15
}
16
}) }) ( i ) ;
17 18
}
19 20
};
Fetching our sessions via XHR 1 2 3 4
v a r f e t c h = function ( u r l s , done ) { v a r r ec e iv e d Da t a = [ ] ; var i , len ; v a r receivedCount = 0 ;
5
f o r ( i =0 , l e n = u r l s . l e n g t h ; i < l e n ; i ++) { ( function ( i ) { $ . ajax ( { url : urls [ i ] , success : function ( data ) { r ec e iv e d Da t a [ i ] = data ; receivedCount += 1 ; i f ( receivedCount == u r l s . l e n g t h ) { done ( r e c ei v ed D at a ) ;
6 7 8 9 10 11 12 13 14
}
15
}
16
}) }) ( i ) ;
17 18
}
19 20
};
Can’t we do better?
Asynchronous map/reduce to the rescue.
Asynchronous map/reduce
I
https://github.com/caolan/async
I
Functional style asynchronous handling
I
. . . and more :)
Asynchronous map/reduce
I
https://github.com/caolan/async
I
Functional style asynchronous handling
I
. . . and more :)
Asynchronous map/reduce
I
https://github.com/caolan/async
I
Functional style asynchronous handling
I
. . . and more :)
Asynchronous map/reduce 1 2 3
v a r f e t c h = f u n t i o n ( u r l s , done ) { async . map( u r l s , ajax , done ) ; };
Asynchronous map/reduce 1 2 3
v a r f e t c h = f u n t i o n ( u r l s , done ) { async . map( u r l s , ajax , done ) ; };
Asynchronous map/reduce 1 2 3
1 2 3 4 5 6
v a r f e t c h = f u n t i o n ( u r l s , done ) { async . map( u r l s , ajax , done ) ; }; v a r a j a x = function ( u r l , done ) { $ . ajax ( { url : url , success : done }) ; };
What comes next?
Performance
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.
I
But is it a noticeable problem?
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.
I
But is it a noticeable problem?
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.
I
But is it a noticeable problem?
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.
I
But is it a noticeable problem?
What comes next?
Conclusion
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.
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
I
Write clean code first. Profile later.