How to ducktype a Hash?

David Garamond [mailto:lists@zara.6.isreserved.com]:

Sean O'Dell wrote:

That's just a confidence issue. I don't care if the object coming
in is broken. I'm not concerned about catching objects which are
implemented improperly; that's actually very rare. If an object
had a signature that said "I am a hash-like object" that would be
fine for me. Duck typing and checking respond_to? are completely
inadequate, and it seems like people argue those points because
Ruby offers nothing else and so what are you going to advocate?
It's those two or rolling your own interface identification
system, which I think is cheesy; that sort of functionality
should come from the framework.

Okay, I'm trying to sum up this thread as well as test whether my
understanding of this whole typing issue in Ruby is more or
less correct.

1. Ruby _has_ types. It's called classes. In fact, all OO
   languages which have a class concept (as opposed to some
   classless OO languages like Self, I think) implement types
   through classes. All object belong to a certain class. That
   class is the object's type.

Actually, Ruby has both types and classes. Many developers confuse
types and classes because in C++ they are one and the same; in Java
they are slightly different, but not noticeably so (with the
introduction of interfaces).

An object of class Array is both an Array and an Enumerable; it also
belongs to the nebulous class of "objects-that-respond-to-#". In a
current project, I am dealing with "objects-that-respond-to-#<<".
This allows me to buffer output in a string, an array, or simply go
to an IO object.

2. However, Ruby does _not_ do type checking for you. This means,
   method declaration is not like this[...]

Again, a clarificatio: Ruby does not restrict method signatures.
This is a Good Thing.

3. Ruby also does not tag a variable with type. This means, you
   don't declare variable's type like this[...]

Correct. Ruby variables are untyped; objects, however, are typed. To
be quite explicit: Ruby variables don't have types at all; the
objects that they reference do.

#2 and #3 are perhaps what people miss when they move from
C++/Java to Python/Ruby. I don't know whether Ruby will ever have
#2 and #3.

I hope not, personally, as it would reduce the flexibility of the
language. Slides from last year's RubyConf, however, suggest that #2
may happen to some degree. I prefer a descriptive rather than
restrictive interface for this stuff, though.

4. Static type checking (or static typing?) is #2 and #3, done at
   compile time. This is what C++ and Java do. Ruby, of course,
   does not have type checking, much less static type checking.

No. Ruby does not have "class-checking" or "interface-checking"
built into the language. It does have type checking in that if an
object does not respond to a method -- or does not respond properly
-- it will cause an exception to be raised (NoMethodError,
ArgumentError).

[snip]

Points 5, 6, and 7 share other (similar) flaws. Note that Ruby's
modules *are* interfaces.

-austin

···

--
austin ziegler * austin.ziegler@evault.com

Ruby has no types. All of Ruby's classes are described, and objects
instantiated, with an arbitrary set of methods and purpose. There is nothing
anywhere in Ruby to reflect on the purpose of a class.

  Sean O'Dell

···

On Monday 07 June 2004 07:35, Austin Ziegler wrote:

Actually, Ruby has both types and classes. Many developers confuse
types and classes because in C++ they are one and the same; in Java
they are slightly different, but not noticeably so (with the
introduction of interfaces).

So are there types in Java, such that would fit the above description?
What about C++ (no interfaces)? Other languages?

FWIW, I think the concept of types in Ruby is wishy-washy. The sort
of thing that humans can talk about but not computers. But the
concept is still there. And ultimately, it's not that different in,
say, Java, where (as you have pointed out) you can abuse an interface.

So how can you reflect on the purpose of a class in Java? Or is it
all a matter of degree?

  # In which case, Ruby's mixins are a drop-in replacement for
  # interfaces.

···

On Tuesday, June 8, 2004, 2:50:50 AM, Sean wrote:

On Monday 07 June 2004 07:35, Austin Ziegler wrote:

Actually, Ruby has both types and classes. Many developers confuse
types and classes because in C++ they are one and the same; in Java
they are slightly different, but not noticeably so (with the
introduction of interfaces).

Ruby has no types. All of Ruby's classes are described, and objects
instantiated, with an arbitrary set of methods and purpose. There is nothing
anywhere in Ruby to reflect on the purpose of a class.

  #
  # Witness Amrita's mixin 'Amrita::ExpandByMember', which happens
  # to be a tag only.

Gavin

>> Actually, Ruby has both types and classes. Many developers confuse
>> types and classes because in C++ they are one and the same; in Java
>> they are slightly different, but not noticeably so (with the
>> introduction of interfaces).
>
> Ruby has no types. All of Ruby's classes are described, and objects
> instantiated, with an arbitrary set of methods and purpose. There is
> nothing anywhere in Ruby to reflect on the purpose of a class.

So are there types in Java, such that would fit the above description?
What about C++ (no interfaces)? Other languages?

I like interfaces better than classes, but C++ classes serve pretty well for
typing. Anywhere you have an object (int, String, whatever) that can be
described as adhering to some principal structure and purpose, that's a type
I think. Ruby, with some effort, can have nearly all the same typing
features as C++...but the problem is, you have to hack at it. The real
advantage of typing isn't just that you can do it when you need to, but when
it's done for you easily. You can rip right out any advantages to typing by
simply making it too hard to use.

FWIW, I think the concept of types in Ruby is wishy-washy. The sort
of thing that humans can talk about but not computers. But the
concept is still there. And ultimately, it's not that different in,
say, Java, where (as you have pointed out) you can abuse an interface.

So how can you reflect on the purpose of a class in Java? Or is it
all a matter of degree?

I think the enforcement mechanisms of inheritance leads C++ and Java
developers to more carefully craft out their classes, and that generally
means that if you need an object with certain capabilities, you simply derive
from a base class and ask for an object of the base class type where you need
it. That, I think, was what the C++ and Java language designers had in mind
for inheritance. It was a way to both describe the purpose of an interface,
and provide implementations of the interface.

That said, I don't like the inheritance way of doing things. I did that a lot
in C++, and Ruby taught me it wasn't necessary and now looking back, I
remember a lot of frustration with it. In fact, I used to LOVE Object Pascal
because it had a mechanism where you could plug in your own methods to
replace class methods. Object Pascal's version of function pointers really
helped me get away from the enslavement of monolithic class hierarchies.

So I'm at a middle ground now. All I want is Ruby the way it is, with the
ability to tell me if a given object adheres to a certain interface or not.

  Sean O'Dell

···

On Monday 07 June 2004 15:42, Gavin Sinclair wrote:

On Tuesday, June 8, 2004, 2:50:50 AM, Sean wrote:
> On Monday 07 June 2004 07:35, Austin Ziegler wrote: