top | item 12262073

From first principles: Why I bet on Scala.js

106 points| lihaoyi | 9 years ago |lihaoyi.com | reply

87 comments

order
[+] virtualwhys|9 years ago|reply
Article is a total tour de force.

The OP has contributed so much to the Scala community; somehow he's a Python + Coffeescript developer by day, and an absurdly prolific Scala library author in the evenings.

As for Scala.js, representing browser interactions in types is such a relief, and to have the entire Scala language available is almost too good to be true: client-server interop is seamless.

Really the only negative for me is the Scala collections library. Of the @100KB Hello World[1] generated blob half of that is Scala collections. There's a small initial "tax" to pay basically, and thereafter size increase is on par with normal javascript.

[1] not totally true, vanilla Hello World is more like 40KB, but once you define a Scala collection then generated blob doubles in size.

[+] hongboz|9 years ago|reply
For people who want to do typed functional programming on JS platform, there is another candidate: BuckleScript for OCaml: https://bloomberg.github.io/bucklescript/js-demo/

The compiler is compiled into JS and native code.

It generates highly readable JS code and easier FFI.

It compiles super fast (generally 10~100 faster than Scala) and generates optimized code.

[+] querulous|9 years ago|reply
there's also elm and purescript, both of which are haskell likes
[+] lihaoyi|9 years ago|reply
I wrote this; ask me anything
[+] atemerev|9 years ago|reply
Scala.js is magic under magic sauce with magical cherry on top of it. Thank you and everyone else involved!

Compiling _entire Scala_ to JavaScript? Without runtime?! To the point of compatibility that Scalaz can be compiled, with all its horrors?!! Wow.

[+] apo|9 years ago|reply
Amazing work - thanks for putting it out there.

In your live coding presentation, you mentioned that the output from compiling scala to js is several files.

I'm interested in generating one file that exposed JavaScript functions that can be easily called from a js runtime.

In other words, I'd like to write a JavaScript library in Scala - not a full-blown application.

What are some good resources showing how to do this?

[+] oever|9 years ago|reply
Closure Compiler uses type annotations on variables and functions that give information on null and undefined. These annotations look like {?Object|undefined} (Object may be null or undefined) and {!Object} (object is guaranteed to not be null).

In Java, NullPointerExceptions is huge problem. IDEs have plugins to check for this error, but there is no standard solution.

Does Scala help in avoiding NullPointerExceptions? Do function signatures specify if a value may be null?

[+] curious2learn|9 years ago|reply
Which resources (books/tutorials) do you recommend for learning Scala.js for someone who does not know Scala or Java or any JVM language, but knows a decent amount of Python, Julia, Go, Javascript, Dart etc. I should add that I am not interested in JVM (at least, now). I want to know what are good resources if one intends to use Scala only for the JS side of things.
[+] edko|9 years ago|reply
Would you bet as much on Scala Native?
[+] saosebastiao|9 years ago|reply
No questions, just praise. I love your scala work, and would love to take my company far enough to be able to approach you to work full time writing scala.
[+] nilknarf|9 years ago|reply
Great post! Just curious, why didn't you include emscripten (C/C++) in your comparisons?
[+] labrador|9 years ago|reply
What do you think of Dart? I need to know this for reasons I can't go into.
[+] bcherny|9 years ago|reply
What do you think of using Dotty's effect system for frontend code?
[+] weego|9 years ago|reply
I've backed the current iteration of my career on Scala and like the idea and some of the practicalities of Scalajs but it is destined to be limited to fun projects. The unavoidable problem is by committing to Scalajs you are accepting that you can no longer go out and get one of any number of JavaScript contractors or staffers to come on board and develop / maintain you client code and have to always have a Scala developer for that job as well which is a magnitude of time and expense different.

The underlying notion of Scala to X ie Scala Native has lots of potential but Scalajs is more of a segue.

[+] JohnnyConatus|9 years ago|reply
Seconded. I love Scala but when I hire for Scala devs there are so few that I just hire the smartest developer I can find with FP experience and their first task is learning Scala.

If I was starting something now I'd be tempted to use TypeScript if I wanted one language on the front-end and the back-end.

[+] cromwellian|9 years ago|reply
The comments on jsinterop with respect to GWT are stale, GWT has a rich non-JSNI based JsInterop system now, as well as a generator that can read Closure and Typescript files and produce typed Java interfaces and classes for calling external JS. It even converts Java8 lambdas directly into JS functions and the reverse.

Also, the design restrictions to ban runtime reflection in GWT are a codesize decision. Allowing reflective calls basically inhibits optimization and forces the retention of tons of metadata.

The Deferred Binding mechanism is essentially dependency injection before DI and annotation processing existed, because GWT hails from 2007. We now recommend using Dagger2 for DI, and Annotation Processors for code generators, so that the system of compile time reflective calls is all part of the standard tool chain.

In the era of mobile browsers, I think 100k is a bridge too far for a hello world, especially in the developing world, so restrictions to the JRE runtime which allow much greater code pruning are a necessary evil. It hasn't really prevented an enormous amount of code sharing.

For example, Google Inbox shares 70% of its Java code between Web, Android, and iOS (via J2Objc)

[+] CuriouslyC|9 years ago|reply
Scala is a cool language, but I can't help feeling that Javascript has a very strong culture around it that pretty much dooms adoption of things that don't feel "Javascript-y". I think the strong commitment to being a Javascript superset is the reason Typescript is blowing up the way it is.
[+] smrtinsert|9 years ago|reply
absolutely agree. they nailed it by repurposing any js dev as a potential ts user. part of the reason ill be pushing ts soon at my current position.
[+] k__|9 years ago|reply
3 things I don't like about Scala:

