# Assignment: number = 42 opposite = trueOK, there are no semicolons. Cool. Not. Why are people so obsessed with eliminating semicolons? This happens in the Java community, too (Groovy). Humans are used to punctuation (=good for the reader) and the writer only saves a single character per line.
The above example shows that there is no var in CoffeeScript and variables are automatically declared. But having to declare variables is one of JavaScript’s best features, because it catches typos. As an aside, var will soon be improved as the block-scoped let.
# Conditions: number = -42 if oppositeThis kind of if statement Reminds me of Perl. It avoids the familiarity of if plus block (which one should always use in JavaScript), without helping readers much.
# Functions: square = (x) -> x * xThe current function definitions are quite verbose. Thus, a short function notation is very useful, especially whenever a function is an argument of another function: callbacks, custom looping constructs etc. I’m not especially fond of the syntax, because it looks un-JavaScript-like but there are unfortunately many constraints placed on a shorter function notation: You cannot put a legal identifier in front of parentheses, because that would be interpreted as a function call. That precludes shorter names for the function operator (function is not a legal identifier) such as fn, but also the legal identifiers λ and ƒ.
# Arrays: list = [1, 2, 3, 4, 5] # Objects: math = root: Math.sqrt square: square cube: (x) -> x * square xThe object syntax brings no improvement and introduces a Python-like style. Mixing styles is not a good idea.
# Splats: race = (winner, runners...) -> print winner, runnersYes. Better parameter declarations for functions. ECMAScript.next [2] might have them, maybe even named/keyword parameters (details). Named parameters are awesome. Python is exemplary in how it handles parameters.
# Existence: alert "I knew it!" if elvis?The question mark operator ? is not much of an improvement compared to using a normal if and a function:
if (defined(elvis)) { ... }But this operator can be used with a dot to safely construct property chains which is truly useful (drawWinner and address can be null, in which case the result zip is null):
zip = lottery.drawWinner?().address?.zipcodeArray comprehensions are cool:
cubes = (math.cube num for num in list)Additional features of CoffeeScript:
if year > 2010 { syntax++ } for i in iter { // i is a fresh let binding! frob(i) } while lo <= hi { let mid = (lo + hi) / 2 // binary search blah blah blah } ... return [i * i for i in range(n)] // array comprehensionNote that the paren-free for-in also has better semantics: It supports iterators and generators. And it changes array iteration to be over values, not keys. These features combined allow one to implement new kinds of iterations: For example, the following code uses a hypothetical helper function keys() that returns an iterator over the names of both own properties and properties inherited via the prototype chain. This is how for-in currently works; call it a legacy mode. In contrast, the paren-free for-in iterates only over own property names of objects.
for k in keys(obj) { // k is a string-typed key }Another possibility is to iterate over properties as (key,value) pairs:
for [key,value] in items(obj) { }Two more points:
You need to mandate either parens around the head, or braces around the body [...]. So C requires parens around head expressions. But many style guides recommend always bracing, to ward off dangling else. Go codifies this fully, requiring braces but relieving programmers from having to parenthesize the head expression.This is a good call. It will lead to cleaner and more uniform JavaScript code.