Ruby vs Perl performance

I don't believe you :P. Show us the code. Did you use RubyInline or something?:slight_smile:

ยทยทยท

2009/2/8 Reid Thompson <reid.thompson@ateb.com>:

running on core2 duo gentoo

Ruby Elapsed 0.045477

rthompso@raker ~ $ ruby mand.rb
Rendering

Ruby Elapsed 0.045477

--
Pozdrawiam

Radosล‚aw Buล‚at
http://radarek.jogger.pl - mรณj blog

You could also look into The project to concert ruby to obj-c which is compiled. Am I dreaming? I can't remember the name

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

ยทยทยท

On 08/02/2009, at 10:09 AM, "William James" <w_a_x_man@yahoo.com> wrote:

William James wrote:

Vetrivel Vetrivel wrote:

I have downloaded perl and ruby program in net.I run both the
programs.But the Ruby program performance very wost than perl.Can
any one tell me the reasons and
soultion to make ruby as faster than perl.
I have attached perl program.

#!/usr/local/bin/ruby

BAILOUT = 16
MAX_ITERATIONS = 1000

class Mandelbrot

       def initialize
               puts "Rendering"
               for y in -39...39 do
                       puts
                       for x in -39...39 do
                               i = iterate(x/40.0,y/40.0)

Don't indent so deeply. It makes the code much harder to read.

Don't write a mandelbrot program in an interpreted language.
Write it in a compiled language like OCaml.

OCaml:

let bailout = 16.0
let max_iterations = 1000

let iterate x y =
let cr = y -. 0.5 and
     ci = x and
     zi = 0.0 and
     zr = 0.0 in
let rec iterate2 zi zr i =
   if i > max_iterations then
     0
   else
     let temp = zr *. zi and
       zr2 = zr *. zr and
       zi2 = zi *. zi in
     if zi2 +. zr2 > bailout then
       i
     else
       iterate2 (temp +. temp +. ci) (zr2 -. zi2 +. cr) (i + 1)
in
iterate2 zi zr 1

let mandelbrot =
for y = -39 to 38 do
   print_endline "";
   for x = -39 to 38 do
     let i = iterate
       (float_of_int x /. 40.0) (float_of_int y /. 40.0) in
     print_string ( if 0 = i then "*" else " " )
   done
done

let _ = mandelbrot

Radosล‚aw Buล‚at wrote:

ยทยทยท

On Sat, Feb 7, 2009 at 3:42 PM, Peter Hickman <peterhi@ntlworld.com> wrote:

Haven't tried it under JRuby though, you might experience better performance
there.

JRuby is faster than 1.9 even without warming. ~2s for jruby, ~2.8s
for ruby1.9.1. With warm up it goes down to ~1.2s and with --fast flag
to ~0.75s.

Nice :slight_smile:

- Charlie

Chad, I generally agree, however...

. . . but I really don't agree with your assessment of Perl's development
cycle as something that "doesn't even come close" to Ruby's.
Furthermore, pigeonholing Perl as a "procedural" language is as unfair to
it as pigeonholing Ruby as "object oriented" is to Ruby. Both of them
have a lot more to offer. Both provide excellent support for many
traditionally functional paradigm programming; both support object
oriented development;

... that statement makes me itch. I try to avoid voicing extreme
opinions, but in this case I have to say: Perl's OO is a bad joke.
Yes, you can program OO style in Perl and there is /some/ support for
this - but it does not really give you much advantage over doing OO in
C (yes, you can do that: even std libraries do it, see open and fopen
et al).

both can be used in a structured, procedural style
when that's the appropriate technique to employ.

Right.

In general, I enjoy programming in Ruby more, these days -- but there are
tasks for which I'd much rather write the code in Perl than in Ruby.
Each has its strengths, and each has its place in my development toolkit
(and neither of them is clearly "faster" in terms of "the entire project
life cycle", especially considering that different projects have very
different lifecycles).

IMHO the best arguments for Perl are these
- often it's installed on a *nix system
- CPAN

Kind regards

robert

ยทยทยท

2009/2/9 Chad Perrin <perrin@apotheon.com>:

--
remember.guy do |as, often| as.you_can - without end

Chad Perrin wrote:

. . .
You talk as though Perl were something like Java or C++. It's not.
. . .

