Hi --
I'm not sure what the best place for this is; sorry. The following are
my views:
What we know as 'duck typing' is not really a programming paradigm,
but a set practices as Mr. Black says--merely the "yin" end of the
type-checking continuum. I first learned about it, although of course
not by that name, from studying C++ templates, where also the
prevailing wisdom is that you shouldn't assume anything more about your
library's client's code than is absolutely necessary. The 'duck
typing' moniker that marks it as a novelty is most useful against the
background of static languages, where type-checking helps prevent
runtime errors. For Ruby, where *every* error is runtime, duck typing
is the raw form of its behavior, and should be recognized as quickly as
possible, because it isn't always good. At its utmost, duck typing is
the total absence of validation. You are saying that nothing about
your client's program is worth trying to predict, that 'if it works, it
works,' and if it doesn't, he'll know because it just blew up.
True, though that's partly why test-driven development is so big among
Rubyists.
Hmm. I see where type-checking came from. As far as Ruby best
practices go, I think 'duck typing' just means using respond_to?() more
than kind_of?() and include?().
At some point in the past I think I posited a distinction between
"soft duck typing" and "hard duck typing"
Very much along the
lines you're describing: soft duck typing involves the "extra" layer
of respond_to? and hard duck typing doesn't. respond_to? is certainly
a sensible precaution to take, in many cases, and one that operates in
the orbit of the object itself (as opposed to kind_of?).
(I'm not quite sure what you mean about include?....)
If you really wanted to, dumping class
use entirely and turning Ruby into a prototype-based language wouldn't
be too hard: you'd use Object::new() only, define only singleton
methods, and extend objects with clone(); and if you wanted to
delegate, you'd keep an array of references of "parent" objects,
Perl-style.
It seems to me (though I don't know any of the prototyped languages in
any depth) that Ruby indeed gives you both: a per-object universe, and
a class system. Ultimately, the former sort of "wins", in the sense
that classes are objects and so on... but actually I think the two are
in a nice balance.
Personally, I feel that Ruby needs more, rather than less, type
safety, to balance its natural inclination otherwise and because no
amount of 'duck typing' disaffirms that erroneous behavior is best
caught as soon as possible.
True -- but it may have to do with how one defines "possible"
One
could say that no amount of early checking can change the fact that
the only absolute way to know what sending a message to an object will
do is to send the message to the object. In practice, one settles for
non-absolute ways, not only because they tend to work but because
they're all that's available. But I'm always fascinated by the
singularity of a Ruby method call: there's nothing else around it that
really, absolutely pertains to it.
But I don't think anyone would advocate a
return to rigid inheritance checking, which realization the deprecation
of type() notably indicates.
Actually the deprecation of type, I believe, has a different cause.
As I understand it, in early Rubies there were problems parsing:
obj.class, so a name other than "class" had to be used for that
method. Now that obj.class can be parsed, "type" is no longer needed
-- and, as Matz has said, it's problematic because it discourages duck
typing.
David
--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
http://www.manning.com/black => RUBY FOR RAILS (reviewed on
Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
(e-mail address removed) => me