[ANN] Ducktator - A Duck Type Validator

By asking if object O respond_to? method M, we can impose certain
conditions, and raise an error if those condition aren't met, rather
than raising a runtime error in the middle of the program or getting
wonky behavior. I.e., think of it as pre-emptive TDD. This isn't
_necessary_ for duck-typing, but it certainly seems to be an extension
of it. Do you want your object, O, to act like a file? Then you better
make sure that it respond_to? read() and write()!

Regards.
Jordan

Austin Ziegler wrote:
>> Actually, the name is more about the fact that you can use regular
>> duck-type techniques (like respond_to?),
>
> Note: if you're calling #respond_to? you're not doing duck typing.
> You're doing contract validation, perhaps, but not duck typing. Duck
> typing is just calling a method and expecting that it will be
> implemented. It's *trusting* your callers to do the right thing.
>
> Now, I sometimes use #respond_to? -- but it isn't duck typing.
>
> Additionally, if it's an external validation suite -- I haven't looked
> at the project -- it isn't really checking against live code.
>
> -austin

I beg to differ, and according to the pick-axe, this interpretation is
correct. Duck-typing isn't to *trust* your callers. Duck typing is to
check if something quacks like a duck and walks like a duck. Well, me
calling respond_to? checks if the object quacks and walks. What you are
describing isn't a technique, it is the absence of a technique.

The problem with #respond_to? is that it only tells you that a method
is supported. It doesn't tell you whether the method takes arguments
that quack like the ones you want to pass, or that the return value
behaves what you like. In other words, you'll have to trust that the
method behaves how you'd like to.

Imagine:

  def make_peace(world)
    world.create_piece if world.respond_to? :create_piece
  end

  class World
    def make_piece(means = War)
      means.use! self
    end
  end

Now make_peace (called with a World) will actually start a war. See
the problem? #respond_to? will only tell you that a method is
supported, but not that it behaves how you'd like (not that static
typing guarantees this either). It saves you from NoMethodError, but
not any other error.

Duck typing is trusting other objects to do the right thing, and
#respond_to? isn't all that useful in that regard.

···

On 9/20/06, Ola Bini <ola.bini@ki.se> wrote:

> On 9/19/06, Ola Bini <ola.bini@ki.se> wrote:

