Hi --
>
>> 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
helps
> perpetuate this fallacy. Object#type is a synonym of
> Object#class.
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"
because,
at the time, there were problems parsing "class" as a
non-keyword,
even in method-call position.
It's unfortunate that that happened, because it's certainly
fanned the
flames of the misunderstanding, but it was for understandable
technical reasons and hopefully it will be resolved so that
"type" can
disappear.
>> There are two common consequences of this
misunderstanding. First,
>> it leads to the creation of new ways of referring to type
(like
>> "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
the
> entire behavior of an object where an interface may be just
a
> subset. From your definition of "type", an object only
has
> one "type" for any given state of that object.
>
> The definition I gave of "duck type" allows an object to
have
> many "duck types" at a time. It all depends on who is
using
> the object.
I would start with your statement and "divide by duck"
An
object's type allows the object to do many things at a time,
and be
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.
There's no
type police. As long as the object does what you claim for
its type,
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
itself.
> The most common usage would be as a method argument, but it
> could also be applied to variables, using return values
from
> methods, etc. I think the broadest definition I could give
> would be that a "duck type" of a given usage of an object
is
> described by what capabilities are used of that object in
that
> context. This includes what methods that object needs to
> respond to, the arity of those methods, the "duck type" of
the
> 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
by
> 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,
or an
>
> > 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
synonyms
for what it is. That's the point: the type is what's there.
I don't
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
don't
> have the same capabilities.
No, not at all: you're missing the (intentional) circularity
-- even
tautology -- of my account of "type". "String-like" is not a
Ruby
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
those other
things would, essentially, be the object's type.
This is circular because it means that the type of object x
is "the
type which is the type of objects whose type is that of
object x."
I never have to say that fred is "String-like" or
"Array-like" or
"<anything>-like". All I have to do is send messages to
fred.
Neither fred nor the caller has to be constrained by
aggregations of
behavior into "String" and "Array" and so forth. All that
matters is
what happens at the moment of the method call.
> The downside of typing your arguments using this "duck
type"
> definition is that you have to pick what methods you want
to
> use up front and document what you are using (or may use).
If
> 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
the
> "type" definition you have, this downside doesn't exist. A
> method has much more freedom of choice. For example, in
the
> above, you could change it to fred.write("dog") later down
the
> road if you limited fred to be anything IO-like.
I personally wouldn't say "anything IO-like" (nor "O-like",
though
that might be closer but rather: anything that responds
to
"write". That's *all* that matters. "IO-like" is a
secondary
concept, built on top of that. Let's say someone said: "no,
it's not
IO-like; I reject that." That person could still send "write"
to fred,
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
being
> able to remove or modify methods doesn't seem like a good
idea
> or serve much use. I'd rather see a new object be created
that
> 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
optimizations.
···
--- "David A. Black" <dblack@wobblini.net> wrote:
On Thu, 18 Aug 2005, Eric Mahurin wrote:
> --- "David A. Black" <dblack@wobblini.net> wrote:
____________________________________________________
Start your day with Yahoo! - make it your home page
http://www.yahoo.com/r/hs