From: Rick DeNatale Date: 2007-03-03T07:27:07+09:00 Subject: Re: Duck Typing Hash-Like Objects On 3/2/07, dblack@wobblini.net wrote: > Hi -- > > On Sat, 3 Mar 2007, Rick DeNatale wrote: > > > All of this is personal perspective of course, but my view of duck > > typing is that it's really a question of the type of a variable rather > > than on objects. In other words in my view variables have types which > > are generated by their usage. Types in this view are like job > > requirements. > > I'm not sure how that detaches it from the object, though, since > variables are going to contain references to objects and messages are > sent to objects rather than variables. Do you mean in terms of > documentation? First of all let me reiterate that this is my personal perspective, based on 20+ years of using a variety of dynamic OO languages. I'm trying to say that the code which uses objects in general sees them through variables. This isn't always evident, and it's muddied because so often the same code which uses a variable initializes it, but in the case of parameters, or the results of expressions based on parameters that code has less control over what the objects referenced by variables really are. One way to think about what I'm saying is to think of the programmer like a playwright who writes a script in terms of dramatis personae or roles, without necessarily knowing or caring which actors will ultimately play those roles. Many years ago I wrote a paper called "Types from the Client's Viewpoint" which talked about this, A PDF of this is available on my blog website at http://talklikeaduck.denhaven2.com/files/TypesFromTheClientsViewpoint.PDF I've been struggling for many years about how to describe this without getting wrapped up in what is really a paradigm shift which confounds discussion since terms like type have subtly different meanings. That paper is an early attempt, but it provides on such attempt. Another glimmer of what I'm trying to say and it's evolution can be seen in my mini-memoir http://talklikeaduck.denhaven2.com/articles/2006/07/29/about-me Because of this paradigm shift problem, I sometimes use the term role instead of type when talking about variables in an analogy the playwright metaphor. One of the key aspects of the paradigm shift is that in a dynamically typed system a strong wall of encapsulation can be erected between the user of an object and the implementation of that object. Traditionally types in programming languages are really names or calculi for describing how a string of bits are to be interpreted by a program using those bits. In a language like Ruby or Smalltalk, all the bit interpretation gets done by the object itself, so the user of the object doesn't or shouldn't care about the implementation of the object. This is why those of us in the dynamic duck typing camp are so adverse to class checking, since the class of an object is an implementation matter. This encapsulation wall at the interface between object and user is what I consider the hallmark of object centered softwre design This is what Alan Kay seemed to have in mind when he coined the term "Object Oriented Programming." Unfortunately, Peter Wegner came along later and coopted the term to require classes and inheritance, both of which might be useful implementation techniques but are non-essential to my mind. And the fact that classes and inheritance are implementation techniques is another thing which makes those familiar with C++ like languages have difficulties in getting duck typing. Since traditionally types are a way of describing an implementation rather than more abstract usage requirements, classes, inheritance, and the concept of a strong type all get wrapped so tightly together that they can't separate them. > > So rather than talking about say an array type, to me duck typing is > > talking about the type of a variable which is used in a certain way, > > which might be somewhat idiosyncratic to the user. Some common such > > types do exist, like a queue, a stack, a generalized collection (with > > various requirements as to access, ordering etc.) given one of these, > > or a more idiosyncratic type, several objects might work as the value > > of the variable in question. > > I don't think duck typing has ever been about a checklist of common > data structures or types (queue, stack, etc.), but more about just > sending messages to objects without a lot of pre-message checking as > to their class and ancestry and so forth. I wasn't saying that all of the roles fall into one of these checklists, but that these and their variations of them are common roles, just like there are common roles like ingenue, jilted lover, thug etc. Other roles are more inventive and complex, like the ex-astronaut rancher building a missile in his barn, or an autistic savant called rain man. > To me, the ultimate duck > typing idiom is: > > def m(x) > x << "string" > end > > There's no checking, no probing the object -- you just ask it to do > something, and deal with what happens. In the end, that's *always* > how things are when writing Ruby. I've always seen "duck typing" as > just a kind of embrace of the conditions under which every single line > of Ruby is code is written anyway. Yes, and this is completely compatible with what I'm saying. Think again about the play, the playwright writes the play, actors are cast, and the production of the play is developed through rehearsal (testing), debugging (re-writes) and sometimes re-casting. Later productions can use different casts, possibly with additional adaptation. > > As an example, lets say I'm looking for something to use to drive a > > nail. The obvious 'type' of thing for this job is a hammer, but a > > heavy wrench, or a rock can also serve since the usage really just > > requires a mass which can be conveniently accelerated so as to impart > > inertia to that nail. If I don't have a hammer to hand, I can press > > one of these other objects into service. > > All these nouns sound more like classes than types. Actually I don't > think the type of a Ruby object can ever be named. It's circular: the > type of an object is... the type of objects that are of this object's > type :-) As soon as it gets noun-like it starts getting class-bound > again. Which nouns? hammer, wrench, rock, yes you can think of these as classes (but more on this in a bit). But mass? Now you are right that it's often hard to name a role, but never say never. The name might stand for a complex type like Romeo, Othello, or Tony Soprano, or it might be a noun phrase like "mass which can be conveniently accelerated...". The point though is that naming it isn't enough. Again in an analogy with writing a play, the playwright's conception of the role doesn't usually spring full-blown when the character's name gets written down, but evolves as the play is written and the character interacts with other characters in the play, and then further evolves as the director begins to interpret the play. Imagine Shakespeare writing Romeo and Juliet in C++, he'd have to pre-declare all the players, and come up with strong types closely bound to the implementation of the actors, before he wrote a line of dialog. Ay there's the rub! -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/