• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
CoffeeScript
 

CoffeeScript

on

  • 575 views

Presented at FluentConf 2013 (May 31st)

Presented at FluentConf 2013 (May 31st)

Statistics

Views

Total Views
575
Views on SlideShare
574
Embed Views
1

Actions

Likes
0
Downloads
0
Comments
0

1 Embed 1

https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    CoffeeScript CoffeeScript Presentation Transcript

    • COFFEESCRIPTaka AwesomeSauce@markbatesFriday, June 7, 13
    • DistributedProgramming withRubyAddison-Wesley2009http://books.markbates.comFriday, June 7, 13
    • ProgramminginCoffeeScripAddison-Wesley2012http://books.markbates.comFriday, June 7, 13
    • Friday, June 7, 13
    • FLUENT13first month freewww.metacasts.tvFriday, June 7, 13
    • A (BRIEF) HISTORYLESSONFriday, June 7, 13
    • Friday, June 7, 13
    • “I need to come up with a scripting languagefor web browsers.I know! Ill make it cool and Lispy!”Dramatic Re-enactment (1995)Friday, June 7, 13
    • Friday, June 7, 13
    • “Yeah, So... Java is getting really popular.So were going to need you to rewrite yourlanguage into something a bit more Java-esque and name it something like JavaScript. Yeah, and were going to need it in a week.Thanks, thatd be great.”Dramatic Re-enactment (1995)Friday, June 7, 13
    • function  LCMCalculator(x,  y)  {    var  checkInt  =  function(x)  {        if  (x  %  1  !==  0)  {            throw  new  TypeError(x  +  "  is  not  an  integer");        }        return  x;    };    this.a  =  checkInt(x)    this.b  =  checkInt(y);}LCMCalculator.prototype  =  {    constructor:  LCMCalculator,    gcd:  function()  {        var  a  =  Math.abs(this.a),            b  =  Math.abs(this.b),            t;        if  (a  <  b)  {            t  =  b;            b  =  a;            a  =  t;        }        while  (b  !==  0)  {            t  =  b;            b  =  a  %  b;            a  =  t;        }        this[gcd]  =  function()  {            return  a;        };        return  a;    },    "lcm":  function()  {        var  lcm  =  this.a  /  this.gcd()  *  this.b;        this.lcm  =  function()  {            return  lcm;        };        return  lcm;    },    toString:  function()  {        return  "LCMCalculator:  a  =  "  +  this.a  +  ",  b  =  "  +  this.b;    }};  function  output(x)  {    document.body.appendChild(document.createTextNode(x));    document.body.appendChild(document.createElement(br));}  [    [25,  55],    [21,  56],    [22,  58],    [28,  56]].map(function(pair)  {    return  new  LCMCalculator(pair[0],  pair[1]);}).sort(function(a,  b)  {    return  a.lcm()  -­‐  b.lcm();}).forEach(function(obj)  {    output(obj  +  ",  gcd  =  "  +  obj.gcd()  +  ",  lcm  =  "  +  obj.lcm());});Friday, June 7, 13
    • FAST FORWARDAbout 15 YearsFriday, June 7, 13
    • Friday, June 7, 13
    • function  LCMCalculator(x,  y)  {    var  checkInt  =  function(x)  {        if  (x  %  1  !==  0)  {            throw  new  TypeError(x  +  "  is  not  an  integer");        }        return  x;    };    this.a  =  checkInt(x)    this.b  =  checkInt(y);}LCMCalculator.prototype  =  {    constructor:  LCMCalculator,    gcd:  function()  {        var  a  =  Math.abs(this.a),            b  =  Math.abs(this.b),            t;        if  (a  <  b)  {            t  =  b;            b  =  a;            a  =  t;        }        while  (b  !==  0)  {            t  =  b;            b  =  a  %  b;            a  =  t;        }        this[gcd]  =  function()  {            return  a;        };        return  a;    },    "lcm":  function()  {        var  lcm  =  this.a  /  this.gcd()  *  this.b;        this.lcm  =  function()  {            return  lcm;        };        return  lcm;    },    toString:  function()  {        return  "LCMCalculator:  a  =  "  +  this.a  +  ",  b  =  "  +  this.b;    }};  function  output(x)  {    document.body.appendChild(document.createTextNode(x));    document.body.appendChild(document.createElement(br));}  [    [25,  55],    [21,  56],    [22,  58],    [28,  56]].map(function(pair)  {    return  new  LCMCalculator(pair[0],  pair[1]);}).sort(function(a,  b)  {    return  a.lcm()  -­‐  b.lcm();}).forEach(function(obj)  {    output(obj  +  ",  gcd  =  "  +  obj.gcd()  +  ",  lcm  =  "  +  obj.lcm());});Friday, June 7, 13
    • class  LCMCalculator      constructor:  (x,  y)  -­‐>        checkInt  =  (x)  -­‐>            if  x  %  1  isnt  0                throw  new  TypeError(x  +  "  is  not  an  integer")            return  x          @a  =  checkInt(x)        @b  =  checkInt(y)      gcd:  -­‐>        a  =  Math.abs(@a)        b  =  Math.abs(@b)        t  =  undefined        if  a  <  b            t  =  b            b  =  a            a  =  t        while  b  isnt  0            t  =  b            b  =  a  %  b            a  =  t        this["gcd"]  =  -­‐>  a        return  a      lcm:  -­‐>        lcm  =  @a  /  @gcd()  *  @b        @lcm  =  -­‐>  lcm        return  lcm      toString:  -­‐>        "LCMCalculator:  a  =  #{@a},  b  =  #{@b}"output  =  (x)  -­‐>    document.body.appendChild  document.createTextNode(x)    document.body.appendChild  document.createElement("br")  [[25,  55],  [21,  56],  [22,  58],  [28,  56]].map((pair)  -­‐>    new  LCMCalculator(pair[0],  pair[1])).sort((a,  b)  -­‐>    a.lcm()  -­‐  b.lcm()).forEach  (obj)  -­‐>    output  "obj  #{gcd}  =  #{obj.gcd()},  lcm  =  #{obj.lcm()}"Friday, June 7, 13
    • WHAT IS COFFEESCRIPT?Friday, June 7, 13
    • What is CoffeeScript?Friday, June 7, 13
    • “A little language that compiles into JavaScript.”What is CoffeeScript?Friday, June 7, 13
    • “A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptWhat is CoffeeScript?Friday, June 7, 13
    • “A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...What is CoffeeScript?Friday, June 7, 13
    • “A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...A Hybrid languages like Ruby and Python.What is CoffeeScript?Friday, June 7, 13
    • “A little language that compiles into JavaScript.”Easily integrates with your current JavaScriptEasier to read, write, maintain, refactor, etc...A Hybrid languages like Ruby and Python.Helpful.What is CoffeeScript?Friday, June 7, 13
    • Not Magic!Limited by what JavaScript can already doWhat CoffeeScript IsNot?Friday, June 7, 13
    • “I’m happy writing JavaScript.I don’t need to learn another language.”Friday, June 7, 13
    • FINE WITH MEFriday, June 7, 13
    • BUT...Friday, June 7, 13
    • ANOTHER (BRIEF)HISTORY LESSONFriday, June 7, 13
    • .MODEL SMALL.STACK 64.DATAVAL1 DB 01HVAL2 DB 01HLP DB 00HV1 DB 00HV2 DB 00HNL DB 0DH,0AH,$.CODEMAIN PROCMOV AX,@DATAMOV DS,AXMOV AH,01HINT 21HMOV CL,ALSUB CL,30HSUB CL,2MOV AH,02HMOV DL,VAL1ADD DL,30HINT 21HMOV AH,09HLEA DX,NLINT 21HMOV AH,02HMOV DL,VAL2ADD DL,30HINT 21HMOV AH,09HLEA DX,NLINT 21HDISP:MOV BL,VAL1ADD BL,VAL2MOV AH,00HMOV AL,BLMOV LP,CLMOV CL,10DIV CLMOV CL,LPMOV V1,ALMOV V2,AHMOV DL,V1ADD DL,30HMOV AH,02HINT 21HMOV DL,V2ADD DL,30HMOV AH,02HINT 21HMOV DL,VAL2MOV VAL1,DLMOV VAL2,BLMOV AH,09HLEA DX,NLINT 21HLOOP DISPMOV AH,4CHINT 21HMAIN ENDPEND MAINFriday, June 7, 13
    • .MODEL SMALL.STACK 64.DATAVAL1 DB 01HVAL2 DB 01HLP DB 00HV1 DB 00HV2 DB 00HNL DB 0DH,0AH,$.CODEMAIN PROCMOV AX,@DATAMOV DS,AXMOV AH,01HINT 21HMOV CL,ALSUB CL,30HSUB CL,2MOV AH,02HMOV DL,VAL1ADD DL,30HINT 21HMOV AH,09HLEA DX,NLINT 21HMOV AH,02HMOV DL,VAL2ADD DL,30HINT 21HMOV AH,09HLEA DX,NLINT 21HDISP:MOV BL,VAL1ADD BL,VAL2MOV AH,00HMOV AL,BLMOV LP,CLMOV CL,10DIV CLMOV CL,LPMOV V1,ALMOV V2,AHMOV DL,V1ADD DL,30HMOV AH,02HINT 21HMOV DL,V2ADD DL,30HMOV AH,02HINT 21HMOV DL,VAL2MOV VAL1,DLMOV VAL2,BLMOV AH,09HLEA DX,NLINT 21HLOOP DISPMOV AH,4CHINT 21HMAIN ENDPEND MAINAssemblyFriday, June 7, 13
    • #include <stdio.h>int fibonacci(){int n = 100;int a = 0;int b = 1;int sum;int i;for (i = 0; i < n; i++){printf("%dn", a);sum = a + b;a = b;b = sum;}return 0;}CFriday, June 7, 13
    • public static void fibonacci() {int n = 100;int a = 0;int b = 1;for (int i = 0; i < n; i++) {System.out.println(a);a = a + b;b = a - b;}}JavaFriday, June 7, 13
    • def fibonaccia = 0b = 1100.times doprintf("%dn", a)a, b = b, a + bendendRubyFriday, June 7, 13
    • “I can write an app just as well in Javaas I can in Ruby, but damn it if Rubyisn’t nicer to read and write!”Friday, June 7, 13
    • SAME GOES FORCOFFEESCRIPTFriday, June 7, 13
    • SYNTAXFriday, June 7, 13
    • $(function() {success = function(data) {if (data.errors != null) {alert("There was an error!");} else {$("#content").text(data.message);}};$.get(/users, success, json);});$ ->success = (data) ->if data.errors?alert "There was an error!"else$("#content").text(data.message)$.get(/users, success, json)JavaScript CoffeeScriptFriday, June 7, 13
    • Syntax RulesNo semi-colons (ever!)No curly braces*No ‘function’ keywordRelaxed parenthesesWhitespace significant formattingFriday, June 7, 13
    • # Not required without arguments:noArg1 = -># do something# Not required without arguments:noArg2 = () -># do something# Required with Arguments:withArg = (arg) -># do somethingParentheses Rules# Required without arguments:noArg1()noArg2()# Not required witharguments:withArg("bar")withArg "bar"Friday, June 7, 13
    • # Bad:$ "#some_id" .text()# $("#some_id".text());# Good:$("#some_id").text()# $("#some_id").text();Parentheses RulesFriday, June 7, 13
    • WhitespaceFriday, June 7, 13
    • Whitespace$(function() {success = function(data) {if (data.errors != null) {alert("There was an error!");} else {$("#content").text(data.message);}};$.get(/users, success, json);});Friday, June 7, 13
    • Whitespace$(function() {success = function(data) {if (data.errors != null) {alert("There was an error!");} else {$("#content").text(data.message);}};$.get(/users, success, json);});Friday, June 7, 13
    • Whitespace$ ->success = (data) ->if data.errors?alert "There was an error!"else$("#content").text(data.message)$.get(/users, success, json)Friday, June 7, 13
    • ConditionalsdoSomething() if truedoSomething() unless trueif truedoSomething()unless truedoSomething()if truedoSomething()elsedoSomethingElse()Friday, June 7, 13
    • Objects/HashessomeObject = {conf: "FluentConf", talk: "CoffeeScript"}someObject =conf: "FluentConf"talk: "CoffeeScript"someFunction(conf: "FluentConf", talk: "CoffeeScript")Friday, June 7, 13
    • Objects/Hashesvar someObject;someObject = {conf: "FluentConf",talk: "CoffeeScript"};someObject = {conf: "FluentConf",talk: "CoffeeScript"};someFunction({conf: "FluentConf",talk: "CoffeeScript"});Friday, June 7, 13
    • String Interpolationname = "FluentConf 2013"console.log "Hello #{name}"# Hello FluentConf 2013console.log Hello #{name}# Hello #{name}Friday, June 7, 13
    • String Interpolationname = "FluentConf 2013"console.log "Hello #{name}"# Hello FluentConf 2013console.log Hello #{name}# Hello #{name}var name;name = "FluentConf 2013";console.log("Hello " + name);console.log(Hello #{name});Friday, June 7, 13
    • Heredocshtml = """<div class="comment" id="tweet-#{tweet.id_str}"><hr><div class=tweet><span class="imgr"><imgsrc="#{tweet.profile_image_url}"></span><span class="txtr"><h5><a href="http://twitter.com/#{tweet.from_user}"target="_blank">@#{tweet.from_user}</a></h5><p>#{tweet.text}</p><p class="comment-posted-on">#{tweet.created_at}</p></span></div></div>"""Friday, June 7, 13
    • Heredocsvar html;html = "<div class="comment" id="tweet-" + tweet.id_str+ "">n <hr>n <div class=tweet>n <span class="imgr"><img src="" + tweet.profile_image_url + ""></span>n <span class="txtr">n <h5><a href="http://twitter.com/" + tweet.from_user + "" target="_blank">@" + tweet.from_user + "</a></h5>n <p>" +tweet.text + "</p>n <p class="comment-posted-on">"+ tweet.created_at + "</p>n </span>n </div>n</div>";Friday, June 7, 13
    • Functionsp = (name) ->console.log "Hello #{name}"p(FluentConf 2013)Friday, June 7, 13
    • Functionsvar p;p = function(name) {return console.log("Hello " + name);};p(FluentConf 2013);Friday, June 7, 13
    • Loops &Comprehensionsfor someName in someArrayconsole.log someNamefor key, value of someObjectconsole.log "#{key}: #{value}"Friday, June 7, 13
    • Loops &Comprehensionsvar key, someName, value, _i, _len;for (_i = 0, _len = someArray.length; _i < _len; _i++) {someName = someArray[_i];console.log(someName);}for (key in someObject) {value = someObject[key];console.log("" + key + ": " + value);}Friday, June 7, 13
    • Loops &Comprehensionsnumbers = [1..5]console.log number for number in numbersFriday, June 7, 13
    • Loops &Comprehensionsvar number, numbers, _i, _len;numbers = [1, 2, 3, 4, 5];for (_i = 0, _len = numbers.length; _i < _len; _i++) {number = numbers[_i];console.log(number);}Friday, June 7, 13
    • Loops &Comprehensionsnumbers = [1..5]console.log number for number in numbers when number <= 3Friday, June 7, 13
    • Loops &Comprehensionsvar number, numbers, _i, _len;numbers = [1, 2, 3, 4, 5];for (_i = 0, _len = numbers.length; _i < _len; _i++) {number = numbers[_i];if (number <= 3) {console.log(number);}}Friday, June 7, 13
    • Loops &Comprehensionsnumbers = [1, 2, 3, 4, 5]low_numbers = (number * 2 for number in numbers when number <= 3)console.log low_numbers # [ 2, 4, 6 ]Friday, June 7, 13
    • Loops &Comprehensionsvar low_numbers, number, numbers;numbers = [1, 2, 3, 4, 5];low_numbers = (function() {var _i, _len, _results;_results = [];for (_i = 0, _len = numbers.length; _i < _len; _i++) {number = numbers[_i];if (number <= 3) {_results.push(number * 2);}}return _results;})();console.log(low_numbers);Friday, June 7, 13
    • Classesclass Employeeemp = new Employee()emp.firstName = "Mark"Friday, June 7, 13
    • Classesvar Employee, emp;Employee = (function() {Employee.name = Employee;function Employee() {}return Employee;})();emp = new Employee();emp.firstName = "Mark";Friday, June 7, 13
    • Classesclass Employeeconstructor: (@options = {}) ->salary: ->@options.salary ?= "$250,000"emp = new Employee()console.log emp.salary() # "$250,000"emp = new Employee(salary: "$100,000")console.log emp.salary() # "$100,000"Friday, June 7, 13
    • Classesvar Employee, emp;Employee = (function() {Employee.name = Employee;function Employee(options) {this.options = options != null ? options : {};}Employee.prototype.salary = function() {var _base, _ref;return (_ref = (_base = this.options).salary) != null ? _ref : _base.salary = "$250,000";};return Employee;})();emp = new Employee();console.log(emp.salary());emp = new Employee({salary: "$100,000"});console.log(emp.salary());Friday, June 7, 13
    • Extending Classesclass Manager extends Employeesalary: ->"#{super} w/ $10k Bonus"manager = new Manager()console.log manager.salary() # "$250,000 w/ $10k Bonus"Friday, June 7, 13
    • Extending Classesvar Manager, manager,__hasProp = {}.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; };Manager = (function(_super) {__extends(Manager, _super);Manager.name = Manager;function Manager() {var _base;Manager.__super__.constructor.apply(this, arguments);}Manager.prototype.salary = function() {return "" + Manager.__super__.salary.apply(this, arguments) + " w/ $10k Bonus";};return Manager;})(Employee);manager = new Manager();console.log(manager.salary());Friday, June 7, 13
    • Bound Functionsclass Userconstructor: (@name) ->sayHi: ->console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)->console.log "about to execute callback..."callback()console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)Friday, June 7, 13
    • Bound Functionsabout to execute callback...Hello undefined...executed callbackabout to execute callback...Hello undefined...executed callbackFriday, June 7, 13
    • class Userconstructor: (@name) ->sayHi: ->console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)->console.log "about to execute callback..."callback()console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)Bound FunctionsFriday, June 7, 13
    • class Userconstructor: (@name) ->sayHi: ->console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)->console.log "about to execute callback..."callback()console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)Bound FunctionsFriday, June 7, 13
    • class Userconstructor: (@name) ->sayHi: =>console.log "Hello #{@name}"bob = new User(bob)mary = new User(mary)log = (callback)->console.log "about to execute callback..."callback()console.log "...executed callback"log(bob.sayHi)log(mary.sayHi)Bound FunctionsFriday, June 7, 13
    • Bound Functionsabout to execute callback...Hello bob...executed callbackabout to execute callback...Hello mary...executed callbackFriday, June 7, 13
    • Bound Functionsclass Userconstructor: (@name) ->sayHi: =>console.log "Hello #{@name}"Friday, June 7, 13
    • Bound Functionsvar User,__bind = function(fn, me){ return function(){ return fn.apply(me,arguments); }; };User = (function() {User.name = User;function User(name) {this.name = name;this.sayHi = __bind(this.sayHi, this);}User.prototype.sayHi = function() {return console.log("Hello " + this.name);};return User;})();Friday, June 7, 13
    • FINALLYOne of my favorite featuresFriday, June 7, 13
    • Existential Operatorif foo?console.log "foo"Friday, June 7, 13
    • Existential Operatorif (typeof foo !== "undefined" && foo !== null) {console.log("foo");}Friday, June 7, 13
    • BUT WAIT! THERE’SMORE!Friday, June 7, 13
    • Existential Operatorconsole?.log "foo"Friday, June 7, 13
    • Existential Operatorconsole?.log "foo"if (typeof console !== "undefined" && console !== null) {console.log("foo");}Friday, June 7, 13
    • Existential Operatorif currentUser?.firstName?console.log currentUser.firstNameFriday, June 7, 13
    • Existential Operatorif currentUser?.firstName?console.log currentUser.firstNameif ((typeof currentUser !== "undefined" && currentUser !==null ? currentUser.firstName : void 0) != null) {console.log(currentUser.firstName);}Friday, June 7, 13
    • FINALLYFriday, June 7, 13
    • The RavenFriday, June 7, 13
    • Once upon a mignight dreary while I pondered, weak and weary,Over many quaint and curious volume of forgotten lore -While I nodded, nearly napping, suddenly there came a tapping,As of some one gently rapping, rapping at my chamber door"Tis some visiter". I muttered, "tapping at my chamber door" -"only this and nothing more."Ah distinctly I remember it was in the bleak December;And each separate dying ember wrought its ghost upon the floor.Eagerly I wished the morrow - vainly I had sought to borrow,From my books surcease of sorrow - sorrow For the lost Lenore -For the rare and radiant maiden whom the angels name Lenore -Nameless here For evermoreThe RavenFriday, June 7, 13
    • The Ravenvar __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length;i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };while (I(pondered, weak && weary, Over(many(quaint && curious(volume inforgotten(lore - While(I(nodded, nearly(napping, suddenly(there(came(a(tapping,As in some(one(gently(rapping, rapping(at(my(chamber(door)))))))))))))))))))) {  Once(upon(a(mignight(dreary))));}"Tis some visiter".I(muttered, "tapping at my chamber door" - "only this andnothing more.");Ah(distinctly(I(remember(it(__indexOf.call(the(bleak(December)), was) >= 0)))));And(each(separate(dying(ember(wrought(its(ghost(upon(the(floor.Eagerly(I(wished(the(morrow - vainly(I(had(sought(to(borrow, From(my(books(surcease in sorrow -sorrow(For(the(lost(Lenore - For(the(rare &&radiant(maiden(whom(the(angels(name(Lenore -Nameless(here(For(evermore)))))))))))))))))))))))))))))))))))));Friday, June 7, 13
    • What Didn’t I Cover?Default ArgumentsRangesSplatted ArgumentsScopingSecurityStrict ModeFixes common‘mistakes’OperatorsThe `do` keywordSource MapsPlenty more!Friday, June 7, 13
    • Thank you!Friday, June 7, 13
    • Thank you!myName = "Mark Bates"you.should buyBook("Programming in CoffeeScript").at("http://books.markbates.com")you.should follow(@markbates)Friday, June 7, 13