On Mon, 19 Jul 2004 13:54:53 +0200, Nospam wrote:

> Hi,

Hi

> <snip>
> 
> What I mean is, this...
> 
> class Example
>    def example
>      puts "Hello World!"
>    end
> end
> 
> ... can also be written in C using the Ruby C API, am I right? So why 
> wouldn't it be possible to convert all Ruby code to C code using the 
> Ruby C API?

Yes, that's possible, but depending on the C code you write, there
isn't much performance gain.  You can write any ruby code in C,
but if you just convert it litteraly to C, there isn't much performance
gain. For example when you write
  arr[1] = 2 #arr is an Array
you could use rb_ary_store(arr, 1, INT2FIX(2)), but that wouldn't be
equivalent to the ruby code.  When the Array#[] method would change, the
ruby code would see the change, but the C code wouldn't.  The solution
would be to use something like rb_funcall(arr, rb_intern("[]"), 0), but
then there would be no performance benefit, because ruby still has to look
up the method.  The point is that it is possible to write more efficient
ruby code in C, but it isn't really ruby code anymore.

> 
> This would probably result in some performance gain (no need to parse 
> the code anymore at run-time), but for some people more important, you 
> can distribute your Ruby applications closed-source. In the future the 
> performance gain maybe could be increased by performing special 
> optimizations during the conversion process.
> 

The parsing fase doesn't take so much performance, since it is only done
at loading time.

> Am I right on this, or do I forget something important which makes the 
> above quite hard to do?
> 
> With kind regards,
> 
> Peter

Well, I do think it is possible to compile Ruby, but it would be to hard.
Firstly eval and module_eval should be thrown away, because they need to
be able to parse code at runtime.
Continuations make compiling very messy, since the stack needs to be
copied. This can also can cause troubles when interfacing with native
c-calls.  (I wonder how the current Ruby-interpreter manages this...)

The best way is IMO to have a different language that resembles Ruby
as much as possible, but allows it to be compiled easily.  (I am sure
Matz wouldn't allow Ruby to be crippled to allow compilation).
It would have limitations that Ruby doesn't have (no eval or continuations),
but it would be a nice alternative for coding in C.  In fact code blocks
and closures aren't that difficult to compile, and I think any decent
compilable language should have them.

As for Ruby, the best performance gain would be by using a Just-In-Time
compiler. This way, the compiler can make assumptions about the code, and
recompile when this assumptions are wrong.  Take for example the following
code:
  5.times do { |i| puts i }
Here the compiler could inline the code for times and produce very
efficient code.  The same goes for other standard library functions like
Array#[], etc.  However it is still possible to redefine Numeric#times
(though I don't see a good reason to!).  If the method would be redefined,
then the just-in-time compiler could recompile it.  The same goes for
method arguments. When an argument to a method is always from the same
class, the compiler can call the methods on that object directly (without
lookup), or even inline them. However when different kinds of objects get
passed to the method, then the JIT-compiler could recompile the method, so
that it works with all objects.

In this way the JIT can create well performing code, and at the same time
keep the dynamic nature of Ruby.  When methods are redefined, or added,
the jit-compiler makes the changes.
It would be nice to have such an interpreter, but it would be a
considerable amount of work to implement it, as it would need a
complete rewrite of the Ruby-interpreter.

Regards,
Kristof