Duck Typing

In the Method Redefinition thread, this explanation of Duck Typing is
offered …

What Duck typing is based mostly on realising what sort of operations
you want to do with the object and testing for those operations,
rather than testing for the class. As Dave is fond of saying: type and
class aren’t the same.

This is slightly different than my understanding of Duck Typing. I
would phrase it more like this:

Duck typing is based mostly on realising what sort of operations
you want to do with the object and just doing them, rather than
worrying if the object inherits from the proper base class or
interface.

I’ve heard others also explain duck typing in terms of explicitly
testing for particular methods and I feel that leaves the wrong
impression. If we say Ruby supports duck typing, then newcomers are
left with the impression that you need to do a lot of testing for
particular methods (which you don’t).

I would call this an example of Duck Typing …

class Dog
def talk
puts “Woof”
end
end
class Duck
def talk
puts “Quack”
end
end
[Dog.new, Duck.new].each { |a| a.talk }

… even though there is no explicit method testing going on. After
all, if it walks and talks like a duck …

So, am I off base?

···


– Jim Weirich jweirich@one.net http://onestepback.org

“Beware of bugs in the above code; I have only proved it correct,
not tried it.” – Donald Knuth (in a memo to Peter van Emde Boas)

Not AFAIC. Testing for methods is one of those things that can sound
important in theory, but who ever programs like that? After all, if
the method you’re after isn’t supported, what are you going to do?
Choose another one? :wink:

Of course, in frameworks and libraries there is often some funny
meta-programming going on, but that’s a special case, and it still
runs on the old assumption that you’re confident of what the code is
doing.

Gavin

···

On Saturday, September 13, 2003, 10:23:16 AM, Jim wrote:

[…]

I would call this an example of Duck Typing …

class Dog
def talk
puts “Woof”
end
end
class Duck
def talk
puts “Quack”
end
end
[Dog.new, Duck.new].each { |a| a.talk }

… even though there is no explicit method testing going on. After
all, if it walks and talks like a duck …

So, am I off base?

Hi –

In the Method Redefinition thread, this explanation of Duck Typing is
offered …

What Duck typing is based mostly on realising what sort of operations
you want to do with the object and testing for those operations,
rather than testing for the class. As Dave is fond of saying: type and
class aren’t the same.

This is slightly different than my understanding of Duck Typing. I
would phrase it more like this:

Duck typing is based mostly on realising what sort of operations
you want to do with the object and just doing them, rather than
worrying if the object inherits from the proper base class or
interface.

I’ve heard others also explain duck typing in terms of explicitly
testing for particular methods and I feel that leaves the wrong
impression. If we say Ruby supports duck typing, then newcomers are
left with the impression that you need to do a lot of testing for
particular methods (which you don’t).

Or even, more generally, left with the impression that there’s an
on/off switch: if you say “is_a?” a lot, then you’re not doing duck
typing, whereas if you say “respond_to?” a lot, then you are – when
in fact it’s really Ruby that’s doing the duck typing, and you’re
just deciding how to react to it.

