>> Duck typing co-exists peacefully with the existence of
>> classes -- or
>> at least it can. The biggest problem I've seen over the
>> years in the
>> matter of understanding Ruby's particular class/prototype
>> blend is the
>> "class == type" fallacy.
> Using the term "type" by itself instead of something else
> perpetuate this fallacy. Object#type is a synonym of
Yes, but that use is deprecated. The explanation given by
Matz in the
past, as I recall, is that he chose to add the synonym "type"
at the time, there were problems parsing "class" as a
even in method-call position.
It's unfortunate that that happened, because it's certainly
flames of the misunderstanding, but it was for understandable
technical reasons and hopefully it will be resolved so that
>> There are two common consequences of this
>> it leads to the creation of new ways of referring to type
>> "duck type", which is redundant and superfluous).
> Your definition of "type" is quite different from the
> definition I gave of "duck type". Your definition of the
> "type" of an object is the "sum of all of its capabilities"
> i.e. ALL of the methods it responds to. I think that
> definition is about as relevant to ruby and duck-typing as
> class is. This definition of "type" is close to a java
> "interface", but is more restrictive because it represents
> entire behavior of an object where an interface may be just
> subset. From your definition of "type", an object only
> one "type" for any given state of that object.
> The definition I gave of "duck type" allows an object to
> many "duck types" at a time. It all depends on who is
> the object.
I would start with your statement and "divide by duck"
object's type allows the object to do many things at a time,
addressed in many ways. I don't feel the need to have a
label for the
subsets. Just ask the object.
(I guess you could call a subset of a type, too, a type.
type police. As long as the object does what you claim for
that's its type.)
> Each usage of an object may have a different view
> of what the "duck type" is. My definition of "duck type"
> really refers to the usage of an object not the object
> The most common usage would be as a method argument, but it
> could also be applied to variables, using return values
> methods, etc. I think the broadest definition I could give
> would be that a "duck type" of a given usage of an object
> described by what capabilities are used of that object in
> context. This includes what methods that object needs to
> respond to, the arity of those methods, the "duck type" of
> arguments for those methods, and the "duck type" of what is
> returned from those methods.
> Take a look at the original definition of duck-typing given
> Dave Thomas. Here is the example he gave:
> > When I write
> > fred << "dog"
> > in Ruby, I don't care whether fred is a String, a File,
> > Array
> In this context, the "duck type" of fred is something that
> reponds to <<(aString).
> By your definition of "type" being "the sum of all of its
> capabilities", you'd have to pick what "type" fred is -
> String-like, File-like, or Array-like.
On the contrary: I *don't* have to pick or describe or find
for what it is. That's the point: the type is what's there.
even have to name it.
From what you said above, I don't see any debate over how I
defined "duck type" (other than the name). I only see you
clarifying what you meant by "type". I still don't see a
concrete definition of yours, but it sounds like you might mean
the same as what I said for "duck type". But, when you say
"type" is "the sum of all of its capabilities" and "an
object's type can change and evolve during runtime" this says
to me your "type" is associated with the object itself and not
how the object is used. All that really matters regarding
"type" in my opinion is how an object is used. What a
particular object's entire capabilities and the fact that they
can change over time is orthongonal.
I'm not sure why you don't like the term "duck type". It is
directly associated with the term "duck typing" and is quite
clear in that context. I don't understand the need to talk
about/document an abstract "type" beyond the context of "duck
typing". Can you think of anything else?
> If you said that fred
> was something File/IO-like you could use an IO, File, or
> StringIO for fred, but not a String or Array because they
> have the same capabilities.
No, not at all: you're missing the (intentional) circularity
tautology -- of my account of "type". "String-like" is not a
type. It may be a partial description of a type -- and it
may be a
convenient or expedient shorthand for labeling an object's
capabilities -- but it is not a type. An object could be
"String-like", and also be other things. String-like plus
things would, essentially, be the object's type.
This is circular because it means that the type of object x
type which is the type of objects whose type is that of
I never have to say that fred is "String-like" or
"<anything>-like". All I have to do is send messages to
Neither fred nor the caller has to be constrained by
behavior into "String" and "Array" and so forth. All that
what happens at the moment of the method call.
> The downside of typing your arguments using this "duck
> definition is that you have to pick what methods you want
> use up front and document what you are using (or may use).
> you later want to change the implementation to use other
> methods, you'll need to change the docs and possibly break
> callers using objects under the original duck-type. With
> "type" definition you have, this downside doesn't exist. A
> method has much more freedom of choice. For example, in
> above, you could change it to fred.write("dog") later down
> road if you limited fred to be anything IO-like.
I personally wouldn't say "anything IO-like" (nor "O-like",
that might be closer but rather: anything that responds
"write". That's *all* that matters. "IO-like" is a
concept, built on top of that. Let's say someone said: "no,
IO-like; I reject that." That person could still send "write"
as much as you can.
My point was that if you document your method to take an
IO-like object (which I thought was your way - sum of the
capabilities of an object), you have the freedom to use any of
the IO methods. If initially the method is implemented using
<<, it may work with anything that has the << method now, but
you run the risk of something breaking if the implementation
changes to use different or additional methods. If you
document a method like this, you give the method implementation
freedom to use a wide range of methods, but limit the caller to
objects that implement that entire interface.
Of course that is not the duck-typing or ruby way. The
duck-typing way is to document what capabilities you want/need
from an argument and that's it. This gives more freedom to the
caller and less to the method implementation.
> Personally, I don't think adding methods are too bad, but
> able to remove or modify methods doesn't seem like a good
> or serve much use. I'd rather see a new object be created
> have these methods removed/modified instead.
It comes in handy for class methods
But, do you ever use the intermediate versions of the class
without the class methods? The way class methods are
implemented now uses a meta class of Class that is modified
along the way. It didn't have to be done that way.
For comparision, look at these two:
x = "Hello world!".reverse # returns a new object
x = "Hello world!".reverse! # modifies existing object
In Java, compare the optimizations that could be done with
String (immutable) vs. StringBuffer (mutable). There are many
optimizations that can be done in String relative to
StringBuffer because it is immutable. I assert the same can be
said of mutable vs. immutable classes (or meta classes), but I
think the difference is more significant once you get deep into
--- "David A. Black" <email@example.com> wrote:
On Thu, 18 Aug 2005, Eric Mahurin wrote:
> --- "David A. Black" <firstname.lastname@example.org> wrote:
Start your day with Yahoo! - make it your home page