10. November, 2008
in by Michael Neumann

Christopher Nelson talked about Ruby in the Browser at this years’ RubyConf 2008. He mentioned RubyJS, my Ruby to Javascript compiler, as well as a new library called Red, which also translates Ruby to Javascript, but in a slightly different way.

There are lots of interesting articles about RubyJS and rubyjs_on_rails on his blog.

10. April, 2008
10. April, 2008
in by Michael Neumann

As you can see on the following pictures, RubyJS runs fine even within a browser on a mobile phone. It’s a bit slower of course, but it’s funny to follow the progress of the tests which you can’t see in a browser on a PC, because it’s way too fast. The mobile is a Sony Ericsson P1i.

RubyJS on mobile 1

RubyJS on mobile 2

10. April, 2008
10. April, 2008
in by Michael Neumann

I am pleased to announce the first public release of RubyJS, a Ruby to Javascript compiler. It is now available as a Rubygem, so that you can install it with a single command:

gem install rubyjs

To see what it compiles, and whether the generated Javascript code runs in your browser, take a look at it’s test suite. Watch out for the color red! If everything is “green”, it runs fine within your browser.

Right now there are only two examples, the obvious Hello World example (Ruby code here) and another example (Ruby code here) that demonstrates some preliminary support for Ruby Web Toolkit (an unfinished port of Google Web Toolkit), which btw will hopefully be completed by a this years Google Summer of Code project.

9. April, 2008
9. April, 2008
in by Michael Neumann

In this morning I made a benchmark that compares an example written in Javascript using Prototype against the equivalent version in RubyJS (which uses plain Ruby code).

The RubyJS version:

sum = 0
500_000.times {|i| sum += i}

The Javascript/Prototype version:

var sum = 0;
(500000).times(function(i) {sum += i;});

Not only is the Ruby(JS) version more readable (IMHO), but it is also faster.

26. March, 2008
26. March, 2008
in by Michael Neumann

This morning I came across HotRuby, a virtual machine for YARV (Ruby 1.9) bytecode for Javascript and Flash. When I started implementing RubyJS I also considered this approach (also using Ocaml bytecode :), but then abandoned it due to performance issues.

I quickly implemented the benchmark they give using RubyJS. It takes 11.57 seconds in HotRuby but only 4 seconds in RubyJS. The same benchmark executed in Ruby 1.8 takes around 24 seconds!!! But only 0.12 seconds if you replace the “+=” by ”«”, so I consider this a very bad benchmark because it only benchmarks the performance of String allocation in the underlying VM/interpreter and not that of RubyJS/HotRuby. A benchmark with a lot of method calls, as is usual in a regular Ruby application, would be a much better benchmark. I think this would show even better results for RubyJS.

14. February, 2008
26. February, 2008
in by Michael Neumann

I finally made it to put the slides of my RubyConf 07 talk RubyJS - Efficient Ruby to Javascript Compilation online.

13. February, 2008
13. February, 2008
in by Michael Neumann

I am looking for someone to sponsor me, so that I can continue work on RubyJS, my Ruby to Javascript compiler and finish the Google Web Toolkit port, called RWT. Interested? Then read my proposal and contact me.

11. December, 2007
11. December, 2007
in by Michael Neumann

Finally, the recording of my talk at RubyConf 2007 is online here. Slightly too technical and too monotone voice :). The other talks can be found here.

6. August, 2007
11. September, 2007
in
»
»
by Michael Neumann

I'm not yet sure how I will name my library which is similar to Google Web Toolkit and is based on my RubyJS. Yesterday, I implemented some DOM related stuff in under two hours. GWT uses class methods of the DOM class everywhere, e.g.:

DOM.setElementAttribute(Element elem, String attr, String value)

I don't follow this approach, because I think it's more elegant to move them into an Element class and make it an instance method instead:

el = Element.createDiv
el.setAttribute("a", "b")

The same applies to Events. This allows me to write for example:

Element['root'].appendChild(
  Element.createDiv.setInnerHTML('abc').
          setAttribute('title', 'tooltip'))

instead of:

root = DOM.getElementById('root')
elem = DOM.createDiv
DOM.setInnerHTML(elem, 'abc')
DOM.setElementAttribute(elem, 'title', 'tooltip')
DOM:appendChild(root, elem)

which looks much less like OO in my hence opinion.

9. July, 2007
9. July, 2007
in by Michael Neumann

