Hi --

The on-going discussion of explicit typing and Ruby has whetted my
appetite for traveling further into the typeless universe :-)  But
mainly, it's got me trying to think fairly deeply and precisely into
the question of why this notion keeps coming back, in spite of its
fairly manifest (and, I think, pretty universally acknowledged)
extrinsicness to Ruby.  These comments, then, pertain to typelessness,
and to the question of why some people's embrace of the Ruby model is
equivocal.  (They're not specific to the 'R' initiative, though
obviously that's been at the center of recent debate.)

There's a scene in Buster Keaton's film "Sherlock, Jr." where Keaton
is on an out-of-control motorcycle, about to come to a huge gap
between two stretches of elevated road -- i.e., he's about to plummet.
But two trucks come along on the road underneath, from opposite
directions, and converge for just an instant in precisely such a way
that Keaton can glide across their tops and onto the road on the other
side of the gap.  A second earlier or a second later, he would indeed
have plummeted -- but for just that instant, the necessary components
were in place.

Ruby objects remind me of that scene.  They are what they are at a
given moment, whether or not that's what they were or what they will
be.  And in their momentary permutations and capabilities, they can do
some very powerful things.

All of this is so enthralling to me that I'm always surprised when
people advocate explicit typing (in one form or another) for Ruby.  It
seems that, in spite of everything (including the existence of other
languages for those made queasy by typelessness), a number of Ruby
users are more drawn to type-based programming than away from it.  I
wonder why this is.

I don't have a particular or conclusive answer, just some thoughts.
Mainly these have to do with Ruby methods and syntax, rather than
other factors (like whether managers will accept a dynamically typed
language).

One possible factor, I think, is the #type method.  As I mentioned on
IRC this evening, I sometimes wish Ruby didn't have it.  It's harder
to make the argument that objects don't have types, when the objects
themselves willingly tell you their types.... :-)  And I might add
#is_a? and #kind_of? to the list.  Maybe they're necessary for
reflection.  It's interesting to try to program without them.

Another thing people often point to that might deter people from
learning a truly type-unchecked programming style is the wordiness of
the most often-mentioned alternative, the "respond_to?" test:

   thing.action if thing.respond_to?(action)

This has the look and feel of duplicate, workaround code.  Whereas
this:

   raise ArgumentError unless obj.is_a?(Thing)

doesn't, and neither does this:

   case obj
     when /String/ ....
     when /Array/  ....

(And of course this:

   def meth(String s)

wouldn't either :-)

So one problem might be that while the focus is on what an object will
respond to, the #respond_to? test itself is by no means the most
concise or elegant available idiom.  This means that testing for type
offers a path of less resistance -- so people take it.

(Of course, in looking at behavior in Ruby as fundamentally per-object
and dynamic, testing with #respond_to? isn't conclusive anyway, since
the response in question may or may not be what one wants.  But it's
on the right path, because it's addressing the present of the object,
not its past.)

You can also do this:

   begin
     a.meth
   rescue NameError
     ...

I've done that, for instance, in my dbdbd (database definer) program.
It uses 1-originating array notation to index columns, but can also
use field-names.  So the reader method for the sort_key (for example)
is:

   def sort_key
     @sort_key - 1
   rescue NameError
     @sort_key
   end

which I think looks better than:

   def sort_key
     if @sort_key.respond_to?(:-)
       @sort_key - 1
     else
       @sort_key
     end
   end

or any of the many variants of that.  But the rescue version is
relatively slow.

There's also been talk of a sort of conditional method call, where the
call would only happen if the object responds to the method.  The
problem with that is: what happens if it fails?  You can't just return
nil or false, since those might be what the successful method call
would have returned.

I don't have any conclusive, ummm, conclusions to draw.  Just
wondering what people think of all of this.  There was talk briefly of
the idea of multi-dispatch and method signatures on respond_to?
criteria, rather than type.  Maybe that's a way to bring that more
accessibly and concisely into the syntax.  (Though I'm not sure
exactly what that way would consist of, syntactially.)



David

-- 
David Alan Black                      | Register for RubyConf 2002!
home: dblack / candle.superlink.net     | November 1-3
work: blackdav / shu.edu                | Seattle, WA, USA
Web:  http://pirate.shu.edu/~blackdav | http://www.rubyconf.com