Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How CoffeeScript deprecates Javascript

How CoffeeScript deprecates Javascript

B731002ef4fa2ee7423e4b15e177f5b3?s=128

Stefano Verna

May 22, 2012
Tweet

Transcript

  1. How CoffeeScript deprecates JavaScript

  2. A bit of history

  3. A bit of history from 1995

  4. None
  5. 1995 Netscape Navigator 2.0 vs. IE 1.0 (Microsoft Windows 95

    Plus! Pack)
  6. 1995 Netscape wanted a lightweight interpreted language that would complement

    Java by appealing to nonprofessional programmers, like Microsoft's Visual Basic.
  7. 1995 Brendan Eich CTO Mozilla Foundation

  8. 1995 JS had to “look like Java”, only less so.

    It had to be Java’s dumb kid brother or boy- hostage sidekick. Plus, it had to be done in ten days.
  9. 1995 Not a bad language, for a 10 days effort.

    % Prototypal inheritance % First-class functions % First-class closures % Object and Array literals % Loose typing
  10. 1995 Not a great language, neither. × Ugly, verbose syntax

    × Dependency on globals × No block scopes × Equality coersion × A lot more
  11. 1995 Javascript: The Good Parts Javascript: The Definitive Guide

  12. 1995 For 5 long years, it’s just news ticker and

    countdown timers. 2000
  13. 1995 For 5 long years, it’s just news ticker and

    countdown timers. 2000
  14. XMLHttpRequest 2000 Internet Explorer 5.0

  15. No one gives a fuck. 2000 AJAX days still have

    to come.
  16. 2004 Until 2004. (AJAX finally implemented on most browsers.)

  17. 2004

  18. 2005

  19. 2005

  20. 2005 Sam Stephenson 37signals

  21. var names = []; for (var i = 0, l

    = people.length; i < l; i++) { var person = people[i]; var name = person.name.slice(0, 1).toUpperCase() + person.name.slice(1); names.push(name); }
  22. names = people.map do |person| person.name.capitalize end

  23. names = people.map do |person| person.name.capitalize end var names =

    people.map( function (person) { return person.name.capitalize(); } );
  24. Beautiful, readable, ruby-ish syntax High use of monkey-patching Namespace clashing

  25. Beautiful, readable, ruby-ish syntax High use of monkey-patching Namespace clashing

  26. 2006 John Resig Khan Academy

  27. var names = $.each(people, function(person) { return capitalize(person.name); } );

    jQuery.noConflict() A broader audience, a safer approach A step backward in readability
  28. So, basically, we’re trapped x

  29. unless. x

  30. We start thinking about Javascript more like bytecode %

  31. None
  32. A desktop-like development experience There’s no HTML, CSS or JS

    No direct interaction with the browser Java ObjC Python 2008
  33. @implementation AppController : CPObject { } - (void)applicationDidFinishLaunching:(CPNotification)note { theWindow

    = [[CPWindow alloc] initWithContentRect:CGRectMakeZero() styleMask:CPBorderlessBridgeWindowMask]; contentView = [theWindow contentView]; var label = [[CPTextField alloc] initWithFrame:CGRectMakeZero()]; [label setStringValue:@"Hello World!"]; [label setFont:[CPFont boldSystemFontOfSize:24.0]]; [label sizeToFit]; [label setAutoresizingMask:CPViewMinXMargin | CPViewMaxXMargin]; [label setFrameOrigin:CGRectMake(100,100)]; [contentView addSubview:label]; [theWindow orderFront:self]; } @end
  34. But I like the web! I just want the bad

    parts fixed! (
  35. 2009 Jeremy Ashkenas DocumentCloud

  36. 2009 Underneath all those awkward braces and semicolons, JavaScript has

    always had a gorgeous object model at its heart. CoffeeScript is an attempt to expose the good parts of JavaScript in a simple way. The golden rule of CoffeeScript is: "It's just JavaScript". CoffeeScript generates clean and readable JavaScript.
  37. (function() { /* your program here */ }).call(this); Private by

    default (self-executing function) # Your program here
  38. function greet (name) { return "Hello " + name; }

    Function syntax & automatic return greet = (name) -> "Hello " + name
  39. function greet (name) { return "Hello " + name; }

    Function syntax & automatic return greet = (name) -> "Hello " + name Approved feature in ECMAScript.next http://goo.gl/JsXQ5
  40. greet = (name) -> if name == "@tenderlove" "ZOMG! HI

    " + name + "!!!" else "Hello " + name Everything is an expression var greet = function(name) { if (name === "@tenderlove") { return "ZOMG! HI " + name + "!!!"; } else { return "Hello " + name; } };
  41. var names, person; names = (function() { var _i, _len,

    _results; _results = []; for (_i = 0, _len = people.length; _i < _len; _i++) { person = people[_i]; _results.push(capitalize(person.name)); } return _results; })(); names = for person in people capitalize person.name Everything is an expression /2
  42. "ZOMG! HI #{ name }!!!" Ruby-style string interpolation "ZOMG! HI

    " + name + "!!!";
  43. foo = false bar = "0" console.log foo == bar

    # -> false console.log foo != bar # -> true Strict comparisons (no more equality coertion) var bar, foo; foo = false; bar = "0"; console.log(foo === bar); console.log(foo !== bar);
  44. foo = false bar = "0" console.log foo == bar

    # -> false console.log foo != bar # -> true Strict comparisons (no more equality coertion) var bar, foo; foo = false; bar = "0"; console.log(foo === bar); console.log(foo !== bar); In JS, if you use == you’ll get the exactly opposite result!
  45. var changeNumbers, inner, outer; outer = 1; changeNumbers = function()

    { var inner; inner = -1; return outer = 10; }; inner = changeNumbers(); No more var (Ruby-like scoping) outer = 1 changeNumbers = -> inner = -1 outer = 10 inner = changeNumbers()
  46. var changeNumbers, inner, outer; outer = 1; changeNumbers = function()

    { var inner; inner = -1; return outer = 10; }; inner = changeNumbers(); No more var (Ruby-like scoping) outer = 1 changeNumbers = -> inner = -1 outer = 10 inner = changeNumbers() In JS, you omit “var” you’re leaking variables on the outer scope!
  47. var languageOfChoice = function(lang) { if (lang == null) {

    lang = "Ruby"; } return "" + lang + " rocks!"; }; Parameter default values languageOfChoice = (lang = "Ruby") -> "#{ lang } rocks!"
  48. var languageOfChoice = function(lang) { if (lang == null) {

    lang = "Ruby"; } return "" + lang + " rocks!"; }; Parameter default values languageOfChoice = (lang = "Ruby") -> "#{ lang } rocks!" Approved feature in ECMAScript.next http://goo.gl/JsXQ5
  49. var __slice = [].slice; var languagesOfChoice = function() { var

    best, others; best = arguments[0], others = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return "I love " + best + ", but I like also " + (others.join(", ")); }; Arguments splat languagesOfChoice = (best, others...) -> "I love #{ best }, but I like also #{ others.join(", ") }"
  50. var __slice = [].slice; var languagesOfChoice = function() { var

    best, others; best = arguments[0], others = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return "I love " + best + ", but I like also " + (others.join(", ")); }; Arguments splat languagesOfChoice = (best, others...) -> "I love #{ best }, but I like also #{ others.join(", ") }" Approved feature in ECMAScript.next http://goo.gl/JsXQ5
  51. console.log [ 1, 2, 3, ] console.log { foo: 1,

    bar: 2, } JSLint validatable code (runs everywhere) console.log([1, 2, 3]); console.log({ foo: 1, bar: 2 });
  52. console.log [ 1, 2, 3, ] console.log { foo: 1,

    bar: 2, } JSLint validatable code (runs everywhere) console.log([1, 2, 3]); console.log({ foo: 1, bar: 2 }); IE would have thrown a compilation error on this one!
  53. return if elements.length == 0 launch() if ignition is on

    volume = 10 if band isnt SpinalTap letTheWildRumpusBegin() unless answer is no if car.speed < limit then accelerate() winner = yes if pick in [47, 92, 13] Statement Modifiers & Operator aliases
  54. Multiline strings var mobyDick = "Call me Ishmael. Some years

    ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..."; var html = "<strong>\n cup of coffeescript\n</strong>"; mobyDick = "Call me Ishmael. Some years ago -- never mind how long precisely -- having little or no money in my purse, and nothing particular to interest me on shore, I thought I would sail about a little and see the watery part of the world..." html = """ <strong> cup of coffeescript </strong> """
  55. class Animal constructor: (@name) -> move: (meters) -> alert @name

    + " moved #{meters}m." dog = new Animal("Fido") var Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + (" moved " + meters + "m.")); }; return Animal; })(); Built-in classical OOP (the @ alias)
  56. var Animal, Snake, __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; }; Snake = (function(_super) { __extends(Snake, _super); function Snake() { return Snake.__super__.constructor.apply(this, arguments); } Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake; })(Animal); Inheritance class Snake extends Animal move: -> alert "Slithering..." super 5
  57. Bound functions (fat arrow) class @View constructor: (@name) -> @el

    = $("<div/>").appendTo("body") @attachEvents() attachEvents: -> @el.click -> alert "#{@name} view!"
  58. class @View constructor: (@name) -> @el = $("<div/>").appendTo("body") @attachEvents() attachEvents:

    -> this.el.click( function() { alert(_this.name + " view"); } ); Bound functions (fat arrow)
  59. class @View constructor: (@name) -> @el = $("<div/>").appendTo("body") @attachEvents() attachEvents:

    -> var _this = this; this.el.click( function() { alert(_this.name + " view"); } ); Bound functions (fat arrow)
  60. Bound functions (fat arrow) class @View constructor: (@name) -> @el

    = $("<div/>").appendTo("body") @attachEvents() attachEvents: -> @el.click => alert "#{@name} view!"
  61. Bound functions (fat arrow) Approved feature in ECMAScript.next http://goo.gl/JsXQ5 class

    @View constructor: (@name) -> @el = $("<div/>").appendTo("body") @attachEvents() attachEvents: -> @el.click => alert "#{@name} view!"
  62. Closure wrappers var number = 10; function check() { return

    number; }; number = 20; check();
  63. Closure wrappers var number = 10; function check() { return

    number; }; number = 20; check(); // 20
  64. Closure wrappers for (var i = 0; i < 5;

    i++) { $("<div/>") .text(i) .appendTo("body") .click(function() { alert("Clicked " + i); }); }
  65. Closure wrappers for (var i=0; i<5; i++) { (function(i) {

    $("<div/>") .text(i) .appendTo("body") .click(function() { alert("Clicked " + i); }); })(i); }
  66. Closure wrappers for i in [0...5] do (i) -> $("<div/>")

    .appendTo("body") .text(i) .click -> alert("Clicked #{i}")
  67. Everything else you might miss from Ruby. • Array slicing

    • Destructured assignments • Block regular expressions • Optional parenthesis • Existential operators
  68. Thanks! @steffoz U stefanoverna.com Y