From: Ryan Pavlik Date: 2003-11-06T15:40:23+09:00 Subject: Re: Managing metadata about attribute types On Thu, 6 Nov 2003 15:05:58 +0900 Simon Kitching wrote: > I don't think that the concept of strict typechecking deserves quite > such a roasting :-) Yeah same, I'm not sure why it's a big deal... it's been pretty helpful in debugging. If I specify something it doesn't like, I see exactly where it came from. There are cases where, for instance, I might assign an attribute, or add something to a list that gets used later, only to have an error occur in never-never land. No indication as to who the offending party was. > For me, when looking at a method like > def foo(param) > ... > end > the question is "what contract is the param required to adhere to?". > And maybe "what is the contract of the returned object". > > If the code is strictly-typed, like > void foo(Map map) > end > then I know exactly what contract the param must adhere to: it's > documented in the javadoc on the Map class. [Isn't that the definition > of "type"? A contract of behaviour?] As in my (just) previous message, this is exactly what it is. Even if you say "I want this thing to respond to #[] and #[]=", you could label that set... and it basically becomes a class. > Ok, there are flaws to strict typing. The first is that the contracts > tend to over-specify. The foo method probably only wants a few of the > methods from the Map class, but the concrete class of the object I pass > must implement them *all*. In fact, the Java collections class has an > ugly hack to resolve this issue: methods are allowed to throw an > Unsupported exception, which means an object might only partially fulfil > the required contract. However 90% is probably good enough. This is where mixins are nice. You can do "microtyping" (is that a word yet?), and pull in each set of interfaces. This has the added benefit of attached semantics, so you know that your #[] isn't a call to a block, but an array dereference, for instance. Most of the time you don't even need this... it happens naturally with superclasses. > And for java's Object-based collections, you lose part of the contract: > what is the object type *in* the map. Generics (templates for Java) will > resolve this issue (I hope). Generics sound too much like templates to me. IMO, templates, generics, and the like, are all hacks to get around the fact the language is static. Personally, I think that if you want something that's not a generic array, you should just make a subclass that filters its contents. I realize that this isn't easy in ruby for many of the base classes, but it's a simple and effective solution. Instead of making subclasses, you could even just test the filter. There are other related solutions. > In programming languages which are always distributed with > non-obfuscated source code, the source can be inspected to determine the > contract. This isn't too bad a solution, provided the library author > writes clean code and comments it well. > In the end, the problem is simply one of human<->human communication. > The author of a library needs to tell the user of the library about > various contracts. Strict typing is one end of the spectrum of this > communication. It results in well-specified code, but at the cost of > extra developer labour. Ruby is the other end; it results (generally) in > completely unspecified code (see "read the source" above) but imposes > little overhead on the developer. I generally don't like to have to do things that the computer could just as easily do a better job of, with information I need to give it anyway. The extra work on my part of entering the classname here and there isn't so strenuous and labor-intensive that it cuts into productivity. Debugging and copying information, though, does. My theory is that I should only have to tell the computer _once_, in _one_ place, what I mean, and it should be able to use that information repeatedly in as broad a manner as possible. Thus, if I specify my method wants a Date object, it should do everything from making sure I get one to automatically providing the user with the appropriate widget. > Compiler-assisted programming, where the compiler tells the user when > they got it wrong is just a bonus. I wouldn't miss this as much as the > lack of *communication* about types. Basically, I agree. The reason I wrote ST was not just because I was nervous about getting types wrong, it was because I needed to document what those types were, in a manner the code could ask itself about them. As above, the extra checking has improved debugging time drastically, and that's definitely a bonus. > I don't think that a true measure of the effectiveness of strict typing > can be had by saying "I wrote a big application and didn't need strict > typing". I suggest you try *using* a big library someone else wrote, and > see if you miss it :-). Then deliver that app to a customer and see if > they turn up any cases where you made a mistake about the contract of a > method or parameter. I concur. It's not _necessary_, in the sense it can't be done without. I could write a huge application with it, and then remove it later, and the application would still run. That, of course, is not the point. > Obviously I'm biased; my experience is mainly in strictly-typed > languages. For smallish apps I can clearly see the benefits of Ruby. I am lax with strick checking with many scripts and modules; usually this is because it doesn't matter, and I won't need to query things anyway, but I've often regretted it as well. > In fact, given a combination of good unit-tests and well-modularised > code (so I can see all the places an object is manipulated and therefore > deduce its contract), I could be convinced of Ruby for large projects > too. But I think I will always wish that the *type* of parameters (and > return values!) were simply documented via type declarations like Java. This will work, but I don't have like it---redundant work just diverts me from the problem at hand. A thousand programmers having to re-deduce the contract is a lot of wasted time. -- Ryan Pavlik "Do not question wizards, for they are quick to turn you into a toad." - 8BT