Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > ruby abstraction

Reply
Thread Tools

ruby abstraction

 
 
James O'Brien
Guest
Posts: n/a
 
      07-18-2010
[Note: parts of this message were removed to make it a legal post.]

Hi,

I'm a newbie with a background in Java. I've just about finished working
through an introductory ruby book and I didn't see anything about abstract
classes or indeed interfaces.

I have found the concept of an interface invaluable in my Java programming
and wondered if there were an equivalent concept in Ruby?

I'm open to the idea that interfaces might not be needed in Ruby but I'd
very much like this properly explained since as a thought-experiment I
propose Java without interfaces would be worse - therefore what is it
specifically about Ruby which means it is not as needed? I'm well versed in
the benefits of test driven code and documentation but we have this in Java
too (and still find interfaces a useful abstraction tool). So is there
something I'm missing or are interfaces something people here would like to
see added to the Ruby language? I agree Ruby is wonderful but loyalties
aside can someone actually put it in words for me why it doesn't need
interfaces.

many thanks for your replies

 
Reply With Quote
 
 
 
 
Steve Klabnik
Guest
Posts: n/a
 
      07-18-2010
[Note: parts of this message were removed to make it a legal post.]

There aren't interfaces in Ruby, because Ruby is dynamically typed. So
rather than see if an object is of the right type, you ask it if it responds
to a certain message, using Object#respond_to?

I'm open to the idea that interfaces might not be needed in Ruby but I'd
> very much like this properly explained since as a thought-experiment I
> propose Java without interfaces would be worse - therefore what is it
> specifically about Ruby which means it is not as needed?



It comes down to the whole dynamic/static thing. Ruby's philosophy is 'screw
the types, does it do what you want or not?'

 
Reply With Quote
 
 
 
 
David Masover
Guest
Posts: n/a
 
      07-18-2010
On Saturday, July 17, 2010 08:21:10 pm James O'Brien wrote:
> I have found the concept of an interface invaluable in my Java programming
> and wondered if there were an equivalent concept in Ruby?


Yes and no.

Yes, there is certainly a concept of an "interface" -- this is an abstract
concept that really applies to all languages. But no, it's not built-in to the
language.

More specifically, the Java concept of an interface is only really needed
because Java is statically typed.

> as a thought-experiment I
> propose Java without interfaces would be worse


Probably.

Take some common examples from the Java standard library -- Map would be a
good one. Now, Interfaces are especially cool because I don't have to care
that an object actually uses a hash internally -- it might use btrees, it
might use something entirely different -- all I care about is that it claims
to behave roughly like a Map is supposed to, and it presents get(), put(), and
so on.

So, for example, I could declare an object to have a type like this:

Map<String, List<String>> files;

You could conceivably store these files as a HashMap, mapping filenames to
lists of lines in the file. Of course, the cool part about interfaces is that
it could also be a thin wrapper around a real filesystem (so you don't have to
slurp them all at once), or it could talk to a database, or any number of
things.

But on closer examination, was that actually the right abstraction? What are
you doing with those files that you care that they're lists of strings, and
not one giant string or an IO stream of some sort?

In the statically-typed world of Java, it makes sense that you would define
your interfaces up front like this, because everything needs to have a type,
and types are all defined and planned out ahead of time. It's not just that
it'd be horrible design to do this:

Object files;

It's that it wouldn't work -- in order to call any methods on it, you still
need to typecast it to something you know how to interact with.

In Ruby, things are a bit different. We have this concept called "duck typing"
-- if it quacks like a duck, it may as well be a duck, who cares what it
actually is? If it isn't a duck, it should break our unit tests, which is I
think where it ties in to your comments here:

> I'm well versed in
> the benefits of test driven code and documentation but we have this in Java
> too


Since Ruby is dynamically-typed (and duck-typed), I don't specify the
interface I need -- at least, not directly. I specify it by how I actually use
the object in question:

puts files['readme.txt']

Now, there's still an implicit interface -- in this case, "Something that
responds to [], and returns something which puts knows how to turn into a
string." But I don't have to spell that out in code -- again, either it works
(which it does, 99% of the time) or it causes a runtime issue, which is what
unit tests are for.

That's the crucial difference -- in Ruby, I can just blindly fire a method
call on an object, without knowing what type it is. In Java, I can only call
methods on the object when I know it's of a type that supports those methods,
and which type it is.

