Note: I never switched to CoffeeScript.
This week I stumbled again on CoffeeScript when these slides by Aseem Kishore made the round on twitter. CoffeeScript itself influenced the new standard and provides some syntactical improvements. I have been playing around with it lately and really like to use arrow functions, class inheritance and splats today, but I think CoffeeScript is too lax when it comes to omitting braces and keywords.
1. always wrap function parameters in parentheses
Readability is important. Without parentheses it’s hard to see where functions are called—even for syntax highlighters like prism.js. It’s also inconsistent as one has to use parantheses calling functions without parameters.
request = new XMLHttpRequest request.responseType = type request.onload = handleResponse request.open method, url, true request.setRequestHeader 'X-Requested-With', 'XMLHttpRequest' request.send()
request = new XMLHttpRequest() request.responseType = type request.onload = handleResponse request.open(method, url, true) request.setRequestHeader('X-Requested-With', 'XMLHttpRequest') request.send()
Now you can see on the first sight which parts of the code are assignments and which ones are function calls.
2. always write return if you intend to do so
CoffeeScript always returns the last statement of a function. This leads to lines with just a variable name, but lines with just a variable name could also be part of an array for example. It’s also not explicit if you return early. Look at the last line. In my opinion it looks unintentional.
getVar = (para) -> context = this or window if not /^\'/g.test(para) return context[para] para
getVar = (para) -> context = this or window if not /^\'/g.test(para) return context[para] return para
3. wrap functions which are not the last argument in parentheses
Without parantheses and the return statement this looks like a syntax error to me. Apparently this is also hard to understand for CoffeeScript’s compiler as this syntax isn’t valid when compiled with the new CoffeeScript Redux compiler. The Redux compiler is also smart enough not to wrap the function in parentheses when compiled.
func = string.split('.').reduce (obj,i) -> obj[i] or false , obj
func = string.split('.').reduce( ((obj,i) -> return obj[i] or false ), obj)
4. wrap objects in curly braces
This again fights inconsistency. Arrays have to be wrapped in braces so should objects.
Why should I use more parentheses?