I'll have the duck!

dblack@wobblini.net wrote:

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.

*Whew!* That's a relief.

At some point in the past I think I posited a distinction between
"soft duck typing" and "hard duck typing" :slight_smile: 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?....)

I meant Module#include?(), as the mixin-checking counterpart to
inheritance-checking.

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.

I agree. Classes and modules complement each other well, and an
immutable object prototype kept around only for cloning really isn't
very different from a class definition. I like the support for
multiple approaches.

> 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" :slight_smile: 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.

The atomicity of a Ruby call makes for a nice, visceral experience,
doesn't it? :smiley: I'm glad you pinpointed the definition of 'possible,'
because therein, as they say, lies the rub, and as it turns out I have
feelings about that, too. I'd advocate the use of respond_to?(),
because, as you say, it seems a 'sensible precaution.' I would
relegate method_missing() to the court of last resort and absolve
library designers from worrying about it. Because it's so powerful,
its use can't be predicted or guaranteed to operate properly; and if,
as I believe, every Best Practice should have a back door available for
exigency, method_missing() can never be a Best Practice, because it is
the ultimate back door.
  I think you understood my point, though. Too much duck typing and you
have to throw up your hands in surrender.

> 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.

Oh, really? Thanks for setting me straight.

···

On Tue, 25 Jul 2006, Dumaiu wrote:

CLOS (Common Lisp Object System) has multi-dispatch too.

It is more powerful than smalltalk or ruby's message based OOP
approach. It is also hard to design in, if you aren't used to it.
Given that some people coming from static languages are still
wrestling with plain old duck typing, I think it would be overkill for
ruby, and hard on a lot of people. It's just not ruby's niche.

Jürgen

···

On Tue, Jul 25, 2006 at 08:14:59PM +0900, Christian Neukirchen wrote:

Ron Jeffries <ronjeffries@acm.org> writes:

> On Mon, 24 Jul 2006 08:09:58 +0900, transfire@gmail.com wrote:
>
>>Now anything that responded to #to_a could use #transform. I'm not sure
>>how far this can be taken. Can classes be undone altogegther? But in
>>anycase, it seems very cool, and I wonder what kind of overall effect
>>it could have on coding?
>
> there's a language called "self" that has no classes, only prototypes. if you
> can find some material on that, i think you'll find it interesting.

While you're at it, have a look at Slate, that also removes single-dispatch.

> Ron Jeffries
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

--
The box said it requires Windows 95 or better so I installed Linux

I'd say that duck typing is more a means of allowing you to defer
rigidity until it's actually beneficial. It has little or nothing to do
with delaying validation, and everything to do with avoiding the
unfortunate circumstance of having to validate before it's convenient
for your code to have something to validate.

···

On Thu, Aug 03, 2006 at 12:01:50AM +0900, Jürgen Strobel wrote:

On Tue, Jul 25, 2006 at 01:05:11PM +0900, Dumaiu wrote:

> 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.

By your argument, exceptions are bad too, because they catch errors
"late". And IMHO exception handling was one of the better points when
going from C to C++. Think of duck typing as yet another technique not
to litter your code with error checking, but still do it
somewhere/sometime. You do handle C++ exceptions too, do you, if not
neccessarily right next to throwing them?

I repeat: duck typing is not to produce bombing out code, but a new*
way to handle dynamic and flexible type validation "late", with the
objective to ease development and produce clean code.

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
"The ability to quote is a serviceable
substitute for wit." - W. Somerset Maugham

Robert Dober wrote:

Robert Dober wrote:
<snip>
>> and hence any hash-like object.
>
> Yeah great, you see that is what troubles me, it is completely cool to
talk
> about hash-like object, but what is a hash-like object? Which messages
> must
> a hash-like object respond to? All of Hash, I suppose, thus a subclass,
or
> only some, then we can talk about protocols again, but the failure to be
> able to define the protocol just worries me.
That's the whole point. Duck-typing means that your class only needs to
define the methods (of Hash, in this case) that the called method
(transform here) needs, *not* the whole Hash class, *without* having to
specify a protocol. If you want to specify a protocol, there's one
example of how to do it here:

Ruby Monitor-Functions - Or Meta-Meta-Programming in Ruby

Well I have read that, kind of, it is a little bit heavy, too heavy I am
afraid.
I still do not get the point, are you saying I am right (let dogs life) or
are you saying I am wrong (let only ducks life).

