Things about Functional JavaScript

Post on 16-Apr-2017

117 views 4 download

Transcript of Things about Functional JavaScript

Functional Javascript

snowmantw@gmail.com2012/5/24 JS Group

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