From: dblack@... Date: 2002-09-29T12:09:32+09:00 Subject: thoughts on typelessness 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