So, in Java, interfaces actually let you do things you wouldn't otherwise be
able to do. In Ruby, I don't really see what purpose interfaces would have, or
what they would enable me to do. I much prefer the implicit duck-typing
interfaces. If it's a situation where I need an explicit interface as
documentation, I think documentation works well enough.

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-18-2010
On 07/18/2010 06:53 AM, David Masover wrote:
> On Saturday, July 17, 2010 08:21:10 pm James O'Brien wrote:
>> I have found the concept of an interface invaluable in my Java programming
>> and wondered if there were an equivalent concept in Ruby?

>
> Yes and no.




> Yes, there is certainly a concept of an "interface" -- this is an abstract
> concept that really applies to all languages. But no, it's not built-in to the
> language.
>
> More specifically, the Java concept of an interface is only really needed
> because Java is statically typed.
>
>> as a thought-experiment I
>> propose Java without interfaces would be worse

>
> Probably.


You could not have Java without interfaces. You would at least have to
drop static typing and this would be a major change to the language. I
don't think you would still call the result of this operation "Java".

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 
Reply With Quote
 
James O'Brien
Guest
Posts: n/a
 
      07-18-2010
[Note: parts of this message were removed to make it a legal post.]

David,

many thanks! i found your explanation very useful.. and an article on duck
typing is well worth reading e.g http://en.wikipedia.org/wiki/Duck_typing for
any other ruby newbies out there!


n Sun, Jul 18, 2010 at 5:53 AM, David Masover <(E-Mail Removed)> wrote:

> On Saturday, July 17, 2010 08:21:10 pm James O'Brien wrote:
> > I have found the concept of an interface invaluable in my Java

> programming
> > and wondered if there were an equivalent concept in Ruby?

>
> Yes and no.
>
> Yes, there is certainly a concept of an "interface" -- this is an abstract
> concept that really applies to all languages. But no, it's not built-in to
> the
> language.
>
> More specifically, the Java concept of an interface is only really needed
> because Java is statically typed.
>
> > as a thought-experiment I
> > propose Java without interfaces would be worse

>
> Probably.
>
> Take some common examples from the Java standard library -- Map would be a
> good one. Now, Interfaces are especially cool because I don't have to care
> that an object actually uses a hash internally -- it might use btrees, it
> might use something entirely different -- all I care about is that it
> claims
> to behave roughly like a Map is supposed to, and it presents get(), put(),
> and
> so on.
>
> So, for example, I could declare an object to have a type like this:
>
> Map<String, List<String>> files;
>
> You could conceivably store these files as a HashMap, mapping filenames to
> lists of lines in the file. Of course, the cool part about interfaces is
> that
> it could also be a thin wrapper around a real filesystem (so you don't have
> to
> slurp them all at once), or it could talk to a database, or any number of
> things.
>
> But on closer examination, was that actually the right abstraction? What
> are
> you doing with those files that you care that they're lists of strings, and
> not one giant string or an IO stream of some sort?
>
> In the statically-typed world of Java, it makes sense that you would define
> your interfaces up front like this, because everything needs to have a
> type,
> and types are all defined and planned out ahead of time. It's not just that
> it'd be horrible design to do this:
>
> Object files;
>
> It's that it wouldn't work -- in order to call any methods on it, you still
> need to typecast it to something you know how to interact with.
>
> In Ruby, things are a bit different. We have this concept called "duck
> typing"
> -- if it quacks like a duck, it may as well be a duck, who cares what it
> actually is? If it isn't a duck, it should break our unit tests, which is I
> think where it ties in to your comments here:
>
> > I'm well versed in
> > the benefits of test driven code and documentation but we have this in

> Java
> > too

>
> Since Ruby is dynamically-typed (and duck-typed), I don't specify the
> interface I need -- at least, not directly. I specify it by how I actually
> use
> the object in question:
>
> puts files['readme.txt']
>
> Now, there's still an implicit interface -- in this case, "Something that
> responds to [], and returns something which puts knows how to turn into a
> string." But I don't have to spell that out in code -- again, either it
> works
> (which it does, 99% of the time) or it causes a runtime issue, which is
> what
> unit tests are for.
>
> That's the crucial difference -- in Ruby, I can just blindly fire a method
> call on an object, without knowing what type it is. In Java, I can only
> call
> methods on the object when I know it's of a type that supports those
> methods,
> and which type it is.
>
> So, in Java, interfaces actually let you do things you wouldn't otherwise
> be
> able to do. In Ruby, I don't really see what purpose interfaces would have,
> or
> what they would enable me to do. I much prefer the implicit duck-typing
> interfaces. If it's a situation where I need an explicit interface as
> documentation, I think documentation works well enough.
>


 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      07-18-2010
