matz / ruby-lang.org (Yukihiro Matsumoto) writes:

> |Sorry, I'm having a hard time accepting that it's okay for operations to
> |produce broken objects.
> 
> Don't feel sorry.  I agree it's sloppy.  Maybe I didn't think enough
> deep when I accepted this RCR.  Let's discuss for "better way".

I think one of the underlying issues here is nothing to do with
sub-objects. Instead it's the fact that the interpreter bypasses the
constructors for many built-in types althogether. Thus is is basically
impossible to enforce contracts on (say) Strings.

Say instead that the interpreter's [] method for strings looked
something like:


   class String
     def [](*params)
       # .. work out characters to include
       return type.new(characters)
     end
   end

(yes, I know there's a probem here--I'll get to it :)

If this were to happen, then anyone who subclasses String must provide
a constructor that is compatible with String's constructor. Fail to do
so, and the up-cast fails. I can't see any other way of having
classes return objects of derived types.

Now, on to the problem. Right now we have a problem with built-in
classes such as String: we can't implement them in Ruby, because we
need to be able to pass them Strings to initialized them. In the []
example above, I said "return type.new(characters)", but what is the
type of characters.

So, I'm thinking that perhaps something to think about in Rite is
having built-in frozen classes for primitive types, _String, and so
on. These classes would be no more that value containers: they'd have
almost no operators. The implementations of String could then be
expressed in terms of operations on these _Strings (probably by
delegating to them, rather than subclassing them). This would mean
that we would have far more flexibility when playing with types such
as String. We could rewrite the whole String class in Ruby just to
experiment with new behaviors.


Dave