Ruby vs Perl performance

  • Thread starter Vetrivel Vetrivel
  • Start date
D

David Masover

Igor said:
OO itself is not chaotic and does not, as I have already said, promote
anarchy, which you are suggesting.

Was I suggesting anarchy? I thought I was suggesting a specific feature:
Rip a method out of one class and apply it to another.

I fail to see how that's more inherently anarchistic than:

- Re-opening classes at runtime
- Redefining methods, or whole classes, also at runtime
- Adding a method or mixing a module into just one instance
- All of the above with user input (eval)
- Doing no type checking whatsoever
- Overriding basic operators (make 2+2==5)
- Corrupt basic assumptions (make nil.nil? false) and crash

Ruby's strength is in what you're calling "anarchy" -- except when you
choose to call it "flexibility".
There are rules that have to be
adhered to, only they are much more relaxed than are rules in
hierarchical structured pyramids of structured organizations. [snip]
There are rules that govern the freedom of selecting
procedural or structured methods, and when to abide by the orthogonal OO
principles. Failing to understanding these principles leads to chaos and
anarchy.

You've certainly not done a good job of explaining or defining such rules.
The fact that you see meritocracy in the same light as
aristocracy

Show me where I said that.
In procedural languages you have to enforce these rules
yourself, in OO ideally the language enforces these concepts.

Erm... Why aren't you using Java again?

If I wanted a language to enforce those rules, I'd be back to something
like:

class Hello {
public static void main(String [] args) {
System.out.println("Hello, world!");
}
}

I don't. It's fine if the language can enforce them -- in Perl, I can do
things like 'use strict' or 'use warnings'. In Ruby, I can simply grep
through my source files to make sure I haven't stooped to using eval
anywhere I don't absolutely have to.

So, if there was an UnboundMethod#bind! method, which would bind that
method to an object completely unrelated, I could choose not to use that
method. So could you. I don't see how its very existence threatens that.

It's a lot easier to ignore functionality you don't need than it is to
find functionality you do need missing.
Module is
not a class,

Actually, Module _is_ a class.
And
lastly, an instance method should not be treated as a loosely defined
function, nor should an object exhibit some foreign behaviour of some
arbitrary function, it totally violates encapsulation.

So do:

- instance_variable_set
- instance_variable_get
- send
- instance_eval
- Binding#eval
- extend
- class << foo

And, to a lesser extent:

- Modules as mixins (unless _very_ carefully written, they're touching
the same instance variable namespace)
- class_eval
- include
- const_set
- define_method

Am I missing any?

If you wanted a language that enforced encapsulation, I say again, go
back to Java, or to C++. You'll find encapsulation in Ruby is every bit
as much convention as it is in Perl.

The language makes it harder to violate that convention by accident,
that's all. And if you want to enforce it, all you have to do is grep
through your codebase for cases of instance_variable_set, and similar
constructs.

Take a quick look at that first list. Have you really never used any of
those? Are you sure?
Your propositions
and suggestions translate into total chaos and anarchy, where any
identity could be shared among all members of the universe

I'm suggesting that it be possible to rebind a method.

Again: How is that worse than any of the above? You're acting as if it
would destroy the fabric of the universe!

I was expecting opposition along the lines of "This would be difficult,
the way the Ruby interpreter is written." Instead, I'm getting the kind
of response I would expect from the bad old Rails community: "You can't
do that because we think it's a bad idea, so we're protecting you from
yourself."
many objects are actors and actors are subjects with
responsibilities and behaviours, by which you classify them.

Right. I don't know about you, but I classify them by their actual,
demonstrated behavior, not their ancestry.

Why, then, does the system for copying methods from one object to
another restrict by ancestry, and not by behavior?
This is is pure baloney. Perl was designed as such,

And Linux was designed as a terminal emulator. Quite literally. Look
where it is now.

Now who's arguing aristocracy? Perl can never be OO, because it wasn't
designed that way? Languages evolve.
The
same is true for JavaScript, which, metaphorically speaking, became of
old age only after ten years of it's existence.