I think I remember the phrase “duck-typed language” from one of your
posts a while ago, which I thought really summed it up (though it may
be a harder phrase to break people in with :slight_smile: It captures the idea
that the inferential, dynamic concept of type resides in the language
itself.

David

···

On Sat, 13 Sep 2003, Jim Weirich wrote:


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

In the Method Redefinition thread, this explanation of Duck Typing is
offered …

What Duck typing is based mostly on realising what sort of operations
you want to do with the object and testing for those operations,
rather than testing for the class. As Dave is fond of saying: type and
class aren’t the same.

This is slightly different than my understanding of Duck Typing. I
would phrase it more like this:

Duck typing is based mostly on realising what sort of operations
you want to do with the object and just doing them, rather than
worrying if the object inherits from the proper base class or
interface.

I’ve heard others also explain duck typing in terms of explicitly
testing for particular methods and I feel that leaves the wrong
impression. If we say Ruby supports duck typing, then newcomers are
left with the impression that you need to do a lot of testing for
particular methods (which you don’t).

I agree completely.

I would call this an example of Duck Typing …

class Dog
def talk
puts “Woof”
end
end
class Duck
def talk
puts “Quack”
end
end
[Dog.new, Duck.new].each { |a| a.talk }

… even though there is no explicit method testing going on. After
all, if it walks and talks like a duck …

So, am I off base?

No. That is how I think of Duck Typing as well. Just call the methods.
Don’t bother with method existence checking, Ruby does it for you. (By
raising NoMethodError)

Jason Creighton

···

On Sat, 13 Sep 2003 09:23:16 +0900 Jim Weirich jweirich@one.net wrote:

What Duck typing is based mostly on realising what sort of operations
you want to do with the object and testing for those operations,
rather than testing for the class. As Dave is fond of saying: type and
class aren’t the same.

vs

Duck typing is based mostly on realising what sort of operations
you want to do with the object and just doing them, rather than
worrying if the object inherits from the proper base class or
interface.

OK - it’s my phrase, so I get to referee :slight_smile:

You’re both right, depending on the context. Duck typing is as Jim
describes in his example. It’s what an object does, not its lineage,
that determines its type.

However, some folks feel compelled to check the types of the parameters
passed to methods. When this is done, and when you’re testing for
capability, then you should test by checking the object’s supported
methods, not its type.

Cheers

Dave

···

On Friday, September 12, 2003, at 07:23 PM, Jim Weirich wrote:

Or even, more generally, left with the impression that there’s an
on/off switch: if you say “is_a?” a lot, then you’re not doing duck
typing, whereas if you say “respond_to?” a lot, then you are – when
in fact it’s really Ruby that’s doing the duck typing, and you’re
just deciding how to react to it.

Exactly!

I think I remember the phrase “duck-typed language” from one of your
posts a while ago, which I thought really summed it up (though it may
be a harder phrase to break people in with :slight_smile: It captures the idea
that the inferential, dynamic concept of type resides in the language
itself.

Hmmm … this (http://blade.nagaokaut.ac.jp/ruby/ruby-talk/79002) is the
only post from goggle that had my name and duck typed language. I’m not
sure its the one you were thinking about.

···

On Fri, 2003-09-12 at 21:29, dblack@superlink.net wrote:


– Jim Weirich jweirich@one.net http://onestepback.org

http://www.ruby-lang.org – Making is safe for Duck Typers everywhere!

Hi, first of all: I am very happy to have a programming language with
such a communicative and friendly mailinglist!!! :slight_smile:

 GREAT!

(Whether it will be a good idea or not to mirror the posts into a newsgroup
– we will see. Previously I had made bad experiences, since my email
postbox was overloaded with spam. Spammers do scan newsgroups for
addresses… but this is quite another topic…)

Back to the ducks !

Or even, more generally, left with the impression that there’s an
on/off switch: if you say “is_a?” a lot, then you’re not doing duck
typing, whereas if you say “respond_to?” a lot, then you are – when
in fact it’s really Ruby that’s doing the duck typing, and you’re
just deciding how to react to it.

If both works: is_a? and respond_to? : What is the advance of one
over the other beside the fact, that one has a cool name : “Duck
typing”?

Is one slower, less clean or … ? I am just curious…

Quak! :slight_smile:
Meino

···

From: dblack@superlink.net
Subject: Re: Duck Typing
Date: Sat, 13 Sep 2003 10:29:52 +0900

[…]

Not AFAIC.

[…]

AWGTHTGTATA
Are We Going To Have To Go Through All This Again?

LOL

···

On Sat, 13 Sep 2003 09:51:29 +0900, Gavin Sinclair gsinclair@soyabean.com.au wrote:

  • Henon

Hi –

···

On Sat, 13 Sep 2003, Jim Weirich wrote:

I think I remember the phrase “duck-typed language” from one of your
posts a while ago, which I thought really summed it up (though it may
be a harder phrase to break people in with :slight_smile: It captures the idea
that the inferential, dynamic concept of type resides in the language
itself.

Hmmm … this (http://blade.nagaokaut.ac.jp/ruby/ruby-talk/79002) is the
only post from goggle that had my name and duck typed language. I’m not
sure its the one you were thinking about.

Yes, that’s it – the phrase was used sort of in passing, but striking
nonetheless :slight_smile:

David


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

Please avoid top-posting.<<

Is this a top-posting? How do i submit a sub
top-posting?

Anyway i submitted a post about rexml perhaps
intermittantly caching a file. I figured out why.

before, i was loading the xml like this…

$global =
REXML::Document.new(File.new(‘xml/global.xml’))

and not closing file.

now, instead, i do this
$globalFile = File.new(‘xml/global.xml’)
$global = REXML::Document.new($globalFile)

$globalFile.close

and close $globalFile at the end.

Anyway, alls groovy now.

THanks,:stuck_out_tongue:

···

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

Meino Christian Cramer wrote:

From: dblack@superlink.net
Subject: Re: Duck Typing
Date: Sat, 13 Sep 2003 10:29:52 +0900

Hi, first of all: I am very happy to have a programming language with
such a communicative and friendly mailinglist!!! :slight_smile:

GREAT!

(Whether it will be a good idea or not to mirror the posts into a newsgroup
– we will see. Previously I had made bad experiences, since my email
postbox was overloaded with spam. Spammers do scan newsgroups for
addresses… but this is quite another topic…)

Back to the ducks !

Or even, more generally, left with the impression that there’s an
on/off switch: if you say “is_a?” a lot, then you’re not doing duck
typing, whereas if you say “respond_to?” a lot, then you are – when
in fact it’s really Ruby that’s doing the duck typing, and you’re
just deciding how to react to it.

If both works: is_a? and respond_to? : What is the advance of one
over the other beside the fact, that one has a cool name : “Duck
typing”?

Is one slower, less clean or … ? I am just curious…

Don’t misunderstand. David is saying that this is some people’s
impression of what duck typing means.

Note the second part: “–when in fact it’s really Ruby that’s doing
the duck typing, and you’re just deciding how to react to it.”

It’s not a coding style or technique; it’s an attribute of the
language.

Hal

Meino Christian Cramer wrote:

If both works: is_a? and respond_to? : What is the advance of one
over the other beside the fact, that one has a cool name : “Duck
typing”?

Is one slower, less clean or … ? I am just curious…

You really shouldn’t use #is_a? or #respond_to? much at all. That’s not what
duck typing is about.

Just write your method to use methods that the passed in object should
have, by
the contract of the method. Then test to make sure your program works.

Excessively using #is_a? and #respond_to? is essentially trying to turn ruby
from a dynamically typed language into an ad-hoc statically typed language,
which isn’t in the spirit of duck typing at all.

The only real reason you should be using these methods is if you need to
take different actions depending on which of several methods is available.
If you’re just checking whether the only method you use exists or not,
you’re
just doing extra work most of the time. The interpreter will tell you if it
isn’t there.

It can be a confusing issue if you haven’t read the discussions before.
There
was a big one some weeks back, so it might be worth it to read the ruby-talk
archives to clear some stuff up without duplicating all of it again.

Cheers.

  • Dan

There are two Ruby idioms that you may prefer to this.

  1. File.open with a block:

globalXML = nil
File.open(“xml/global.xml”) do |f|
globalXML = REXML::Document.new(f)
end

This implicitly closes the file at the end of the block.

  1. File.read:

globalXML = REXML::Document.new(File.read(“xml/global.xml”))

-austin
P.S. Top posting is the practice of replying before the quoted text. It is
particularly frowned upon when the entire quoted message is included
following the reply.

···

On Sat, 13 Sep 2003 11:55:19 +0900, paul vudmaska wrote:

now, instead, i do this
$globalFile = File.new(‘xml/global.xml’)
$global = REXML::Document.new($globalFile)
$globalFile.close


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.09.13
* 00.31.58

Hi Hal,

thanks for your reply !

Don’t misunderstand. David is saying that this is some people’s
impression of what duck typing means.

Note the second part: “–when in fact it’s really Ruby that’s doing
the duck typing, and you’re just deciding how to react to it.”

It’s not a coding style or technique; it’s an attribute of the
language.

Ok…but to use this type of duck inside of ruby…I have code
/something/… and if something else seems (at least to me… :wink: do
the same trick…I am curious why it is better to trigger that duck
inside of ruby. Or am I still wrong here…

Another code snippet I did in irb gaves me headaches also. Here it
is:

a=Array.new // a shiny new array, full of ducks :wink:
=>
a=[[1,2],3] // fill in some extra ducks
=> [[1, 2], 3]
a.respond_to?(:) // check whether we have an array
=> true // expected…
a[0].respond_to?(:) // check wether first entry itself is
// an array
=> true // ok, expected, too
a[1].respond_to?(:) // now the "pure " 3…is it an array, too ?
=> true // OH! SURPRISE! It is an array…! (?)
b=a[1] // lets put it in a clean variable
=> 3
b.respond_to?(:) // now…
=> true // Again … it seems to array-able

What do I wrong here???

Background is the following:

I have either an hash of the following pattern

a=Hash.new

a=[“”, [“”,"filename]]

OR of that pattern:

a=[“”, [[“”,“filename],[”","filename],…]]

To print both versions, I have handle the value of the hash differently.

Currently my method tries to figure out, how to print, with the
help of “respond_to?”.

And it fails due to the above things I did in irb.

I am sure, that I have something understood totally wrong
here…but…

Kind regards,
Meino

···

From: Hal Fulton hal9000@hypermetrics.com
Subject: Re: Duck Typing
Date: Sat, 13 Sep 2003 17:13:17 +0900

Hal

You really shouldn’t use #is_a? or #respond_to? much at all. That’s not what
duck typing is about.

Just write your method to use methods that the passed in object should
have, by
the contract of the method. Then test to make sure your program works.

Excessively using #is_a? and #respond_to? is essentially trying to turn ruby
from a dynamically typed language into an ad-hoc statically typed language,
which isn’t in the spirit of duck typing at all.

The only real reason you should be using these methods is if you need to
take different actions depending on which of several methods is available.
If you’re just checking whether the only method you use exists or not,
you’re
just doing extra work most of the time. The interpreter will tell you if it
isn’t there.

It can be a confusing issue if you haven’t read the discussions before.
There
was a big one some weeks back, so it might be worth it to read the ruby-talk
archives to clear some stuff up without duplicating all of it again.

Cheers.

  • Dan

Thanks for your reply, Dan…will go to the archives !

Kind regards,
Meino

···

From: Dan Doel djd15@po.cwru.edu
Subject: Re: Duck Typing
Date: Sat, 13 Sep 2003 18:57:25 +0900

Even then, there are cases where you can use the (cleaner or not
depending on your pov and how many times you have to do it) alternative
of creating a common name for the methods, and aliasing it to the
appropriate method within each class. In java terms, you’re using open
classes to retroactively derive from a common interface.

martin

···

Dan Doel djd15@po.cwru.edu wrote:

The only real reason you should be using these methods is if you need to
take different actions depending on which of several methods is available.

However, #respond_to? – which I do use often as a library writer
– is valuable in producing meaningful exceptions. In Text::Format,
I allow you to supply a custom “hyphenator.” The hyphenator must
respond to a certain call – and I think it has to have a certain
arity. If it doesn’t, when you’re adding the hyphenator to the
formatter object, I raise an exception. I don’t check when I’m
running the code, becauuse I know any object provided will
have this hyphenator.

I will also use #kind_of? (#is_a?) when I need to distinguish
between an Array, a Hash, a String, and a Numeric. Once we’re above
that level of operation, I tend to use duck typing.

-austin

···

On Sat, 13 Sep 2003 18:57:25 +0900, Dan Doel wrote:

Meino Christian Cramer wrote:

If both works: is_a? and respond_to? : What is the advance of one
over the other beside the fact, that one has a cool name : “Duck
typing”?

Is one slower, less clean or … ? I am just curious…
You really shouldn’t use #is_a? or #respond_to? much at all.
That’s not what duck typing is about.

Just write your method to use methods that the passed in object
should have, by the contract of the method. Then test to make sure
your program works.


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.09.13
* 10.42.31

I disagree, with some proof by counterexample.

The assertion is this: Ruby does not have an attribute of the language
that is “duck typing”, it is merely a style of coding.

  1. By the definitions given in this thread, duck typing is taking a
    given object and pretending it’s the type you want, and letting
    the language give you an error if it doesn’t work like you
    expected.

    (If you disagree with this definition, you can provide an
    alternate one, but arguing over definitions is useless.)

  2. We can accomplish this because the language lets us specify a
    call to a method without checking the type at “compile-time”
    (parse-time, in ruby’s case):

    x.a    # This call is not validated until it is executed
    
  3. We can further accomplish this because the language does not
    require we specify types to a methodcall, thus allowing us to
    pass any object.

  4. Statements 2-3 are the only functional provisions necessary for
    accomplishing the practice in statement 1.

  5. Many non-Ruby dynamic languages provide the functionality in
    statements 2-3. Examples include JavaScript, Common Lisp (CLOS),
    Scheme, Python, Perl, and PHP.

  6. These languages make no special provisions for duck typing, but
    it can be practiced, because the functional requirements of 2-3
    are met.

  7. In any of the given languages, and Ruby, one can choose to check
    types or not check types.

Therefore: Based on statements 1-5, “duck typing” is not specific to
ruby, but rather made possible by the dynamic nature of a language.
Based on statements 6-7, duck typing is neither specifically provided
for nor compulsory, so it is not an attribute of the language.

Thus, because it can be practiced, or not practiced; in ruby, or in
other languages; it must be a style available in dynamic languages,
rather than a specific feature of a particular language.

···

On Sat, 13 Sep 2003 17:13:17 +0900 Hal Fulton hal9000@hypermetrics.com wrote:

Is one slower, less clean or … ? I am just curious…

Don’t misunderstand. David is saying that this is some people’s
impression of what duck typing means.

Note the second part: “–when in fact it’s really Ruby that’s doing
the duck typing, and you’re just deciding how to react to it.”

It’s not a coding style or technique; it’s an attribute of the
language.


Ryan Pavlik rpav@mephle.com

“Damn ye and ye black ops mind games!” - 8BT

There are two Ruby idioms that you may prefer to this.

  1. File.open with a block:

globalXML = nil
File.open(“xml/global.xml”) do |f|
globalXML = REXML::Document.new(f)
end

This implicitly closes the file at the end of the
block.

  1. File.read:

globalXML =
REXML::Document.new(File.read(“xml/global.xml”))
<<

Thanks for the tips! File.read, this will be ideal for
me!

···

Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com

What you see is Fixnum#

-------------------------------------------------------------- Fixnum#
fix[ n ] → 0, 1

···

On Sat, Sep 13, 2003 at 07:53:18PM +0900, Meino Christian Cramer wrote:

Another code snippet I did in irb gaves me headaches also. Here it
is:

a=Array.new // a shiny new array, full of ducks :wink:
=>
a=[[1,2],3] // fill in some extra ducks
=> [[1, 2], 3]
a.respond_to?(:) // check whether we have an array
=> true // expected…
a[0].respond_to?(:) // check wether first entry itself is
// an array
=> true // ok, expected, too
a[1].respond_to?(:) // now the "pure " 3…is it an array, too ?
=> true // OH! SURPRISE! It is an array…! (?)
b=a[1] // lets put it in a clean variable
=> 3
b.respond_to?(:) // now…
=> true // Again … it seems to array-able


 Bit Reference---Returns the nth bit in the binary representation of
 fix, where fix[0] is the least significant bit.
    a = 0b11001100101010
    30.downto(0) do |n| print a[n] end
 produces:
    0000000000000000011001100101010

What do I wrong here???

Background is the following:

I have either an hash of the following pattern

a=Hash.new

a=[“”, [“”,"filename]]

I guess this is only your notation and not the code you’re feeding to ruby :slight_smile:

OR of that pattern:

a=[“”, [[“”,“filename],[”","filename],…]]

To print both versions, I have handle the value of the hash differently.

Currently my method tries to figure out, how to print, with the
help of “respond_to?”.

And it fails due to the above things I did in irb.

That’s because String has an instance method named , too.
You’d have to use is_a? Array, but I’d rather change the code so that
in the first pattern you have an array of length 1.

ie

bla[“0xff”] = [[“bla”, “file.rb”]]
bla[“0x01”] = [[“foo”, "file2.rb], [“bar”, “file3.rb”]]

This way the same code can work for both cases.


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

…and scantily clad females, of course. Who cares if it’s below zero
outside.
– Linus Torvalds