From: Robert Klemme Date: 2004-05-19T04:08:49+09:00 Subject: Re: How to duck type? - the psychology of static typing in Ruby That was an interesting read! "Paul Sanchez" schrieb im Newsbeitrag news:pjs-CC200C.08190318052004@localhost... > In article , > Marek Janukowicz wrote: > > > On Tue, 18 May 2004 08:48:04 +0200, Robert Klemme wrote: > [...] > > > I alway have to look up definitions... > > > http://en.wikipedia.org/wiki/Dynamic_typing#Static_vs._dynamic_type_checking > > > > > > Unfortunately I'm not familiar with Objective C so I can't judge on that. > > > > I cannot say I know Objective C well too, but I get some basic concepts. > > > > > From what I've seen so far I'd assume it's similar to Java which is regarded > > > as statically typed although you have access to type information at runtime > > > (as seems to be the case with Objective C). But the crucial part is that > > > you declare types (of variables, of method arguments) in code and these > > > types are checked by the compiler. > > Yes and no. Objective C started off with ANSI C and added a > Smalltalk-like object model on top of it. The C portions are strongly > typed, but the object framework made use (initially) of a generic object > type called "id", which in practice mapped to "Object*" in the > underlying C implementation of the runtime. (Objective-C was initially > a pre-processor which generated pure C and linked to the runtime > libraries.) Since Objective C uses a single inheritance model, > "Object*" could point to objects of any class because all classes were > rooted in "Object". So, if I understand this correctly, ObjC is quite similar to Java. Where ObjC uses id Java uses a reference of type Object. The difference seems to be that you can invoke arbitrary methods on an "id" reference whereas you have to downcast in Java. > > But the feature I described in my previous post has no equivalent in > > Java - I'll try to explain it (I may be very wrong, so anyone knowing > > Obj-C better please correct me): > > > > In Obj-C, when you create a variable to hold a pointer to an object of > > class Object, you have 2 choices: > > > > Object *obj; > > id obj; > > > > the second pointer is "typeless", because it can point to an object of > > any class. I wonder if similar mechanism could be useful in Ruby. > > This isn't quite correct, "id" was initially just a pre-processor > mapping for "Object*". Later NeXT added "NSObject" as an alternate root > class for the object hierarchy, and "id" came to mean "pointer to an > instance of any class regardless of root class". They also added typed > object declarations, so that "Object*" or "NSObject*" (or "MyObject*") > were more restrictive than "id" and could only point to their respective > classes + lineal descendents. Pretty much as it is in Java. > Objective C took a different approach by creating "protocols" (which > were adopted by Java as "interfaces"). Protocols are groups of method > signature declarations, with no implementation. If a class implements a > protocol, then invoking any of the methods declared in the protocol for > instances of that class is guaranteed to be legal. This reminds me a bit of GNU C's "signatures". AFAIR you could declare a signature as a collection of method signatures and assign any instance whose class implements all methods contained in the signature. The class need not be declared to implement this signature (as is the case with Java interfaces). That could be used to retrofit signatures to existing library code. > However, there are > no guarantees about what will actually happen. The focus and checking > is entirely on the existence of behaviors, while leaving the > responsibility for the actual behavior (implementation) to each > individual class. Well, that's always like this, isn't it? Even Eiffel - which goes quite far with regard to DBC - does not force any implementation. After all, there is no way to do that actually. > In Ruby everything is an object, so the type > declaration and checking for method arguments and return values doesn't > gain you anything. About all you could check would be the existence of > methods as a set, rather than checking them one at a time. You couldn't do that statically because the set of methods can change over the lifetime of an instance. And if you mix typed and typeless code (excuse the sloppy language) most checks will happen at runtime anyway. As said earlier, I don't see much use in adding "compile time" checks to Ruby. It doesn't fit. > I worry more about the hazard of undeclared variable names. There's a > story, probably apocryphal, about a space probe being lost back in the > 1960's because somebody held down a keypunch key too long and turned the > variable X into XX on the left-hand of an assignment. Since FORTRAN4 > didn't require explicit declaration of variables, the calculation was > stuffed into XX (which appeared nowhere else in the program) and X > contained an incorrect value for subsequent calculations. Because of > this story, I worry sometimes that variables need not be delcared in > Ruby. I realize that since everything is an object there's no need for > type declarations. However, I think variable set declarations would > make some sense - "Here's the set of variable names I'll be using, and > anything not in this set is a typo." If there were proper tests in place they'd certainly catched that one. Declarations could only prevent the accidental usage of an undeclared variable. But they can't ensure calculcations and algorithms are done properly. > Disclaimer - I'm not a computer scientist, I've just been programming in > a bunch of languages for a long time. If I've said anything outrageous, > please be gentle. :-) It's ok for me. I couldn't find anything offensive here. Kind regards robert