It's my opinion that opposition to duck-typing is a bad idea (especially when dealing with Ruby, given how pervasive it is), but that doesn't make it wrong. It is perfectly possible for both dogs and ducks to co-exist.

Mixins are another nice way to think about it

class Dog
    include Duck
... # no this is *not* the Perl6 Thingy Jabbawalky operator :wink:
end

d = Puppet
d.implements? Duck ==> true

If you're always supplying Duck's functionality as a mixin, you can do:

Duck === d
=> true

The beauty of duck-typing is that you don't have to, though.

If you wanted an Object#implements? method which doesn't rely on implementation via mixin, you could do it like this:

class Object
   def implements?(module)
     my_methods = Set.new(self.public_methods)
     module_methods = Set.new(module.instance_methods)
     return my_methods.superset?(module_methods)
   end
end

Again, that misses the point somewhat, though - duck-typing lets you not have to think about the concept of a defined interface (in the Module sense, at least). If your method only calls #foobar on a passed object, then that object only need respond to the #foobar method.

but maybe this is here already, gotta check.
Thx for your considerations
I repeat nevertheless
Ducks are great, unless they kill Dogs :wink:

You can always check the class of an object, and there are ways to make the syntax less cumbersome than it might otherwise be.

···

On 7/24/06, Alex Young <alex@blackkettle.org> wrote:

> On 7/24/06, transfire@gmail.com <transfire@gmail.com> wrote:

--
Alex

You piqued my curiosity with that. But "lo" is really hard to google
for. Do you have any reference links?

Actually it is pretty easy to google: Io programming language :wink:

http://www.iolanguage.com/about/

Regards,
Rimantas

···

--
http://rimantas.com/

Mat Schaffer wrote:

I much prefer its (less mature) derivative, Io. Everything is a message to something else, and everything is a prototype. Very simple, very powerful (even, dare I say, more powerful than Ruby, albeit a bit less pretty).

- Jake McArthur

You piqued my curiosity with that. But "lo" is really hard to google for. Do you have any reference links?

http://www.iolanguage.com/about/

···

On Jul 23, 2006, at 10:59 PM, Jake McArthur wrote:

--
Alex

You piqued my curiosity with that. But "lo" is really hard to google
for. Do you have any reference links?
-Mat

http://www.iolanguage.com/

Enjoy :wink:

···

--
Fabio Aquotte

Hi --

···

On Tue, 25 Jul 2006, transfire@gmail.com wrote:

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 :wink: 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 :slight_smile:

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

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.

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

···

On Tue, 2006-07-25 at 02:49 +0900, transfire@gmail.com wrote:

I agree. If we were going to go that route, we'd probably want to give
Ruby a functional syntax, at which point we'd just be using Lisp anyway.
Let's keep Ruby its own language.

···

On Wed, Aug 02, 2006 at 11:32:13PM +0900, Jürgen Strobel wrote:

CLOS (Common Lisp Object System) has multi-dispatch too.

It is more powerful than smalltalk or ruby's message based OOP
approach. It is also hard to design in, if you aren't used to it.
Given that some people coming from static languages are still
wrestling with plain old duck typing, I think it would be overkill for
ruby, and hard on a lot of people. It's just not ruby's niche.

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
"The ability to quote is a serviceable
substitute for wit." - W. Somerset Maugham

That is one of the most concise statements on the benefits of
duck-typing I've ever read. Thanks, Chad!

Jacob Fugal

···

On 8/2/06, Chad Perrin <perrin@apotheon.com> wrote:

I'd say that duck typing is more a means of allowing you to defer
rigidity until it's actually beneficial. It has little or nothing to do
with delaying validation, and everything to do with avoiding the
unfortunate circumstance of having to validate before it's convenient
for your code to have something to validate.

Jürgen Strobel <strobel@secure.at> writes:

> there's a language called "self" that has no classes, only prototypes. if you
> can find some material on that, i think you'll find it interesting.

While you're at it, have a look at Slate, that also removes single-dispatch.

CLOS (Common Lisp Object System) has multi-dispatch too.

It is more powerful than smalltalk or ruby's message based OOP
approach. It is also hard to design in, if you aren't used to it.
Given that some people coming from static languages are still
wrestling with plain old duck typing, I think it would be overkill for
ruby, and hard on a lot of people. It's just not ruby's niche.

