It looks like Ruby and Python
fibonacci = (x) -> return 0 if x == 0 return 1 if x == 1 return fibonacci(x-1) + fibonacci(x-2) fibonacci 10 # returns 55
It's hard to deploy and debug
TypeError: Cannot call method 'updateAttributes' of null at Promise.Handler.handleUpdate (/myapp/lib/handlers/handler.coffee:55:22) at Promise.addBack (/myapp/node_modules/mongoose/lib/promise.js:128:8) at Promise.EventEmitter.emit (events.js:96:17) at Promise.emit (/myapp/node_modules/mongoose/lib/promise.js:66:38)
It gives me a bunch of great language features
congratulate(user) for user in @users where user.isWinner() # loop comprehensions "Hello, my name is #{@firstName} #{@lastName}." # string interpolation for i in [0..10] # ranges subset = myArray[2..5] # range slicing zip = account?.user?.address?.zip # existential operator { number, street, zip } = @getAddress() # destructuring
It doesn't support named functions
// Y u no possible in coffeescript? function square(x) { return x * x; }
It helps avoid typical JavaScript bad practices
var foo = 3; // good foo = 3; // really bad false == ' \t'; // this is true... wtf? false === ' \t'; // much better
It makes a prototypal language look like classical inheritance
class User constructor: () -> @admin = false fullName: () -> "#{@firstName} #{@lastName}"
It's easy to write readable DSLs
require('zappa') -> @use 'bodyParser', 'methodOverride', @app.router, 'static' @configure development: => @use errorHandler: {dumpExceptions: on} production: => @use 'errorHandler' @get '/': -> @render 'index' @on connection: -> @emit welcome: {time: new Date()} @on shout: -> @broadcast shout: {@id, text: @data.text}
It has started Yet Another Religion War
function js(region) { if (region == null) { region = 'world'; } return 'I am the king of the ' + region + '!'; } cs = (bodyPart = 'ass') -> "Kiss my #{bodyPart}, grandpa!"
Time for me to get a beer