Live data from Hacker News

Opal: Ruby to JavaScript Compiler

opalrb.org

51–60 of 69 posts

Re: Opal: Ruby to JavaScript Compiler

#52

I'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…

The core of the issue here is that, in Ruby, it's all about messages and method invocation, right?

I'd suggest that, while correct, your observation about types is a strawman--the generated Javascript (while quite slow!) follows the semantics of the Ruby language correctly; the addition operator is just a function, and with different context could've done something entirely differently. We could've, say, briefly overwritten the + operator on Fixnum or done silly alias_method tricks.

Re: Opal: Ruby to JavaScript Compiler

#54
post #49

I'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…

Not necessarily. You can compile a Ruby VM from C to JS, as people have done. That should give you somewhere around 2 times slower performance, or better, not 264 times slower (and with very little effort). 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 dece…

> You can compile a Ruby VM from C to JS, as people have done.

That sounds to me like it would just kill your startup perf. Users would have to download an entire Ruby VM every time they hit your site, wouldn't they?

Maybe I'm just a luddite, but spending network resources downloading a garbage collector written in JS only so that I can run it in JS... which natively supports GC just seems really gross to me.

Don't get me wrong, I think Emscripten is very very cool. It just feels like a strange fit for applications written in a language whose semantics aren't that far from JS.

Re: Opal: Ruby to JavaScript Compiler

#55

I'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…

Looks like we should have eliminated the loop entirely. 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.

> 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.

Note that the Opal code also has this.

Re: Opal: Ruby to JavaScript Compiler

#56

I'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…

The core of the issue here is that, in Ruby, it's all about messages and method invocation, right? I'd suggest that, while correct, your observation about types is a strawman--the generated Javascript (while quite slow!) follows the semantics of the Ruby language correctly; the addition operator is just a function, and with different context could've done something entirely differently. We could've, say, briefly over…

> follows the semantics of the Ruby language correctly;

Exactly, the compiled code follows the Ruby language correctly. It's also unusably slow.

It's possible to generated compiled code that also follows the Ruby language semantics by using knowledge of which portions of those semantics the actual program in question relies on. That program can be a lot faster.

In other words, if you haven't overloaded arithmetic operators, your program compiled to JS shouldn't pay the runtime penalty as if you had.

That's a compiler's job: preserve semantics but make the resulting code run as fast as possible by whatever means necessary.

If you've got a way to compile Ruby to JS that has tolerable arithmetic perf and doesn't do type analysis or generate a huge volume of code, I would definitely like to know more about it.

Re: Opal: Ruby to JavaScript Compiler

#57
post #49

Earlier quoted context omitted.

Not necessarily. You can compile a Ruby VM from C to JS, as people have done. That should give you somewhere around 2 times slower performance, or better, not 264 times slower (and with very little effort). 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 dece…

> You can compile a Ruby VM from C to JS, as people have done. That sounds to me like it would just kill your startup perf. Users would have to download an entire Ruby VM every time they hit your site, wouldn't they? Maybe I'm just a luddite, but spending network resources downloading a garbage collector written in JS only so that I can run it in JS... which natively supports GC just seems really gross to me. Don't g…

I see your point, but don't think it is quite as bad as that. For one thing, it would be cached etc., so it is about as bad as every site on the web using jQuery (that is, not great, but not horrible either).

Yes, it seems ironic to download a GC written in JS, when JS can do GC. But JS can only do SOME types of GC. For example, it lacks destructor callbacks, which things like Lua require. Some other language might need weakrefs which JS also lacks. So it is not quite that unreasonable to download a GC, as you can get the right semantics you want.

But I do agree it gets less clear when the semantics are very close to JS. I'm not sure if Ruby is close enough, though (CoffeeScript certainly is).

Re: Opal: Ruby to JavaScript Compiler

#58

Earlier quoted context omitted.

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.

Ok, but is finding X given Y tractable? 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

Couldn't you translate source given the ability to translate behaviour? If some behaviour in language X can be simulated by a state machine in Y, then you could just emit said state machine as the translation of the behaviour, give its output to the next state machine, etc. And gradually build up the behaviour of a program in X, but using a bunch of generated code in Y instead of just an interpreter. In other terms, if an interpreter for / simulation of X may be expressed in Y, then for each bytecode / AST node in X you could just inline the bytecode handling you would use in Y into the compiled output.

Re: Opal: Ruby to JavaScript Compiler

#59

Earlier quoted context omitted.

Ok, but is finding X given Y tractable? 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

Couldn't you translate source given the ability to translate behaviour? If some behaviour in language X can be simulated by a state machine in Y, then you could just emit said state machine as the translation of the behaviour, give its output to the next state machine, etc. And gradually build up the behaviour of a program in X, but using a bunch of generated code in Y instead of just an interpreter. In other terms,…

I think thats a very clever algorithm.

But I think your first articulation amounts to converting a turing machine to a huge generated state machine, which would be impossible. The behavior of the X program given one input could be modeled as a sequence of states if it terminates. But the process of generation that you described would have to be repeated for all possible inputs into the simulated X program, which would be impossible.

Maybe a single "behavior" could be modeled by a state machine, but it would also seem impossible to me to decompose a program into individual units of behavior.

But as for bytecode -- one could always compile the X code into bytecode, and then decompile that bytecode into Y code. If you can always find a common bytecode language for two languages X and Y, then I think that would be a generic algorithm for X->Y.

Edit: I guess that common bytecode could just be in a language that describes a turing machine.

Post reply on HN