LiveScript - eine funktionale Alternative

Dipl.-Inf. (FH) Marco Emrich

Oct 2014 @ XP-Days

wma_slide_background

Douglas Crockford

„I don't think of myself as a guru ...“
Source: http://www.yuiblog.com
wma_slide_background

The Good Parts

wma_slide_background

The Good Parts

Source: http://www.michaelthelin.se
wma_slide_background

Brendon Eich

Brendon Eich - Inventor of JavaScript
wma_slide_background

JS in 10 days

„...he had 10 days to create and produce a [...] programming language ...“
www.computer.org/csdl/mags/co/2012/02/mco2012020007.pdf
wma_slide_background


JS

wma_slide_background

Can we improve?

wma_slide_background

Jeremy Ashkenas

„YES!“
wma_slide_background

HTCYOFPL

wma_slide_background

CoffeScript

wma_slide_background

CoffeScript

  • „a beautiful language that compiles to JS“
  • „More readability, less LOC, less pain“
  • „It's just JavaScript“ - coffeescript.org
  • Prevents beginners from JS-landmines
wma_slide_background

CoffeScript Critism

  • „CoffeeScript doesn’t go far enough“
  • „not enough reason to switch“
  • Targets ES3.0/IE6 ... seriously?
  • Bad scoping rules
  • Has landmines on it's own
  • and more ....
wma_slide_background


CS

wma_slide_background

Can we improve?

wma_slide_background

LifeScript

wma_slide_background

LifeScript

  • Builds upon CoffeeScript (Fork)
  • It's not just JavaScript
  • Targets ES5/ES6 (--harmony)
  • Functional Programming! Yeah!
wma_slide_background

Activly Maintained

Oct. 4: LiveScript 1.3

wma_slide_background

Github

Screenshot from Oct. 10

wma_slide_background

Production ready?

wma_slide_background

Production Ready

wma_slide_background

Tool Support: IDE

  • VIM
  • Emacs (3 different plugins)
  • Webstorm/IntelliJ/RubyMine
  • Brackets
  • Visual Studio
  • Kommodo
  • Kate
  • BBEdit
  • Gedit
wma_slide_background

Tool Support

wma_slide_background


LS

wma_slide_background

♥♥
LS

wma_slide_background

Hello World

LiveScript


                            console.log \HelloWorld
                        
wma_slide_background

Get rid of these $@)#{!

LiveScript


if 2 + 2 == 4
  console.log \Heyho
                        
wma_slide_background

Everything is a value

LiveScript


x = if 2 + 2 == 4
    then 10
    else 0                        
wma_slide_background

that

LiveScript


hours-per-day = 8

if hours-per-day?
  that * 5
                        
wma_slide_background

Functions

LiveScript


add = (x, y) -> x + y

console.log add 2, 3
console.log add 2 3
console.log 3 `add` 4
                        
wma_slide_background

Readable jQuery

LiveScript


$ \div .find \a .html!
                        
wma_slide_background

Functions: Default Values

LiveScript


add = (x = 4, y = 3) -> x + y
add 2
                        
wma_slide_background

Argumentless

LiveScript


sayHello = -> \Hallo

#alert(sayHello)

sayHello()
sayHello!
sayHello().length
sayHello!length
#[1 2 3].reverse!slice 1
                        
wma_slide_background

Literals

LiveScript


l 64_000km
l 2~1000
l 6~12
l 16~ff

l on, off
l yes, no
                        
wma_slide_background

String interpolation

LiveScript


l "The answer is #{2 + 2}"
variable = "world"
l "Hello #variable"
                    
wma_slide_background

Multiline-Strings

LiveScript


l 'string can be multiline
   and go on and on
   beginning whitespace is
   ignored'
                    
wma_slide_background

Multiline-Strings: Heredoc

LiveScript


l '''
  string can be multiline
  with newlines
  and go on and on
  beginning whitespace is
  ignored
'''
                    
wma_slide_background

Objects

LiveScript


person =
  age:      23
  eye-color: 'green'
  height:   180cm

oneline = color: 'blue', heat: 4
                        
wma_slide_background

Objects: Shorthands

LiveScript


x = 1
y = 2
obj = {x: x, y: y}
obj = {x, y}

{+debug, -live}
                        
wma_slide_background

Lists

LiveScript


[1 2 3 true \word 'hello world']
                        
wma_slide_background

Lists

LiveScript


my-list =
  32 + 1
  $ \body .width!
  'beautiful'
                        
wma_slide_background

Lists

LiveScript


tree =
  * 1
    * 2
      3
    4
  * 5
    6
    * 7
      8
    9
                        
wma_slide_background

Lists

LiveScript


<[list of words]>
                        
wma_slide_background

Ranges

LiveScript


l [1 to 5]
l [1 to 11 by 2]
l [4 to 1]
l [to 5]
l [\A to \D]
                      
