Hi --

On Sat, 9 Aug 2003, Mills Thomas (app1tam) wrote:

> > -----Original Message-----
> > From: dblack / superlink.net [mailto:dblack / superlink.net]
> > Sent: Friday, August 08, 2003 11:00 AM
> > To: ruby-talk / ruby-lang.org
> > Subject: Re: Ducktype, right?
> >
> > >
> > > ### in Ruby
> > > yourRobot.quack if ducktype(yourRobot, duckness)
> > > duckHerder.buy(myRobot) if ducktype(myRobot, duckness)
> >
> > (I'm not sure I'd file the second example under "duck typing"
> > (since it's argument-checking rather than object capability
> > checking), but you could probably come up with a method name
> > that was a superset of both :-)
> >
>
> I guess I'm not sure what duck typing is, then.  My example was assuming I
> was using the original method from my first post.  Thus, duckness is a list
> of ducky methods.  My second example was selling myRobot to a duckHerder
> since, for all intents and purposes, myRobot acts like a duck.  The
> duckHerder would also consider myRobot to be a duck, assuming we agreed on
> duckness.  I thought that was duck-typing.

The wisest answer would probably be: if it walks like duck typing and
talks like duck typing, then it is duck typing :-)  But I meant only
that I've never heard the term applied to that kind of argument checking
(where the object being checked for capabilities isn't actually the only
being asked to do anything).

I guess I'd tend to say that the concept of "agreeing on duckness",
where "duckness" is taken to be an immutable list of method names, is more
a particular way of addressing the ambient fact of duck typing (i.e.,
the fact that the "type" of Ruby objects is essentially inferential)
than it is, per se, duck typing.

Actually the best way to get at this is to put the spotlight on
something relatively unexciting-looking in your code: duckHerder.buy.
We've been taking that method call for granted -- but it also operates
in the universe of duck typing.  You're assuming that, at that moment
in its existence, the duckHerder object knows how to respond to "buy".
And probably that it will respond in a certain way.  In fact, we all do
this all the time; it would drive one crazy (and perhaps *be* crazy) to
do a "responds_to?" before every method call.  But, even in a relatively
"innocent" case like this, the type of the object is the sum of what it
can do at that moment, and the only measure of that is to measure it.

Of course you *could* apply the technique you've used elsewhere:

  if ducktype(duckHerder, spender)
    duckHerder.buy ...

But my point is that, even if you don't (and at some point one has to
stop!), you're still dealing with "duck typing" -- even if, in a given
case, you deal with it by deciding to trust to the percentages (the
unlikelihood that the object's interface has been altered) perhaps in
combination with a suite of tests.

In any case, the main thing is the underlying thing -- the dynamism and
extensibility of Ruby objects, and the implications this has for "type".
I tend to think of the notion of duck typing as a way of encapsulating
the idea: "'type' in Ruby is, at best, something you can only know after
the fact, and fleetingly, so don't put too much weight on it."


David

-- 
David Alan Black
home: dblack / superlink.net
work: blackdav / shu.edu
Web:  http://pirate.shu.edu/~blackdav