CoffeeScript
The
Beau1ful
Way
to
Write
JavaScript
by
amir
salihefendic
-‐
amix@amix.dk
-‐
amix.dk
My
history
with
JavaScript
• WriDen
more
than
50.000
lines
of
JavaScript
• One
of
the
first
to
use
node.js
in
produc1on
• Scaled
a
node.js
comet
server
to
handle
100.000+
concurrent
users
• I
like
JavaScript,
but
I
think
it
can
be
improved
What
is
beau1ful
code?
My
defini1on
of
Beau1ful
Code
• Beau+ful
code
uses
the
least
amount
of
code
to
solve
a
given
problem
• Beau+ful
code
is
readable
and
understandable
• Beau+ful
code
is
achieved
not
when
there
is
nothing
more
to
add,
but
when
there
is
nothing
leP
to
take
away.
Just
like
great
designs
• The
minimal
length
is
a
side-‐effect
of
beau1ful
code
and
not
a
goal
or
a
measure
Example
of
Ugly
Code
function f(n) {
var s= 0;
if(n == 0) return(s);
if(n == 1) {
s += 1;
return(s);
}
else {
return(f(n - 1) + f(n - 2));
}
}
Example
of
Beau1ful
Code
function fib(n) {
return n<2 ? n : fib(n-1) + fib(n-2)
}
or
function fib(n) {
if (n < 2)
return n
return fib(n-2) + fib(n-1)
}
Is
it
possible
to
write
beau1ful
JavaScript?
YES
it
is,
but
it
could
be
much
easier
What
is
JavaScript?
• JavaScript
is
a
func1onal
language
• JavaScript
is
an
object
oriented
language,
but
it
uses
prototype
inheritance
• JavaScript
is
very
dynamic
and
is
a
lot
closer
to
Lisp
than
C/Java,
but
it
has
a
C/Java
syntax
• …
JavaScript
is
highly
misunderstood.
Beneath
the
dirty
surface
there’s
a
diamond
and
CoffeeScript
aims
to
expose
this
diamond
“
JavaScript
had
to
look
like
Java
only
less
so,
be
Java’s
dumb
kid
brother
or
boy-‐hostage
sidekick.
Plus,
I
had
to
be
done
in
ten
days
or
something
worse
than
JavaScript
would
have
happened.
—
Brendan
Eich
(creator
of
JavaScript)
Makes
it
much
easier
to
create
beau+ful
JavaScript
code
by
removing
a
lot
of
annoyances
What
is
CoffeeScript?
• CoffeeScript
is
a
language
that
compiles
to
JavaScript.
It’s
a
transpiler
compiling
from
one
language
to
another
• CoffeeScript
is
an
aDempt
to
expose
the
good
parts
of
JavaScript
in
a
simple
way
• CoffeeScript
does
not
deprecate
your
old
JavaScript
code
• CoffeeScript
will
work
in
every
JavaScript
implementa1on
and
tends
to
run
as
fast
or
faster
than
the
equivalent
handwriDen
JavaScript
Example
of
CoffeeScript
code
square = (x) -> x * x
cube = (x) -> square(x) * x
Gets
compiled
to
following
JavaScript
code
var cube, square;
square = function(x) {
return x * x;
};
cube = function(x) {
return square(x) * x;
};
node.js JavaScript HTTP server
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8080, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8080/');
node.js CoffeeScript HTTP server
http = require 'http'
[host, port] = ['127.0.0.1', 8080]
http.createServer((req, res) ->
res.writeHead 200, 'Content-Type': 'text/plain'
res.end 'Hello World\n'
).listen(port, host)
console.log "Server running at http://#{ host }:#{ port }/"
CoffeeScript
Highlight
Arrays
on
steroids
#Python's list comprehensions
list = [1, 2, 3, 4, 5]
cubes = (math.cube num for num in list)
#Slicing
copy = list[0...list.length]
#Array generators
countdown = (num for num in [10..1])
CoffeeScript
Highlight
Strings
from
Ruby
author = "Wittgenstein"
quote = "A picture is a fact. -- #{ author }"
mobyDick = "Call me Ishmael. Some years ago -
never mind how long precisely -- having little
or no money in my purse, and nothing
particular..."
CoffeeScript
Highlight
Inheritance
made
easy
class Animal
constructor: (@name) ->
move: (meters) ->
alert "#{ @name } moved #{meters} m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
CoffeeScript
Highlight
Solving
this
nightmare
loader.prototype.loadStuff = function() {
this.state = 'loading';
$.get('getStuff', function(data) {
//this is not what we think it is...!
this.state = 'loaded';
});
};
Solved
in
CoffeeScript
using
=>
loader::loadStuff = ->
@state = 'loading’
$.get 'getStuff', (data) =>
@state = 'loaded'
CoffeeScript
Highlight
Write
less
code!
function frob(obj) {
var rest = [].slice.call(arguments, 1),
results = []
for (var k in obj) if (obj.hasOwnProperty(k)) {
v = obj[k]
if (blurgh(v, rest)) {
results.push(v)
}
}
return results
}
This
above
is
an
one-‐liner
in
CoffeeScript:
frob = (obj, rest...) -> [v for v of obj if blurgh(v, rest)]
source
Extended
usage
of
CoffeeScript
Domain
Specific
Languages
(DSL)
Ac1veRecord’s
DSL
in
CoffeeScript
Rails
Ac1veRecord
DSL
lets
you
easily
express
rela1onships
between
model
classes
class Post extends ActiveRecord
has_many: 'comments’
class Comment extends ActiveRecord
belongs_to: 'post'
Sinatra’s
DSL
in
CoffeeScript
Sinatra
is
a
popular
Ruby
web
framework
and
DSL
for
crea1ng
web
applica1ons.
get '/helloWorld/:name', (name) ->
"Hello #{ name }"
Rake’s
DSL
in
CoffeeScript
Rake
is
Ruby’s
make
system
–
it’s
also
a
DSL.
task "kill_hal", ->
alert "I am sorry Dave, I'm afraid I can't do that"
CoffeeScript
features
in
ES.next?
• Following
features
could
be
added
to
ES.next:
– let
iden1ty
=
(x)
-‐>
x
– callback
=
(msg)
=>
this.vmail.push(msg)
– CoffeeScript
inheritance
– @foo
for
this.foo
– if
x
>
y
return
x
(Op1onal
parenthesis)
• Source:
Brendan’s
JS.conf
talk
External
Links
• The
official
CoffeeScript
page
hDp://jashkenas.github.com/coffee-‐script/
• CoffeeScript’s
annotated
source
code…
Beau1ful
hDp://jashkenas.github.com/coffee-‐script/documenta1on/docs/grammar.html
• CoffeeScript’s
community
hangs
around
GitHub
hDps://github.com/languages/CoffeeScript
• My
blog
posts
on
JavaScript
and
CoffeeScript
hDp://amix.dk/blog/label/11#JavaScript
Ques1ons?