top | item 9002656

Scala.js no longer experimental

337 points| densh | 11 years ago |scala-lang.org | reply

131 comments

order
[+] noelwelsh|11 years ago|reply
I was very sceptical of Scala.js, but decided to use it in a low risk project (http://github.com/underscoreio/doodle) to render to the HTML canvas and I am shocked at how well it works. The community is moving very quickly as well, and many advanced Scala projects have had the necessary tweaks applied to run in Scala.js.

Looking at broader trends, there is a clear movement towards static typing on the Javascript VM, as in-browser programs become more complicated. Google is developing SoundScript, there has been talk about gradual typing in ES7, Facebook has their type checker etc. To some extent I think adding static types to (the mess that is) Javascript is more work than may be worthwhile. I see the most practical developments in the alternative JS languages, such as Elm and Purescript, and now Scala.js, that start from a cleaner slate. The Javascript committee have done a shockingly good job making Javascript a compilation target with tail calls and so on in ES6.

[+] CCs|11 years ago|reply
I'm skeptical of any x-to-JS compiler as usually I end up debugging 2 different codes, where the second one is machine generated. After that you try to work around on the first to make the generated one do what you want.

On the other hand the Scala people know how to write compilers. We're live, in production, with Scala since 2011 and it's a joy: it actually delivers what's promised. Heard the same thing from Twitter, LinkedIn and Netflix too.

So maybe it worth a try; especially if it will integrate with ReactJs / React Native. Sounds like a match made in heaven.

[+] jbooth|11 years ago|reply
So here's my question, how come no browser has a way for a java applet to manipulate the DOM? We've got GWT compiling java to JS, we've got this compiling scala to JS.. and the JVM was originally built to run inside of a browser. Why can't we just close the circle? I guess people don't want their website visitors to see a "you must upgrade java" popup first thing?
[+] desdiv|11 years ago|reply
Google is developing SoundScript

Aren't they doing Dart as well? That has optional typing. Plus they have GWT, which is Java to JS.

Don't get me wrong, I'm super grateful to receive their fruits of labor for free, but this looks like a case of the left hand not knowing what the right hand is doing.

[+] facepalm|11 years ago|reply
There just are programmers who feel static typing is the only correct way to program. Google has always been in that camp (company wide directive, I suppose). Meanwhile, most of the internet runs on PHP.

I hope it will play out so that the statical types people can use something with statical types, and the dynamic types people can happily continue with their static types.

[+] apo|11 years ago|reply
Let's say I want to use Scala.js to build, not an application, but a JavaScript library. The library exposes a JavaScript API that JavaScript code can call. The library's objects can be used in full from JavaScript.

Can I do this with Scala.js? If so, how?

Very few, if no, *-to-JavaScript cross-compilers can do this. For example, Dart might seem to be that language, but on closer inspection, it's not. Your library is locked inside a JavaScript VM-like data structure.

Although you can get a JavaScript object out of Dart-to-JavaScript compiled library, you need to manually hook up every function in its API yourself. In other words, it's not practical to use Dart to build a JavaScript library that exposes a sophisticated JavaScript API.

Is this possible in Scala.js?

[+] euroclydon|11 years ago|reply
Are you saying that Scala.js ships with a Scala VM in JS, like EMScripten?
[+] _ea1k|11 years ago|reply
I understand why these types of compilers lack reflection support, but it still bothers me (and general makes me want to avoid them). JavaScript is naturally a very dynamic environment, and both Java and Scala have some pretty strong dynamic capabilities of their own.

But somehow when they are combined (GWT or Scala.js) you end up with something that is more static than Java or JavaScript. I know the reasons have to do with the static compilation optimization, but I still think this is a huge downside relative to languages that are designed for the browser from the start.

[+] noelwelsh|11 years ago|reply
Reflection is very much the last option when using Scala, as it breaks the ability to statically reason about code.
[+] adrusi|11 years ago|reply
I don't understand why compilers can't simply emit global variables containing structural descriptions of types. It seems like such a trivial thing to do. It would increase the size of the binary, but it would be possible to disable in projects that aren't using reflection, even automatically if the code never imports the reflection package.

Maybe someone can explain this.

[+] scorpwarp23|11 years ago|reply
That's exciting. I have worked extensively with Scala during my Master's project. What I'd really like to know is what this means in the context of the current trend of JavaScript (both client and server-side).

I'm currently working exclusively on MeteorJS, Node.JS and Angular and fail to see the relevance other than porting Scala applications to the web and making Web App development easier for developers familiar with Scala. However, without the kind of structure and inherent capabilities that a MeteorJS or DerbyJS offers, what's the USP here?

[+] brudgers|11 years ago|reply
Scala.js, Clojure.js etc. treat JavaScript as assembly language and the browser as a target architecture. It's not about porting applications. It is about accessing the same data structures and abstractions on both ends of the wire when writing code.

For languages like Scala this means things as obvious as keeping class based inheritance with traits when writing client code for the browser. Those classes can share the same hierarchy with the server side.

This means that the decisions about where to execute a feature becomes less likely to be driven by differences between client and server language features. The effort can be put into determining which execution environment better solves the problem.

[+] julius|11 years ago|reply
This sounds great. I have not really used Scala before. 3 questions:

- How good do IDEs understand Scala these days? Compared to C#/Java, where IDEs instantly know a crazy lot about your code. I am looking at features like IntelliSense, marking wrong code, marking typos, marking unused code, telling me about unhandled Exceptions etc.

- Is there any difference, on the IDE side, between Scala support and Scala.JS support?

- Is a development cycle possible, where I save and I can instantly reload the page in my browser to see the differences?

- (Bonus Question) How well does it integrate with React. If my memory is not fooling me, Scala supports something like Inline-XML. Can I write React-Code, like I write JSX code with it? Any examples?

[+] sjrd|11 years ago|reply
- IDEs for Scala are pretty good, nowadays. They do all of what you mentioned (except unhandled exceptions, because that's a Java-specific thing).

- There's no difference between Scala and Scala.js support. To your IDE, Scala.js is Just Scala.

- There is a development cycle, absolutely, and it's pretty fast! With Workbench (https://github.com/lihaoyi/workbench) you don't even need to reload the page: it does so automatically!

- For React, there is essentially scalajs-react (https://github.com/japgolly/scalajs-react). It does not support inline-XML per se, because it relies more on ScalaTags instead (https://github.com/lihaoyi/scalatags), but at some point there was a proof of concept showing it was possible to implement with macros.

[+] caente|11 years ago|reply
- How good do IDEs understand Scala these days? Compared to C#/Java, where IDEs instantly know a crazy lot about your code. I am looking at features like IntelliSense, marking wrong code, marking typos, marking unused code, telling me about unhandled Exceptions etc.

IntellIj has a very nice plug-in, it will tell you a lot about your code, including suggestions of best practices. The down side is that the more "functional" your code gets, the slower IDE becomes(that's also true for Eclipse), but chances are that when that happens, you won't care about having an IDE. So IntellIj will be great to get you started, it does help a LOT.

Is there any difference, on the IDE side, between Scala support and Scala.JS support?

Not sure about this, it seems like you can just code in IntelliJ/Eclipse, but the debugging has to happen in the browser, it does work very nicely(you debug the scala code, not the generated javascript)

I owe you the bonus question :-P

[+] the_af|11 years ago|reply
Let me contradict the other answers with my personal experience: the two IDEs for Scala I know, Scala-IDE (Eclipse based) and IntelliJ are relatively bad.

- They are very slow.

- They have poor refactoring support (Scala-IDE's support is still marked as experimental; all but the simplest refactoring will often randomly break code, either by not doing a full refactor, or by introducing gibberish).

- Until the latest version of Scala-IDE, you couldn't inspect variable contents while debugging. I can confirm the latest version does let you inspect variables, but I'm not sure how stable this is.

- This is the killer disadvantage for me: both Scala-IDE and IntelliJ give spurious compilation errors pretty often, even for relatively trivial code. I know there are valid technical reasons why this isn't solved yet, but to me it's unacceptable that an IDE for a statically typed language gives spurious compilation errors: after all, compile-time errors are the main tool a statically typed language gives us. It's the one feature that absolutely must work correctly.

- Even trivial autocomplete randomly stops working for Scala-IDE. This may be related to the spurious compilation errors.

I've been told the unofficial recommendation from the Scala community is to disable incremental compilation in the IDE and compile with SBT. Consider what this says about the maturity of current IDEs.

[+] heathermiller|11 years ago|reply
Or, said another way, Scala now officially runs on both the JVM and in the browser.
[+] tootie|11 years ago|reply
Am I correct in my inference that Scala in the browser cannot import Java classes? Meaning this isn't some backdoor to a Java-to-JavaScript compiler?
[+] scorpwarp23|11 years ago|reply
Yea. However, wouldn't you think that the current trend in JavaScript makes this a confusing endeavour in terms of what the end result really is?
[+] Taig|11 years ago|reply
The "Hello World" example yields a 3500 LOC js file. I expected a high count but that still managed to shock me. Well, I'm still pretty excited about this announcement and looking forward to give it a try.
[+] frowaway001|11 years ago|reply
The important thing is that it doesn't grow proportionally.

Adding a second line to your "Hello World" doesn't give you 7000LOC, just like using jQuery in two places instead of one doesn't automatically double jQuery's library size.

[+] kybernetikos|11 years ago|reply
> It’s mostly about the strong typing for me. Nothing revolutionary about that idea, but it’s just as true on the client as on the server: having the compiler type-check your code makes it much quicker to get complex, sophisticated systems up and running.

I used to believe that this was obviously true. Then I went from doing a lot of programming in JS where even with a large codebase, I could see the code fail in seconds to programming in Scala where type errors would not always appear in the editor, but you'd have to do a compile step that takes ages to actually see them.

Now I'm much less sure about the benefits of typing. What is actually useful is fast failure and short iteration cycles. Seeing the errors as you write is the fastest failure there is, but if I have to run a 30 second build to see a type error, that is much worse than dynamic types but seeing the error in less than a second.

Its true that carefully thought about types can catch errors you might not see immediately, but you can fix this to some extent with putting effort into making sure your code fails fast, and adding unit tests and while this doesn't give you proof-level guarantees, for most practical work, with discipline, it's good enough (even if emotionally unsatisfying).

Maybe one day I'll find a system that lets me encode constraints into the type system and have it actually tell me about violations quickly, and I'll happily leave dynamic land behind (for most things), but I've come to the conclusion that arguing about type systems misses the point, and the point is that failing fast is better than failing late. Within a single environment, failing at application startup is better than failing at an arbitrary point in the future. Failing at compile time is better than failing at startup. Failing at edit time is better than failing at compile time. But if your compile time is slower than my runtime, you're losing.

[+] frowaway001|11 years ago|reply
Error highlighting is usually instantaneous.
[+] drapper|11 years ago|reply
More and more languages have that now (F#, Ceylon, Haxe,...), I wonder how well it works in practice, especially in terms of:

- libraries availability

- code size and speed

- debugging capabilities

- ...and interoperability with JS (I recall that F# uses TypeScript definition files, that's a nice approach)

Anyone has more experience with it?

[+] sjrd|11 years ago|reply
- library availability: in Scala.js you have quite a number of core libraries available (see www.scala-js.org), but you also have direct access to JavaScript libraries

- interoperability with JS: Scala.js has its own TypeScript-like definition classes. But you can also interop in a dynamically typed way with the js.Dynamic type. In any case, the interop is very natural. Even the Scala syntax is close to JS syntax so method calls and property access just look the same.

- Code size: not exactly great, but manageable.

- Code speed: Scala.js has a very good optimizer that brings down typical macro benchmarks between 0.7x and 2x the time of the JS version (yes, 0.7x means it's actually faster!)

- Debugging capabilities: because of Source Maps, you basically step through your Scala.js code and step break points right inside your browser. All modern compile-to-JS languages have that.

[+] john2x|11 years ago|reply
Link to F#-to-JS compiler?
[+] amelius|11 years ago|reply
How about running Scala in multiple threads? And how about dealing with structurally-shared data?
[+] mercurial|11 years ago|reply
I'm curious to know the size of a scala.js hello world program.
[+] jducoeur|11 years ago|reply
As mentioned upthread, hello world isn't really representative. A more useful metric is probably what I'm doing -- a large, complex single-page business app with lots of specialized gadgetry.

Including the standard Scala.js prelude (100-200k), that currently clocks in at a bit under a megabyte. That's quite reasonable for a program of its complexity, and loads pretty fast. And once that is loaded and in the browser cache, the UI is lightning fast afterwards...

[+] sjrd|11 years ago|reply
Hello worlds are about 100 KB not gzipped, but this is not a good measurement. As your application grows, this doesn't grow as fast. Scala.js is meant for medium to large size applications anyway.
[+] ArturSoler|11 years ago|reply
Simple Scala.js JS "binaries" are quite big (from ~170kb before compression) because they add the part of the Scala standard library that they need.

From there, though, output size does not increase fast.

[+] smandou|11 years ago|reply
Traceur (ES6 compiler) itself has a runtime of several hundreds kb. Nothing you can't avoid at some point. There is an overhead for sure. But in most cases, execution time is spent in native calls (Dom rendering especially).
[+] samspot|11 years ago|reply
Mine is 20kb after google closure optimization. 139kb unminified.
[+] cmstoken|11 years ago|reply
Looks like I'm gonna have to ditch React and IO now. I think those are getting outdated. Will be rewriting all apps in Scala.js.
[+] therockhead|11 years ago|reply
How much of Scala and its APIs can be used? For example can you use Scala Actors in Scala.js?
[+] nowxue|11 years ago|reply
This is awesome, thanks to the scala.js team and community for the hard work.
[+] joajoa|11 years ago|reply
I know it's a shameless plug, but if you want to convert any Java bytecode with less semantic differences than scala.js and full reflection support you might want to give https://www.defrac.com/ a try.
[+] adrusi|11 years ago|reply
Not really the same thing, scalajs is supposedly has full compatibility with Scala, but it doesn't try to go beyond that. Its embracing JavaScript as a platform.

100% code reuse across all platforms is unachievable. What a lot of do today is complete horseshit relative to the state of the art, but different platforms have different ui conventions and following their rules can't be abstracted away into some library, obeying these conventions requires some intuition about human psychology.

By embracing the JavaScript platform, the scalajs folks are leaving the playing field open as to how to deal with multiple platforms. Maybe we can hook up scalajs to react and react native, there seems to be a bit of hype around that.

[+] wampler|11 years ago|reply
Is Scala.js recommended for small apps? Say something like Hello World?
[+] sjrd|11 years ago|reply
It's not unrecommended, but it's definitely not where it shines most. It's difficult to get below the 100 KB not gzipped size. Although if you use jQuery in your JS hello world, you also gather up 33 KB just for jQuery, so it's still the same order of magnitude.
[+] kashif|11 years ago|reply
oh god! it was fine as an experiment but...
[+] 725686|11 years ago|reply
Stop the programming language proliferation madness!