Damn Fine CoffeeScript

60
Damn Fine CoffeeScript

description

Introduction to CoffeeScript held at GTUG Sthlm May 2011.

Transcript of Damn Fine CoffeeScript

Page 1: Damn Fine CoffeeScript

Damn Fine

CoffeeScript

Page 2: Damn Fine CoffeeScript

Focus

Language

Page 3: Damn Fine CoffeeScript

Some Kind of Holy

Python

Ruby

JavaScrip t

Page 4: Damn Fine CoffeeScript

Raw

var render = function (width, height, draw, filePath) { var canvas = new Canvas(width, height), ctx = canvas.getContext('2d'); draw.call(ctx); var out = fs.createWriteStream(filePath), stream = canvas.createPNGStream(); stream.on('data', function(chunk) { out.write(chunk); }); stream.on('end', function() { console.log("Created: " + filePath); });};

Page 5: Damn Fine CoffeeScript

Brewed

render = (width, height, draw, filePath) -> canvas = new Canvas(width, height) draw.call canvas.getContext '2d' out = fs.createWriteStream filePath stream = canvas.createPNGStream() stream.on 'data', (chunk) -> out.write chunk stream.on 'end', -> console.log "Created: #{filePath}"

Page 6: Damn Fine CoffeeScript

Basically

●function is () ->● local variables● indentation● omittable parentheses

Page 7: Damn Fine CoffeeScript

True To JavaScript

The golden rule of CoffeeScript is: "It's just JavaScript"

Page 8: Damn Fine CoffeeScript

Less Syntactic Noise

stream.on('end', function() { console.log("Created: " + filePath);});

Page 9: Damn Fine CoffeeScript

stream.on 'end', -> console.log "Created: #{filePath}"

Page 10: Damn Fine CoffeeScript

My perspective

Node

A platform: JS machine + CommonJS stdlib

Page 11: Damn Fine CoffeeScript

Runtimes

Page 12: Damn Fine CoffeeScript

It's just

Coffee In Coffee

Page 13: Damn Fine CoffeeScript

Browser

Just JS (generated)

Page 14: Damn Fine CoffeeScript

Convert & Eval...

<script src="/extras/coffee-script.js"></script><script type="text/coffeescript"> # coffee time</script>

Page 15: Damn Fine CoffeeScript

Node

$ npm install coffee-script

Page 16: Damn Fine CoffeeScript

REPL

$ coffee

Page 17: Damn Fine CoffeeScript

101

# Assignment:number = 42opposite = true

Page 18: Damn Fine CoffeeScript

Conditions

if happy and knowsIt clapsHands() chaChaCha()else showIt()

date = if friday then sue else jill

options or= defaults

number = -42 if opposite

Page 19: Damn Fine CoffeeScript

Functions

square = (x) -> x * x

cube = (x) -> square(x) * x

fill = (container, liquid="coffee") -> "Filling the #{container} with #{liquid}..."

noop = ->

Page 20: Damn Fine CoffeeScript

In JQuery

$('span').each -> it = $(this) if it.is('.style-1, .style-20') or not it.attr('class') it.replaceWith(it.html())

Page 21: Damn Fine CoffeeScript

Data

# Arrays:list = [1, 2, 3, 4, 5]

# Objects:math = root: Math.sqrt square: square cube: (x) -> x * square x

Page 22: Damn Fine CoffeeScript

modes = {ready: yes, balance: off}

bitlist = [ 1, 0, 1 0, 0, 1 1, 1, 0]

Page 23: Damn Fine CoffeeScript

How True To JavaScript?

Page 24: Damn Fine CoffeeScript

Compile

$ coffee -c some.coffee

# or just print out$ coffee -p some.coffee

Page 25: Damn Fine CoffeeScript

number = 42opposite = true

number = -42 if opposite

list = [1, 2, 3, 4, 5]

math = root: Math.sqrt square: square cube: (x) -> x * square x

Page 26: Damn Fine CoffeeScript

var list, math, number, opposite;number = 42;opposite = true;if (opposite) { number = -42;}list = [1, 2, 3, 4, 5];math = { root: Math.sqrt, square: square, cube: function(x) { return x * square(x); }};

Page 27: Damn Fine CoffeeScript

Lexical Scopes & Safety

outer = 1changeNumbers = -> inner = -1 outer = 10inner = changeNumbers()

Page 28: Damn Fine CoffeeScript

var changeNumbers, inner, outer;outer = 1;changeNumbers = function() { var inner; inner = -1; return outer = 10;};inner = changeNumbers();

Page 29: Damn Fine CoffeeScript

Syntactic

Thin Coat of Sugar

And Some Boilerplate

Page 30: Damn Fine CoffeeScript

Sugar++

# Splats:race = (winner, runners...) -> print winner, runners

# Existence:alert "I knew it!" if elvis?

Page 31: Damn Fine CoffeeScript

