Slide 1

Slide 1 text

Iced Coffee Float Mindos Cheng Saturday, 20 April, 13

Slide 2

Slide 2 text

Before start...... Saturday, 20 April, 13

Slide 3

Slide 3 text

Gugod in second meeting room Saturday, 20 April, 13

Slide 4

Slide 4 text

ihower in the first Saturday, 20 April, 13

Slide 5

Slide 5 text

Why stay here? Saturday, 20 April, 13

Slide 6

Slide 6 text

Okey. Warned. Saturday, 20 April, 13

Slide 7

Slide 7 text

Programmers are lazy. Saturday, 20 April, 13

Slide 8

Slide 8 text

We don’t write complex repeating codes Even for doing the right thing. Saturday, 20 April, 13

Slide 9

Slide 9 text

We hate debug messy code, either. Saturday, 20 April, 13

Slide 10

Slide 10 text

We hate overtime. Saturday, 20 April, 13

Slide 11

Slide 11 text

Also, we like beautiful code. Saturday, 20 April, 13

Slide 12

Slide 12 text

do it once for all. Saturday, 20 April, 13

Slide 13

Slide 13 text

So some nice people write compilers. Saturday, 20 April, 13

Slide 14

Slide 14 text

Coffeescript => Coco => Livescript Saturday, 20 April, 13

Slide 15

Slide 15 text

“Easy things should be easy, and hard things should be possible.” -- Larry Wall Saturday, 20 April, 13

Slide 16

Slide 16 text

Function Call sink = (v)-> v * 0.9 sink 8 var sink; sink = function(v){ return v * 0.9; }; sink(8); Saturday, 20 April, 13

Slide 17

Slide 17 text

Function Call sink = (v)-> v * 0.9 sink 8 var sink; sink = function(v){ return v * 0.9; }; sink(8); Saturday, 20 April, 13

Slide 18

Slide 18 text

Chaining $ 'div' .addClass 'done' .removeClass 'Light' $('div') .addClass('done') .removeClass('Light'); Saturday, 20 April, 13

Slide 19

Slide 19 text

Backcall <-! $ 'h1' .on 'click' alert 'boom!' $('h1').on('click', function(){ alert('boom!'); }); Saturday, 20 April, 13

Slide 20

Slide 20 text

Backcall <-! $ 'h1' .on 'click' alert 'boom!' ! means no return $('h1').on('click', function(){ alert('boom!'); }); Saturday, 20 April, 13

Slide 21

Slide 21 text

Closure sink = do -> factor = 0.9 (v)-> map (* factor), v sink [3, 2, 0] var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); sink([3, 2, 0]); Saturday, 20 April, 13

Slide 22

Slide 22 text

Closure sink = do -> factor = 0.9 (v)-> map (* factor), v sink [3, 2, 0] var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); sink([3, 2, 0]); Saturday, 20 April, 13

Slide 23

Slide 23 text

Closure sink = do -> factor = 0.9 (v)-> map (* factor), v sink [3, 2, 0] var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); sink([3, 2, 0]); Saturday, 20 April, 13

Slide 24

Slide 24 text

Closure sink = do -> factor = 0.9 (v)-> map (* factor), v sink [3, 2, 0] var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); sink([3, 2, 0]); Saturday, 20 April, 13

Slide 25

Slide 25 text

“Buildin” Library times = (x, y) --> x * y times 2, 3 #=> 6 double = times 2 double 5 #=> 10 var times, double; times = curry$(function(x, y){ return x * y; }); times(2, 3); double = times(2); double(5); function curry$(f, bound){ var context, _curry = function(args) { return f.length > 1 ? function(){ var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } From http://livescript.net/ Saturday, 20 April, 13

Slide 26

Slide 26 text

Class Made Easy class A (num) -> @x = num method: (y) -> @x + y a = new A 3 b = new A 4 a.method 6 b.method 7 var A, a, b; A = (function(){ A.displayName = 'A'; var prototype = A.prototype; var constructor = A; function A(num){ this.x = num; } prototype.method = function(y){ return this.x + y; }; return A; }()); a = new A(3); b = new A(4); a.method(6); b.method(7); From http://livescript.net/ Saturday, 20 April, 13

Slide 27

Slide 27 text

