Things about Functional JavaScript
-
Upload
chenghui-weng -
Category
Presentations & Public Speaking
-
view
122 -
download
4
Transcript of Things about Functional JavaScript
http://goo.gl/5WCjI
snowmantw : Vimer / Linux User λ Haskell learnerG self-studierJS developerMS student -> Dept. of Computer Science, NCCU
C C++ PHP JS Haskell Java
Functional Javascript
What ?
JavaScript's C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. It has arrays instead of lists and objects instead of property lists. Functions are first class. It has closures. You get lambdas without having to balance all those parens.
“JavaScript: The World's Most Misunderstood Programming Language”by Douglas Crockford
JavaScript's C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. It has arrays instead of lists and objects instead of property lists. Functions are first class. It has closures. You get lambdas without having to balance all those parens.
“JavaScript: The World's Most Misunderstood Programming Language”by Douglas Crockford
So, Javascript is a Functional ProgrammingLanguage
function id( a ){
return a;}
function curried( a ) {
return function ( b ) {return a + b;
}}
First-Class Function
Curry
function compose( gn ) {
return function ( fn ) {return function( a ) {
return gn( fn ( a ) ) ;}
}} High-Order Function
curried( a )curried( a ) ( b )curried( a ) ( c )curried( b ) ( c )
curried( a ) :: a functioncurried( b ) :: another fn
Curry can make a new function without definition
curried( a )curried( a ) ( b )curried( a ) ( c )curried( b ) ( c )
curried( a )curried( a ) ( b )curried( a ) ( c )curried( b ) ( c )
new_fn1 = curried( 1 )new_fn2 = curried( 2 )new_fn1 ( 1 ) == 1 + 1new_fn2 ( 1 ) == 2 + 1
We “defined” two functionswithout definition !
curried( a )curried( a ) ( b )
High-Order Function
take one or more fn as an input
OR output a function ( like Curry )
curried( a )curried( a ) ( b )
compose( curried( a ) )
compose( curried( a ) ) ( curried( b ) )
compose( curried( a ) ) ( curried( b ) ) ( a )
Yet another high-order function
A normal function
A value
curried( a )curried( a ) ( b )
compose( curried( 3 ) ) ( curried( 4 ) )
compose( curried( 3 ) ) ( curried( 4 ) ) ( 5 )
Generate value when all conditions are satisfied
Now We Have…
First-Class Function
Now We Have…
Curry
That’s all; It’s so sad
Now We Have…
High-Order Function
- Pure Function- Immutable Variable - Encapsulated Impure Features- ( More ) High Order Function- Lazy Evaluation- Functional Data Structure- Type System
Javascript lacks
Why they matter ?
Immutable Variablemut = 1 ;
function victim( ) {return 10 / mut ;
}
$.get ( ‘/change/mut’ , function(data) {mut = 0;
});
Immutable Variablefunction bad_fn ( arr ){
var mut = 0;
for( ; mut != arr.length ; mut ++ ){
arr[ mut ] += mut;}
return mut;}
Pure Function
Side-Effect Free
Impure Function
OOPs… It may cause serious problems
gn(3) = 3gn(3) = 3gn(3) = 3
gn(3) = 3gn(3) = 3gn(3) = 4
Impure Functioni_m_an_innocent_fn :: ( ) -> Int
function i_m_an_innocent_fn(){ launch_nuclear_missles(); return 3;}
Need to be Encapsulated
Pure X Impurevar innocent_var =
3 * 4 + pow ( 2, 4 ) - i_m_an_innocent_fn() +floor ( 10 * varA ) …
… It’s just a numerical expression
( I lied )
We ( the laugnage ! ) shouldn’t allow pure functions to mix with
impure functions.
A Real World Case ( 2 x 4 hr ) render : function(nst) {
var t = this, s = t.settings, id = t.id, sl = tinymce.ScriptLoader;
// Page is not loaded yet, wait for it
// DEBUG : No, we don't need 'tinymce style' check here......// Because we use bigpipe tech, this condition statement // will always keep failed.//// snowmantw @ 2012-04-25 18:00:41+08:00//// if (!Event.domLoaded) {// Event.add(window, 'ready', function() {// t.render();// });// return;// }
Encapsulated Impure Features
Pure Functions need to be ‘wrapped’
Encapsulated Impure Features
X
Encapsulated Impure Features
This is why type system matters
Encapsulated Impure Features
‘return’ can “lift” one pure fn‘s result
Encapsulated Impure Features
make pure ‘digitToInt’ impure
Encapsulated Impure Features
It is the Monad version ‘。’
。
Encapsulated Impure Features
Encapsulated Impure Features
(>>=) ‘bind’ can glue another Action ( functions return Monadic value)
No pure function can get and use values
from Monad,unless we wrap it and make it impure, too.
Monad also make “Statements” in functional way
main = printStrLn “This is a interactive program !” >>printStrLn “----” >>printStrLn “Input Something: ” >>readline >>= \maybe_str -> case maybe_str of
Nothing -> return () Just line -> printStrLn “Input from user: ” >>
printStrLn line
Monad also make “Statements” in functional way
function main( ) { console.log( “ This is a interactive program ! ” ) ; console.log( “ ---- “ ) ; var input = readline( ) ; if ( “” == input ) { return ; } console.log( “Input from user: ” ) ; console.log( input ) ;}
Why Bother ?
We can assume that there are no impure functions leaking to
the pure world
And pure functions still can be reusable
components in our program
Just need to be wrapped first
It’s important because…
In most cases we just need
Modular Programming, not Object-Oriented
Programming
And the concepts of pureness and composition
just fit the need
Welcome to The World of Composition Function composition ( pure ) ‘。’: make larger and pure function
Monad bind ( impure ) ‘ >>=’: make useful and larger COMPUTATION
Arrow compose ( purer than Monad ) ‘>>>’: make useful and larger COMPUTATION
You can build your whole program with composition
BTW: Composite "Pattern" is Nothing
fa a = b ; fb b = c ; fc = fb . faclass functorA { <Tb> public Tb exec( Ta a ) { return Tb b; } }
class functorB{ <Tc> public Tc exec( Tb b ) { return Tc c; } }
BTW: Composite "Pattern" is Nothing
fa a = b ; fb b = c ; fc = fb . faclass FunctorCompose{ public Functor compose( fa, fb ) { //....... } }
// Use in some method(new FunctorCompose()).compose(fa ,fb)
Sounds good, but…
“It’s not Javascript !”
The Problem:How can we program more functionally in the Javascript world ?
Concepts
id; map; foldl; getChar; putStrLn; (+) ....
map (+1) ; getChar >>= putChar ; f . g
prog = map putStrLn >> getChar >>= return . digitToInt >>= \x-> return (!!) x str_xs >>= putStrLn
Libraries
Keep your functions pure ( Dot )
function fn( x ){ return x;}
$IO.impure = function( x ){ return x + read_from_server ( );}
All we can use is the '$' and '_'Impure functions should be restricted in some contexts
Underscore.js ( Line )
_.reduce ( [ 1,2,3 ], function(m,n){ return m+n; },0)
`map` and other high order functions
_.map ( [ 1,2,3 ], function(n){ return n+1; } )
http://underscorejs.org/
Functional Javascript ( Line )
' x -> y -> x+y '.lambda()(2);
More functional features than Underscore.js
' y x -> x+2*y '.lambda()(2, 3);
http://osteele.com/sources/javascript/functional/
jQuery ( Plane )
var pure_val = $( DOM ) . manipulateDOM ( ) . pureCB ( function ( ) { ... } ) . it_has_unwrapper_fns () ;
"jQuery is Monad“: http://goo.gl/cFErMhttp://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/
http://jquery.com//
It's ( almost ) a " DOM Monad "
Javascript Arrowlet ( Plane )
http://www.cs.umd.edu/projects/PL/arrowlets/api-arrowlets.xhtml
Redefine the "Process"
Javascript Arrowlet ( Plane )targetA .next(EventA("click")) .next(start2) .next(EventA("click")) .next(cancel2) .next(Repeat).repeat().run();
http://www.cs.umd.edu/projects/PL/arrowlets/api-arrowlets.xhtml
Fully event-driven programmingRedefine the "Process"
Flapjax ( Plane )<p>The time is {! timerB(100) !}.</p>
Functional Reactive ProgrammingNeed supported compilers
http://www.flapjax-lang.org/
Languages
CoffeeScript ( Language )
function curried ( a ) { return function ( b ){
return a + b; } }
f a b = a + b
f = a->b-> a + b
Why syntax mattersa >>=b >>=c >>=d >>=e
a >>=( b >>=c >>=d >>=e )
a >>=( b >>=( c >>=d >>=e ))
a >>=( b >>=( c >>=( d >>=e )))
Why syntax mattersa >>=b >>=c >>=d >>=e ......
a >>=( b >>=( c >>=( d >>=e ...... ))))))))))))))))))))
Parenthesis Hell
Why syntax matters
First-Class Function + Monad
$( R.id.ButtonToClick ). click ( function(event){$( R.id.TextViewToShow ).text(
( new SimpleDataFormat( “h:mm:ss a” ) ).format( new Date() ) ;);
} );
But CoffeeScript is just a little language…
- Pure Function- Immutable Variable - Encapsulated Impure Features- ( More ) High Order Function- Lazy Evaluation- Functional Data Structure- Type System
Personal Project: FunTang language
https://github.com/snowmantw/FunTang
Personal Project: FunTang language
CoffeeScript
Functional Features+
Personal Project: FunTang language
Will focus on- Compile into CoffeeScript- Immutable Variable- Pure Function- Integrated Arrow- Fully Event-Driven Process
In early stage
Thanks for Your Attention