wma_slide_background

Ranges

LiveScript


list = [\a to \d]

l list[1, 3]
l list[1 to 3]
l list[*-2]

                      
wma_slide_background

Ranges

LiveScript


l [1 til 3]

list = [\a to \d]
list[1 til 3] = [7 8]
l list
                      
wma_slide_background

Operators: ==, is

LiveScript


2 + 4 == 6
/^e(.*)/ == 'enter'
                      
wma_slide_background

Operators: ==, is

LiveScript


\boom is 'boom'
2 + 2 is not 4
0 + 1 isnt 1
                      
wma_slide_background

Exercise: Functions

LiveScript


# hello should startWith h
'hello' `startsWith` 'h'
                        
wma_slide_background

Operators: <, <?

LiveScript


l 1 < 2 < 4
l 4 <? 8
                        
wma_slide_background

Operators: in, of

LiveScript


l 2 in [1 2 3 4 5]
l \id of id: 23, name: \rogers
                        
wma_slide_background

Operators: for Lists

LiveScript


d <[ one two three ]> * \-
d <[a b]> ++ <[c d]>
                        
wma_slide_background

Operators: for Strings

LiveScript


d "Hello World" * 3
d 'say yeah' - /e/
d 'say-yeah-ho' / \-
                        
wma_slide_background

Operators: typeof

LiveScript


l typeof /^/
#l typeof! /^/
                        
wma_slide_background

Loops

LiveScript


for x in [1 to 5]
  l x
                        
wma_slide_background

Loops

LiveScript


result = for i in [1 to 5]
 i * 2
                        
wma_slide_background

Loops

LiveScript


result = for i in [1 to 5] | i % 2 == 0
 i * 2
                        
wma_slide_background

Loops

LiveScript


result = for let x, i in [\a to \f]
 "#i: #x"
                        
wma_slide_background

Loops

LiveScript


result = for k, v of {a: 1, b: 2}
  "#k#v"
                        
wma_slide_background

Comprehensions

LiveScript


d [x * 2 for x to 10]
                        
wma_slide_background

Comprehensions

LiveScript


object = a: 1, b: 2, c: 3

d ["#k: #v" for k, v of object]
                        
wma_slide_background

Comprehension: Shorthand ..

LiveScript


d [.. + 1 for [1 2 3]]
                        
wma_slide_background

Comprehension: Shorthand ..

LiveScript


list-of-obj =
  * name: 'Alice'
    age: 23
  * name: 'Betty'
    age: 26

d [..name for list-of-obj]
                        
wma_slide_background

Switch

LiveScript


f = (p) ->
  | p.length < 3 => "too small"
  | p.length < 7 => p.length
  | otherwise    => p.slice 3

f "Hello World"
                        
wma_slide_background

Factorial (FP Style - Yeah)

LiveScript


fact = ->
  | it == 0 => 1
  | otherwise => it * fact(it - 1)

#l fact 170
                        
wma_slide_background

Exercise: Primes

Example Implementation in JS


isPrime = function(n) {
  var div;
  return (function(){
    var i, to, results = [];
    for (i = 2, to = n / 2; i <= to; ++i) {
      results.push(i);
    }
    return results$;
  }()).every(function(){
    return n % div !== 0;
  });
};                        
wma_slide_background

Exercise: Primes

LiveScript


isPrime = (n) -> false

[i for i from 1 to 20 | isPrime i] * ' ' == "1 2 3 5 7 9 11 13 15 17 19"


                        
wma_slide_background

OOP

wma_slide_background

similar to ...

wma_slide_background

but better!

wma_slide_background

OOP

LiveScript


class A
  (@x) ->
  property: 1
  method: (y) ->
    @x + @property + y

a = new A 3
a.x        #=> 3
a.property #=> 1
a.method 6 #=> 10
                        
wma_slide_background

more OOP

...autobinding with ~>

constructor and statics with @@

inheritance with extends

mixins with implements

super ... and super!

Object.defineProperty with ~

clone and cloneport with ^^, <<<< and with

wma_slide_background

more OOP

and even more ...
wma_slide_background

Functional Programming

wma_slide_background

Currying

LiveScript


times = (x, y) --> x * y
times 2, 3
#double = (x) -> times 2, x
#double = times 2
#double 5
                        
wma_slide_background

Destructoring

LiveScript


[first, second] = [1, 2]

l first
l second
                        
wma_slide_background

Destructoring - Rest

LiveScript



[head, ...tail] = [1 to 5]

l head
l tail
                        
wma_slide_background

Destructoring - Middle

LiveScript



[first, ...middle, last] = [1 to 5]

l first
l middle
l last
                        
wma_slide_background

Destructoring - Objects

LiveScript


{name, age} =
  weight: 110
  name: 'emma'
  age: 20
                        