That only shows how little you know about JavaScript. It was actually
originally written as a dialect of LISP, and only later given a C-like
syntax to make the PHBs happy.

Because of its Lisp heritage, I can guess, but cannot prove, that it
always had closures, and always had functions as first-class objects.
Attempting to look at the history of object-oriented Javascript, you
find that it is mostly about people finding ways to express the kind of
object systems they want, using the powerful prototypal object system
that was already in place.

In fact, when it comes down to it, there's no reason you can't program
Javascript the way you program Ruby. It's not difficult to write a sane
each() method, or add a class hierarchy (as opposed to prototypal
inheritance). However, it is much more difficult to write Ruby the way I
wrote Javascript, when I had to use it for more than just a web client,
and some things, as I've mentioned, are actually impossible. You speak
of "anarchy", but it worked, and it worked very well.
 
W

William James

Reid said:
William James wrote:

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

To make timing more accurate, let's calculate the set 100 times
but draw it only 1 time.

Result: 1.99286559999999 (laptop with 2GHz Pentium M)


(** Note that bailout has been changed. **)
let bailout = 4.0
let max_iterations = 1000


let iterate ci cr =
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 0.0 0.0 1

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


let start_time = Sys.time () in
for iter = 1 to 100 do
mandelbrot iter
done;
print_endline "";
System.Console.Write (Sys.time () - start_time);
print_endline "";
 
I

Igor Pirnovar

David said:
I fail to see how that's more inherently anarchistic than:

- Re-opening classes at runtime
- Redefining methods, or whole classes, also at runtime
- Adding a method or mixing a module into just one instance
- All of the above with user input (eval)
- Doing no type checking whatsoever
- Overriding basic operators (make 2+2==5)
- Corrupt basic assumptions (make nil.nil? false) and crash

Indeed, all this can lead to anarchy and chaos, but that is your doing!
There must be a reason for redefining a class, if it is a subversion
than indeed it is anarchy, but how many creators sabotage their own
creation?. Language enforcing the rules does not mean that it should
stop you from making incorrect assumptions such as 2+2==5.
Statistically, type checking is not needed and mostly presents an
unnecessary clutter in the code with little if any benefit at all. And
what's nil.nil - some devilish construct of yours?
Ruby's strength is in what you're calling "anarchy" -- except when you
choose to call it "flexibility".

I do not call Ruby anythingexcept OOPL from start to the end. And most
certainly all that you call inherently anarchistic above if used to
model the reality you are trying to reproduce with your design is power
unheard of in the traditional OOPLs.
You've certainly not done a good job of explaining or defining such
rules.

I did not invent nor made up those rules, they are spelt out in Booch,
and nicely packed in design patterns. You can adhere to these rules in
any language even assembler, it only is much harder to do so in
procedural languages. Besides, it is not so much about following these
rules as understanding them. Your misplaced comments about most of the
details you are bringing up in this discussion and most noticeably about
encapsulation show a serious deficit in this area on your part.
Show me where I said that.

Are not the following your words: "Except that Ruby enforces the
aristocracy with respect to which methods
belong to which classes". I have gone to great length explaining the
difference between taxonomy that classifies things by its membership and
the other that takes into account the merits. The two are orthogonal and
do not mix as you are suggesting by attributing knighthood based on
behaviour (activity, methods, functions, processing) rather on ancestral
principles based on name or membership, as is known to us throughout the
history.
... It's fine if the language can enforce them -- in Perl, I can do
things like 'use strict' or 'use warnings'...
Again you are mixing apples and oranges. Perl's strict does not qualify
for encapsulation, orthogonality of aggregation or composition and
inheritance, for rule of favouring delegation over inheritance,... heck
I do not even know you understand what I am talking about! And I have no
time explaining or defining all this to you. For any OO programmer,
designer or analyst these are pure facts nobody questions or doubts any
more.
So, if there was an UnboundMethod#bind! method, which would bind that
method to an object completely unrelated, I could choose not to use that
method. So could you. I don't see how its very existence threatens that.

You are a master of sabotage. I believe you do this only in forum
discussions and not to your code and creative processes, however if this
writing is a creative process, you must somewhat of an anarchist.
It's a lot easier to ignore functionality you don't need than it is to
find functionality you do need missing.