Jürgen

CLOS has classes, though.

···

--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org

We seem to agree even if you think we don't.

"avoiding ... validation before it's convenient" vs. "delayed validation".

"defer rigidity" vs. "dynamic and flexible type validation"

Now where is the difference apart fom wording?

-Jürgen

···

On Thu, Aug 03, 2006 at 12:39:38AM +0900, Chad Perrin wrote:

On Thu, Aug 03, 2006 at 12:01:50AM +0900, Jürgen Strobel wrote:
> On Tue, Jul 25, 2006 at 01:05:11PM +0900, Dumaiu wrote:
>
> > 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.
>
> By your argument, exceptions are bad too, because they catch errors
> "late". And IMHO exception handling was one of the better points when
> going from C to C++. Think of duck typing as yet another technique not
> to litter your code with error checking, but still do it
> somewhere/sometime. You do handle C++ exceptions too, do you, if not
> neccessarily right next to throwing them?
>
> I repeat: duck typing is not to produce bombing out code, but a new*
> way to handle dynamic and flexible type validation "late", with the
> objective to ease development and produce clean code.

I'd say that duck typing is more a means of allowing you to defer
rigidity until it's actually beneficial. It has little or nothing to do
with delaying validation, and everything to do with avoiding the
unfortunate circumstance of having to validate before it's convenient
for your code to have something to validate.

--
The box said it requires Windows 95 or better so I installed Linux

No that is not what I want (I do that an awful lot but that is very doggish)
As a matter of fact I want to be ducky, but on the save side.
I'll explain

module A
    def a; "a"; end
    def b; "b", end
end
class DogOne
    include A
end
class DogTwo
   def a; :a; end
   def b; :b; end
end

[DogOne.new, DogTwo.new].map{ |doggy| doggy.implement? A} ==>
[true, true]

···

On 7/24/06, Alex Young <alex@blackkettle.org> wrote:

Robert Dober wrote:
> On 7/24/06, Alex Young <alex@blackkettle.org> wrote:
>
>>
>> Robert Dober wrote:
>> > On 7/24/06, transfire@gmail.com <transfire@gmail.com> wrote:
>> <snip>
>> >> and hence any hash-like object.
>> >
>> > Yeah great, you see that is what troubles me, it is completely cool
to
>> talk
>> > about hash-like object, but what is a hash-like object? Which
messages
>> > must
>> > a hash-like object respond to? All of Hash, I suppose, thus a
subclass,
>> or
>> > only some, then we can talk about protocols again, but the failure
>> to be
>> > able to define the protocol just worries me.
>> That's the whole point. Duck-typing means that your class only needs
to
>> define the methods (of Hash, in this case) that the called method
>> (transform here) needs, *not* the whole Hash class, *without* having to
>> specify a protocol. If you want to specify a protocol, there's one
>> example of how to do it here:
>>
>> Ruby Monitor-Functions - Or Meta-Meta-Programming in Ruby
>
> Well I have read that, kind of, it is a little bit heavy, too heavy I am
> afraid.
> I still do not get the point, are you saying I am right (let dogs life)
or
> are you saying I am wrong (let only ducks life).
It's my opinion that opposition to duck-typing is a bad idea (especially
when dealing with Ruby, given how pervasive it is), but that doesn't
make it wrong. It is perfectly possible for both dogs and ducks to
co-exist.

> Mixins are another nice way to think about it
>
> class Dog
> include Duck
> ... # no this is *not* the Perl6 Thingy Jabbawalky operator :wink:
> end
>
> d = Puppet
> d.implements? Duck ==> true
If you're always supplying Duck's functionality as a mixin, you can do:

Duck === d
=> true

        ====

As a matter of fact I am completely in love with ruby and even with
ducktyping, but
I am terribly in need of *early* failure.
I want to fail my programs as early as possible

e.g.

def eat ( someAniamal)
  ....
  someAnimal.a ===> error

is bad (for me, but early failure is a well accpted principle)
while

def eat( somaAniaml)
   assure someAnimal.implements? A
is better

In other words, yes I love to use Dogs but when I use Ducks (and there are
very good reasons to use Ducks, e.g. agile development) I want to get to
know my duck fast.

The beauty of duck-typing is that you don't have to, though.