I am saying nothing of that kind!?

The fact that you are lumping Perl together with C++ and Java or Ruby
for that matter speaks volumes, and I simply do not have time to debate
this. But I can not allow myself not to reiterate that Perl is a
procedural language, and that its OO capabilities do not impress me at
all. OO in Perl is worse than C's GNOME extension. To use OOP in Perl is
just not worth the trouble. I also love Perl but not for it's OOP but
rather that for which it was designed in the first place, which is
procedural stuff and efficient shell programming that is almost as
powerful as C. However, there are times when even Perl is too convoluted
and a simple Unix shell script will do much better. At the same token I
believe, that to use Ruby as a replacement for shell script as many use
Perl, is a brain damaging proposition. The bottom line is Ruby is an
OOPL and is the most powerful in this domain. With Ruby, scripting is
just an additional bonus, and is not at all what it was designed for.
Arguably Ruby is one of The Best OOPLs, and as I have already said
nothing so far comes close to it, let alone Perl which is nothing more
than super duper scripting language, with a bonus to wrap it in a
reasonable OO paradigm, which, by the way, is rather poorly understood
by those who use Perl the most.

Using Perl on large projects is no longer a desirable enterprise, though
in the past it used to be a knockout when it competed with C. With the
advent of OO, Perl had to be tweaked to provide this alternative,
however that alternative sucks, and that is why Python took over its
domain. Thankfully, Ruby was born to replace these OO concoctions that I
cherish only as interesting OO fossils. On the other hand, what is good
and healthy lives long, and I believe procedural Perl will never die.
Though with some effort you can do anything you could do in Perl also in
Ruby. But isn't that true for all programming languages. This is known
since the 60's when COBOL programs were sprinkled with Assembler
procedures.

ยทยทยท

--
Posted via http://www.ruby-forum.com/\.

William James wrote:

Igor Pirnovar wrote:

William James wrote:
> Vetrivel Vetrivel wrote:
> Don't indent so deeply. It makes the code much harder to read.
>
> Don't write a mandelbrot program in an interpreted language.
> Write it in a compiled language like OCaml.

OCaml, Ada, C, C#, Perl, French ... I think all of these things are
rather misplaced here. Isn't this about Ruby? The fact is that one
needs to choose a language that best meets their

"one" is singular, so it's "best meets his".

ยทยทยท

--
Posted via http://www.ruby-forum.com/\.

Radosล‚aw Buล‚at wrote:

ยทยทยท

2009/2/8 Reid Thompson <reid.thompson@ateb.com>:

running on core2 duo gentoo

Ruby Elapsed 0.045477

rthompso@raker ~ $ ruby mand.rb
Rendering

Ruby Elapsed 0.045477

I don't believe you :P. Show us the code. Did you use RubyInline or something?:slight_smile:

see post from 1:14 am --- rubyinline

Robert Klemme wrote:

Yes, you can program OO style in Perl and there is /some/ support for
this - but it does not really give you much advantage over doing OO in
C (yes, you can do that: even std libraries do it, see open and fopen
et al).
  
I haven't done enough C to say for sure, but I loved Perl's OO. There definitely seems to be more there -- inheritance via @ISA, constructors via bless -- and while some find it ugly to expose all the underpinnings, that is one thing I love about Perl.

It's also one of the same reasons I love Ruby -- I don't have to get my hands dirty.

Take the simplest example, a method. In Ruby, it'd be:

class Foo
  def bar(arg)
    ...
  end
end