So I finished work on RubyJS for now. It's mostly complete. Further changes are done on demand. Today I prototyped a first GWT port and thought about API issues. I'm not yet sure whether I want to port it. I'm more into taking a good idea as a basis and then do the stuff myself.

For example what in GWT is:

Button b = new Button("Hello", new ClickListener() {
  public void onClick(Widget sender) {
    Window.alert("...");
  }
});

becomes in RubyJS:

b = Button.new("Hello")
b.on_click do
  Window.alert("...")
end

Or:

b = Button.new("Hello").on_click do
  Window.alert("...")
end

I think there is much room for improvements.

The Javascript code for the core library is currently at ~9 KB. Compare this with the Prototype library which is at ~70 KB. And those 9 KB are without (space) optimizations turned on. So there is still much room left.

9. July, 2007
9. July, 2007
in by Michael Neumann

The last couple of hours I added the following features to RubyJS:

  • Iterators
  • Modules
  • Whole program code-generation, including automatic dependency checking (that sounds complicated, but it's nothing more than introspecting which classes/modules to generate code for and in which order)

Again some statistics:

> cat *.rb | wc -l
    2450

> cat *.rb | grep -E -e '^[[:space:]]*#' | wc -l
     623
6. July, 2007
6. July, 2007
in by Michael Neumann

Again, the implementation of iterators in my new RubyJS version is much better than in the old version. At first one must understand how iterators works.

def m
  p(yield 1)
  p(yield 2)
end

m {|i| i+1}

The example above will print out 2 and 3. So the result of the iterator is the result of yield. Now there are two keywords in Ruby next and break that are useful in the context of iterators:

m {|i|
  next if i == 1
  i+1
}

m {|i|
  break if i == 1
  i+1
}

The first iterator using next will print out 3, whereas the second which uses break will not print out anything. So next is for iterators what is return for methods. And as such, as iterators are implemented as Javascript functions, it maps directly to return. The second using break is special. It breaks out of the calling method, so the second line in method m is not called anymore (and even the "p" call in the first line is not reached). This has to be implemented with an exception that has to be catched in the method m and converted into a return. Now that's pretty general as return is a statement in Javascript and sometimes we want it to be used inside an expression. This is only possible if we use an exception instead.

Now the equivalent converted to Javascript:

function m(block)
{
  try {
    this.p(block(1));
    this.p(block(2));
  } catch(e) {
    if (e === Return) return e.value;
    else throw(e);
  }     
}

m(function(i) { return i+1; });

m(function(i) { if (i==1) return nil; return i+1; });

m(function(i) { if (i==1) throw(Return(nil)); return i+1; });
4. July, 2007
4. July, 2007
in by Michael Neumann

Total number of lines:

> cat *.rb | wc -l
    1587

Total number of lines that are comments:

> cat *.rb | grep -E -e '^[[:space:]]*#' | wc -l
     394

So around 1/4 of the total number of lines are comments. That doesn't say anything about quality though. But it shows that it's not a quick hack :). It's code that is well described, especially the compiler, which needs most explanation. This is important that I can continue work on RubyJS after I come back from holidays in a few weeks :)

21. May, 2007
27. June, 2007
in by Michael Neumann

I really dislike Javascript. That’s why I wrote RubyJS some time ago. With RubyJS you can basically translate your Ruby scripts to Javascript. Of course there are some minor problems due to their incompatible object models etc. For example Ruby has integers and floats, while Javascript only has numbers. Then Ruby has mutable strings while Javascript has not. Of course all this can be simulated by RubyJS easily but of course this comes not for free. For immutable strings there are two choices, either restrict RubyJS to use immutable operations on strings or box every Javascript string into a RubyString object. On the other hand, Ruby’s Arrays perfectly fit to Javascript arrays. Hashes do not!

Today I took a look at other languages. For example, would it be possible to convert Ocaml to Javascript? Haskell? For Haskell there even exists an approach using YHC (York Haskell Compiler). But, while Haskell is a very nice language, it lacks some OO support, that can be found in Ocaml. How about Erlang? It should be possible using the BEAM bytecode and translating it to Javascript. There is only one problem. Lists. There are not native in Javascript, but are used heavily in Erlang. After some time, I took a deeper look at Ocaml. It shouldn’t be that hard to translate Ocaml’s bytecode or it’s lambda-terms (-dlambda option) to Javascript. The advantage would be that you have a strongly typed langauge. No more ugly Javascript errors. But then, you don’t have open classes (or open modules). That’s a pain if you are coming from Ruby (or Javascript).