On Sun, Jul 18, 2010 at 6:46 AM, James O'Brien <(E-Mail Removed)> wrote:
> David,
>
> many thanks! i found your explanation very useful.. and an article on duck
> typing is well worth reading e.g http://en.wikipedia.org/wiki/Duck_typing for
> any other ruby newbies out there!


FWIW, I wrote a paper about role-based 'types' nearly 20 years ago,
when I was at IBM. I've shared it with a few experienced Rubyists who
seemed to find a certain resonance with the ideas. Recently Alexander
Cockburn (of Crystal fame) with whom I have a shared hertitage at IBM
back then, tells me he still uses the paper when talking to clients
about dynamic typing.

http://talklikeaduck.denhaven2.com/f...sViewpoint.PDF

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/pers...-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

 
Reply With Quote
 
Robert Klemme
Guest
Posts: n/a
 
      07-19-2010
2010/7/19 Clifford Heath <(E-Mail Removed)>:

> Interfaces provide Java with dynamic method dispatch, without the
> cost(*) of having every individual method in the dispatch table as
> is the case with Ruby and other dynamic languages.


That sounds interesting. Can you please elaborate a bit more or
reference some documentation about this? Thanks!

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 
Reply With Quote
 
Clifford Heath
Guest
Posts: n/a
 
      07-19-2010
James O'Brien wrote:
> I have found the concept of an interface invaluable in my Java programming
> and wondered if there were an equivalent concept in Ruby?
> I'm open to the idea that interfaces might not be needed in Ruby


