When comparing CoffeeScript vs Scala.js, the Slant community recommends CoffeeScript for most people. In the question“What are the best languages that compile to JavaScript? ” CoffeeScript is ranked 9th while Scala.js is ranked 12th. The most important reason people chose CoffeeScript is:
With CoffeeScript, there's never really a question of what is going on. If you're worried that something went wrong in the compilation process, the output is very human readable and mostly 1 to 1 with the CoffeeScript code, making debugging easier as the code that is being executed by the interpreter can be double checked.
Specs
Ranked in these QuestionsQuestion Ranking
Pros
Pro Compiles to readable Javascript
With CoffeeScript, there's never really a question of what is going on. If you're worried that something went wrong in the compilation process, the output is very human readable and mostly 1 to 1 with the CoffeeScript code, making debugging easier as the code that is being executed by the interpreter can be double checked.
Pro Widely used
CoffeeScript is the most popular of the compile to Javascript languages, so long term support is much less of a worry than with others.
It also means there are many plugins and tools for integrating it into many different build systems, giving it it nearly universal support.
Pro Lightweight syntax
Javascript is a very verbose language so CoffeeScript's goal is to lighten it to make it less tedious.
Various design choices are built around making CoffeeScript more terse with things like optional parenthesis in function calls, cleaner function declarations, no curly braces, and significant white space. Because Javascript can get pretty deeply nested at times, having a lightweight syntax helps with readability.
The result is a language with a minimalistic syntax with lots of syntax sugar.
Pro It's just JavaScript
The golden rule of CoffeeScript is: "It's just JavaScript". The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa). The compiled output is readable and pretty-printed, passes through JavaScript Lint without warnings, will work in every JavaScript runtime, and tends to run as fast or faster than the equivalent handwritten JavaScript.
Pro Syntax for humans, not compilers.
CoffeeScript adds syntax that is not only more terse than javascript, smoothing over the rough edges, but also enforces a more human readable syntax to the point where a non-programmer can understand some logic.
Many programmers that are not use to coffeescripts syntax will find it foreign if they don't read the single page API, but generally it is quick to understand and although self documenting code is a myth coffeescript is definitely very close.
if hungry then eat food for food in fridge when food isnt poison and it isnt bedtime
Seems a lot more concise and comprehensible to many programmers and most others than the alternative syntax:
var food, i, len;
if (hungry) {
for (i = 0, len = fridge.length; i < len; i++) {
food = fridge[i];
if (food !== poison && it !== bedtime) {
eat(food);
}
}
}
Pro Function syntax is great for callbacks
Passing functions as callbacks is central to how Javascript is written, but the default syntax for functions is very verbose and hard to read. Various CoffeeScript syntax decisions help with ease of writing and reading functions.
The most obvious change is that the function keyword is changed from function
to ->
. Writing out the word function
is very clunky especially when you need to use multiple nested functions.
One of the more opinionated choices of CoffeeScript is the use of significant whitespace, and optional parens around function arguments. While this can be used poorly, it can also be used to great effect with nested functions. For example, a function that takes an object that defines anonymous functions will end in a mess of parens and curly braces:
asyncAction({
success: function(data){ /* handle data */ },
error: function(error){ /* handle errors */ }
});
In CoffeeScript you could rewrite this as:
asyncAction
success: (data) -> /* handle data */
fail: (error) -> /* handle errors */
Other helpful features are automatic returning of the last statement to make short anonymous functions easier so (a, b) -> a+b
would replace function (a, b) { return a+b; }
, as well as binding functions to the current context object with =>
.
Pro Splats
Because Javascript functions can take variable amounts of parameters, it is helpful to be able to use splats to extract an array of arguments in a function.
For example, if you have a function like: (a, b, rest...) ->
any amount of parameters sent to the function after a
, b
will be stored in an array in the variable rest
. You can also put splats at the start or middle of the arguments list, such as (a, middle..., b) ->
.
When calling a function you can use a splat to apply an array as arguments as well.
Pro Everything is an expression
Even for
loops and if
statements. For example, to get mapped array, you don't have to use any Array methods, just the language features:food = ( stuff for stuff in fridge when stuff.isEatable() )
Pro Familiar to Ruby programmers
CoffeeScript was created by a Ruby programmer and a number of syntax features are modelled on Ruby equivalents, so will be familiar to Ruby programmers. For example, implicit returns, i.e. the last variable of each function is implicitly returned, so "return" keyword need not be present.
Pro Extremely easy to document with literate coffeescript
Skip the documentation build, just write documentation with literate CoffeeScript.
CoffeeScript has a literate mode which let's you use markdown (used by almost everything, such as reddit, github, stack exchange, etc) with code indented how you would normally in markdown and simply enables you to run the code.
This enables you to quickly write FORMATTED, custom documentation that's easily displayed with no build step for the documentation.
Pro Source maps allow you to debug code in CoffeeScript
With source maps, you can get the proper location of where an error occurred directly in precompiled code, making it easier to debug without the tedious step of translating the compiled code back to the original code in your head.
Pro Significant whitespace
Having indention-based code blocks is particularly helpful in JavaScript because of its functional callback based nature. In JavaScript you find yourself writing functions within object and passing functions to functions. You can find statements ending with a confusing melange of braces like )}})})
. With significant whitespace, most of the needs for braces go away.
Pro Default choice for Ruby on Rails
Pro Maintainable code
Easy to read and easy to work with structures like list.
Pro Type inference
Scala offers type inference, which, while giving the same safety as Java's type system, allows programmers to focus on the code itself, rather than on updating type annotations.
Pro Implements a mature language
In contrast to other options, Scala.js is a compiler plugin for an already existing and mature language: Scala.
As such, it benefits automatically from the existing compiler, from the language design choices made for Scala, which exists and is established in the industry since years.
Pro Easy, type-safe, interop with JavaScript
The JavaScript-interop of Scala.js is very direct and lightweight.
Pro The strength of Scala on the server
The strength of Scala (JVM) on the server can not be underestimated, and is probably superior to any other choice listed here (where applicable; many have no server-side equivalent).
Being able to use such a powerful language (and ecosystem) on the server AND on the client, and sharing code between the two, is a big advantage.
Pro Extensive standard libraries
Scala.js implements most of the Scala standard library and many parts of the Java one. Among others, it supports Scala's rich collection library.
Pro Dead-code elimination
Scala.js performs dead-code elimination out of the box (when running in the "fullOpts" mode).
Pro Multiparadigm
Scala supports both Functional and Object Oriented styles of programming. Beginners can learn both paradigms without having to learn a new language, and experts can switch between the two according to what best suits their needs at the time.
Pro Crossbuilding
Keeps your client and server sources in sync.
Pro Incremental compilation
Through SBT, Scala.js supports incremental compilation out of the box. That is: SBT automatically picks-up the changes (think "watch" in other tools) and only recompiles what is needed.
This makes the development cycle fast and very pleasant to work with.
Pro Excellent tooling (IDE) support
The same good and mature tooling that can be used for Scala can be used for Scala.js out of the box (code-completion, refactoring, immediate feedback, etc.).
Pro Immutable values
The immutable values make it perfect for working with concurrency.
Pro Macros
Because Scala.js is a plugin to the Scala compiler, the whole power of the Scala language is available at compile-time. Which includes macros. Very expressive things can be done, in a type-safe way, which are difficult or impossible in other languages.
Pro Simple build system compared to Javascript
While SBT is arguably not as simple as Maven, it beats the chaos of the JavaScript build ecosystem.
Cons
Con Terse syntax can lead to ambiguity
It can sometimes be hard to be sure of what CoffeeScript will compile down to because of the optional parentheses and significant white spacing. Over multiple lines the same statement can be written in many different ways, and it's not always clear what the intended interpretation is.
For example:foo bar and hello world
can compile to either:
foo(bar) && hello(world)
foo(bar && hello(world))
Con Initializing a variable and assigning it are essentially the same thing
Because of how variables are initialized and reassigned in CoffeeScript, it becomes very easy to accidentally overwrite a variable as the codebase increases. As complexity increases, the only way to safely create a variable is by pressing Ctrl + F and by examining the current file to ensure that there's no conflict.
Con Last expression is returned by default
While this is a pro for small functions, it requires self-discipline to check if unnecessary overheads are introduced:
eat_full = ->
for food in fridge
break if full
cook food if food.requires_cooking()
eat food
This will return array of eat
function results. Can be fixed by adding empty return
at the end.
Con Can be intimidating for beginners
Scala is an industrial language. It brings functional programming to the JVM. All books/tutorials cover friendly aspects of Scala, but there are corners of the language that one can wander into that are not friendly to beginners.
Con A complex language with a lot of incidental complexity that results in significant mental overhead
Con Combines OOP and functional programming for a hodge-podge paradigm
Its excellent mix of functional and OOP programming just like Python to use the tool best suited