And what a generality is again this? I have not found it in any of the
pertinent methodologies discussed here. Most likely it is a convenient
concoction of yours for the sake of argument and no substance or merit
for that matter.
Actually, Module _is_ a class.

Modularity packs abstractions into discrete units. Abstractions are
represented by classes. There is no way on the Earth to turn this
definition around. Namely a class can never be a module nor is module a
class as you are suggesting. Yes, you could make your own concoctions
but that ain't gonna be OO!
Am I missing any?

As I have shown you above, a great deal and much more.

Have fun, cheers
 
R

Reid Thompson

as info -- pulled down and configured F# et al on my box.
compiled and ran the above code via Mono/F# -- gets in the .08xxx range
fairly consistently -- best run 0.075988
 
R

Reid Thompson

as info -- pulled down and configured F# et al on my box.
compiled and ran the above code via Mono/F# -- gets in the .08xxx range
fairly consistently -- best run 0.075988

not very familiar with mono/et al --- compiled with --optimize,
regularly gets in the .7xxx range, best 0.06399
 
D

David Masover

Igor said:
David Masover wrote:



Indeed, all this can lead to anarchy and chaos, but that is your doing!

Exactly my point. So if I am allowed these things which can lead to
anarchy, why am I not allowed this other thing that can lead to anarchy?

Unless you mean they are "my doing" in that I wrote these capabilities
into Ruby, which I didn't.
Language enforcing the rules does not mean that it should
stop you from making incorrect assumptions such as 2+2==5.

I'm talking about:

class Fixnum
alias_method :eek:ld_plus, :+
def +(other)
if self == 2 && other == 2
5
else
self.old_plus(other)
end
end
end
Statistically, type checking is not needed and mostly presents an
unnecessary clutter in the code with little if any benefit at all.

Ok, but what does that have to do with statistics? And does it not
strictly enforce the rules you seem to care about?
And
what's nil.nil - some devilish construct of yours?

All objects respond to .nil?, and I'm surprised you made it this far in
a discussion of Ruby without knowing about this.

And, since classes are open, you can do this:

class NilClass
def nil?
false
end
end

Go ahead, type that into irb. Watch it crash on the very next command.
power
unheard of in the traditional OOPLs.

Traditional, like, I don't know, Smalltalk? It seems just as reflective.
Are not the following your words: "Except that Ruby enforces the
aristocracy with respect to which methods
belong to which classes". I have gone to great length explaining the
difference between taxonomy that classifies things by its membership and
the other that takes into account the merits. The two are orthogonal and
do not mix as you are suggesting by attributing knighthood based on
behaviour (activity, methods, functions, processing) rather on ancestral
principles based on name or membership, as is known to us throughout the
history.

Except that which objects are allowed to have a certain method is
restricted entirely by ancestral principles.

I did not say that I saw a meritocracy in the same light as an
aristocracy -- that's something you're inferring beyond what I actually
said. In this particular instance, Ruby is _not_ a meritocracy.
Again you are mixing apples and oranges. Perl's strict does not qualify
for encapsulation, orthogonality of aggregation or composition and
inheritance,

True enough. It is, however, an example of choice vs being forced to --
Perl's strict mode will force me to declare variables. However, if I
don't turn it on, the language will let me define variables as I like.

It is an unrelated feature, but Ruby does similar things -- in 1.9, we
have send and public_send. If I want to be safe, and respect
encapsulation, I use public_send. If I don't, I use send.
And I have no
time explaining or defining all this to you. For any OO programmer,
designer or analyst these are pure facts nobody questions or doubts any
more.

Clearly, I am an OO programmer. And clearly, I doubt them.

And clearly, you have time to write long, rambling responses that
_don't_ explain these principles. Argument from Authority?
You are a master of sabotage.

Nice ad-hominem. It doesn't answer my question.
And what a generality is again this? I have not found it in any of the
pertinent methodologies discussed here.

No, I consider it to be a self-evident truth, and something you see in
the design of Ruby.

