I'll have the duck!

D

dblack

Hi --

I also like it because I don't think that there's anything especially
fundamental about classes. With predicate classes, all you're really
saying is that "if I've got something that can do x and y, then I know
that I can equally validly think of it as something that can do z".

The concept really piqued my interest, and since ruby gives us such nice
metaprogramming abilities, why not do it?


module DuckTyping
@@quacks = Hash.new{ |h,k| h[k] = {} } [...]
Duck.new.quack_loudly #=> "QUACK!"
Dog.new.quack_loudly #=> NoMethodError

I guess you'd have to think of a new name to refer to what has in the
past been called "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
 
D

dblack

Hi --

I wonder then, if we take up John Carter's notion on duck as mixin,
then Enumerable can be defined as:

ducktype :each do
def collect
each{ |e| yield(e) }
end
...
end

Although clearly the distinction between a mixin and a ducktype is the
ducktypes global influence. Quite powerful! Yet, I do imagine that with
this is place someone would call for selector namepsaces to reign in
the abundant flocks ;) Onefurther step would have to be taken, at the
very least. a means of constraining them to specific scopes. Perhaps
that's a simple as limiting them the module space they are defined in?

In any case very interesting. I really wonder just how far one can take
this shift in paradigm?

If it's a shift in paradigm, then it isn't "duck typing" (which is a
term invented to describe aspects of programming in Ruby).

Please choose a different animal :)


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
 
C

Chad Perrin

If it's a shift in paradigm, then it isn't "duck typing" (which is a
term invented to describe aspects of programming in Ruby).

Please choose a different animal :)

The term "duck typing" predates Ruby, as I recall. I seem to remember
it being applied to Objective-C, for instance.

. . not that anyone outside of NeXT used Objective-C for most of its
existence.
 
D

dblack

Hi --

The term "duck typing" predates Ruby, as I recall. I seem to remember
it being applied to Objective-C, for instance.

. . . not that anyone outside of NeXT used Objective-C for most of its
existence.

I've always thought that Dave Thomas coined it, and that it then
caught on (including outside of Ruby). Either way -- I think that
using "duck" in method and class names dilutes the meaning of "duck
typing", and also does a disservice to the stuff people are writing,
some of which may be quite interesting. When I see these
prototype-style libraries named "duck" this and that, I'm just aware
of the fact that duck typing isn't something one can implement in
code, and that therefore the point of this code is being obscured
rather than revealed by the naming.


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
 
C

Chad Perrin

I've always thought that Dave Thomas coined it, and that it then
caught on (including outside of Ruby). Either way -- I think that
using "duck" in method and class names dilutes the meaning of "duck
typing", and also does a disservice to the stuff people are writing,
some of which may be quite interesting. When I see these
prototype-style libraries named "duck" this and that, I'm just aware
of the fact that duck typing isn't something one can implement in
code, and that therefore the point of this code is being obscured
rather than revealed by the naming.

You may well be right. I'm afraid I'm not an expert in the etymology of
the term "duck typing". I'll take your word for it, for the time being.
 
D

Daniel Schierbeck

Daniel said:
I also like it because I don't think that there's anything especially
fundamental about classes. With predicate classes, all you're really
saying is that "if I've got something that can do x and y, then I know
that I can equally validly think of it as something that can do z".

The concept really piqued my interest, and since ruby gives us such nice
metaprogramming abilities, why not do it?


module DuckTyping
@@quacks = Hash.new{ |h,k| h[k] = {} }

def ducktype(*reqs, &block)
o = Object
before = o.methods
o.class_eval(&block)
after = o.methods

for methodname in (after - before)
@@quacks[methodname.to_sym][reqs] =
o.instance_method(methodname.to_sym)
o.send:)remove_method, methodname.to_sym)
end
end

def ducktype_method(methodname)
@@quacks[methodname.to_sym].each do |reqs, m|
if reqs.all?{ |r| self.respond_to?(r) }
return m
end
end
return nil
end

def method_missing(methodname, *args, &block)
if m = ducktype_method(methodname)
m.bind(self).call(*args, &block)
else
super
end
end
end
Object.module_eval{ include DuckTyping }


ducktype :quack do
def quack_loudly
quack.upcase
end
end


class Duck
def quack
"quack!"
end
end

class Dog
def bark
"woof!"
end
end

Duck.new.quack_loudly #=> "QUACK!"
Dog.new.quack_loudly #=> NoMethodError


nifty?

Isn't this stuff used i Aspect Oriented Programming as well? I only know
what I've read in the RCR, so I'm not sure.


Cheers,
Daniel
 
7

7rans

