In article <20050130152440.A4430 / cs.mcgill.ca>,
 Navindra Umanee <navindra / cs.mcgill.ca> wrote:

> Yukihiro Matsumoto <matz / ruby-lang.org> wrote:
> > |Okay, so object.class will supposedly tell you what class an object
> > |is...  but you can override that method and nobody really cares.  So
> > |Ruby doesn't guarantee anything about type safety.
> > 
> > Define "type safety" here.  I consider it as that every type error can
> > be found (at run time), and no fatal error (e.g. segmentation fault)
> > can be caused by type mismatch.
> > 
> > What is yours?  Ability to tell an object's class?  Inability to
> > change the class of an object at run time?
> 
> Thinking about it, I think my problem is that I didn't have a proper
> concept of what a type is in Ruby.  However, if I revert back to duck
> typing as a concept, I finally get a definition:
> 
> In Ruby, an object is of type Duck if:
> 
> (1) The object walks like a duck.
> (2) The object quacks like a duck.
> 
> Since Ruby always makes sure an object is of type Duck if it needs a
> duck, Ruby is type safe.
> 
> Duck typing is a loose concept however as shown in the previous
> discussions (an object can be an arbitrary number of types and/or
> types overlap), and I am not sure if you can call such a thing strong
> typing although Ruby is type safe within the definition of duck
> typing.
> 
> Cheers,
> Navin.

Hi Navin.,

I think you're making the mistake of equating objects and object 
references.  Objects have a specific type, and the type of an object 
doesn't change.  Variables, on the other hand, are just object 
references.  The object they refer to changes with assignment.  If you 
fire up irb, you can check the type of a given object by sending it the 
"type" message.  For example:

irb(main):001:0> (2**30 - 1).type
=> Fixnum
irb(main):002:0> (2**30).type
=> Bignum

If I assign the part of the first expression in parentheses to a 
variable x, then x now refers to a variable of type Fixnum:

irb(main):003:0> x = (2**30 - 1)
=> 1073741823
irb(main):004:0> x.type
=> Fixnum

If I add 1 and store the result in x, the variable x now references an 
object of type Bignum:

irb(main):005:0> x = x + 1
=> 1073741824
irb(main):006:0> x.type
=> Bignum

The type of object "1073741823" hasn't changed:

irb(main):007:0> 1073741823.type
=> Fixnum

but x no longer references that object.  It's important to note that an 
expression can yield a type which is different than the types of the 
operands within that expression, e.g., <Fixnum> + <Fixnum> can yield a 
<Fixnum> or <Bignum>.  If the result is assigned to a variable, the 
variable seems to change type if you equate a reference with the thing 
being referenced.

In Java, you have objects and primitives, which are distinct types of 
things that can't be intermixed.  Java requires you to declare the type 
associated with a variable to avoid the kind of insanity which would 
occur if you started trying to send messages to primitives.  That 
results in ugliness such as Arrays.sort(), which has to have many 
overloaded implementations - one for Objects, and one each for each type 
of primitive.  Contrast with Ruby, where any array can be sorted as long 
as the elements respond to <=> or you provide a block to be used for 
comparisons.

Getting back to the subject line - In Java, the distinction between 
primitives and objects requires that variables be declared with a type.  
I think it takes Java programmers a while to realize that in Ruby 
variables are always object references, so the "everything is an object" 
philosophy means that type declarations are unnecessary.

--paul