For example: The ability to deliberately break encapsulation, and use
instance_eval, or send instead of public_send, etc, is something I've
certainly found useful in my own code. Tell me, have you never found a
use for these? Or even for class_eval?

How would you feel if someone removed them, because they felt they were
"sabotage", that they violated the "purity" of Ruby's OO system?

Certainly, you don't want to just be using them all the time, because
that would lead to, as you said, "anarchy". But when you need them, you
need them, and nothing else will do.
Modularity packs abstractions into discrete units. Abstractions are
represented by classes. There is no way on the Earth to turn this
definition around. Namely a class can never be a module nor is module a
class as you are suggesting.

Modules are not classes, you are right. However, the global constant
Module is a class. That is what I meant.

Oh, and classes are modules. You can verify this for yourself:

Class.new.kind_of? Module
 
M

Mike Gold

Igor said:
I did not invent nor made up those rules, they are spelt out in Booch,
and nicely packed in design patterns. You can adhere to these rules in
any language even assembler, it only is much harder to do so in
procedural languages. Besides, it is not so much about following these
rules as understanding them. Your misplaced comments about most of the
details you are bringing up in this discussion and most noticeably about
encapsulation show a serious deficit in this area on your part.

This is the most telling part of the voluminous stream of consciousness
you've been piping to comp.lang.ruby lately.

If you are committed to measuring everything in accordance with Booch,
you will find a whole legion of sinners here. Indeed, that I and others
keep wondering why you are not using Java or C++ makes sense in light of
this. For the most part Ruby goes duck-typing route, which is
fundamentally different than the route of Java or C++
patterns/methodologies you find in Booch.

Ruby is like Lisp in this regard. The flexibility is there to allow a
program to adapt to new information found only at runtime. A program is
able to rewrite itself according to the situation. This is the
essential power which made Lisp suitable for AI. It is impossible in
Java or C++, unless you greenspun a half-ass lisp interpreter to do what
you need (http://en.wikipedia.org/wiki/Greenspun's_Tenth_Rule).

Take the example of delegation. There is no notion of Java-like
interfaces or C++-like classes of just pure virtuals. In Ruby a
delegate can have no relation, ancestry-wise, to the object it wraps.
It violates all the Booch rules: it should be outlawed!

Yet that's the Ruby way: create an object and "let it ride". Just start
quacking and go. To hell with the indoctrination ceremonies which
bestow permission to quack. Strange women lying in ponds distributing
swords is no basis for a system of government!
 
D

David Masover

Chad said:
Really? Without templating, I'm not sure there's a *point* to PHP. It's
basically Perl with a lot of the good stuff stripped out, and templating
added into the core language.

Very true. However, templating as a part of the core language is perhaps
one of the stranger parts of it, and is certainly something which is
ripe for abuse.

I think the main point to PHP now is sheer ubiquity -- all the apps
already written in PHP, including some really impressive systems like
Drupal, and all the hosts which provide PHP out of the box, with the
programmer having to do nothing more complicated than FTP to deploy.
This also makes it dangerously quick to pick up -- you've already got a
cheap and/or free website that lets you FTP in some static HTML files,
and you want to, say, add a hit counter. Copy and paste some snippet
into that HTML, change the extension to .php, and you're now a PHP
developer.

Either way, that is sort of a representative sample -- templating is
part of the core language. It's really something that ought to be done
in a library -- there's more than one good templating system (haml,
anyone?), and you don't want your entire program to be a template.

Perl used to be the same way, though. I think a recent release --
"recent" meaning "within the past five years or so" -- they moved
"formats" out of the core language and into a library.

But I think that's getting even more offtopic, so to bring it back to
Ruby... The one piece that really seems out of place is the Regex
syntax, but I can't complain. Everything else, whether pure or not,
comes together in such a way as to make it easy to turn it into whatever
you need -- Markaby is another example of why not to build templating
into the core language. Why put something in the core language when it
can be done in a DSL?
 
D

David Masover

Robert said:
Are you aware that Perl's MI via @ISA is probably the worst way one
can implement MI in?