--
  Ola Bini (http://ola-bini.blogspot.com)
  JvYAML, RbYAML, JRuby and Jatha contributor
  System Developer, Karolinska Institutet (http://www.ki.se)
  OLogix Consulting (http://www.ologix.com)

  "Yields falsehood when quined" yields falsehood when quined.

--
- Simen

Definitively not. What do you do if that method returns false? Basically you can only raise an exception. Of course, you can use a different exception type and message but that's it.

If you need respond_to? to choose a different path of execution because a method needs to cope with different types that's ok but it's not duck typing.

Regards

  robert

···

On 20.09.2006 16:37, Ola Bini wrote:

Austin Ziegler wrote:

On 9/19/06, Ola Bini <ola.bini@ki.se> wrote:

Actually, the name is more about the fact that you can use regular
duck-type techniques (like respond_to?),

Note: if you're calling #respond_to? you're not doing duck typing.
You're doing contract validation, perhaps, but not duck typing. Duck
typing is just calling a method and expecting that it will be
implemented. It's *trusting* your callers to do the right thing.

Now, I sometimes use #respond_to? -- but it isn't duck typing.

I beg to differ, and according to the pick-axe, this interpretation is correct. Duck-typing isn't to *trust* your callers. Duck typing is to check if something quacks like a duck and walks like a duck.

You're incorrect here. I do not need to check if someone responds to
#<< if I want to call #<< on an object. I simply call #<<. I then
*document* that I'm calling #<< on a received object and that if you
don't implement #<< in a sensible way, your code is going to break.

I trust my callers not to be stupid and send me an object that doesn't
implement #<< in this case. Checking for #<< would be the height of
stupidity.

Duck typing is treating an object like the type of object you need it
to be. It's a technique, not an absence. It's learning to let go of
the false sense of security that static typing gives people (and it
*is* a false sense of security). In my early days with Ruby, I
implemented #method_missing on a few things but didn't implement
#respond_to? on those same things. My code would have probably worked
with my style of duck typing, but would definitely not pass
validation.

Method presence validation is really useful during testing, but is of
limited use outside of it. (However, I have used it for other things
to add methods dynamically to classes, too.)

-austin

···

On 9/20/06, Ola Bini <ola.bini@ki.se> wrote:

Austin Ziegler wrote:
> On 9/19/06, Ola Bini <ola.bini@ki.se> wrote:
>> Actually, the name is more about the fact that you can use regular
>> duck-type techniques (like respond_to?),
> Note: if you're calling #respond_to? you're not doing duck typing.
> You're doing contract validation, perhaps, but not duck typing. Duck
> typing is just calling a method and expecting that it will be
> implemented. It's *trusting* your callers to do the right thing.
>
> Now, I sometimes use #respond_to? -- but it isn't duck typing.
>
> Additionally, if it's an external validation suite -- I haven't looked
> at the project -- it isn't really checking against live code.
I beg to differ, and according to the pick-axe, this interpretation is
correct. Duck-typing isn't to *trust* your callers. Duck typing is to
check if something quacks like a duck and walks like a duck. Well, me
calling respond_to? checks if the object quacks and walks. What you are
describing isn't a technique, it is the absence of a technique.

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

I snipped context, but I explicitly said "if it's an external
validation suite." Based on your example (also snipped), it's not an
external validation suite.

I doubt that I'd use it, but I think that this may have some value. It
is not, however, part of what I consider to be duck typing. It's
contract enforcement.

-austin

···

On 9/20/06, Ola Bini <ola.bini@ki.se> wrote:

Why couldn't it check against live code?

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

Ola Bini wrote:

I beg to differ, and according to the pick-axe, this interpretation is correct. Duck-typing isn't to *trust* your callers. Duck typing is to check if something quacks like a duck and walks like a duck. Well, me calling respond_to? checks if the object quacks and walks. What you are describing isn't a technique, it is the absence of a technique.

Austin is right. If you're checking types, that isn't duck typing.

Hal

Robert Klemme wrote:

···

On 20.09.2006 10:58, MonkeeSage wrote:

Robert Klemme wrote:

I do not think that the use of respond_to? is a regular duck typing
technique. As Eric put it, respond_to? is exactly not applied regularly
when duck typing.

Don't get me wrong, I don't say your lib is useless (in fact I envision
numerous uses for test cases etc.) but I think this claim of yours is wrong.

Not to push the issue, but Wikipedia seems to think that this is a
valid claim [1]:

"[...A]n object having all the methods described in an interface can be
made to implement that interface dynamically at runtime, even if the
object's class does not include the interface in its implements
clause. It also implies that an object is interchangeable with any
other object that implements the same interface, regardless of whether
the objects have a related inheritance hierarchy."

respond_to? in ruby is just a dynamic way of checking that "an object
is interchangeable with any other object that implements the same
interface".

The article does not claim that a client needs to check this. And in Ruby you generally do not do that either, you just use it. It just states that it's possible for an object to /dynamically/ implement a certain interface although it is not declared.

The problem with "just use it", is that you will have no control over error handling in this case. In most situations, the error is the programmers, in which case it doesn't matter, but when reading in something you're not entirely sure what it is, it's better to be able to report consistently what's wrong to the user instead of failing randomly with a method_missing in the middle of nowhere.

--
  Ola Bini (http://ola-bini.blogspot.com)
  JvYAML, RbYAML, JRuby and Jatha contributor
  System Developer, Karolinska Institutet (http://www.ki.se)
  OLogix Consulting (http://www.ologix.com)

  "Yields falsehood when quined" yields falsehood when quined.

The problem with #respond_to? is that it only tells you that a method
is supported.

It doesn't even reliably tell you that:

>> class Mystery
>> def method_missing(meth, *args, &block)
>> if meth == :supported
>> true
>> else
?> super
>> end
>> end
>> end
=> nil
>> m = Mystery.new
=> #<Mystery:0x32b8e0>
>> m.supported
=> true
>> m.respond_to? :supported
=> false

James Edward Gray II

···

On Sep 20, 2006, at 10:07 AM, Simen Edvardsen wrote:

No, you better not. If I use #<<, then I can "write" to a String, a
StringIO, an IO (socket, file, etc.), or an Array. Checking for #write
limits you to (mostly) actual IO objects. Reading is a little harder,
but I tend not to bother checking for that -- I generally just call
#read and tell people in the API that #read will be called at some point
and it better return something useful.

It isn't preemptive TDD to do validation, and in Ruby ALL errors are
runtime. Method presence validation is useful and sometimes necessary;
if you look at Text::Format, you'll see that I do both method presence
and arity validation for hyphenator objects on assignment. But I don't
pretend that this is anything *but* runtime checking.

-austin

···

On 9/20/06, MonkeeSage <MonkeeSage@gmail.com> wrote:

By asking if object O respond_to? method M, we can impose certain
conditions, and raise an error if those condition aren't met, rather
than raising a runtime error in the middle of the program or getting
wonky behavior. I.e., think of it as pre-emptive TDD. This isn't
_necessary_ for duck-typing, but it certainly seems to be an extension
of it. Do you want your object, O, to act like a file? Then you better
make sure that it respond_to? read() and write()!

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

Hi,

Austin is right. If you're checking types, that isn't duck typing.

Although I am not Dave Thomas, I consider it is a _variation_ of duck
typing, if the type describes behavior, not structure nor type name.
Signature validation is approximation of type-by-behavior. As Austin
stated, some doesn't consider it duck typing, I agree. But Keeping
strict definition of duck typing is not that important to justify
strong words in the list (and blogs).

For signature validation, we should note that respond_to? does not
work well for objects with method_missing.

              matz.

···

In message "Re: [ANN] Ducktator - A Duck Type Validator" on Thu, 21 Sep 2006 08:59:45 +0900, Hal Fulton <hal9000@hypermetrics.com> writes:

This is demonstrably untrue. Duck typing is not about validation. It's
about trusting your callers to do the right thing -- and then doing
the right thing when they don't.

-austin

···

On 9/20/06, Ola Bini <ola.bini@ki.se> wrote:

The problem with "just use it", is that you will have no control over
error handling in this case.

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

Of course, respond_to? doesn't tell you about what the method does. But
it isn't meant to. To check an object's signature is not the same thing
as to check that it does what you want it to do. A file object that
responds to write() may output a file in the current working directory;
but a mock object which is _acting like_ a file object may just write
to screen, or may not write anything at all. But at least you can tell
that it _acts like_ a file object so far as its signature is concerned
(viz., duck typing).

Regards,
Jordan

Austin is right. If you're checking types, that isn't duck typing.

Boy, we really love to argue about semantics, don't we?

What does it matter whether Ducktator "implements duck typing" or "validates duck types" or "enforces duckly contracts" or "ducktates method signatures" or "imposes a reducktionist philosophy" or "is just ducky" or is none of those things?

Is the term "duck typing" overloaded? Yes (see Eric's ruby-talk:215359). Is it getting more overloaded? Yes. Do newbs come in here with opinions of the meaning of "duck typing" that differ from yours? Yes. Is that going to happen more frequently? Probably. Is that going to prevent you from explaining what you mean by example? No. Do we need separate terms to describe the different meanings Eric enumerated (and potentially others)? Well, no, but it'd be helpful. I'll start.

For backwards compatibility with the great majority, "duck typing" will mean "just calling methods on an object, without doing any validation on the behavior of that object."* Using respond_to? as a guard -- let's call that "duck but verify." Using is_a? (and friends) as a guard -- well, "crap" comes to mind, but let's just go with "Class testing."

(On a related note... we didn't ever decide on a replacement for the term "singleton class," did we? I liked "shadow class," myself. :P)

And "static" means "not at run-time," no?

Devin
(In short: "What matz said.")

* Though, for me, "duck typing" meant just that: If it looks like a duck and walks like a duck... Which allows for pretty much anything except Class testing (sticking a q-tip in the duck's mouth and waiting 2 weeks for the lab tests to come back). Really, "just calling methods" is more equivalent to catching something, stripping it, cooking it, taking a bite, and going "yup, tastes like duck." But hey, peer pressure.

Not without doing more than #respond_to? checking. See other responses
that I've made.

-austin
P.S. Please don't snip context when you're posting a response to
someone. Just because you might be using a threaded newsreader or
mailer doesn't mean that everyone is. A little context goes a long
way.

···

On 9/20/06, MonkeeSage <MonkeeSage@gmail.com> wrote:

Of course, respond_to? doesn't tell you about what the method does. But
it isn't meant to. To check an object's signature is not the same thing
as to check that it does what you want it to do. A file object that
responds to write() may output a file in the current working directory;
but a mock object which is _acting like_ a file object may just write
to screen, or may not write anything at all. But at least you can tell
that it _acts like_ a file object so far as its signature is concerned
(viz., duck typing).

--
Austin Ziegler * halostatue@gmail.com * http://www.halostatue.ca/
               * austin@halostatue.ca * You are in a maze of twisty little passages, all alike. // halo • statue
               * austin@zieglers.ca

Austin Ziegler wrote:

···

On 9/20/06, Ola Bini <ola.bini@ki.se> wrote:

The problem with "just use it", is that you will have no control over
error handling in this case.

This is demonstrably untrue. Duck typing is not about validation. It's
about trusting your callers to do the right thing -- and then doing
the right thing when they don't.

To extend Austin's point a little: In ruby, it really has to be this way. What if an object responds to a message by way of method_missing? There's no easy way to validate that.

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Devin Mullins wrote:

Do we need separate terms to describe the different meanings Eric enumerated (and potentially others)? Well, no, but it'd be helpful. I'll start.

Oh, and lastly:

Can we expect everybody in the world to conform to a standard set of vocabulary, should we come to agree on one? HELL NO!

That is all.

Devin

Haskell is a statically typed programming language. Hugs is a Haskell
interpreter. Is the language Hugs interprets not statically typed,
because the type checking is performed at runtime?

Static typing, I think, is about having type checking as a separate
(conceptually, not necessarily implementation-wise) phase from the
phase that actually performs the program's function, but lets not
start a fight over that, too.

···

On 9/21/06, Devin Mullins <twifkak@comcast.net> wrote:

And "static" means "not at run-time," no?

--
- Simen

Austin Ziegler wrote:

No, you better not. If I use #<<, then I can "write" to a String, a
StringIO, an IO (socket, file, etc.), or an Array. Checking for #write
limits you to (mostly) actual IO objects.

Then you'd be asking if the object _acts like_ (quacks like) an
enumerable, would you not? Why wrap that in a begin....rescue clause
and only spot it after the fact when you can catch it ahead of time?
Certainly it doesn't violate duck-typing to ask what an object acts
like (which is what imposing conditions on an object would be doing)?!

Regards,
Jordan

Of course the whole scheme really relies on the library writer to
provide very good documentation - they have to (re)discover and
document every method call they perform on every object passed to
them. Unless they fall back to the old ways and say "this method
expects a string, and all that that implies". Which doesn't help the
user of the library much because say they want to pass in something
else that works a little like a string, but does not exhaustively
support every method the String class supports? They have to read the
library source and discover and document every method call on the
object...

···

On 9/20/06, Joel VanderWerf <vjoel@path.berkeley.edu> wrote:

Austin Ziegler wrote:
> On 9/20/06, Ola Bini <ola.bini@ki.se> wrote:
>> The problem with "just use it", is that you will have no control over
>> error handling in this case.
>
> This is demonstrably untrue. Duck typing is not about validation. It's
> about trusting your callers to do the right thing -- and then doing
> the right thing when they don't.

To extend Austin's point a little: In ruby, it really has to be this
way. What if an object responds to a message by way of method_missing?
There's no easy way to validate that.

Devin Mullins wrote:

Devin Mullins wrote:

Do we need separate terms
to describe the different meanings Eric enumerated (and potentially
others)? Well, no, but it'd be helpful. I'll start.

Oh, and lastly:

Can we expect everybody in the world to conform to a standard set of
vocabulary, should we come to agree on one?

You know, it would really help :slight_smile:

···

--
Posted via http://www.ruby-forum.com/\.