I've always thought that Dave Thomas coined it, and that it then
caught on (including outside of Ruby). Either way -- I think that
using "duck" in method and class names dilutes the meaning of "duck
typing", and also does a disservice to the stuff people are writing,
some of which may be quite interesting. When I see these
prototype-style libraries named "duck" this and that, I'm just aware
of the fact that duck typing isn't something one can implement in
code, and that therefore the point of this code is being obscured
rather than revealed by the naming.

This argument has been made before, notably by you, and it simply does
not hold-up to scrutiny. First of all, how can a programming language
do anything that does not arise from implementation. That's completely
contradictory. But I'll take that to be a misstatement, and you
actually just mean that duck-typing is not something you explicitly
declare, but rather is an implicit occurance of not imposing type
restrictions on method arguments. However you are wrong to think that
there is no imposition being made at all. When an object is the
receiver of a message to which it does not respond, it readily object
with a resulting NoMethodError. So disavowing #respond_to? as
antithetical to duck-typing is simply delusional. Explicit is just the
otherside of the implicit coin. Defining a set of methods based on a
conformity to a "duck type" is therefore not contrary to the original
coinage, but in reality furthers it by taking into account all side.
Which is what I was saying with my original post, that the "duck"
concept as currently implemented may yet be only half turned. It would
then be clear that your hold to this specific idea of the
inexpressibility of a duck type is effective only at stymieing
innovation in the area.

T.
 
D

Dumaiu

I think that AOP is a much more specific approach tailored for
particular types of problems in particular types of OO applications
where the the classes can't be separated nicely. AspectR looks to me
(on the surface) to have more in common with Erik Veenstra's
wrap_method() routine, linked to earlier in the thread.
 
D

Dumaiu

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.
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?(). 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.
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. But I don't think anyone would advocate a
return to rigid inheritance checking, which realization the deprecation
of type() notably indicates.
 
D

dblack

Hi --

This argument has been made before, notably by you, and it simply does
not hold-up to scrutiny. First of all, how can a programming language
do anything that does not arise from implementation. That's completely
contradictory. But I'll take that to be a misstatement, and you
actually just mean that duck-typing is not something you explicitly
declare, but rather is an implicit occurance of not imposing type
restrictions on method arguments.

No misstatement: Duck typing isn't something one can implement in
code. If you say, "So-and-so codes in an elegant way", that doesn't
mean that the next step is to create an ElegantWay module. Duck
typing, as Dave Thomas has put it, is a way of thinking about
programming in Ruby. You may write a module that people who think
that way find useful, but that doesn't mean that it should be called
DuckTyping. You cannot implement a way of thinking, per se, in code.
However you are wrong to think that
there is no imposition being made at all. When an object is the
receiver of a message to which it does not respond, it readily object
with a resulting NoMethodError. So disavowing #respond_to? as
antithetical to duck-typing is simply delusional. Explicit is just the
otherside of the implicit coin. Defining a set of methods based on a
conformity to a "duck type" is therefore not contrary to the original
coinage, but in reality furthers it by taking into account all side.
Which is what I was saying with my original post, that the "duck"
concept as currently implemented may yet be only half turned. It would
then be clear that your hold to this specific idea of the
inexpressibility of a duck type is effective only at stymieing
innovation in the area.

I seem to have hit some kind of nerve here. (To parapharse your
earlier comment: I'll take your characterization of me as "delusional"
as a misstatement :) But reread what I wrote originally. It's got
nothing to do with stymying innovation. I'm just suggesting that
hitching all of this experimentation to the "duck/quack" wagon, when
it comes to method and class and module names, does a disservice to
both the duck typing concept (which isn't about writing modules called
Duck) and to the code you're writing (the possible usefulness of which
is obscured by the peculiar names).


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
 
D

dblack

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
 
S

Srinivas JONNALAGADDA

I wonder then, if we take up John Carter's notion on duck as mixin,
then Enumerable can be defined as:

ducktype :each do
def collect
each{ |e| yield(e) }
end
...
end

From the code above, this appears to be going in the direction of formal
'interface' concept. If 'each' is a "ducktype", and 'each' has a set of
well defined methods, except for the fact that code exists in those
methods, this is tantamount to publishing an interface.
From the little that I understand, the whole concept of duck typing is
about *not* being concerned with a full published interface (or, a full
published inheritance) of the receiver; rather, we are only concerned
with whether the receiver answers the _current_ message.

I could be wrong in understanding your code example, though!

Greetings,
JS
 
D

Daniel DeLorme

I've always thought that Dave Thomas coined it, and that it then
caught on (including outside of Ruby). Either way -- I think that
using "duck" in method and class names dilutes the meaning of "duck
typing", and also does a disservice to the stuff people are writing,
some of which may be quite interesting. When I see these
prototype-style libraries named "duck" this and that, I'm just aware

So your objection is merely semantic? If DuckTyping isn't the "proper"
word to use, what would you suggest? That little module I knocked
together was just a way to mix-in methods into any object that responds
to the proper quacks--er, messages. DuckTyping seems like a good way to
describe that to me.
of the fact that duck typing isn't something one can implement in
code, and that therefore the point of this code is being obscured
rather than revealed by the naming.

That sounds very silly, like saying that OOP or functional programming
can't be implemented in code.

Daniel
 
7

7rans

No misstatement: Duck typing isn't something one can implement in
code. If you say, "So-and-so codes in an elegant way", that doesn't
mean that the next step is to create an ElegantWay module. Duck
typing, as Dave Thomas has put it, is a way of thinking about
programming in Ruby. You may write a module that people who think
that way find useful, but that doesn't mean that it should be called
DuckTyping. You cannot implement a way of thinking, per se, in code.

Well, besides the fact that all code is the implementation of a way of
thinking, have you considered that you may be restricting the concept
arbitrarily? You say DuckTyping is like ElegantWay, and yet I was able
to use DuckType in psuedo-code in a meaningful way. I'd like to see you
do the same with ElegantWay. If what you say is true, how is that
possible?

Of course, you may argue that it's not meaningful, and that actually I
just have a delusional concept of duck typing that allows me to think
it's meaningful. Yet somehow everyone else in this discussion was able
to undestand me. Or are we all just delusional? Well, however you want
to slice up the semantic salad, the bottom line is I'm trying to *talk*
to people, and I'm going to use words that convey my meaning as
concisely as possible. "Duck" works fantasically well here --trying to
explain in another way, or coining another term would only make it more
difficult. Moreover, if I had, I imagine someone would have eventually
say, "isn't this just duck typing". After all, it's already been
erroneously called prototype-based OOP and AOP.
I seem to have hit some kind of nerve here. (To parapharse your
earlier comment: I'll take your characterization of me as "delusional"
as a misstatement :) But reread what I wrote originally. It's got
nothing to do with stymying innovation. I'm just suggesting that
hitching all of this experimentation to the "duck/quack" wagon, when
it comes to method and class and module names, does a disservice to
both the duck typing concept (which isn't about writing modules called
Duck) and to the code you're writing (the possible usefulness of which
is obscured by the peculiar names).

Bull hockey (does this do a disservice to bulls or hockey? ;-)

The problem, David, is that you are adding _nothing constructive_ to
the conversation. You are merely being persnickety over terminology. No
one else is having any trouble over the use the word "duck" in the
code, or what it represents. Certainly I don't expect "duck" to become
a keyword of the language, but it serves perfectly well for this
exploration -- it is ultimately an analogy after all, "if it walks like
duck and talks like a duck..." We're using the analogy.

T.
 
7

7rans

Hmmm... David, my point is simply this: I understand your concern with
regards to the intended coinage of "duck typing" by Dave Thomas. But
this discussion is too protozoic to be overly concernd with exacting
nomenlature at this point. It is enough to _convey_ the idea intended.

T.
 
D

Dumaiu

Daniel said:
So your objection is merely semantic? If DuckTyping isn't the "proper"
word to use, what would you suggest? That little module I knocked
together was just a way to mix-in methods into any object that responds
to the proper quacks--er, messages. DuckTyping seems like a good way to
describe that to me.

It's confusing. For my part, I wouldn't mind so much seeing a module
called 'DuckTyping'--I would think, 'Okay, here's someone taking a shot
at codifying a general concept'; but encountering the words 'duck' and
'quack' in actual method names makes me suspicious that someone is
trying to be "cute." Or the issue can be linguistic. To take the
example of your test module, on line 2 I see

@@quacks = +whatever+

and my mind hits a rut. Is this a list of objects|methods|classes that
are capable of quacking, or of the different vocal sounds that ducks
make? Similarly, farther down you have a method called

ducktype_method(methodname)

But is 'ducktype_method' a noun or a verb? Perhaps you can apperceive
the meaning of a method definition at first glance, but I (and probably
some others) have to think about it, and the reuse of the same minimal
vocabulary

ducktype :quack do
def quack_loudly
quack.upcase
end
end

is frustrating. It would be even more so if I were brand-new to Ruby.
That sounds very silly, like saying that OOP or functional programming
can't be implemented in code.

For this comparison to be valid, you would have to turn duck typing
into a programming paradigm: Duck-Oriented Programming. Is that really
worth it?
 
D

Dumaiu

Perhaps you should try being 'delusional,' for a change; doesn't your
customary lucidity become oppressive sometimes? Take a break. For
example, the next time someone levies that accusation, you say, 'Thank
you, madam; two lumps.'

-J
 
D

dblack

Hi --

So your objection is merely semantic? If DuckTyping isn't the "proper"
word to use, what would you suggest? That little module I knocked
together was just a way to mix-in methods into any object that responds
to the proper quacks--er, messages. DuckTyping seems like a good way to
describe that to me.

The problem is that "duck typing" is already "taken" :)
That sounds very silly, like saying that OOP or functional programming
can't be implemented in code.

I do wish we could keep "silly" and "delusional" and so on out of it.
Anyway -- my point is that duck typing is not a library-level language
facility that you or I can write and 'require' and thus add to Ruby.
Even if there's a module called DuckTyping, people who ignore that
module are still 100% as capable of using a duck-typing approach as
people who use the module. The existence of the module is orthogonal
to both the duck-typing friendliness of the language, and the
duck-typing programming style of the people using the language.

It's a bit like writing a module called ObjectOrientation. The module
might do something wonderful, but it doesn't add object orientation to
Ruby :) (I think I stole that example from Chad Fowler, from a
discussion of something else a couple of years ago.)

So my suggestion was, and is, to name your module something else, and
then trust duck-typing devotees (and others) to examine it and decide
whether it helps them out.


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
 
D

Daniel DeLorme

The problem is that "duck typing" is already "taken" :)

*sigh*
And So, Faced With Insurmountable Semantic Opposition And A
Total Lack Of Suggestions, I Was Faced With The Lonely Task
Of Renaming My Proof-Of-Concept Module, Carefully Removing
Any Offending Reference To The Word "Duck":


module DependentMethods
@@dependent_methods = Hash.new{ |h,k| h[k] = {} }

def depending_on(*requisites, &block)
o = self.is_a?(Class) ? self : self.class
requisites.unshift(o)

before = o.instance_methods
o.class_eval(&block)
after = o.instance_methods

for methodname in (after - before)
methodname = methodname.to_sym
@@dependent_methods[methodname][requisites] = o.instance_method(methodname)
o.send:)remove_method, methodname)
end
end

def dependent_method(methodname)
@@dependent_methods[methodname.to_sym].each do |requisites, m|
if self.kind_of?(requisites[0])
if requisites[1..-1].all?{ |r| self.respond_to?(r) }
return m
end
end
end
return nil
end

def method_missing(methodname, *args, &block)
if m = dependent_method(methodname)
m.bind(self).call(*args, &block)
else
super
end
end
end
Object.module_eval{ include DependentMethods }


depending_on :quack do
def quack_loudly
([quack.upcase]*(1+rand(3))).join
end
end

class Anatidae
def quack
"quack!"
end
end

d = Anatidae.new
puts d.quack_loudly #=> "QUACK!"
 
7

7rans

The problem is that "duck typing" is already "taken" :)


I do wish we could keep "silly" and "delusional" and so on out of it.
Anyway -- my point is that duck typing is not a library-level language
facility that you or I can write and 'require' and thus add to Ruby.
Even if there's a module called DuckTyping, people who ignore that
module are still 100% as capable of using a duck-typing approach as
people who use the module. The existence of the module is orthogonal
to both the duck-typing friendliness of the language, and the
duck-typing programming style of the people using the language.

It's a bit like writing a module called ObjectOrientation. The module
might do something wonderful, but it doesn't add object orientation to
Ruby :) (I think I stole that example from Chad Fowler, from a
discussion of something else a couple of years ago.)

So my suggestion was, and is, to name your module something else, and
then trust duck-typing devotees (and others) to examine it and decide
whether it helps them out.

Er... Did someone put you in charge of the duck type club? I am a
duck-typing "devotee". But I am not a dogmatic lexicon beater. My use
of the term "duck" and "type" has a very clear sematic value to the
conversaion percisely because of the term Dave has "taken" --taken to
have a _useful_ meaning. But you want to insist that my use of the term
isn't "proper" and continue to waste our time on matters of "rosey"
triviality. Then let me oblige you in your own pursuit...

The term ducking typing, according to your own convictions can be
nothing of the sort. For it is completely contradictory to call
something a "type" when by defintion it excludes anything type
whatsoever. It would be more appropritate call it duck anti-typing, if
anything. Furthermore a duck is featuerd animal that tends to float
around in ponds all day and fly south for the wnter. I fail to see any
such creatures in your concept.

You see, the words "duck" and "type" were "taken" before you or Dave
hit the scene So I advise you to find another term. :)

T.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top