I've been thinking about it for a bit, and no, I'm really not. Aside
from (maybe) performance, what's wrong with that implementation? After
all, Ruby has Module#ancestors, and the trick is older than dirt as the
various PATH variables in Unix.
 
W

w_a_x_man

To make timing more accurate, let's calculate the set 100 times
but draw it only 1 time.

Result:  1.99286559999999  (laptop with 2GHz Pentium M)

(**  Note that bailout has been changed.  **)
let bailout = 4.0
let max_iterations = 1000

let iterate ci cr =
  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 0.0 0.0 1

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

let start_time = Sys.time () in
for iter = 1 to 100 do
  mandelbrot iter
done;
print_endline "";
System.Console.Write (Sys.time () - start_time);
print_endline "";

This is over twice as fast as the OCaml version.
F# is impressive.
 
R

Robert Klemme

It does, actually, assuming you called it with a hash of options. Perl
objects are most commonly a blessed hash.

That's the first flaw of Perl's OO: you have the free choice to use
hashes or arrays (or even scalars?) as objects.
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.
-> OpenStruct

Maybe I should read the docs, but as I understand it, in Javascript, I
can do this:

f = Foo({
a: 'some_string',
b: 12345,
c: function() {
// some method
}
});

I could even do:

f = Foo(new Bar());

thus creating a spontaneous new child of both Foo and Bar. Keep in mind
that both Foo and Bar are classes, each of which may have methods of
their own -- in this case, Bar's methods (or properties) override Foo's.

Really? I'd say they are overridden by Foo's because this comes later.
But I'm not a JavaScript expert.
To get something even close in Ruby, I'd have to do this:

f = OpenStruct.new
class << f
def c
#some method
end
end

No. This is a one off shot. To get the equivalent of the JavaScript
version (if my JS does not fail me), you need to define a method which
does the initialization, e.g.

def Foo(o = Object.new)
class <<o
attr_accessor :bar, :baz

def c
printf "bar=%4d, baz=%4d\n", bar, baz
end
end

o.bar = 123
o.baz = 890

o
end

Then you can do

x = Foo
y = Foo(Bar.new)
z = Foo(any_other_expression)

Although I have to say that I'd rather package this in a module and do

module Foo
def self.create(o = Object.new)
o.extend(self)
o.bar = 123
o.baz = 890
o
end

attr_accessor :bar, :baz

def c
printf "bar=%4d, baz=%4d\n", bar, baz
end
end

<snip/>

The details really do not matter. My point is simply this: I prefer to
use Ruby over Perl because of the clean syntax as well as the profound
OO. And I still have all (or at least most of) the options I have in
Perl's bare metal world. I find the balance in Ruby highly superior.
There are, however, libraries to make the OO less painful in Perl.

Which still makes them non core artifacts and leave the option for
multiple OO models in the same program. Doesn't sound healthy to me.
Now, not doing that often is probably a good idea -- not using
Kernel#eval often might also be a good idea. But I don't like it when a
tool tells me what I may or may not do, simply because it's not a good idea.

Maybe you haven't come to appreciate the power gained from restriction.
Often more creativity and productivity is unleashed in more restricted
environments.
I'm not trying to sell Perl's OO as the best thing, or even "better".
But I'm defending it as inherently less useful than Ruby's.

Is this really what you intended to say?
Someone
might as easily say that Ruby's OO is inherently less useful than
Java's, because Java does stricter (static) type-checking.

As always it depends on the point of view - or the criteria you apply.
I do mostly OO programming - even in scripts - and for that I appreciate
the way OO is done much more than Perl's way.

Cheers

robert
 
M

Michal Suchanek

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?

Actually you sort of can except the binding is not permanent.

module Kernel

module Q175
Require = Kernel.instance_method :require
def scan
...
end
end

undef_method :require
def require file
loc = Q175::scan file
res = Q175::Require.bind(self).call file
STDERR.puts "require: #{file} => #{loc}" if res && loc
res
end
end

Thanks

Michal
 
D

David Masover

Robert said:
That's the first flaw of Perl's OO: you have the free choice to use
hashes or arrays (or even scalars?) as objects.