Interfaces provide Java with dynamic method dispatch, without the
cost(*) of having every individual method in the dispatch table as
is the case with Ruby and other dynamic languages. In other words,
Ruby has interfaces; every method is its own interface. If you want
to group those methods logically, you are free to (as long as you
don't use the same method name in two groups!).

Unlike Java, Ruby also allows new methods to be added at runtime.
That requires every method lookup to traverse the inheritance chain
in a linear fashion, instead of one dynamic lookup per dispatch.
Caching method lookups helps a bit, but the linear search is still
the main reason that Ruby's method dispatch is slower than Java's.

(*) It turns out that to search a method table is little to no more
costly than to search an interface table, so Java gains nothing there.

Clifford Heath.
 
Reply With Quote
 
Rick DeNatale
Guest
Posts: n/a
 
      07-19-2010
On Mon, Jul 19, 2010 at 2:55 AM, Clifford Heath <(E-Mail Removed)> wrote:
> James O'Brien wrote:
>>
>> I have found the concept of an interface invaluable in my Java programming
>> and wondered if there were an equivalent concept in Ruby?
>> I'm open to the idea that interfaces might not be needed in Ruby

>
> Interfaces provide Java with dynamic method dispatch, without the
> cost(*) of having every individual method in the dispatch table as
> is the case with Ruby and other dynamic languages. In other words,
> Ruby has interfaces; every method is its own interface. If you want
> to group those methods logically, you are free to (as long as you
> don't use the same method name in two groups!).
>
> Unlike Java, Ruby also allows new methods to be added at runtime.
> That requires every method lookup to traverse the inheritance chain
> in a linear fashion, instead of one dynamic lookup per dispatch.
> Caching method lookups helps a bit, but the linear search is still
> the main reason that Ruby's method dispatch is slower than Java's.
>
> (*) It turns out that to search a method table is little to no more
> costly than to search an interface table, so Java gains nothing there.


Is the * the equivalent of Emily Litella's "Never Mind!"
http://en.wikipedia.org/wiki/Emily_Litella

There's thirty or more years of experience in getting dynamic method
dispatch to run efficiently. Techniques such as polymorphic inline
caching, dynamic (re)compilation and others. One of the pioneers of
this work was David Ungar who analyzed Smalltalk performance as his
PhD dissertation, then spearheaded Self which was a language which
turned the dynamic lookup knob up to 11 (it did away with the
distinction between methods and instance variables) which exacerbates
the problems of having to do continuous dynamic lookups and found
techniques to make the language performant. Such techniques formed
the basis of the HotSpot JIT technology in Java.

There is a wealth of literature on efficient implementation of dynamic
languages, particularly in the proceedings of OOPSLA in the mid 1980s
forwards.

To date, the MRI implementations have used rather naive techniques.
JRuby does take advantage of JVM implementation techniques, albeit a
bit less directly than say MagLev which is built on a similarly
sophisticated VM which was engineered for Smalltalk rather than Ruby a
language whose underlying object model more closely maps to Ruby than
does Java.

Now, I'm far from an expert on JVM implementation, but the last time I
looked, it seemed that interfaces were really only used in method
dispatch as a way to provide the equivalent of what Ruby uses symbols
for. In ruby the method invocations

a.foo
a.foo(1)
a.foo("abc")

All resolve to the same method, where in Java these would be different
overloaded methods based on different types and numbers of parameters
(different signatures). So the combination of method name and
parameter type list needs to be mapped to a 'selector' of a method
defined in a particular (super)class or interface. The java bytecodes
to call a method typically involve fetching a 'token' from a class or
interface (which is known because of the type of the variable
'receiving' the call, and then calling a dispatch function with the
receiver, the token, and the argument values. This is very similar to
what happens in Ruby except that instead of a token based on the name
and parameter types, Ruby just uses the symbol form of the method
name.

What happens on the other side of the dispatch function is hidden, but
the effect is for the VM to find the right method implementation and
invoke it.

The traditional C++ implementation of virtual functions uses the
compiler's knowledge of the called object type and the class hierarchy
of that type to find a virtual function table and index that to find a
pointer to the method. This turns out to be very fragile, and is why
large C++ programs have LOTS more make dependencies than does a
typical C program, meaning that small source code changes can require
MANY files to be recompiled to make sure everyone has the right
locations of VFTs and virtual function indexes.

If you're interested in this try googling for "fragile base class
problem." This issue be-deviled those who tried to use C++ to build
"framework-based" OS APIs during the days of C++ fever.

http://talklikeaduck.denhaven2.com/2...ith-gill-bates *
http://talklikeaduck.denhaven2.com/2...0/oh-the-irony

Another related bit of history is the war between different
semi-static/semi-dynamic "object models" like IBM's SOM vs.
Microsoft's COM *. Although I was playing for the "IBM team" I never
thought much of either to be honest.

http://en.wikipedia.org/wiki/IBM_System_Object_Model
http://en.wikipedia.org/wiki/Component_Object_Model


This approach falls down completely when the type hierarchy can change
at run-time and I'm pretty sure that most JVMs do the actual method
lookup more dynamically and use caching to achieve performance.

* BTW, Tony Williams who is considered as the co-inventor of COM was
IIRC the guy presenting in this meeting, and if he wasn't the
presenter he was in the room.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Github: http://github.com/rubyredrick
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/pers...-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale

 
Reply With Quote
 
David Masover
Guest
Posts: n/a
 
      07-20-2010
On Sunday, July 18, 2010 02:35:03 am Robert Klemme wrote:
> On 07/18/2010 06:53 AM, David Masover wrote:
> > On Saturday, July 17, 2010 08:21:10 pm James O'Brien wrote:
> >> as a thought-experiment I
> >> propose Java without interfaces would be worse

> >
> > Probably.

>
> You could not have Java without interfaces. You would at least have to
> drop static typing and this would be a major change to the language. I
> don't think you would still call the result of this operation "Java".


I don't think so. It would be much like Java without Generics -- frustrating
to work with, but possible. Basically, it kills any sort of polymorphism
between things which don't share a common ancestor -- so you make more use of
inheritance in some situations (take Collections, it wouldn't be so bad if we
had to inherit from AbstractCollection, AbstractList, etc), and aggressively
abuse modular decomposition (anywhere you have one object that needs to
pretend to be two types, make two related objects!), and you could make it
work.

In fact, IIRC, this is how C++ does it -- it's just made much easier due to
multiple inheritance. I never quite understood why Java allows multiple
interfaces to be applied to the same object, and even to the same interface,
but not multiple inheritance.

I'm not suggesting this would be a good idea, mind you -- but then, I'm also
not entirely sure either Java or C++ is a good idea.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Ruby/Google (Ruby abstraction of Google API) is dead? Ethan Herdrick Ruby 1 05-11-2006 06:38 AM
Abstraction Layers And Their Importance Silverstrand Front Page News 0 01-31-2006 04:48 AM
HDL Abstraction of Dynamic Logic Alex VHDL 2 09-18-2005 04:00 PM
SqlConnections, abstraction etc Ben ASP .Net 4 06-24-2004 05:46 PM
An high abstraction level Model free API Stefano Java 0 10-13-2003 10:11 AM



Advertisments