var race;var __slice = Array.prototype.slice;var race = function() { var runners, winner; winner = arguments[0], runners = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return print(winner, runners);};if (typeof elvis !== "undefined" && elvis !== null) { alert("I knew it!");}

Page 32: Damn Fine CoffeeScript

Expressions, Implicitness, Return

Page 33: Damn Fine CoffeeScript

Unpacking

[first, second] = [1, 2, 3, 4]

_ref = [1, 2, 3], first = _ref[0], second = _ref[1];

Page 34: Damn Fine CoffeeScript

{puts, inspect} = require 'util'

_ref2 = require('util'), puts = _ref2.puts, inspect = _ref2.inspect;

Page 35: Damn Fine CoffeeScript

Comprehensions!

cubes = (math.cube num for num in list)

Page 36: Damn Fine CoffeeScript

var cubes;cubes = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = list.length; _i < _len; _i++) { num = list[_i]; _results.push(math.cube(num)); } return _results;})();

Page 37: Damn Fine CoffeeScript

Comprehensive

yearsOld = max: 10, ida: 9, tim: 11

ages = for child, age of yearsOld child + " is " + age

Page 38: Damn Fine CoffeeScript

Closing Over Loops

for filename in list do (filename) -> fs.readFile filename, (err, contents) -> compile filename, contents.toString()

Page 39: Damn Fine CoffeeScript

Operator Names

CoffeeScript JavaScript

is, isnt ===, !==

and, or, not &&, ||, !

true, yes, on true

false, no, off false

in, of in, N/A

@, this this

:: prototype

Page 40: Damn Fine CoffeeScript

Different Kinds of Else

●unless●a?●a ? b●a ?= b●a?.b

Page 41: Damn Fine CoffeeScript

Classesclass Animal constructor: (@name) ->

move: (meters) -> alert @name + " moved " + meters + "m."

class Snake extends Animal move: -> alert "Slithering..." super 5

class Horse extends Animal move: -> alert "Galloping..." super 45

sam = new Snake "Sammy the Python"tom = new Horse "Tommy the Palomino"

sam.move()tom.move()

Page 42: Damn Fine CoffeeScript

var Animal, Horse, Snake, sam, tom;var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child;};

Page 43: Damn Fine CoffeeScript

Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + " moved " + meters + "m."); }; return Animal;})();

Page 44: Damn Fine CoffeeScript

Snake = (function() { __extends(Snake, Animal); function Snake() { Snake.__super__.constructor.apply(this, arguments); } Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake;})();

Page 45: Damn Fine CoffeeScript

Binding => This

Account = (customer, cart) -> @customer = customer @cart = cart

$('.shopping_cart').bind 'click', (event) => @customer.purchase @cart

Page 46: Damn Fine CoffeeScript

var Account;var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };Account = function(customer, cart) { this.customer = customer; this.cart = cart; return $('.shopping_cart').bind('click', __bind(function(event) { return this.customer.purchase(this.cart); }, this));};

Page 47: Damn Fine CoffeeScript

And more...

Page 48: Damn Fine CoffeeScript

● Literals: Functions, Objects and Arrays● If, Else, Unless, and Conditional Assignment

Page 49: Damn Fine CoffeeScript

● Splats...● Array Slicing and Splicing● Loops and Comprehensions● Destructuring Assignment

● Everything is an Expression

Page 50: Damn Fine CoffeeScript

● Operators and Aliases● Lexical Scoping and Variable Safety● Classes, Inheritance, and Super● Function Binding

Page 51: Damn Fine CoffeeScript

● Switch and Try/Catch● Chained Comparisons● String Interpolation, Heredocs, and Block

Comments● Extended Regular Expressions● Embedded JavaScript

Page 52: Damn Fine CoffeeScript

Future/Now

Page 53: Damn Fine CoffeeScript

Coding in Coffee

sameness?

seeing clearly..

transparencies..

choices...

Page 54: Damn Fine CoffeeScript

Paths Ahead?

Harmony...

Page 55: Damn Fine CoffeeScript

Tinkering Fun!

Node goodies: Zombie.js, Canvas, ...

Page 56: Damn Fine CoffeeScript

Developing a CommonJS Lib

Page 57: Damn Fine CoffeeScript

$ npm link .

$ coffee --watch src

$ cake

Page 58: Damn Fine CoffeeScript

Cakefile{spawn, exec} = require 'child_process'

SRC = 'js/src'LIB = 'js/lib'

task 'build', "compile coffee to js", -> build onErrorExit

task 'watch', "continously compile coffee to js", -> cmd = spawn "coffee", ["-cw", "-o", LIB, SRC] cmd.stdout.on "data", (data)-> process.stdout.write data cmd.on "error", onErrorExit

build = (cb)-> console.log "Coffee compiling..." exec "rm -rf #{LIB} && coffee -c -l -b -o #{LIB} #{SRC}", (err, out)-> cb err

onErrorExit = (err)-> if err process.stdout.write "#{err.stack}\n" process.exit -1

Page 59: Damn Fine CoffeeScript

Thanks!