Why is this a flaw? In Ruby, everything's an object. On closer
examination, we use instance variables in objects more or less the same
way a Perl object would use hash members.
Really? I'd say they are overridden by Foo's because this comes
later. But I'm not a JavaScript expert.

Since Foo is a user-definable function, it's actually entirely up to the
author of said function. I believe the sample I gave was using the
argument to override defaults in Foo.
No. This is a one off shot.

You're right. I was simplifying.
To get the equivalent of the JavaScript version (if my JS does not
fail me), you need to define a method which does the initialization, e.g.

def Foo(o = Object.new)
class <<o
attr_accessor :bar, :baz

def c
printf "bar=%4d, baz=%4d\n", bar, baz
end
end

o.bar = 123
o.baz = 890

o
end

I suppose that is roughly equivalent. I would have chosen something
else, like:

module Foo
def a
...
end
...
end

def foo(o = Object.new)
o.send :include, Foo
end

So, you can get close with something like:

foo(
OpenStruct.new(
:a => 'some_string',
:b => 12345
).extend(Module.new {
def c
# some method
end
})
)

I don't know about you, but that reads a lot less naturally to me.
Fortunately, Ruby is flexible enough that if I really wanted it, I could
probably define some DSL that does the right thing -- something like:

foo(MyStruct.new {
a 'some_string'
b 12345
c do
# some method
end
})
The details really do not matter. My point is simply this: I prefer
to use Ruby over Perl because of the clean syntax as well as the
profound OO. And I still have all (or at least most of) the options I
have in Perl's bare metal world. I find the balance in Ruby highly
superior.

I agree. Or rather, not so much because the OO is profound, but because
it is much cleaner to access, for most things.
Which still makes them non core artifacts and leave the option for
multiple OO models in the same program.

I don't see that being more of a problem than duck typing vs other
models in Ruby.

If you want to be consistent within a program, write up a coding style
for that program. If you want your language to enforce a coding style,
Java and Python will each do that for you, in their own ways.
Maybe you haven't come to appreciate the power gained from
restriction. Often more creativity and productivity is unleashed in
more restricted environments.

Like Picasso's Blue Period, I get it. And it can certainly be useful for
learning.

I still don't see why it's good for the _environment_ to do that
restriction, rather than making it self-imposed. Certainly, I almost
never allow myself to use eval, and my code is better for it -- but note
that key word. _Almost_ never.
Is this really what you intended to say?

Probably not. Probably "defending it as _not_ inherently less useful..."
As always it depends on the point of view - or the criteria you apply.
I do mostly OO programming - even in scripts - and for that I
appreciate the way OO is done much more than Perl's way.

I do mostly OO programming, and I prefer Ruby -- but as a matter of
taste. I've just had enough experience with Perl to respect it, too,
even its object system.

I've also had enough experience with PHP to lose all respect for it...
The problem with PHP is they have absolutely no taste. (Apologies to
Steve Jobs.)
 
D

David Masover

Michal said:
Actually you sort of can except the binding is not permanent.

No, I don't think so. I've tried in a method somewhat similar to yours,
and I get the same results.
module Kernel

That's probably why. Everything includes Kernel, so if you grab an
UnboundMethod from Kernel, you should be able to apply it everywhere.

Try this:

module Foo
def foo
:foo #ok, I'm unimaginative
end
end

Foo.instance_method:)foo).bind(Object.new).call

See what happens? Doesn't matter whether Foo is a class or a module, you
can only bind methods of it to objects which are somehow its
descendants. If it's a module, you can only do this to things which have
included that module, making it somewhat less useful.

Speaking of which, modifying Kernel -- yet another thing more dangerous
than letting UnboundMethods bind to anything.
 
R

Reid Thompson

William said:
To make timing more accurate, let's calculate the set 100 times
but draw it only 1 time.

Result: 1.99286559999999 (laptop with 2GHz Pentium M)



Echo delay is 2s and 23737us

#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;
int loop = 1;
struct timeval start, stop, echodelay; // start, stop and echo delay times

if((gettimeofday(&start, NULL)) == -1)
{
perror("gettimeofday");
exit(1);
}