Livescript Compiler sink = do -> factor = 0.9 (v)-> map (* factor), v var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); Saturday, 20 April, 13

Slide 28

Slide 28 text

lexer sink = do -> factor = 0.9 (s)-> s * factor NEWLINE:\n ID:sink ASSIGN:= UNARY:do PARAM(: )PARAM: -> INDENT:2 ID:factor ASSIGN:= STRNUM:0.9 NEWLINE:\n PARAM(:( ID:s )PARAM:) -> INDENT:2 ID:s MATH:* ID:factor DEDENT:2 DEDENT:2 NEWLINE:\n parser Compile Block Assign = Var sink Unary do Fun Block Assign = Var factor Literal 0.9 Fun Var s Block Binary * Var s Var factor var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); parser.parse do (lexer.lex code) .compileRoot options Saturday, 20 April, 13

Slide 29

Slide 29 text

Lexer => Tokens sink = do -> factor = 0.9 (s)-> s * factor ID:sink ASSIGN:= UNARY:do PARAM(: )PARAM: -> INDENT:2 ID:factor ASSIGN:= STRNUM:0.9 NEWLINE:\n PARAM(:( ID:s )PARAM:) -> INDENT:2 ID:s MATH:* ID:factor DEDENT:2 DEDENT:2 NEWLINE:\n Saturday, 20 April, 13

Slide 30

Slide 30 text

Handling Parameters (v) (v) -> ret -> ret ( ID:v ) NEWLINE:\n PARAM(:( ID:v )PARAM:) -> INDENT:2 ID:ret DEDENT: 2 NEWLINE:\n PARAM(: )PARAM: -> INDENT:2 ID:ret DEDENT: 2 NEWLINE:\n Saturday, 20 April, 13

Slide 31

Slide 31 text

