I can't say, really. I have written a lot of Javascript/Coffee/Java/Scala/C#/F#/Python/PHP, and made a bunch of crappy websites, but I have never written any code in a language that compiles to assembly (500 lines of C in 20-50 line snippets for various classes probably doesn't count).
While I consider myself "pretty experienced" at doing web-stuff, and thus knowing the pain-points and constraints and prior work, I have no clue at all what the world of C/C++ is like. Scala-Native is in that world, so someone who has a Scala + C/C++ background would have much better instincts than I would
Never used it but it seems like a plausible project; it has Google's infinite $$$ backing it and smart people like Gilad Bracha on the team. They've built up quite a lot (language, tools, package-manager, IDE, ...) from scratch which is pretty impressive.
As a language, it seems pleasant: somewhere around C#, a mix of JS and Java, less "powerful" (or less "crazy" depending on how you look at it) than Scala. I think I personally prefer Scala, but wouldn't complain too loudly if I had to use Dart/Dart instead of Javascript/PHP.
On the other hand, even with Google's backing they seem to not have managed to aggregate as much of an ecosystem in the 4 years they've been available. In particular, server-side-Dart hasn't really taken off, and client-side dart doesn't seem to be that popular compared to say Coffeescript or Typescript or even Clojurescript.
I think the advantage of Scala.js over dart is that we only need to build the JS side of things: there's already a pretty large server-side Scala ecosystem. There's already all the tooling and IDEs set up. There's already the community of people who already know Scala, and do not need to re-learn anything.
Thus even though the Dart-JS ecosystem is probably not that much smaller than the Scala-JS ecosystem, I think Scala-JS is a lot more viable and sustainable (since it can piggy-back on all the Scala-JVM stuff) while Dart-JS and many other new-language communities have a tough struggle to gain enough critical-mass to be self-sustaining
The live coding presentation is two years out of date; Scala.js now compiles to a single JS blob
Everything function marked with @JSExport will be exposed to Javascript. There's no concrete difference between an application with one `@JSExport def main` method that you call to initialize it, and a library with multiple `@JSExport`ed methods. It all works the same way: the `@JSExport`ed functions are exposed, and people can call them.
This repo shows how to make a NPM library using Scala.js
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.
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.
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?
Scala does not have non-nullable types currently (but that might happen in the future), in practice this is not a problem simply because using null is seen as a code smell and basically no Scala library API expects parameters to be null or return null, optional values are usually represented with the standard library class Option: http://www.scala-lang.org/api/2.11.8/#scala.Option
One of the main points of the blog is that Scala.js integrates well with the JavaScript apis and those apis are full of null. A typical loop in the DOM looks like this:
var node = element.firstChild;
while (node) {
// do something
node = node.nextSibling;
}
I wrote a small test function. It appears that Scala.js has no default protections against null values from the browser DOM.
def printNodes(targetNode: dom.Node): Unit = {
var c = targetNode.firstChild
while (c != null) {
if (c.nodeValue != null) {
println(c.nodeValue)
}
c = c.nextSibling
}
}
The return value from firstChild and nextSibling can be null.
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?)
'+' is just a symbol, meaning a lot of different things even in mathematics. All meaning is a product of convention.
As always: cost/benefit! There is a price for the "context switch" out of one set of conventions into another. Sometimes, the benefit far outweighs the cost. For example, there are certain environments where you can jump out of the programming language and simply write a method in SQL. Not embed SQL in code in a string, you can simply write prepared statements as a method. For certain applications, this can be beneficial.
The problem I have with operator overloading, is that it allows the average programmer to switch conventions using some of the the most commonly used conventions with barely a sign that something special is going on. It's too easy to use. It's too easy to miss. It's too easy to get a moment of confusion from it when debugging. (What, I'm in a method? Oh, operator overloading!) And it doesn't produce a great benefit all that often. Yet it has a "nifty" factor that encourages in experienced programmers to make use of it -- precisely the people who probably shouldn't be making that decision.
1. Java platform is overengineered, everytime I had to set up stuff like Maven, I missed the easy JS days.
2. True story, I can infer what a '+' between two strings means, but what about all the non-intuitive operators? (List concats etc. pp.)
3. Not a big fan of IDEs. More of an editor dev, but good to know ICs are now discuraged. I got myself "Programming in Scala" back in the days and it seemed to me, that the Scala makers thought of IC as Scalas killer feature :D
I used to only use plain editors until I started using scala, after which the benefits of an IDE became readily apparent. Unfortunately, all of the IDEs for scala are relative shit compared to their support for Java.
It would be nice to be able to run an integrated debugger (as opposed to a port connection from an SBT spawned JVM), integrate directly with SBT (as opposed to having to run it side by side), provide a full featured REPL (not the neutered version with no completion and poor editor integration), as well as functional import organization, dead code identification, refactoring suggestions, real linting, real code formatting, working extract refactorings, etc..
Well, _the_ Scala IDE currently is Scala plugin for IntelliJ IDEA (works in Community Edition, which is free and open source). All these features work there.
Enumeratee.take(4) &>> Iteratee.fold[Byte, Int](0){
case (acc, b) => acc * 256 + (b & 0xFF)
}
It's a community thing, and much like Java suffered from excessive XML and patterns in the 200Xs, but is much better now, Scala has suffered from excessive operator noise, but it's getting better.
Scala Dotty will maybe have some kind of @infix("+") def add so that if it should be used via a + b it needs the infix else it's only possible todo a.+(b)
p.s. I banned scalaz and shapeless on my company so there aren't too much operator noises.
Do you ban cats too and any library of similar ilk?
Just wondering, do you have your own libraries that use some of the good stuff? I can't imagine living in a world where I'm banned from using...
* Traverse (do you write specialized versions for the cross product of [List, Vector, etc] x [Option, Either, etc] ?)
* Validation (how do you collect errors? mutable.Buffer?)
* NonEmptyList (I've written my own NonEmptyVector that wasn't that hard to write. Do you do that or just assume nonempty and it works out for you?)
* Unapply (maybe this doesn't apply to you because you never use HKT-generic typeclasses?)
I'm genuinely curious as all of these tools get used by me and my coworkers literally every day and without them we'd be writing boilerplate or making unchecked assumptions by the seat of our pants.
* Validation? Actually we are on HTTP so mostly a sealed trait structure is enough for us we barly use `Seq(ValidationError)` from Playframework (only class constructs that manually)
* NonEmptyList - I never came across a palce where I needed NonEmptyList?!
* never needed.
Just keep in mind other languages don't have such abstractions as well (maybe haskell has, but I don't know haskell).
Some people need these high level abstractions and it's fine if you use it but most things are just syntactic sugar.
Basically we sometimes do. But all of that code is basically coming from either the database where we need to construct a list (which could be empty).
Or it's coming from the user.
I guess we have something like 30 occurences of .isEmpty/.nonEmpty in one of our codebases
I came back to the JVM many times in the past and every time it was the same. It always seemed like things changed, but the baseline complexity stayed the same.
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!
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.
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.
Scala-js is fantastic for all of the reasons mentioned in the article. It is one of those tools that has become indispensable when I write web applications. Here is a web app that I built using scala-js:
I feel like you've not seriously used each of them. Ghcjs is very interesting, but also very, very early. The ecosystem is tiny, the compiler produces huge and slow builds, the interop is tricky, the semantics imperfect. It may be a very long time before any of those are resolved, too! Compiling a lazy language to Javascript is no simple trick. Luite deserves all the praise in the world for getting it this far... but there's just a long way to go.
So, in the terms of this article, Ghcjs might be around the same place Scala.js was 2 years ago. In the mean time, Scala.js has taken off in a lot of ways. It's yet to be seen what will happen with Ghcjs.
Your hunch is correct, I have not really used either, I'm just generally interested. From a distance, they both appeared to be ambitious and somewhat immature. I'm curious about your comment regarding tricky interop and "imperfect semantics" of ghcjs, could you elaborate? Certainly laziness does make FFI harder, but I wouldn't call that a problem with the semantics.
Laziness doesn't just make FFI harder (although it does do that too) it also makes code generation harder and implies the need for a sophisticated runtime. All of this makes the generated code bigger, slower, and more opaque.
A strict language can just skip all of that so long as it's willing to live within the limitations of the Javascript model. Scala.js does that for the most part and ends up with both nice FFI and a minimal runtime.
I don't see being strict or lazy as being the main source of the size of the deployed code (especially as Ghcjs inherits an excellent strictness analyser from GHC). Scalajs would have to emulate many JVM characteristics and port many JDK classes. Then you have huge core Scala libraries like collections, which are far larger and more complex than the Haskell equivalents. You will have to back up your argument with numbers to convince me.
You also haven't elaborated on your comment about "imperfect semantics".
The main difference is that Scala.js people sat down and did all the painstaking work, while Haskell devs spent the time talking how intellectually superior the are and got nothing done.
> Haskell devs spent the time talking how intellectually superior the are and got nothing done.
I could give a recap of Haskell development that's happened while Scala.js has been developed to debunk this silly accusation, but it wouldn't change your mind.
Well, Scala.js went from not existing to rock solid in 3 years. The various Haskell-to-JS efforts existed much longer, but none have the support, completeness and maturity of Scala.js.
That is down to who has the most funding. Javascript itself has even more "support, completeness and maturity" than Scalajs. But obviously that's not the deciding factor.
Scala.js was largely done by a single student on top of his other university duties.
I think it's mostly down to determination. Some things are hard, but need to be done.
Haskell people just seem to give up more easily - see all the half-working projects. Nobody finishes stuff, the next dev just starts his own new project, and abandons it later.
Scala.js handily beats JavaScript in terms of IDE support and tooling
That's nonsense. I think it's great that outside contributions (like allowing the use of the Scala's CI infrastructure) are valued, but the actual commits show a clear picture.
There is no determination in failing to get anything done and doing NIH for a decade.
I'm not really interested in putting in the effort to convince you. This opinion arises from conversation I've had with users of ghcjs, developers of ghcjs, and people very familiar with GHC compilation pipeline details and runtime details.
The last I heard, the primary dev of ghcjs intended to build a new codegen which would alleviate some of the issues here, but that hasn't happened yet to my knowledge.
The comment about imperfect semantics arises from a few weirdnesses around JS interaction with laziness. Perhaps the biggest one I remember is that when calling Haskell from JS you have to be prepared for the idea that results may not be fully evaluated. There wasn't any real mechanism to force and block on the Javascript side and certainly no mechanism to handle it asynchronously (promises wouldn't work unless they decorated inner layers of a data types which would be terrible).
This also plays out on the Haskell side in terms of managing retention strategies.
In a strict language both of these obviously just vanish.
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.
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.
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
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
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.
It wasn't mentioned as a criterion, and OpalRuby, Python variants, and Coffeescript all got significant discussion in the article. The ClojureScript omission on all the axes other than "superficial similarity to JavaScript" is still pretty glaring.
It was mentioned as a criterion. Actually, multiple:
- "Perfect IDE support" when described hinges on types
- "Static Optimizability" specifically mentions enjoying
type-driven AOT optimizations
- "Solving Real Problems" mentions types in the
"Refactoring is Painful", "'Non-trivial' abstractions",
and, briefly, in "Scala.js Solves Real Problems"
Furthermore, all of OpalRuby, Python, and CoffeeScript were explicitly dinged on their failures to have statically analyzed types.
But yeah, it does feel like he didn't give ClojureScript as much examination.
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."]])
The point wasn't to show how to build HTML fragments, the point was to show javascript interop.
You could create a nice wrapper-library around anything in any-language, really, but that misses the entire point of that example: to show how interoperability is when you haven't wrapped a nice wrapper-library around everything.
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.
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)
89 comments
[ 2.5 ms ] story [ 157 ms ] threadCompiling _entire Scala_ to JavaScript? Without runtime?! To the point of compatibility that Scalaz can be compiled, with all its horrors?!! Wow.
On the other hand Dotty has a lot of very, very concrete benefits I would like. 2x faster compile times for my Scala code sure would be nice...
While I consider myself "pretty experienced" at doing web-stuff, and thus knowing the pain-points and constraints and prior work, I have no clue at all what the world of C/C++ is like. Scala-Native is in that world, so someone who has a Scala + C/C++ background would have much better instincts than I would
As a language, it seems pleasant: somewhere around C#, a mix of JS and Java, less "powerful" (or less "crazy" depending on how you look at it) than Scala. I think I personally prefer Scala, but wouldn't complain too loudly if I had to use Dart/Dart instead of Javascript/PHP.
On the other hand, even with Google's backing they seem to not have managed to aggregate as much of an ecosystem in the 4 years they've been available. In particular, server-side-Dart hasn't really taken off, and client-side dart doesn't seem to be that popular compared to say Coffeescript or Typescript or even Clojurescript.
I think the advantage of Scala.js over dart is that we only need to build the JS side of things: there's already a pretty large server-side Scala ecosystem. There's already all the tooling and IDEs set up. There's already the community of people who already know Scala, and do not need to re-learn anything.
Thus even though the Dart-JS ecosystem is probably not that much smaller than the Scala-JS ecosystem, I think Scala-JS is a lot more viable and sustainable (since it can piggy-back on all the Scala-JVM stuff) while Dart-JS and many other new-language communities have a tough struggle to gain enough critical-mass to be self-sustaining
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?
Everything function marked with @JSExport will be exposed to Javascript. There's no concrete difference between an application with one `@JSExport def main` method that you call to initialize it, and a library with multiple `@JSExport`ed methods. It all works the same way: the `@JSExport`ed functions are exposed, and people can call them.
This repo shows how to make a NPM library using Scala.js
- https://github.com/rockymadden/scala-node/
If you want to learn how to use `@JSExport` properly, the [core documentation](http://www.scala-js.org/tutorial/basic/) and [Hands-on Scala.js](http://www.lihaoyi.com/hands-on-scala-js/) are great.
Even when it's targeted at the JVM. Scala.JS usage isn't that hard after you read half of the book.
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?
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 ;))
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?)
As always: cost/benefit! There is a price for the "context switch" out of one set of conventions into another. Sometimes, the benefit far outweighs the cost. For example, there are certain environments where you can jump out of the programming language and simply write a method in SQL. Not embed SQL in code in a string, you can simply write prepared statements as a method. For certain applications, this can be beneficial.
The problem I have with operator overloading, is that it allows the average programmer to switch conventions using some of the the most commonly used conventions with barely a sign that something special is going on. It's too easy to use. It's too easy to miss. It's too easy to get a moment of confusion from it when debugging. (What, I'm in a method? Oh, operator overloading!) And it doesn't produce a great benefit all that often. Yet it has a "nifty" factor that encourages in experienced programmers to make use of it -- precisely the people who probably shouldn't be making that decision.
1. Java platform is overengineered, everytime I had to set up stuff like Maven, I missed the easy JS days.
2. True story, I can infer what a '+' between two strings means, but what about all the non-intuitive operators? (List concats etc. pp.)
3. Not a big fan of IDEs. More of an editor dev, but good to know ICs are now discuraged. I got myself "Programming in Scala" back in the days and it seemed to me, that the Scala makers thought of IC as Scalas killer feature :D
It would be nice to be able to run an integrated debugger (as opposed to a port connection from an SBT spawned JVM), integrate directly with SBT (as opposed to having to run it side by side), provide a full featured REPL (not the neutered version with no completion and poor editor integration), as well as functional import organization, dead code identification, refactoring suggestions, real linting, real code formatting, working extract refactorings, etc..
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.
On Java: I think you get the point..p.s. I banned scalaz and shapeless on my company so there aren't too much operator noises.
Just wondering, do you have your own libraries that use some of the good stuff? I can't imagine living in a world where I'm banned from using...
* Traverse (do you write specialized versions for the cross product of [List, Vector, etc] x [Option, Either, etc] ?)
* Validation (how do you collect errors? mutable.Buffer?)
* NonEmptyList (I've written my own NonEmptyVector that wasn't that hard to write. Do you do that or just assume nonempty and it works out for you?)
* Unapply (maybe this doesn't apply to you because you never use HKT-generic typeclasses?)
I'm genuinely curious as all of these tools get used by me and my coworkers literally every day and without them we'd be writing boilerplate or making unchecked assumptions by the seat of our pants.
* Validation? Actually we are on HTTP so mostly a sealed trait structure is enough for us we barly use `Seq(ValidationError)` from Playframework (only class constructs that manually)
* NonEmptyList - I never came across a palce where I needed NonEmptyList?!
* never needed.
Just keep in mind other languages don't have such abstractions as well (maybe haskell has, but I don't know haskell). Some people need these high level abstractions and it's fine if you use it but most things are just syntactic sugar.
The only stupid thing is something like that:
- Future[Option[A1]] - Future[Option[A2]] ... - Future[Option[AN]]
and now I need a `case Some((a1, a2)) =>` without some magic you write a lot of boilerplate.
So a Monad is really something that would be great and probably we will evaluate if we get to use cats.
Edit: Code Snippet:
yes this is something why we consider cats.Do you ever check the length of a list before applying a computation or dispatch based on a result list?
I guess we have something like 30 occurences of .isEmpty/.nonEmpty in one of our codebases
I came back to the JVM many times in the past and every time it was the same. It always seemed like things changed, but the baseline complexity stayed the same.
The underlying notion of Scala to X ie Scala Native has lots of potential but Scalajs is more of a segue.
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.
http://experimental.worldcat.org/vandrmapping
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.
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.
So, in the terms of this article, Ghcjs might be around the same place Scala.js was 2 years ago. In the mean time, Scala.js has taken off in a lot of ways. It's yet to be seen what will happen with Ghcjs.
A strict language can just skip all of that so long as it's willing to live within the limitations of the Javascript model. Scala.js does that for the most part and ends up with both nice FFI and a minimal runtime.
I could give a recap of Haskell development that's happened while Scala.js has been developed to debunk this silly accusation, but it wouldn't change your mind.
I think it's mostly down to determination. Some things are hard, but need to be done.
Haskell people just seem to give up more easily - see all the half-working projects. Nobody finishes stuff, the next dev just starts his own new project, and abandons it later.
Scala.js handily beats JavaScript in terms of IDE support and tooling
The Haskell community has achieved great things even though most contributions are done in people's spare time. That is determination.
There is no determination in failing to get anything done and doing NIH for a decade.
The last I heard, the primary dev of ghcjs intended to build a new codegen which would alleviate some of the issues here, but that hasn't happened yet to my knowledge.
The comment about imperfect semantics arises from a few weirdnesses around JS interaction with laziness. Perhaps the biggest one I remember is that when calling Haskell from JS you have to be prepared for the idea that results may not be fully evaluated. There wasn't any real mechanism to force and block on the Javascript side and certainly no mechanism to handle it asynchronously (promises wouldn't work unless they decorated inner layers of a data types which would be terrible).
This also plays out on the Haskell side in terms of managing retention strategies.
In a strict language both of these obviously just vanish.
[1] http://www.navision-blog.de/blog/2016/08/06/fable-react-nati...
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.
I know you can use asm.js but it looks like they're not using asm.js
>It gets compiled to vanilla JS
thanks
> 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.
But yeah, it does feel like he didn't give ClojureScript as much examination.
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:
You could create a nice wrapper-library around anything in any-language, really, but that misses the entire point of that example: to show how interoperability is when you haven't wrapped a nice wrapper-library around everything.
The real reason is that this 24-page heavily-researched blog post is already too damn long lol
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)