for (loop == 1; loop <= 100; ++loop)
{
for (y = -39; y <= 39; ++y)
{

if (loop == 1){printf("\n");}
for (x = -39; x <= 39; ++x)
{
i = iterate(x/40.0, y/40.0);
if (loop == 1)
{
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;

}
 
R

Reid Thompson

William said:
To make timing more accurate, let's calculate the set 100 times
but draw it only 1 time.

Result: 1.99286559999999 (laptop with 2GHz Pentium M)

mono + F# = 3.919404 ( hits 3.9x... range consistently)
 
I

Igor Pirnovar

(1)
--------------------
David said:
All objects respond to .nil?, and I'm surprised you made it this far in
a discussion of Ruby without knowing about this.

And, since classes are open, you can do this:

class NilClass
def nil?
false
end
end

Go ahead, type that into irb. Watch it crash on the very next command.

I have told you are the master of sabotage. Now tell me why on Earth
would one define things like { true==false } and { 2+2==5 }. I have more
trouble with Ruby crashing because of your sabotage! But that I can live
with, since I understand that Ruby internals depend on the premise {
true != false }!

As for your surprise that how far I have come, I must tell you that I am
only surprised I keep debating you. This is what happens when one
engages in public debates :( Much of what you are saying may be true
from your perspective, however, I simply do not have time to babble so
much.


(2)
----------------
Mike said:
If you are committed to measuring everything in accordance with Booch,
you will find a whole legion of sinners here. Indeed, that I and others
keep wondering why you are not using Java or C++ makes sense in light of
this. For the most part Ruby goes duck-typing route, which is
fundamentally different than the route of Java or C++
patterns/methodologies you find in Booch.

Perhaps you are mislead by the nature of the discussion here, which has
deformed into something other than what the thread's title suggests. I
am not an OO purist and should basically be rather surprised at most of
what you've said above, mostly because of how I entered this discussion.
Let me repeat:

Most likely, with my focus on OO, I am also responsible for the
splintering of this discussion into many branches. But the fact remains
that despite some of its immaturities Ruby is one of the best OOPLs
around today.

I have also repeatedly praised Ruby's inherent duck-typing philosophy,
which ironically seems to be one of the strongest points my opponents
make, when they mindlessly and unjustly build it up as significant
Ruby's flaw. The other point that I was arguing was that Ruby's
flexibility is not its fault but its strength, which again the opponents
of the idea that Ruby is setting standards for future OOP language
developments are constantly attacking with irrelevant arguments. They
support their attacks by dissecting nonsensical algorithms that in
normal circumstances indeed are inherently bad or even evil. Ruby with
many of its extensions, some of which indeed are shared with more
procedural Perl and OB (object-based) Lisp, but especially, as you say,
with its ability to allow programs to effectively rewrite and redefine
themselves at runtime, is a powerful tool. All these attributes do not
make Ruby a procedural language, it remains one of the best, if not The
best, OOPLs around today!
Take the example of delegation. There is no notion of Java-like
interfaces or C++-like classes of just pure virtuals. In Ruby a
delegate can have no relation, ancestry-wise, to the object it wraps.
It violates all the Booch rules: it should be outlawed!

I could not disagree more. You are suggesting the rigidity that can only
be attributed to literary interpretation of the "scripture". It is in
fact Ruby's virtue that it did away with unnecessary virtuals and
abstract classes. But as I am repeatedly saying, it is up to the
designer to ignore these features or reinforce them. Go ahead and
reinforce them with an "abstract" class of "virtual" methods that do
nothing but throw exceptions, to make sure you actually define them. At
the end My code will be shorter and more elegant, and true, for a Java
or C++ virtuoso perhaps less legible.

(3)
------------------
Chad said:
I'm not sure you're clear on the definition of "orthogonal".
. . . and OOP is actually very hierarchical in a lot of ways,
at least as practiced in most languages -- including, to a
lesser extent, Ruby.

The term "orthogonal" is not an OOM (OO methodology) term, though it is
often used in texts and discussions pertaining to OO. Its meaning in OOM
discussions is an evolved meaning that expands even the definition in
Oxford dictionary, where it is explained merely as something
"right-angled". Logically in OOM the term loosely means "the opposite".
An object organization is flat organization, and is orthogonal to
structured pyramid organization. "Is-a" relationship defines hierarchy
and is orthogonal to "has-a" relationship which represents aggregation
or composition. In flat organization one set of rules apply, while in
the structured organization orthogonal rules apply. In this respect
procedural programing is orthogonal to OOP. Now the tricky part is that
OO includes procedural programming as a "part-of" or a "has-a" thing.
This means that programming in procedural way in an OOPL should be
possible without any effort, however, the reverse is not true because
the two programming paradigms are orthogonal. Again this does not mean
that in procedural language it is not possible to program in OO
programing paradigm, it only takes extraordinary effort and/or overhead
to do so. This is how orthogonality is accounted for with respect to OOP
and procedural programming.

Perl is an excellent example of what was just said. It takes an
extraordinary effort to use it as an OOPL. It requires that the
programmer knows much more about OO rules than the programmer who uses
Ruby where everything is an object. A totally and utterly different
question is whether you use these languages correctly be it Perl, C,
C++, Java, Ruby or ooCobol. This is where most of us fail most of the
time, and that is why Design Patterns and Booch OOA/D exist.
 
D

David Masover

Igor said:

Why am I still feeding this troll?
Now tell me why on Earth
would one define things like { true==false } and { 2+2==5 }.

For fun.

But no, you wouldn't on a real project. Because despite what you seem to
think, the fact that a language feature is there doesn't in any way
imply that you have to use it.
I have more
trouble with Ruby crashing because of your sabotage!

Oh, you mean you've actually defined things like (nil.nil? == false)?
That's not very smart.
Much of what you are saying may be true
from your perspective, however, I simply do not have time to babble so
much.

And yet, obviously, you do, or we wouldn't have received this message.
Something to think about before you reply.

The only thing you don't seem to have time for is forming a logical
argument.
I have also repeatedly praised Ruby's inherent duck-typing philosophy,
which ironically seems to be one of the strongest points my opponents
make, when they mindlessly and unjustly build it up as significant
Ruby's flaw.

I don't think anyone's suggesting it's a flaw -- only that your
philosophy would seem to make it one.

For example, if duck typing is not a flaw, why should I not be able to
borrow methods from unrelated classes? If the method works, clearly the
two classes are of the same duck type.
The other point that I was arguing was that Ruby's
flexibility is not its fault but its strength,

Ah. So when it's flexibility you like, it's a strength. When it's
flexibility you don't like, it's "anarchy". Got it.
All these attributes do not
make Ruby a procedural language,

Ruby can, in fact, be used as an exceptionally good procedural language.
I could not disagree more. You are suggesting the rigidity that can only
be attributed to literary interpretation of the "scripture". It is in
fact Ruby's virtue that it did away with unnecessary virtuals and
abstract classes.

Looks like you also don't understand sarcasm.

I have never heard it used to mean that, in computer science or otherwise.

It means, roughly, neither dependent nor mutually exclusive -- if two
things are orthogonal, they have no side effects on each other.

For example, object oriented programming is orthogonal to regular
expressions. You can have a language with rich regex support and no OO,
or, conversely, a language with rich OO and no builtin regex support. Or
you can have a language with both -- in which case, you can probably
make large changes to the object system without affecting regexes, and
vice versa.

Within an object system, I might call two modules "orthogonal" if I can
include one, the other, neither, or both into my class without any
problems -- and, specifically, if I can include both without one
affecting the other. I believe Comparable and Enumerable are orthogonal
in that way.

Further reading:

http://en.wikipedia.org/wiki/Orthogonality#Computer_science

I think you'll probably find that you are the only person on this forum
using "orthogonal" to mean "opposite", because it does not. In fact, you
will not find "opposite" on that page -- despite wildly different
definitions in each of the _eight_ fields mentioned.

I wonder why you didn't simply say "opposite", if that's what you meant?
Or were you just trying to sound smart by using big words?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top