1. It's based on the Java platform.

2. It's excessive use of operator overloading.

3. Mad implicit conversions all over the place.

(yes, I exaggrated a bit ;))

[+] atemerev|9 years ago|reply
1. Java platform is excellent. Also, Scala.js is now Scala for JS platform, and scala-native is coming soon.

2. Have you seen languages like APL or J? Now that's operator overloading. '+' is just a symbol, meaning a lot of different things even in mathematics. All meaning is a product of convention.

3. In modern Scala, implicit _conversions_ are discouraged unless you know what are you doing. Besides, Scala IDEs are excellent in showing applied implicits anywhere in the code (you do use an IDE, right?)

[+] merb|9 years ago|reply
> 2. It's excessive use of operator overloading.

Overloading at least some could be useful. Java 10+ will probably allow something like this, too. You ever worked with BigDecimal?

In Python, Scala where + (__add__) is overloadable you do.

    BigDecimal(1) + BigDecimal(2) + BigDecimal(3)
On Java:

    (new BigDecimal(1).append(new BigDecimal(2)).append(new BigDecimal(3)
I think you get the point..
[+] premium-concern|9 years ago|reply
Roughly none of those points are true (anymore).
[+] grok2|9 years ago|reply
The author explains his reasoning for using Scala.js well and what he says makes me tempted to learn Scala as the "language-to-rule-them-all"!
[+] eggy|9 years ago|reply
Very nice article. I am itching to play around with Scala.js because of it.

I had chosen Purescript over Elm, since I have read about Elm being constricting once you move outside of most of the examples use cases.

[+] s_m|9 years ago|reply
Great article. I'm not a particularly sophisticated Scala user but I love using Scala.js for all the reasons described in this piece. Thanks for all your work on it!
[+] lihaoyi|9 years ago|reply
For all the people asking "Why didn't I talk about X"...

The real reason is that this 24-page heavily-researched blog post is already too damn long lol

[+] stijlist|9 years ago|reply
It's a little strange that ClojureScript is omitted from the sections where it compares favorably to Scala.js, e.g.:

> If you look at other compile-to-JS languages like:

> - Google Web Toolkit which lets you compile Java to Javascript, > - The Opal Ruby Compiler for Ruby > - Brython, PyJS, Skulpt, Transcrypt or RapydScript for Python > - Various flavors of C#-to-Javascript (Salterelle, Bridge.Net, JSIL) > - Or Haskell-to-Javascript compilers (Haste, Faye) > You'll notice one thing in common: none of them have a standard way of writing code that runs on both their "original" runtime (JVM, MRI, CPython, CLI, ...) and on Javascript. And the reason why is straightforward: none of them are compatible enough, complete enough to really let you write "full" Java/Ruby/Python/C#/etc..

ClojureScript is mentioned in the article, but only for this specious comparison:

> Clunky Interop > Many other languages are not as fortunate. For example, here's how you create an element in ClojureScript, compared with Javascript

(let [paragraph (.createElement js/document "p")] (set! (. paragraph -innerHTML) "<b>Bold!</b>"))

var paragraph = document.createElement("p") paragraph.innerHTML = "<strong>It works!</strong>"

> Now, the conversion between these two snippets is mechanical, so it's not something you need a PhD to perform. Nevertheless, it is clear that using Javascript APIs in ClojureScript, while looking like ClojureScript, looks almost nothing like the Javascript it represents.

> This mapping is something that everyone who wishes to learn Clojurescript will have to internalize.

This seems misinformed at best - both Clojure and ClojureScript have interop as a first-class concern, and interop forms are exactly the same between them.

I appreciate the work that Li's done, but I'm disappointed by what seems like a rather disingenuous omission of the only other language which fulfills Li's criteria.

Interop, IDE support (IntelliJ), parent language compatibility, static optimization (judging by the payload size numbers, ClojureScript utilizes dead-code elimination more effectively than Scala.js), performance (ClojureScript immutable vectors are faster to build than JavaScript arrays, far from the 1-2x Scala.js slowdown cited in the article!) - there is (and has been - since 2011) a compile-to-JavaScript language that is in the same league as Scala.js, and arguably eclipses it on many dimensions.

A language-agnostic comparison can't reasonably leave out ClojureScript.

[+] methehack|9 years ago|reply
I'm glad you pointed this out. That's way mal-informed for how you'd build that DOM in clojurescript. I mean, you _could_ do it that way, but there are libraries (like hiccup) that make it more natural.

Here's an example of a react component from the re-agent tutorial (http://reagent-project.github.io/), e.g., but you'd build straight html in the same-ish way using a library:

  (defn simple-component []
    [:div
      [:p "I am a component!"]
      [:p.someclass
        "I have " [:strong "bold"]
        [:span {:style {:color "red"}} " and red "] "text."]])
[+] tel|9 years ago|reply
Except for: types. That's a big deal about what the author liked about Scala.js.
[+] saskurambo|9 years ago|reply
Also haxe have nice features like scala.js bu have a c like syntax conservative and is more practical. Big interaction with externs js with external types definition, dynamics and untyped blocks. And can interact with npm, webpack, closure and browserify. Js code generated is really small
[+] dk8996|9 years ago|reply
This is such a cool tool, being a Scala developer and not really loving writing JavaScript. The only thing is that creating binding for JavaScript lib sounds like a bit of a pain.