from Hacker News

Opal - Ruby to Javascript compiler

by cap10morgan on 10/19/12, 4:49 PM with 49 comments

  • by DanielRibeiro on 10/19/12, 5:53 PM

    Cool idea. Not the first attempt though:

    http://hotruby.yukoba.jp/

    https://github.com/whitequark/coldruby

    http://rb2js.rubyforge.org/

    http://www.ntecs.de/blog/articles/2007/01/08/rubyjs-javascri...

    https://github.com/jessesielaff/red

    http://www.playmycode.com/docs/quby

    https://github.com/mattknox/8ball

    Unfortunately, none of them seem to be to handle the mor dynamic features of ruby, like method_missing, which diminishes the possibility of reusing existing ruby code in the browser.

  • by dyscrete on 10/19/12, 6:33 PM

    It's a great idea, but it seems ridiculous how even simple arithmetic gets translated to an unreadable mess of javascript.

    puts 4 + 2 + 5 + (19 + 3 * 4) - 8 / 10

    translates to:

    (function() { var __opal = Opal, self = __opal.top, __scope = __opal, nil = __opal.nil, __breaker = __opal.breaker, __slice = __opal.slice; var __a, __b, __c, __d, __e, __f, __g, __h; return self.$puts((__a = (__c = (__e = (__g = 4, __h = 2, typeof(__g) === 'number' ? __g + __h : __g['$+'](__h)), __f = 5, typeof(__e) === 'number' ? __e + __f : __e['$+'](__f)), __d = (__e = 19, __f = (__g = 3, __h = 4, typeof(__g) === 'number' ? __g * __h : __g['$*'](__h)), typeof(__e) === 'number' ? __e + __f : __e['$+'](__f)), typeof(__c) === 'number' ? __c + __d : __c['$+'](__d)), __b = (__c = 8, __d = 10, typeof(__c) === 'number' ? __c / __d : __c['$/'](__d)), typeof(__a) === 'number' ? __a - __b : __a['$-'](__b))) })();

  • by doktrin on 10/19/12, 11:25 PM

    Being relatively new to cross-language compilation, how are one language's class APIs typically translated into another?

    For example :

       [1,2,3].shuffle 
    
    [turns into] =>

       (function() {
         var __opal = Opal, self = __opal.top, __scope = __opal, nil = __opal.nil, __breaker = __opal.breaker, __slice = __opal.slice;
      
         return [1, 2, 3].$shuffle()
       })();
    
    Of course, since JS arrays do not have a "shuffle" method, the output reads :

       TypeError: Object 1,2,3 has no method '$shuffle'
    
    Is the answer to simply use class/object methods that are present in both languages?
  • by Xcelerate on 10/19/12, 5:59 PM

    I really like this idea of compiling code to Javascript. Brenden Eich makes some good points for it in his series of slides (starting here: http://brendaneich.github.com/Strange-Loop-2012/#/21).

    I'm working on a little programming language myself that compiles to Javascript. In most languages that do this, I wish there was better information on the mapping between the domain language and its Javascript codomain. I think this would be a good open source project idea: a tool to assist in the compilation of various languages to Javascript. Something to the effect of how source lines in C can be printed above their generated assembly. Anyone want to give it a shot?

  • by jhrobert on 10/20/12, 12:34 PM

    They lost me at the "nil" section.

    RubyScript is what we need => efficient code, à la coffeescript, with a Ruby syntax.

    There is some impedance mismatch between ruby & javascript semantics. Trying to hide this fact has a cost in terms of performance.

    I would love to have some ruby syntax as long as it does not compromize the speed of my code.

    There is a trend these days where syntax and semantics are becoming orthogonal, that's nice.

    Hence GoScript, PascalScript, PrologScript, CppScript, SmallScript...

    Thanks to sourcemaps the issue of the generated code readability has disappeared. Only the performance matters from now on.

  • by vjeux on 10/20/12, 5:54 AM

    Unfortunately their hash table uses Javascript objects. Therefore it does not behave exactly like Ruby.

    Eg:

      # Opal
      h = Hash.new
      h['0'] = 1 
      h[0] = 2
      print h
      # {"0"=>2}
    
      # Ruby
      h = Hash.new
      h['0'] = 1 
      h[0] = 2
      print h
      # {"0"=>1, 0=>2}
    
    It is very hard to reproduce those low level specifications without rebuilding everything from scratch sadly :(
  • by 1qaz2wsx3edc on 10/19/12, 5:37 PM

    Yup, that's some good brainfuck:

          (function() {
            var __opal = Opal, self = __opal.top, __scope = __opal, nil = __opal.nil, __breaker = __opal.breaker, __slice = __opal.slice, __klass = __opal.klass;
            var adam = nil, __a, __b;
            (__b = [1, 2, 3, 4], __b.$each._p = (__a = function(a) {
    
        
              if (a == null) a = nil;
    
              return this.$puts(a)
            }, __a._s = self, __a), __b.$each());
            (function(__base, __super){
              // line 5, (file), class Foo
              function Foo() {};
              Foo = __klass(__base, __super, "Foo", Foo);
    
              var Foo_prototype = Foo.prototype, __scope = Foo._scope;
    
              return Foo_prototype.$name = function() {
          
                if (this.name == null) this.name = nil;
    
                return this.name
              }, 
              Foo_prototype['$name='] = function(val) {
          
                return this.name = val
              }, nil
            })(self, null);
            adam = __scope.Foo.$new();
            adam['$name=']("Adam Beynon");
            return self.$puts(adam.$name());
          })();
  • by jonny_eh on 10/19/12, 5:35 PM

    While very impressive it makes me nervous. The JS it outputs just in the basic tutorial looks extremely complex, I'd hate to debug that code! Compare with CoffeeScript, where the output is quite easy to follow, and therefore debug.
  • by lexy0202 on 10/19/12, 6:47 PM

    Can you interact with the dom inside opal?
  • by sambuna on 10/19/12, 11:03 PM

    I certainly see future for this!
  • by jblock on 10/19/12, 6:45 PM

    Source maps? Source maps.
  • by 5vforest on 10/19/12, 5:46 PM

    What the use case for something like this? Am I missing something?
  • by goggles99 on 10/20/12, 11:09 AM

    Can't those standards committees just do something right for once and create a standard for a vm that will run in the browser (a la Dartium)? Stop this monopoly and oppression of innovation!!!