Earlier quoted context omitted.
It is really a ruby to JS compiler. Ruby, however, is not just a thin layer over JS the way CoffeeScript is. The thing you are referring to is a sign of CoffeeScript being a thin layer over JS, not CoffeeScript's compiler being a "real compiler".
my point was it doesnt transpile Ruby to Javascript.
Opal: Ruby to JavaScript Compiler
41–50 of 69 posts
Re: Opal: Ruby to JavaScript Compiler
#42Earlier quoted context omitted.
As DouweM said; there is a case to be made for having the whole stack in a single language. While I use different languages server side, Ruby (either with Rails or Sinatra) is my go to option more often than not these days. I have used CoffeeScript extensively, but this has always been on contracts where the decision was made by someone else. It is important to learn and use real JavaScript (IMHO) rather than all of…
>I have used CoffeeScript extensively, but this has always been on contracts where the decision was made by someone else. >It is important to learn and use real JavaScript (IMHO) rather than all of these transpiled languages. This is the route I take when I have a choice on the client side; I use JavaScript. I've been using Rails and Coffeescript. Intuitively, I feel like using Javascript directly would be better som…
https://meta.discourse.org/t/is-it-better-for-discourse-to-u...
Re: Opal: Ruby to JavaScript Compiler
#43How would Opal handle meta programming like method_missing and define_method?
Opal supports `method_missing`: http://opalrb.org/docs/method_missing/ `define_method` as well: https://github.com/opal/opal/blob/f958d6b2468e57acf7f324e10a...
Opal.add_stubs(["first", "second", "to_sym"]);
But lets say I am dynamically generating method using a string passed from user input or server then this would fail.
Re: Opal: Ruby to JavaScript Compiler
#44I want to stress, though, that I'm not singling Opal out here. I think Opal is a really cool project, and I hope it works well for lots of people. It's just a good example language since it's on HN right now.
Let's compile this Ruby code to JS with Opal:
a = 0
10000000.times do
a = a + 1
end
puts a
Opal gives us: /* Generated by Opal 0.6.2 */
(function($opal) {
var $a, $b, TMP_1, self = $opal.top, $scope = $opal, nil = $opal.nil, $breaker = $opal.breaker, $slice = $opal.slice, a = nil;
$opal.add_stubs(['$times', '$+', '$puts']);
a = 0;
($a = ($b = (10000000)).$times, $a._p = (TMP_1 = function(){var self = TMP_1._s || this;
return a = a['$+'](1)}, TMP_1._s = self, TMP_1), $a).call($b);
return self.$puts(a);
})(Opal);
We'll compare it to some vanilla JS: var a = 0;
for (var i = 0; i
I don't care at all that the generated code is a little funny looking. That's fine. Opal's code is actually pretty readable to me. What is a problem for some (many?) users is the performance.You'll note that Opal did not compile "a + 1" to "a + 1". Instead it generated "a['$+'](1)". That's because Ruby's arithmetic semantics are different from JavaScript's. To implement those semantics correctly, it needs to use a method call instead of using the built-in arithmetic.
We can profile the two using this fiddle: http://jsfiddle.net/3UtNf/1/
On my laptop, the Opal code is 264 times slower than the raw JS code. In other words, it runs at 0.3% of the speed of the JS code. Now imagine sacrificing that much perf on a mobile device. That's enough to make the language unsuitable for many real-world use cases.
This isn't intractable, though. You just need to compile math down to real JS arithmetic operators when JS's semantics line up with your language's (which typically means, when you're suring you've got numbers and not some other type with a user-defined operator).
Determining where you can do that is the hard part. It requires type analysis. Doing that well in a language that doesn't have a sound static type system requires whole-program analysis. It's extremely complex, monolithic, and leads to very strange output code.
This is why, for example, Dart's dart2js compiler is so complex and heavyweight. It does do this kind of analysis. It compiles this Dart program:
main() {
var a = 0;
for (var i = 0; i
to this JS: function() {
var a, i, line;
for (a = 0, i = 0; i
That has the same performance as the JS code. The reason it does this is because it knows "a" is a number. If we change the Dart code to: class Foo {
operator +(other) => this;
}
main() {
var a = new Foo();
for (var i = 0; i
Then generated JS changes completely: function() {
var i, line;
for (i = 0; i
Interestingly, here you can see the compiler understood that the "+" operator on Foo always returns the same object and was able to inline the call to it and then hoist it out of the loop completely.This is the kind of stuff you need to do if you want to have a language that compiles to JS and (unlike, say CoffeeScript and TypeScript) has semantics that aren't very very similar to JS.
Re: Opal: Ruby to JavaScript Compiler
#45Earlier quoted context omitted.
Ruby and JS are both Turing-complete languages (as with just about any other programming language you'll ever use), which means that one can simulate the other. The simulation might be messy, complicated, or slow, but it will still work. In this case, Ruby and JS are close enough that it can be done without too much trouble (see the compiled JS).
But does "anything written in language A can be simulated using language B" imply "A can compile down to B"?
Re: Opal: Ruby to JavaScript Compiler
#46I'm going to use this as a little example of why compiling to JS is hard. I work on the Dart team, and people often ask what the big deal about JS compilation is. Opal's compiler is a good example of why it can be hard. I want to stress, though, that I'm not singling Opal out here. I think Opal is a really cool project, and I hope it works well for lots of people. It's just a good example language since it's on HN ri…
Also, a disclaimer in case anyone tries this themselves: there is a bunch of plaftorm/library code in the Dart output that's not used by such a trivial program and could be eliminated. The dart2js team is focusing of reducing the size of large programs, which do usually use this code, so eliminating it in small programs isn't much of a real-world win right now.
Re: Opal: Ruby to JavaScript Compiler
#47Re: Opal: Ruby to JavaScript Compiler
#48Earlier quoted context omitted.
As DouweM said; there is a case to be made for having the whole stack in a single language. While I use different languages server side, Ruby (either with Rails or Sinatra) is my go to option more often than not these days. I have used CoffeeScript extensively, but this has always been on contracts where the decision was made by someone else. It is important to learn and use real JavaScript (IMHO) rather than all of…
It seems to me that complaining that you need to use "real JS" instead of a compiled-to-JS language for web apps is like saying you need to use real machine code instead of a compiled-to-machine-code language for an other kind of app.
A transpiler is a very specific subset of a compiler that takes one language that has a "similar" level of abstraction and compiles it to a different language with a "similar" level of abstraction.
C++ compiled to machine code is not at all similar to CoffeeScript transpiled to JavaScript.
If you are working in CoffeeScript/TypeScript/Opal you are still likely to need to understand JavaScript to best leverage existing JavaScript libs/frameworks and to build on or debug those tools when necessary.
A couple of problems arise when you introduce something like CoffeeScript. Now you have added yet an extra layer of knowledge required to the infinite pool of required knowledge
Problems
1) Knowledge required
Now your team is required to know
CoffeeScript(Replace with other transpiled language here) + JavaScript + HTML + CSS + Backend Language of Choice
2) Hiring pool
Eventually you will need to hire someone. This presents a problem from both the employer and employee side
Employer Side (Pointy Haired Boss)
We use CoffeeScript/TypeScript/etc... so we need to post that as a job requirement.
Employee Side
Really smart potential employee who wants to apply knows JavaScript; sees posting requires CoffeeScript. This employee hits indeed.com and sees there are 43,000 javascript jobs. Employee decides to stick with JavaScript and doesn't apply.
This is a bit of an old interview and I don't know Jeremy Ashkenas personally so I don't know his current stance of CoffeeScript, but I'm going to post it here since it's from the horse's mouth and I believe it illustrates why using JavaScript is really a better choice.
"If the question is 'why is CoffeeScript not a DocumentCloud project?' - it's because I can't justify using it for the main DocumentCloud development. Imagine trying to hire someone. 'You'll have to learn to use a new language that we made up...'" - Jeremy Ashkenas
http://readwrite.com/2011/01/07/interview-coffeescript-jerem...
3) Future proofing
I'm just going to link back to the same wycats link someone else posted, because it's much more elegant than how I'd put it.
https://meta.discourse.org/t/is-it-better-for-discourse-to-u...
Re: Opal: Ruby to JavaScript Compiler
#49I'm going to use this as a little example of why compiling to JS is hard. I work on the Dart team, and people often ask what the big deal about JS compilation is. Opal's compiler is a good example of why it can be hard. I want to stress, though, that I'm not singling Opal out here. I think Opal is a really cool project, and I hope it works well for lots of people. It's just a good example language since it's on HN ri…
Things get more complicated if your VM has a JIT, but there are interesting results even there, see pypy.js.
This approach lets you have arbitrary semantics, even ones that differ hugely from JavaScript, with decent performance.
I've suggested this in the past on HN - I think that approach could work for Dart as well. Would be happy to help investigate it.
Re: Opal: Ruby to JavaScript Compiler
#50Earlier quoted context omitted.
But does "anything written in language A can be simulated using language B" imply "A can compile down to B"?
yes. If you can write a body of code X in language B which performs the same operations as any given body of code Y in language A, then all an A->B compiler needs to do is find X given Y.
To me, it seems like compiling is translation of source (usually higher level source to lower level source), whereas simulation is more like translation of behavior.
Edit: and the ability to translate behavior does not seem to imply the ability to translate source