In Perl (and forgive my syntax, it's rusty), it'd be something like:

package Foo;
sub bar {
  my ($self, $arg) = @_;
  ...
}

Now, the Ruby version is much more readable to me, and much easier to work with. But there is something magical about the way the Perl version starts from even more basic primitives. Arguments are simply passed in as an array, which you can either unpack or not, as you like. The current object is passed in as an argument, meaning this is just another subroutine -- it lets you do tricks like this:

my $foo_like_thing = Bar::new();
Foo::bar($foo_like_thing, $some_other_arg);

Kind of like Javascript's call() and apply() -- and I'm not even sure this can be done in Ruby. For all the duck typing goodness, I can't seem to figure out how you'd unbind a method and rebind it to something of an unrelated class, unless there's an explicit tree of inheritance.

Not that this is something I've often (ever?) felt the need to do in Ruby. I'm just using it to illustrate what I like about Perl -- that it's so completely relaxed about this kind of thing. It gives you the bare bones of what's necessary for an object system, and you build whatever you want on top of it -- even with the guts exposed all over the place.

IMHO the best arguments for Perl are these
- often it's installed on a *nix system
- CPAN

I'll agree with that. And for new projects, I will instinctively choose Ruby. But it's for other reasons -- I like Ruby's syntax, and I like everything being an object, and being able to do things like the Rails Object#blank? hack, and iterators, and...

OCaml isn't any "X-sharp" language. It has decent support for both
functional and object oriented styles, and can in fact do the latter in
significantly fewer (and cleaner) lines of code than C#.

There's nothing about vi(m) that prevents one from using other
indentation schemes than an eight-space tab effectively. There's nothing
about GUIness that makes an editor inherently better or more "modern".

If you really think the topic should be limited to Ruby, you might want
to start with taking your own advice, and trying to avoid dragging editor
flame wars and your uninformed opinions about languages other than Ruby
into the discussion.

ยทยทยท

On Sun, Feb 08, 2009 at 08:28:52AM +0900, Igor Pirnovar wrote:

As I said, rather misplaced discussion. This is about Ruby, not about
some obscure X-sharps which all to us look like the old spaghetti code
from 40 or so years ago when structured techniques became popular after
Pascal bursted into the scene. As for the indentation, Vetrivel clearly
has just discovered vi and Unix clones, where tab is the most prominent
feature. Almost all modern source code editors today implement
GtkSourceView widget library, which manages indentation much more
efficiently than half a century old tools, newly discovered by M$
computer illiterate folks. Lets stop babbling about various screw-sharps
and concentrate on educating newcomers about Ruby!

--
Chad Perrin [ content licensed OWL: http://owl.apotheon.org ]
Quoth Jeff Henager: "If the average user can put a CD in and boot the
system and follow the prompts, he can install and use Linux. If he
can't do that simple task, he doesn't need to be around technology."

Wait . . . seriously? I need to find this project. That sounds like
fun.

ยทยทยท

On Mon, Feb 09, 2009 at 12:09:52AM +0900, Julian Leviston wrote:

You could also look into The project to concert ruby to obj-c which is
compiled. Am I dreaming? I can't remember the name

--
Chad Perrin [ content licensed OWL: http://owl.apotheon.org ]
Power corrupts. The command line corrupts absolutely.

Reid Thompson wrote:

Reid Thompson wrote:
>
> Ruby Elapsed 0.045477
>
>
#!/usr/local/bin/ruby

require 'rubygems'
require 'inline'

BAILOUT = 16
MAX_ITERATIONS = 1000

class Mandelbrot

     def initialize
         puts "Rendering"
         for y in -39...39 do
             puts
             for x in -39...39 do
                 i = iterate(x/40.0,y/40.0)
                 if (i == 0)
                     print "*"
                 else
                     print " "
                 end
             end
         end
     end

     inline do |builder|
         builder.c "
         int iterate (double x, double y)
         {
             int BAILOUT = 16;
             int MAX_ITERATIONS = 1000;
             double cr = y-0.5;
             double ci = x;
             double zi = 0.0;
             double zr = 0.0;
             double zr2 = 0.0;
             double zi2 = 0.0;
             int i = 0;
             double temp = 0.0;

             while (1)
             {
                i += 1;
                temp = zr * zi;
                zr2 = zr * zr;
                zi2 = zi * zi;
                zr = zr2 - zi2 + cr;
                zi = temp + temp + ci;

                if ( zi2 + zr2 > BAILOUT)
                {
                    return i;
                }
                if ( i > MAX_ITERATIONS)
                {
                    return 0;
                }
             }
         }"
     end

end

time = Time.now
Mandelbrot.new
puts
puts "Ruby Elapsed %f" % (Time.now - time)

Using the functional language F#:

0.0400575999999999 on my laptop with 2GHz Pentium.

let bailout = 16.0
let max_iterations = 1000

let iterate x y =
  let cr = y - 0.5 and
      ci = x and
      zi = 0.0 and
      zr = 0.0 in
  let rec loop zi zr i =
    if i > max_iterations then
      0
    else
      let temp = zr * zi and
        zr2 = zr * zr and
        zi2 = zi * zi in
      if zi2 + zr2 > bailout then
        i
      else
        loop (temp + temp + ci) (zr2 - zi2 + cr) (i + 1)
  in
  loop zi zr 1

let mandelbrot () =
  for y = -39 to 38 do
    print_endline "";
    for x = -39 to 38 do
      let i = iterate
        (float x / 40.0) (float y / 40.0) in
      System.Console.Write( ( if 0 = i then "*" else " " ) )
    done
  done

let start_time = Sys.time ()
let _ = mandelbrot ();
print_endline "";
System.Console.Write (Sys.time () - start_time)

Robert Klemme wrote:

Yes, you can program OO style in Perl and there is /some/ support for
this - but it does not really give you much advantage over doing OO in
C (yes, you can do that: even std libraries do it, see open and fopen
et al).

I haven't done enough C to say for sure, but I loved Perl's OO. There definitely seems to be more there -- inheritance via @ISA, constructors via bless -- and while some find it ugly to expose all the underpinnings, that is one thing I love about Perl.

It's not that I find it "ugly". It's more that I find it hard to read and remember whichever you have to do to get a class, inheritance, methods, data members etc. IMHO Perl makes OO unnecessary hard. There is a paper written by Larry Wall about the flaws of Perl's OO which I cannot seem to find right now.

It's also one of the same reasons I love Ruby -- I don't have to get my hands dirty.

"Same reason"? That sounds strange to me.

Take the simplest example, a method. In Ruby, it'd be:

class Foo
  def bar(arg)
    ...
  end
end

In Perl (and forgive my syntax, it's rusty), it'd be something like:

package Foo;
sub bar {
  my ($self, $arg) = @_;
  ...
}

Now, the Ruby version is much more readable to me, and much easier to work with.

Exactly!

But there is something magical about the way the Perl version starts from even more basic primitives.

Frankly, I don't like magic in programming - at least not the kind of magic that makes it hard to follow a program when reading it. I have had to maintain too much cryptic code to not highly appreciate readability.

Arguments are simply passed in as an array, which you can either unpack or not, as you like.

You can do that in Ruby as well. Just do

def initialize(*a)
   what, ever, you_like = a
end

The current object is passed in as an argument, meaning this is just another subroutine -- it lets you do tricks like this:

my $foo_like_thing = Bar::new();
Foo::bar($foo_like_thing, $some_other_arg);

What does this? Does it create a Bar and then initializes it as Foo? What do we gain from that? Where is the advantage over declaring classes Foo and Bar and making Bar a subclass of Foo if they are so closely related? (Or use a module for that matter)

Kind of like Javascript's call() and apply() -- and I'm not even sure this can be done in Ruby. For all the duck typing goodness, I can't seem to figure out how you'd unbind a method and rebind it to something of an unrelated class, unless there's an explicit tree of inheritance.

Why would you want to do that? There's a reason why both classes are unlrelated, i.e. chances are that the method would not work in the other class / object. If you want to simply share code then you can use modules which is a much cleaner and safer way to do it.

Not that this is something I've often (ever?) felt the need to do in Ruby. I'm just using it to illustrate what I like about Perl -- that it's so completely relaxed about this kind of thing. It gives you the bare bones of what's necessary for an object system, and you build whatever you want on top of it -- even with the guts exposed all over the place.

The problem with this is: you _have_ to build it yourself. If I only get the basic building blocks and have to reapply them over and over again to get the same result (a bunch of classes with methods and state) then I am wasting time. A genuine object oriented language is much superior.

Kind regards

  robert

ยทยทยท

On 09.02.2009 19:15, David Masover wrote:

<snip>

I haven't done enough C to say for sure, but I loved Perl's OO. There
definitely seems to be more there -- inheritance via @ISA, constructors via
bless -- and while some find it ugly to expose all the underpinnings, that
is one thing I love about Perl.

Are you aware that Perl's MI via @ISA is probably the worst way one
can implement MI in?
That said I admit that one can write nice OO code in Perl with some discipline.

Cheers
Robert

ยทยทยท

On Mon, Feb 9, 2009 at 7:15 PM, David Masover <ninja@slaphack.com> wrote:

--
It is change, continuing change, inevitable change, that is the
dominant factor in society today. No sensible decision can be made any
longer without taking into account not only the world as it is, but
the world as it will be ... ~ Isaac Asimov

it is unacceptable to a great many readers either to resort to
  nontraditional gimmicks to avoid the generic masculine (by using he/she
  or s/he, for example) or to use they as a kind of singular pronoun.

ยทยทยท

On Sun, Feb 08, 2009 at 10:23:15AM +0900, Nico Bonada wrote:

William James wrote:
>
> "one" is singular, so it's "best meets his".
>

Singular they - Wikipedia

--
Chad Perrin [ content licensed OWL: http://owl.apotheon.org ]
from an MS Access tutorial manual: "Programmatically is a Microsoft
euphemism for 'with many lines of code.'"

Chad Perrin wrote:

ยทยทยท

On Mon, Feb 09, 2009 at 12:09:52AM +0900, Julian Leviston wrote:

You could also look into The project to concert ruby to obj-c which is compiled. Am I dreaming? I can't remember the name

Wait . . . seriously? I need to find this project. That sounds like
fun.

i googled, but couldn't find anything -- if you happen to run across it pls ping me with the url

thanks,
reid

William James wrote:

Reid Thompson wrote:

Reid Thompson wrote:

Ruby Elapsed 0.045477

#!/usr/local/bin/ruby

require 'rubygems'
require 'inline'

BAILOUT = 16
MAX_ITERATIONS = 1000

class Mandelbrot

     def initialize
         puts "Rendering"
         for y in -39...39 do
             puts
             for x in -39...39 do
                 i = iterate(x/40.0,y/40.0)
                 if (i == 0)
                     print "*"
                 else
                     print " "
                 end
             end
         end
     end

     inline do |builder|
         builder.c "
         int iterate (double x, double y)
         {
             int BAILOUT = 16;
             int MAX_ITERATIONS = 1000;
             double cr = y-0.5;
             double ci = x;
             double zi = 0.0;
             double zr = 0.0;
             double zr2 = 0.0;
             double zi2 = 0.0;
             int i = 0;
             double temp = 0.0;

             while (1)
             {
                i += 1;
                temp = zr * zi;
                zr2 = zr * zr;
                zi2 = zi * zi;
                zr = zr2 - zi2 + cr;
                zi = temp + temp + ci;

                if ( zi2 + zr2 > BAILOUT)
                {
                    return i;
                }
                if ( i > MAX_ITERATIONS)
                {
                    return 0;
                }
             }
         }"
     end

end

time = Time.now
Mandelbrot.new
puts
puts "Ruby Elapsed %f" % (Time.now - time)

Using the functional language F#:

0.0400575999999999 on my laptop with 2GHz Pentium.

On same box using all C.
Echo delay is 0s and 20842us -> 20842 microseconds = 0.020842 seconds. This is an Intel(R) Core(TM)2 CPU 6320 @ 1.86GHz box w 2GB RAM running gentoo with entire system compiled with CFLAGS="-march=prescott -O2 -g -pipe" + feature splitdebug ( everything compiled with debug except mandInC ).
-rwxr-xr-x 1 rthompso staff 7104 2009-02-10 23:36 mandInC

time calc code pulled from the web...

rthompso@raker ~ $ cat mandInC.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/**
  * this function is for computing the time difference between timeval x and y
  * the result is stored in result
  */
int
timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y)
{
     /* Perform the carry for the later subtraction by updating y. */
     if (x->tv_usec < y->tv_usec) {
         int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
         y->tv_usec -= 1000000 * nsec;
         y->tv_sec += nsec;
     }
     if (x->tv_usec - y->tv_usec > 1000000) {
         int nsec = (x->tv_usec - y->tv_usec) / 1000000;
         y->tv_usec += 1000000 * nsec;
         y->tv_sec -= nsec;
     }

     /* Compute the time remaining to wait.
     tv_usec is certainly positive. */
     result->tv_sec = x->tv_sec - y->tv_sec;
     result->tv_usec = x->tv_usec - y->tv_usec;

     /* Return 1 if result is negative. */
     return x->tv_sec < y->tv_sec;
}

int iterate (double x, double y)
{
     int BAILOUT = 16;
     int MAX_ITERATIONS = 1000;
     double cr = y-0.5;
     double ci = x;
     double zi = 0.0;
     double zr = 0.0;
     double zr2 = 0.0;
     double zi2 = 0.0;
     int i = 0;
     double temp = 0.0;

     while (1)
     {
         i += 1;
         temp = zr * zi;
         zr2 = zr * zr;
         zi2 = zi * zi;
         zr = zr2 - zi2 + cr;
         zi = temp + temp + ci;

         if ( zi2 + zr2 > BAILOUT)
         {
             return i;
         }
         if ( i > MAX_ITERATIONS)
         {
             return 0;
         }
     }
}

int main()
{
     int y = -39;
     int x = -39;
     int i = -1;
     struct timeval start, stop, echodelay; // start, stop and echo delay times

     if((gettimeofday(&start, NULL)) == -1)
     {
         perror("gettimeofday");
         exit(1);
     }
     for (y = -39; y <= 39; ++y)
     {
         printf("\n");
         for (x = -39; x <= 39; ++x)
         {
             i = iterate(x/40.0, y/40.0);
             if (i == 0)
                 printf("*");
             else
                 printf(" ");
         }
     }

     if((gettimeofday(&stop, NULL)) == -1)
     {
         perror("gettimeofday");
         exit(1);
     }
     /* compute time delay */
     timeval_subtract(&echodelay, &stop, &start);

     printf("\nEcho delay is %ds and %dus\n", echodelay.tv_sec, echodelay.tv_usec);

     return 0;
}

William James wrote:

Reid Thompson wrote:

> Reid Thompson wrote:
> >
> > Ruby Elapsed 0.045477
> >
> >
> #!/usr/local/bin/ruby
>
> require 'rubygems'
> require 'inline'
>
> BAILOUT = 16
> MAX_ITERATIONS = 1000
>
> class Mandelbrot
>
> def initialize
> puts "Rendering"
> for y in -39...39 do
> puts
> for x in -39...39 do
> i = iterate(x/40.0,y/40.0)
> if (i == 0)
> print "*"
> else
> print " "
> end
> end
> end
> end
>
> inline do |builder|
> builder.c "
> int iterate (double x, double y)
> {
> int BAILOUT = 16;
> int MAX_ITERATIONS = 1000;
> double cr = y-0.5;
> double ci = x;
> double zi = 0.0;
> double zr = 0.0;
> double zr2 = 0.0;
> double zi2 = 0.0;
> int i = 0;
> double temp = 0.0;
>
> while (1)
> {
> i += 1;
> temp = zr * zi;
> zr2 = zr * zr;
> zi2 = zi * zi;
> zr = zr2 - zi2 + cr;
> zi = temp + temp + ci;
>
> if ( zi2 + zr2 > BAILOUT)
> {
> return i;
> }
> if ( i > MAX_ITERATIONS)
> {
> return 0;
> }
> }
> }"
> end

>
> end
>
>
> time = Time.now
> Mandelbrot.new
> puts
> puts "Ruby Elapsed %f" % (Time.now - time)

Using the functional language F#:

0.0400575999999999 on my laptop with 2GHz Pentium.

let bailout = 16.0
let max_iterations = 1000

let iterate x y =
  let cr = y - 0.5 and
      ci = x and
      zi = 0.0 and
      zr = 0.0 in
  let rec loop zi zr i =
    if i > max_iterations then
      0
    else
      let temp = zr * zi and
        zr2 = zr * zr and
        zi2 = zi * zi in
      if zi2 + zr2 > bailout then
        i
      else
        loop (temp + temp + ci) (zr2 - zi2 + cr) (i + 1)
  in
  loop zi zr 1

let mandelbrot () =
  for y = -39 to 38 do
    print_endline "";
    for x = -39 to 38 do
      let i = iterate
        (float x / 40.0) (float y / 40.0) in
      System.Console.Write( ( if 0 = i then "*" else " " ) )
    done
  done

let start_time = Sys.time ()
let _ = mandelbrot ();
print_endline "";
System.Console.Write (Sys.time () - start_time)

Using the built-in type complex makes the program shorter but
slower.

open Math.Complex;

let max_iterations = 1000

let iterate cmp =
  let rec loop z i =
    if i > max_iterations then
      0
    else
      if magnitude z >= 2.0 then
        i
      else
        loop (z * z + cmp) (i + 1)
  in
  loop zero 1

let mandelbrot () =
  for y = -39 to 38 do
    print_endline "";
    for x = -39 to 38 do
      let i = iterate
        (complex ((float y / 40.0) - 0.5) (float x / 40.0)) in
      System.Console.Write( ( if 0 = i then "*" else " " ) )
    done
  done

let start_time = Sys.time ()
let _ = mandelbrot ();
print_endline "";
System.Console.Write (Sys.time () - start_time)

Yeah it's macruby

Blog: http://random8.zenunit.com/
Learn rails: http://sensei.zenunit.com/

ยทยทยท

On 11/02/2009, at 8:24 AM, Chad Perrin <perrin@apotheon.com> wrote:

On Mon, Feb 09, 2009 at 12:09:52AM +0900, Julian Leviston wrote:

You could also look into The project to concert ruby to obj-c which is
compiled. Am I dreaming? I can't remember the name

Wait . . . seriously? I need to find this project. That sounds like
fun.

--
Chad Perrin [ content licensed OWL: http://owl.apotheon.org ]
Power corrupts. The command line corrupts absolutely.

Robert Klemme wrote:

Robert Klemme wrote:

Yes, you can program OO style in Perl and there is /some/ support for
this - but it does not really give you much advantage over doing OO in
C (yes, you can do that: even std libraries do it, see open and fopen
et al).

I haven't done enough C to say for sure, but I loved Perl's OO. There definitely seems to be more there -- inheritance via @ISA, constructors via bless -- and while some find it ugly to expose all the underpinnings, that is one thing I love about Perl.

IMHO Perl makes OO unnecessary hard.

Very true. Most CPAN modules manage it anyway, these days, but I agree -- OO doesn't have to be that hard.

It is fun, though.

It's also one of the same reasons I love Ruby -- I don't have to get my hands dirty.

"Same reason"? That sounds strange to me.

I love Ruby because I don't have to get my hands dirty. I love Perl because I'm always getting my hands dirty, pretty much out of necessity.

It's something that's unique to each, and something that I love about each, under different circumstances.

Arguments are simply passed in as an array, which you can either unpack or not, as you like.

You can do that in Ruby as well.

Yes, I understand. However, if you look at your example:

def initialize(*a)
  what, ever, you_like = a

You're still explicitly accepting one positional argument -- it just happens to be the magical one that instead matches "zero or more of the remaining positional arguments".

For the same reason, I also find it kind of cool that Perl objects are typically just hashes with methods attached. Ruby objects, while effectively the same thing, tend to hide instance variables away. I like that, it's a cleaner approach, but it is still fun to take a hash of options, perhaps filter them, and then bless them as an object.

Occasionally, this actually is more convenient. For instance, in Ruby, I too often find myself writing code like this:

class Foo
  attr_reader :some, :random, :args
  def initialize some, random, args
    @some = some
    @random = random
    @args = args
  end
end

Or worse, let's say I don't like positional arguments (and I don't):

class Foo
  attr_reader :some, :random, :args
  def initialize options
    @some = options[:some]
    @random = options[:random]
    @args = options[:args]
  end
end

Or worse, say I've written some setters that do something magical. I then want to set those if they've been passed in:

class Foo
  attr_reader :some, :random, :args
  def initialize options
    self.some = options[:some] unless options[:some].nil?
    self.random = options[:random] if options[:random].nil?
    self.args = options[:args] if options[:args].nil?
  end
end

Yes, I could do some metaprogramming. I should stress that I do prefer Ruby to Perl, for exactly that reason -- if this ever gets too annoying, I can probably do something like the following, which has probably already been done somewhere:

module AutoInitializer
  def self.included klass
    klass.extend ClassMethods
  end
  module ClassMethods
    def auto_init *args
      include(Module.new do
        attr_accessor *args
        define_method :initialize do |options|
          args.each do |arg|
            if options.has_key? arg
              self.send "#{arg}=", options[arg]
            end
          end
        end
      end)
    end
  end
end

Now my class is only this:

class Foo
  include AutoInitializer
  auto_init :some, :random, :args
end

That's arguably better, but a bit more work at the beginning. Still, it's worth comparing to the Perl solution:

sub init {
  my($class, $self) = @_;
  bless $self => $class;
}

Granted, there are better ways to do that. It's certainly going to get hairier if there are going to be setters involved. But that is one of the fun side effects of what, at first, seams like a haphazard, tacked-on design.

JavaScript is similar, in some respects. Suppose someone passes me in a hash of options. Well, hashes are objects, so I can just do this:

function Foo(obj) {
  for (var property in obj) {
    this[property] = obj[property]
  }
};

Bam. Not only instant options, but instant extensibility -- nothing prevents a user from passing in a function to override one of mine, thus creating a singleton descendant of my class.

I'm going to stop now, because this is getting a bit long, and the core point hasn't changed -- I like Ruby, and I see how this kind of stuff can be done in Ruby, but I wouldn't immediately dismiss these other object systems.

my $foo_like_thing = Bar::new();
Foo::bar($foo_like_thing, $some_other_arg);

The current object is passed in as an argument, meaning this is just another subroutine -- it lets you do tricks like this:

What does this? Does it create a Bar and then initializes it as Foo?

No, it creates a Bar, and calls Foo's bar method on it, if I've gotten the syntax right.

Kind of like Javascript's call() and apply() -- and I'm not even sure this can be done in Ruby. For all the duck typing goodness, I can't seem to figure out how you'd unbind a method and rebind it to something of an unrelated class, unless there's an explicit tree of inheritance.

Why would you want to do that? There's a reason why both classes are unlrelated, i.e. chances are that the method would not work in the other class / object. If you want to simply share code then you can use modules which is a much cleaner and safer way to do it.

Indeed, modules are usually the saner choice. However, I have done this _often_ in Javascript. Probably the simplest example might be the common each loop:

function each(array, func) {
  for (var i in array) {
    func.call(array[i], i);
  }
}
each(['one','two','three'], function(i) {
  // now 'this' is bound to the value
});

Granted, that's a toy, but it is more convenient that way. And then there are the cases where you want to do something clever -- say you have multiple superclasses:

var Bar = {
  // one big pile of funcitons
}
var Super = {
  // another big pile of functions
}
obj.foo = function() {
  if (i_want_super) {
    Super.bar.apply(this, arguments);
  } else {
    Bar.foo.apply(this, arguments);
  }
}

Maybe some of those are actually superclasses. Maybe they're modules, and you only need a single method, not the whole module.

Either way, I would put the burden back on you. Why is this so dangerous? Why is it any more dangerous than the other duck typing tricks Rubyists use every day? Why shouldn't I be able to do:

a.method(:foo).unbind.bind(b)

when a and b aren't related, but I happen to know they share a common theme? After all, what ties the method to the object -- isn't it mostly going to be calling instance methods, and occasionally accessing instance variables -- so why should 'self' be exempted from the "quacks like" rule?

The problem with this is: you _have_ to build it yourself. If I only get the basic building blocks and have to reapply them over and over again to get the same result (a bunch of classes with methods and state) then I am wasting time.

And then you discover one of the most basic tools in any language: A library.

Take my above AutoInitializer example. I could complain that I have to reinvent it every time, but clearly I don't. I can just file it away in a file called autoinit.rb, and if it turns out to be original, I can upload a gem.

Or I can decide to use openstruct instead.

What matters is how powerful those basic building blocks are, and what it looks like when you're finished.

ยทยทยท

On 09.02.2009 19:15, David Masover wrote:

I could be entirely wrong on this, but http://macruby.org seems to describe something like what you were looking for?

Just a thought.

-Zac

ยทยทยท

On Feb 10, 2009, at 7:45 PM, Reid Thompson wrote:

Chad Perrin wrote:

On Mon, Feb 09, 2009 at 12:09:52AM +0900, Julian Leviston wrote:

You could also look into The project to concert ruby to obj-c which is compiled. Am I dreaming? I can't remember the name

Wait . . . seriously? I need to find this project. That sounds like
fun.

i googled, but couldn't find anything -- if you happen to run across it pls ping me with the url

thanks,
reid