Handling Parameters PARAM(:( ID:v )PARAM:) -> PARAM(: )PARAM: -> (v) -> ret -> ret @last = [tag, value, @line] parameters: !(arrow, offset) -> if @last.0 is \) is @last.1 @lpar.0 = \PARAM( @last.0 = \)PARAM return if arrow is \-> then @token \PARAM( '' else for t, i in @tokens by -1 when t.0 in <[ NEWLINE INDENT THEN => ( ]> then break @tokens.splice (i+1), 0 [\PARAM( '' t.2] if offset then @tokens.splice (@tokens.length + offset), 0 [\)PARAM '' t.2] else @token \)PARAM '' Saturday, 20 April, 13

Slide 32

Slide 32 text

Parser =>AST sink = do -> factor = 0.9 (s)-> s * factor Block Assign = Var sink Unary do Fun Block Assign = Var factor Literal 0.9 Fun Var s Block Binary * Var s Var factor Saturday, 20 April, 13

Slide 33

Slide 33 text

Generate => JS lexer sink = do -> factor = 0.9 (s)-> s * factor NEWLINE:\n ID:sink ASSIGN:= UNARY:do PARAM(: )PARAM: -> INDENT:2 ID:factor ASSIGN:= STRNUM:0.9 NEWLINE:\n PARAM(:( ID:s )PARAM:) -> INDENT:2 ID:s MATH:* ID:factor DEDENT:2 DEDENT:2 NEWLINE:\n parser Compile Block Assign = Var sink Unary do Fun Block Assign = Var factor Literal 0.9 Fun Var s Block Binary * Var s Var factor var sink; sink = function(){ var factor; factor = 0.9; return function(v){ return map((function(it){ return it * factor; }), v); }; }(); Saturday, 20 April, 13

Slide 34

Slide 34 text

Generate => JS ast compileRoot compile compileClosure compileBlock ... Saturday, 20 April, 13

Slide 35

Slide 35 text

compileRoot compileRoot: (options) -> o = {level: LEVEL_TOP, scope: @scope = Scope.root = new Scope, ...options} if saveTo = delete o.saveScope o.scope = saveTo.savedScope or= o.scope delete o.filename o.indent = if bare = delete o.bare then '' else TAB if /^\s*(?:[/#]|javascript:)/test @lines.0?code prefix = @lines.shift!code + \\n if delete o.eval and @chomp!lines.length if bare then @lines.push Parens @lines.pop! else @makeReturn! code = @compileWithDeclarations o # Wrap everything in a safety closure unless requested not to. bare or code = "(function(){\n#code\n}).call(this);\n" [prefix] + code Saturday, 20 April, 13

Slide 36

Slide 36 text

compileWithDeclarations compileWithDeclarations: (o) -> o.level = LEVEL_TOP pre = '' if i = @neck! rest = @lines.splice i, 9e9 pre = @compile o @lines = rest return pre unless post = @compile o (pre and "#pre\n") + if @scope then that.emit post, o.indent else post Saturday, 20 April, 13

Slide 37

Slide 37 text

compile compile: (o, level ? o.level) -> return @compileExpressions o, level if level o.block = this; tab = o.indent codes = for node in @lines node = node.unfoldSoak o or node continue unless code = (node <<< {+front})compile o, level node.isStatement! or code += node.terminator tab + code codes.join \\n Saturday, 20 April, 13

Slide 38

Slide 38 text

compileExpression compileExpressions: (o, level) -> {lines} = @chomp!; i = -1 while lines[++i] then lines.splice i-- 1 if that.comment lines.push Literal \void unless lines.length lines.0 <<< {@front}; lines[*-1] <<< {@void} return lines.0.compile o, level unless lines.1 code = ''; last = lines.pop! for node in lines then code += (node <<< {+void})compile(o, LEVEL_PAREN) + ', ' code += last.compile o, LEVEL_PAREN if level < LEVEL_LIST then code else "(#code)" Saturday, 20 April, 13

Slide 39

Slide 39 text

compileRoot compileWithDeclaration var declaration Compile Saturday, 20 April, 13

Slide 40

Slide 40 text

compile compileExpression Assign. compile Fun. compile For. compile Require. compile Assign. compile Assign. compile For. compile For. compile Require. compile Require. compile Fun. compile Fun. compile Saturday, 20 April, 13

Slide 41

Slide 41 text

Cool things Destructuring {name, age} = {weight: 110, name: 'emma', age: 20} name #=> 'emma' age #=> 20 Piping [1 2 3] |> map (* 2) |> filter (> 3) |> fold1 (+) #=> 10 Partition scores = [49 58 76 43 88 77 90] [passed, failed] = partition (> 60), scores passed #=> [76, 88, 77, 90] failed #=> [49, 58, 43] From http://livescript.net/ http://livescript.net/blog/livescript-one- liners-to-impress-your-friends.html Saturday, 20 April, 13

Slide 42

Slide 42 text

Cool things Units 64_000km Truth Values true false on off yes no From http://livescript.net/ http://livescript.net/blog/livescript-one- liners-to-impress-your-friends.html Saturday, 20 April, 13

Slide 43

Slide 43 text

In Parallel Universe Units consistent check ship. setSpeed 64_000m ...... ship. setSpeed 65_000 # okey ...... ship.setSpeed 64_000km # Warning Truth Values check ? Functional Syntax Optimization Saturday, 20 April, 13

Slide 44

Slide 44 text

In Parallel Universe Functional Syntax Optimization fold1 (+), [1 to 5] fold1(curry$(function(x$, y$){ return x$ + y$; }), [1, 2, 3, 4, 5]); function curry$(f, bound){ var context, _curry = function(args) { return f.length > 1 ? function(){ var params = args ? args.concat() : []; context = bound ? context || this : this; return params.push.apply(params, arguments) < f.length && arguments.length ? _curry.call(context, params) : f.apply(context, params); } : f; }; return _curry(); } Saturday, 20 April, 13

Slide 45

Slide 45 text

In Parallel Universe Functional Syntax Optimization fold1 (+), [1 to 5] fold1(curry$(function(x$, y$){ return x$ + y$; }), [1, 2, 3, 4, 5]); src = [1 to 5] x = src[0] for i from 1 til src.length x+=src[i] x var src, x, i$, to$, i; src = [1, 2, 3, 4, 5]; x = src[0]; for (i$ = 1, to$ = src.length; i$ < to$; ++i$) { i = i$; x += src[i]; } x; Saturday, 20 April, 13

Slide 46

Slide 46 text

Livedemo http://livescript.net/ Saturday, 20 April, 13

Slide 47

Slide 47 text

Questions? Saturday, 20 April, 13

Slide 48

Slide 48 text

Thanks! Saturday, 20 April, 13