wma_slide_background

Argument Destructoring

LiveScript


set-cords = ({x, y}) -> "#x,#y"
set-cords y: 2, x: 3
                        
wma_slide_background

Argument Destructoring with Defaults

LiveScript


set-cords =
  ({x = 1, y = 3} = {}) -> "#x,#y"
set-cords y: 5
#set-cords!
                        
wma_slide_background

Access Operator

LiveScript


'Hallo'.length
(.length)('Hallo')
                   
wma_slide_background

Operators: require

LiveScript


require! 'prelude-ls'
require! <[ fs path ]>

require! {
  fs
  path
  lib: foo
}
                        
wma_slide_background

Prelude: Map

LiveScript


{map} = require 'prelude-ls'
data = [{name: 'alice', age: 19},
        {name: 'tessa', age: 17}]

map (.name), data
                   
wma_slide_background

Prelude: Map

LiveScript


{map} = require 'prelude-ls'
map (.toUpperCase!), ['hi', 'there']

#map (.join '-'), [[1, 2, 3], [4, 5]]
                        
wma_slide_background

Currying + Map

LiveScript


{map} = require 'prelude-ls'
map (* 2), [1 2 3]
                        
wma_slide_background

Prelude: Filter

LiveScript


{filter, even} = require 'prelude-ls'
filter even, [1 to 6]
                        
wma_slide_background

Prelude: Filter

LiveScript


{filter} = require 'prelude-ls'
data = [{name: 'alice', age: 19},
        {name: 'tessa', age: 17}]
filter (.age > 18), data
                        
wma_slide_background

Sum and Fold

LiveScript


{map, sum, fold1} = require 'prelude-ls'
sum [1 2 3]
#fold1 (+), [1 2 3]
                        
wma_slide_background

Minimum

LiveScript


{minimum, fold1} = require 'prelude-ls'
minimum [14 35 -7 46 98]
#fold1 (<?), [14 35 -7 46 98]
                        
wma_slide_background

Partition

LiveScript


{partition} = require 'prelude-ls'
scores = [49 58 76 43 88 77 90]
[passed, failed] = partition (> 60), scores
d passed
                        
wma_slide_background

Composition mit << und >>

LiveScript


even    = -> it % 2 == 0
invert  = -> not it
odd     = invert << even
#odd     = even >> invert
odd 4
                        
wma_slide_background

Streaming with |>

LiveScript


{filter, even, sum, map} = require 'prelude-ls'

sum(map((* 2), filter(even, [1 to 5])))

[1 to 5] |> filter even |>
  map (* 2) |> sum
                        
wma_slide_background

Constants

LiveScript


const x = 10
#if false then x = 3
                        
wma_slide_background

Compile Flag

--const

wma_slide_background

Callback Flattening

LiveScript


<- setTimeout _, 500
<- setTimeout _, 500
l (new Date).getSeconds()
                        
https://www.flickr.com/photos/alebaffa/8939535066
https://www.flickr.com/photos/tcanales/344050956
https://www.flickr.com/photos/funnyclippics/2404373039/in/photostream/
https://www.flickr.com/photos/badjonni/6978256416
https://www.flickr.com/photos/greyloch/2754795048/in/photostream/
wma_slide_background

Fizzbuzz anyone?

wma_slide_background

1 ... 100
/ 3: Fizz
/ 5: Buzz
/ 7: Bazz

1,2,Fizz,4,Buzz,
Fizz,Bazz,8,Fizz,Buzz,
11,Fizz,13,Bazz,FizzBuzz,16

wma_slide_background

FizzBuzz (Readable - somewhat)

LiveScript


[1 to 100].map (number) ->
  [k for k, v of {
    Fizz: 3, Buzz: 5, Bazz: 7
  } when number % v == 0] * '' or
  number
                        
https://www.flickr.com/photos/jdhancock/4036482004/in/photostream/
wma_slide_background

FizzBuzz (Golf Version)

LiveScript


[1 to 100]map ->
  [k+\zz for k,v of {
    Fi:3,Bu:5,Ba:7
  }|it%v<1]*''||it
                        

64 characters

wma_slide_background
wma_slide_background

Exercise: String Calculator

LiveScript


calc = -> null

d calc("")  == 0
d calc("3") == 3
d calc("1,2,3") == 6
d calc("1,1000,2,3") == 6
d calc("//*1*1000*2*3") == 6
d calc("//:2:2:9999:2345:5") == 9
                        
https://www.flickr.com/photos/jdhancock/4036482004/in/photostream/
wma_slide_background

Exercise: String Calculator (Golf-Version)

LiveScript

0 characters

wma_slide_background

Seminare & Consulting

wma_slide_background

@marcoemrich

www.webmasters.de

www.amazon.com/Marco-Emrich

github.com/marcoemrich