Hi --

On Thu, 6 Nov 2003, Ryan Pavlik wrote:

> On Thu, 6 Nov 2003 12:45:39 +0900
> dblack / wobblini.net wrote:
>
> <snip>
> > I believe that's by design; as I understand it, the StrongTyping
> > module performs parameter gatekeeping based exclusively on the
> > class/module ancestry of an object (the namespaces to which it
> > belongs, as Rich and Chad were discussing), not on what the object
> > actually can do.  This means, as you say, that objects which might fit
> > the bill may not get through, if their class/module ancestry is wrong,
> > and also that objects which do not fit the bill can get through -- for
> > example:
> <snip>
>
> This is the fundamental philosophical disagreement, or
> miscommunication, or what have you.  If an object fits the bill, and
> its class/ancestry is wrong, then there is a error in design.
> It should not be the case that this happens, or you have found an
> error in your code.

At this point you're waging a battle directly against the design of
Ruby.  Ruby allows you to extend objects at runtime; to decide that
this is sloppy or wrong or a second-rate programming technique is
entirely arbitrary.

When you check whether or not an object's response to #is_a?  includes
an element you've specified, that's the one and only thing you're
checking.  It's not as if Ruby somehow pulls up its socks and
straightens its tie and says "Better stop this dynamic stuff!" when it
sees a call to #is_a?  It doesn't; it remains dynamic, and the
programming techniques required to ascertain the interface of an
object do not change.  (Besides, its socks and tie were just fine to
start with :-)

> I realize not all of Ruby is documented in this manner; that's a
> simple matter to change.  A few smaller modules would solve this; for
> instance, Set, HashedSet, IndexedSet, etc.  Array would be an
> IndexedSet; modules such as CGI would include HashedSet.  Then you
> could ask for the simple behavioral pattern you desire, and know that
> you have it.  You would further be assured that this #[] means what
> you want it to.

I think I must be not getting something here; it sounds like you're
suggesting that every possible behavior of every future object in
every Ruby program be anticipated by modules in the core distribution,
with multi-barreled names to suit the purpose.  I'm thinking that
can't really be what you mean.

Also, remember that you're never 100% assured that #[] or any other
method means what you want it to.  It's ducks all the way down :-)
(http://www.the-funneled-web.com/hawking.htm) Every method call
operates under the same conditions as every other.  You can light a
candle, dance a jig, call #is_a? twenty times... but in the end,
obj#[] is whatever obj#[] is.  You can't change Ruby for a few
nanoseconds at a time through sheer willpower.

Hence the quest to harness the dynamism, rather than wishfully think
that it comes and goes.

> This isn't really any different than duck typing, except you're just
> making sure that it really does quack, it doesn't just have a bill.

Also, to reintroduce something Chad brought up: this isn't just a
matter of the illusory nature of the rigor of #is_a?  It's also about
missed opportunities.  It's quite possible to write Ruby programs that
mimic statically-typed languages as closely as possible, and where
checking an #is_a? list almost certainly will, in practice, indirectly
give you accurate information about an object's type.  But that means
that, in the name of some kind of imagined rigor or discipline or
something, one has decided to program using a small, somewhat
impoverished subset of Ruby's capabilites.  One then ends up with
pretty-looking (because it's Ruby :-) pseudo-statically-typed code.

Mind you, as with discussions of thread safety and name clashes, a lot
of the possible weakness of #is_a?-checking pertain to what would
happen if little gremlins got into your program and changed
everything.  In practice, if you decide to treat Ruby classes as
immutable and Ruby objects as wannabe statically-typed, you will
probably do OK (though your code may lack scaleability).  But it's
important to remember that, in doing this, you're not dealing
*directly* with the types of objects.

In the end, everyone has to do what they think best.  I'm more
interested in an object's type than its response to #is_a?, so I tend
to feel comfortable with extending objects dynamically and putting
them in situations where they can do their thing.  If you spot (real)
errors in the design of any of my programs, please let me know :-)


David

-- 
David Alan Black
home: dblack / wobblini.net        # New email address
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav