46 comments

[ 0.24 ms ] story [ 63.6 ms ] thread
I'm not terribly convinced by these things that compile to javascript. I don't much care for javascript, but I'd rather take the bull by the horns than deal with a bunch of generated code, especially in any kind of commercial setting where it's going to be a lot easier to hire JS people rather than people who are both X-lang and JS experts.

That said, it's very much a cool hack, and worth doing on that basis alone.

I'm inclined to agree. I'm not one of those Javascript bashers. It's a handy enough language and tweaking/hacking/breaking JS enabled webpages is the way a lot of us amateur coders dip a toe in the water.

Unfortunately I think JS is having a lot of responsibility heaped on its slightly creaky shoulders these days, due to the growth in mobile intarwebsing and every man and his dog looking for a quick way to build the app that is going to bring them fame and fortune. As a result of this, we're seeing a lot of these frameworks which compile [arguably!] 'better' fuller-featured languages down into JS.

Personally I'd rather a scenario where people could code in <insert language of choice> and embed this in HTML as easily and ubiquitously as JS can be embedded. A bit of a pipe-dream I know, but wouldn't it be great if we could exploit the cross-platform accessibility of web apps, without having to turn everyone into a Javascript hacker?

> Personally I'd rather a scenario where people could code in <insert language of choice> and embed this in HTML as easily and ubiquitously as JS can be embedded.

That would indeed be amazing. Anyone want to build it? :P

How is assembly going for you? What is fundamental to the web is the APIs (dom/websockets/webgl/...) not the fact that they are exposed through javascript. Dart seems especially nice considering that they go out of their way to provide (most?) html5 apis in dart and also Angular.

In fact the dom is defined in an IDL which can generate the dom API not only in javascript but a lot of other languages (Java/C++/etc)

Javascript isn't really comparable to Assembly though, is it?
No, it's really not.

This is an argument that tries to emotionally justify the limitations of web browsers that force us to compile down alternative languages into web "assembly".

He still have point,what matters is the APIs you have access to,not coding in language X or Y,especially when your goal is not to develop "web pages" but web apps that arent "brochures".
One big problem with this is that you still end up having to use raw JS anyway. Debugging is usually a big hassle too.
He may add source maps and debugging will not be cumbersome. Handling Coffeescript is not difficult if you can jump and add breakpoints in your browser over the original code.
in Coffeescript you don't have to `...` jump to raw javascript every couple lines
Opal creator here. Debugging in Opal is no problem at all with source maps. I only need to look at generated code when Im working on improving the compiler/fixing bugs. Developing end apps always results in using the chrome debugger stepping through source-mapped code.

About the raw JS, to use my current app as an example, I have one line of inline JS (using `...` notation) which is just to initialize FastClick. Writing a ruby wrapper wasn't worth it for one method call. Anytime I see more then 1 line of inline JS inside a file, a ruby wrapper ends up being a much better idea, or indeed using the `Native` class which handles all the corner issues of calling native JS libs.

I think the problem with Opal is the documentation, which needs huge improvements, to show the proper/realistic development experience with it.

What kind of client side coding are you using it for?
Various projects. Two recent ones are a POS system running on the iPad. The app is wrapped using Cordova for native scanner/receipt printer access, but the rest is built in Opal with a Sinatra backend. So lots of client models, lots of UI rendering using our opal-haml integration. Considering the POS system is dealing with thousands of product lines, performance on the iPad is great. Also, testing using rspec for all the opal client side code as the models are shared on the backend. Testing the same code using the same specs on both client and server is really nice, and saves a huge amount of duplication. It all comes from some extensions to Vienna which treats the opal stuff as a view layer replacement. Hoping to blog most of it soon, including the Cordova integration.
Yeah, debugging in opal is really nice actually from what we've seen.
If one needs to write code like:

    `#{context}.lineTo(#{x}, #{height})`
...you're doing it wrong. Please do figure out a way to "automagically" make things work without `...` or just don't bother.

`...` should be a last resort option for when you just need to do something that can't be done any other way, not something that should be peppered over the entire code.

Could you explain what is so offensive about using `...` here?
In 48 lines of code, he has 12 lines where he's evaluating JavaScript between backticks (and not all those 48 lines are significant). If you're having to do that much evaluation of raw JavaScript, then what is the point of using a compile-to-JS language at all?

With CoffeeScript, I think I've "had" to use backticks all of about twice (I probably didn't actually have to, but it seemed easier at the time - I don't remember the exact circumstances).

Also, as others have said, the JavaScript that this outputs is a real mess (in comparison with, say, CoffeeScript).

I wouldn't mind the outputed javascript - it's unfair to compare it with coffeescript as cs is just a thin syntax layer whereas opal giver you all the goodies of rubyan oop (like, method_missing? :) ), so there is a price that needs to be paid for this. But having to drop to raw js everywhere kind of nulls the advantage. Just think of all the errors that a linter or parser could have caught, but now it can't, and on top of this add it to the inherent pain of debugging a transcompiled language and... not fun :| I liked the idea of ruby to js but this doesn't seem like an acceptable solution.
Yea. They have a canvas wrapper that this guy did not use so you don't have to do that. With that being said, this project https://github.com/rubys/ruby2js is more appealing to me. Sure it doesn't pass more RubySpec tests than Rubinius like Opal does, but it works.

The Angular interoperability is especially appealing to me. It also generates readable javascript.

