coffee script
DESCRIPTION
TRANSCRIPT
COFFEESCRIPT“It’s just JavaScript”
Me• Zarar Siddiqi
• Agile Coach with a developer’s itch
• http://www.linkedin.com/in/zararsiddiqi• [email protected]
• Confluence page for This Week @: • https://kb.epam.com/pages/viewpage.action?pageId=107875299
• Next week: Agile Games!
Agenda• Why Bother?• Basic Concept• Simple But High ROI Features• Other Nice Features• Code Playground
• Windows Installation• Examples
• Conclusion (or something like it)• Discussion
WHY BOTHER?
1.1: LIBRARIES
#1: JavaScript Use Exploding
1.2: MVVM, SINGLE-PAGE APPS
1.3: MOBILE
1.4: SERVER
#2: Problems with JavaScript• Ambiguous constructs leading to verbosity
• function, prototype, extend, var, (function() {});
• Error-prone with late visibility• Trailing commas, string concatenation, context binding, equality
• Limited features• List comprehension, string interpolation, conditional modifiers
• Namespace pollution• All <script> files loaded in one global scope
• PHP Problems• Easy to get started; easy to go downhill
The math is simple
Lots of JS
Easy to write
messy JS
Lots of messy
JS
BASIC CONCEPT
How it works
file.coffee Compile file.jspage.html
<script> tag
Analogous to less for CSS - http://lesscss.org/
Benefits• .coffee has less code to maintain – 35-45% less
• Produces JSLint validated code (http://jslint.com)• http://javascript.crockford.com/code.html
• Easy-to-read code (Influenced by Ruby, Python, Haskell)
• Focuses on JavaScript: The Good Parts (Douglas Crockford): http://amzn.to/176RA4
• Written by smart people, very strong community support, mature (3.5 years)
• Easy to unit test (Jasmine) - http://pivotal.github.io/jasmine/
SIMPLE BUT HIGH ROI FEATURES
#1: Defining classes- Some ways of defining objects in JavaScript:
- Using function- Using prototype- var obj = {}
Let’s look at some examples…
Here’s one way…// Using a functionfunction Apple (country) { this.country = country; this.color = "red"; this.getInfo = getAppleInfo;} function getAppleInfo() { return this.country + ' has ' +
this.color + 'apples'.;}
Here’s another…// Using the prototypefunction Apple (country) { this.country = country; this.color = "red";} Apple.prototype.getInfo = function() { return this.country + ' has '
+ this.color + 'apples'.;};
This will work too…// Using object literals var apple = { country: "Sweden", color: "red", getInfo: function () { return this.country + ' has '
+ this.color + 'apples'.; }}
Equivalent CoffeeScript classclass Apple
constructor: (@country) -> @color = "red" getInfo: -> "{@country} has {@color} apples"
class BakedApple extends Appleconstructor: ->
super(“Canada”) @color = “brown”
// No method keyword// @ instead of this// Implicit assignment// Indentation
// Sensible class declaration
// Interpolation// Implicit returns
// Easy inheritance model
#2: The var problem
Example 1
function foo() { var name = “Bob”; age = 29; }
alert(name);alert(age);
Example 2
function printTen() { for (i=0; i<10; i++) { console.log(i); } return true}
printTen();alert(i);
CoffeeScript default scope is local
CoffeeScript
foo: -> name = "Bob" age = 29
JavaScript
printTen: function() { var i, _i; for (i = _i = 0; _i <= 10; i = _i += 1) { console.log(i); } return true;}
printTen();alert(i);
function foo() { var age, name; name = "Bob"; age = 29;}
printTen: -> for i in [0..10] by 1 console.log i return true printTen()alert(i)
#3: Outer Scope Referencing
JavaScript
function User(name) { this.name = name;}
User.prototype.save = function() { var _this = this; $.post('/user/save', function(data){ $('.msg').html(_this.name+"saved."); });};
CoffeeScript
class User constructor: (@name) -> save: -> $.post '/user/save', (data) => $('.msg').html("#{@name} saved.")
#4: Object Literal Readability / Writability
CoffeeScript
config = user: id: 'jsmith' name: first: 'John' last: 'Smith' password: 'pass ' email: '[email protected]' host: 'localhost' port: 3306 conn: -> App.connect()
JavaScript
config = { user: { id: 'jsmith', name: { first: 'John', last: 'Smith' }, password: 'pass', email: '[email protected]' }, host: 'localhost', port: 3306, conn: function() { return App.connect(); }};
#5: Testing Equality"" == "0" // false0 == "" // true0 == "0" // true false == "false" // false false == "0" // true false == undefined // falsefalse == null // falsenull == undefined // true" \t\r\n" == 0 // true Type
Coercion!
Solution: Use the is and isnt keywords which compare without coercing and are more readable:
if a is b doSomething()
SYNTACTIC SUGAR“make things easier to read or to express.”
A spoonful of sugar…# Existence checkingif happy? console.log "clap your hands"
# Skip null checkstruck.getTires()?.change()
# Tuple-like assignments[a, b] = [1, 2]
if (truck.getTires() != null) truck.getTires().change()
if (typeof happy !== "undefined" && happy !== null)
Some more sugar…# Iterate over a list with indexfor item, i in someList alert “Item #{i} is #{item}“
# Conditional modifiers
# Conditional modifiersturnOn() if buttonPressed is truestatus = 'expired' unless withinRange()
A whole jar of sugar…• http://coffeescript.org/
CODE PLAYGROUND
Installation
After downloading and installing NodeJS from http://nodejs.org/download/
Execute following from command prompt:
C:\>npm -g install coffee-scriptC:\>coffeecoffee>
FINALLY…
As with everything…• Use the right tool for the right job
• If it’s a small piece of JS, don’t bother. If it’s a JS-heavy project, consider it
• Philosophical Debate:
Highly disciplined developers following a style guide vs.
A language that helps standardize the produced code
Resources• CoffeeScript Home Page
• http://coffeescript.org/
• JS2Coffee (Coffee2JS)• http://js2coffee.org/
• Should you learn CoffeeScript?• http://net.tutsplus.com/articles/interviews/should-you-learn-coffeesc
ript/
• Google Search – CoffeeScript Sucks• http://goo.gl/MNQrY
• Brendan Eich• https://brendaneich.com/2011/05/my-jsconf-us-presentation/
• The Little Book on CoffeeScript• http://arcturo.github.io/library/coffeescript/