Yes I agree 100% but the not-so-beauty is that I cannot (veryeasily)

If you wanted an Object#implements? method which doesn't rely on

implementation via mixin, you could do it like this:

class Object
   def implements?(module)
     my_methods = Set.new(self.public_methods)
     module_methods = Set.new(module.instance_methods)
     return my_methods.superset?(module_methods)
   end
end

yes I could, why not, nice idea

Again, that misses the point somewhat, though - duck-typing lets you not

  have to think about the concept of a defined interface (in the Module
sense, at least). If your method only calls #foobar on a passed object,
then that object only need respond to the #foobar method.

Is this really a feature, all the times, I do not think so.

but maybe this is here already, gotta check.
> Thx for your considerations
> I repeat nevertheless
> Ducks are great, unless they kill Dogs :wink:
You can always check the class of an object, and there are ways to make
the syntax less cumbersome than it might otherwise be.

--
Alex

Thx again for your thaughts

Robert

Hi --

If you're always supplying Duck's functionality as a mixin, you can do:

Duck === d
=> true

The beauty of duck-typing is that you don't have to, though.

I'd go further: the definition of duck typing is that you don't :slight_smile:

I think Dave Thomas was always pretty explicit about saying that duck
typing, in practice as well as theory, is something one does *instead*
of checking class/module ancestry. I think the use of Duck, duck,
quack, etc. as class and method names is kind of misleading. It moves
the class-checking approach into the "duck" namespace -- which means
that "duck typing" gets redefined, and it also means that the thing
originally called "duck typing" is left without a name.

What it always comes down to for me is this: in Ruby, at the moment
that you send a message to an object, you send a message to an object.
No amount of checking of class membership -- not even, technically,
the prior checking of respond_to? -- has any bearing on what happens
when that message is sent.

Duck typing is Dave's name for an approach to Ruby programming that
attempts to live in harmony with this underlying state of things in
Ruby, rather than covering it up or pretending it isn't there.

There are two major ramifications of duck typing:

   1. it leads you to understand what's actually happening every
      time you call a method in Ruby;
   2. it points the way to interesting and productive things you
      can do to harness the way Ruby works, rather than fighting it.

I've always agreed with Jim Weirich that Ruby is "a duck-typed
language". In other words, as far as Ruby is concerned, everyone is
duck typing: everyone is sending messages to objects, and those
message-sending events are never connected directly to an object's
ancestry. Hence #1 in the list above.

As for #2 -- it's not that it's a mark of shame to use #is_a? and
#respond_to?, but rather that Ruby does provide a programming
environment in which it's possible, thanks to a design that eschews
certain constraints, to do otherwise, with good results.

Final note to Alex: much of what's here is in response to the whole
thread, even though it's in a response to your post :slight_smile:

David

···

On Mon, 24 Jul 2006, Alex Young wrote:

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

Right. io, not LO..... silly sans-serif fonts.
Thanks!
-Mat

···

On Jul 24, 2006, at 8:52 AM, Rimantas Liubertas wrote:

You piqued my curiosity with that. But "lo" is really hard to google
for. Do you have any reference links?

Actually it is pretty easy to google: Io programming language :wink:

http://www.iolanguage.com/about/

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.

···

On Tue, Jul 25, 2006 at 05:48:29AM +0900, dblack@wobblini.net wrote:

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 :slight_smile:

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
print substr("Just another Perl hacker", 0, -2);

Duck typing appeals to me specifically because it lets me say that I
have a class of People and I can treat them as a list without having
to do specific inheritence, et c.

Also, on the other-languages discussion, IO is also a
prototype-based-OO language.

M.T.

You're welcome -- and thanks for the compliment.

···

On Thu, Aug 03, 2006 at 12:49:57AM +0900, Jacob Fugal wrote:

On 8/2/06, Chad Perrin <perrin@apotheon.com> wrote:
>I'd say that duck typing is more a means of allowing you to defer
>rigidity until it's actually beneficial. It has little or nothing to do
>with delaying validation, and everything to do with avoiding the
>unfortunate circumstance of having to validate before it's convenient
>for your code to have something to validate.

That is one of the most concise statements on the benefits of
duck-typing I've ever read. Thanks, Chad!

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
"There comes a time in the history of any project when it becomes necessary
to shoot the engineers and begin production." - MacUser, November 1990