You have to drop down to JavaScript at some point, though in practice you would not write this much JavaScript mixed with Ruby in an app. The joy of using Opal is having the JavaScript wrapped away in a module, letting you use pure Ruby for your app.

The author used a lot of JavaScript here, likely for teaching purposes, but he could instead have used pure Ruby to interface with canvas using opal-browser. https://github.com/opal/opal-browser/blob/master/opal/browse...

The example in this post is definitely a bad example of inline js in Opal. This is better handled by the `Native` bridge class, or writing a wrapper for it.

On the other hand, being able to drop down to native javascript anytime you like is a huge win.

@adam maybe you can give us a tutorial on doing this properly? Opal is amazing and being able to wrap things like ImpactJS and other js libs is enormously powerful.
This is amazing but I agree with others, dealing with generated code can be tricky in production environments.
Def. give this a try. You'll change your tune a bit.
I looked at this just a few days ago but decided not to pursue it any further because of how much junk JS it needs to generate and how readable that junk JS would be during debugging.
Very cool project. Like others say, it can be a pain to debug generated code in opal, clojure, elixir etc. But that's also true of the code generated by the C compiler. This is a chicken-and-egg thing. Either consumer hardware gets so fast that it's feasible to implement the language vm's in javascript or browsers will support other mechanisms for implementing them. But only when these projects are used by many people, which will happen when the code is easy to debug.
Opal debugging seems to be better than some of the other ones I've played with.
How is this "Ruby in Your Browser", per se? You're just saying that you've used Ruby to build a web page now in the browser, correct?

I ask because I'm seeking something more like a Ruby on Rails Implementation waiting for you in your browser, in effect, when you arrive at the service's website, which you can then take with you if you'd like, as a VM, in any number of ways.

Well, funny enough you can do rails with opal (they implemented Active Support (https://github.com/opal/opal-activesupport), which was kind of an answer to DHH and another before him thinking it couldn't be done, BUT... the real power comes from using it with something like rails. For example, we use it with rails 4.1rc2 at present to have ruby everywhere. So instead of just .js files or coffeescript, we have .js.rb files that pass through opal. Amazing readability improvements and a great feelings just going straight ruby across the board. There are some really slick little frameworks like `lissio` and `vienna` as well that offer `sinatra` like solutions right on opal.

The maker of `lissio` also started hacking on a little project that is not complete, but gives an idea of a WIP lissio project here: https://github.com/meh/gwentoo

Just kinda nice to see how it goes together and how very flexible it is.

Nice work. I too wish browsers had native support for Ruby.

Like have others have said, I'm really turned off by the `...` js evaluations all over the code. I wonder why that opal-jquery gem doesn't have cleaner ways for interacting with the DOM. Is that the only way you can do it?

Why is it so hard for browsers to implement a common set of byte-code. Then we all get what we want and it would make it much simpler to port your favorite language to the browser.

This compile to javascript trend seems so brittle and frail.

I have been wondering this myself for a while. While I believe there are probably reasons you couldn't exactly map behavior of all of today's popular scripting languages into a common byte-code, you could probably approach something close to it.

Part of the problem is that Webkit has a very narrow mission of wanting to only be standards compliant. This is really holding back innovation given how widely used it is in Safari and until recently Chrome.

It seems to me that in order to make it happen, it would need wide support from one of the major browser vendors.

We may finally see this, if only as a side effect of Eich's departure from Mozilla.

Google and Mozilla are the only mainstream browser vendors that have an incentive to offer a bytecode alternative to the JavaScript status quo, whereas Apple and Microsoft would simply be undermining their respective platform positions.

This means that Mozilla could have worked with Google to form a bloc; Chrome and Firefox would have been the only browsers to support better web technology, and that might have been enough to force Microsoft and Apple's hand.

Instead, Eich stuck to his "JavaScript First" guns for years, wasting market opportunities and in the process, serving as the swing vote that held the entire web back.

I hope that the next CEO of Mozilla realizes that for platforms like Firefox OS to have a snowball's chance in hell, they need to work with Google to move past HTML/CSS/JS.

Chrome (or rather Chromium) will soon have Dart support built into it. There you go.
Why is compile to JavaScript any different than compile to byte code? Is the "frail" comment from experience or intuition?
You'd think this would be obvious. It's an inefficient and poorly designed "bytecode":

- The only number representation available is floating point.

- Concurrency is impossible except for the nearly useless web workers API; this prevents a language author from exposing any other type of concurrency mechanism.

- Anyone wishing to implement the "byte code" specification must implement or integrate a full Javascript parser and runtime.

On top of that, you have no control over memory management (which makes properly implementing lots of languages impossible).
We're using this on a large'ish project at the moment and thrilled with the productivity gains. Right now we're using Rails 4.1RC2 + Opal and thrilled with the readability that we now have across the board. This is good sized project for several thousand concurrent users and was to test the waters before using for something larger on our plate.
I'm curious what kind of features you have on the client side that you're using this for.
Quite a few with some diversity. Right now there are a mapping functions / integration with Google Maps and various social functions, including heavy communications (mostly text at the moment). We have a bit of animation and using the opal-jquery plugin as well, which is quite nice. The opal-browser library also gives a nice Nokogiri feel to working with the DOM.
Oh, and fyi, going to be using it for some heavy graphics soon and even going to test out some game development. Personally I intend on wrapping ImpactJS for Opal and then using it for a demanding project so we can work entirely in ruby.