Duck typing and safety.

Steven Schveighoffer schveiguy at yahoo.com
Fri Aug 13 10:36:49 PDT 2010


On Fri, 13 Aug 2010 13:20:32 -0400, Ryan W Sims <rwsims at gmail.com> wrote:

> On 8/13/10 10:01 AM, simendsjo wrote:
>> While reading std.range, I though that a ducktyping design without
>> language/library support can be quite fragile.
>>
>> Consider the following example:
>>
>> import std.stdio;
>>
>> struct S
>> {
>> void shittyNameThatProbablyGetsRefactored() { };
>> }
>>
>> void process(T)(T s)
>> {
>> static if( __traits(hasMember, T,  
>> "shittyNameThatProbablyGetsRefactored"))
>> {
>> writeln("normal processing");
>> }
>> else
>> {
>> writeln("Start nuclear war!");
>> }
>> }
>>
>>
>> void main()
>> {
>> S s;
>> process(s);
>> }
>>
>>
>> If you rename S's method, process() does something completely different
>> without a compile time error. By using interfaces this is avoided as the
>> rename would break the interface.
>> Is there any idoms you can use to avoid stuff like this? Relying on
>> documentation doesn't seem like a good solution.
>
> If what you want is compile-time type safety, then duck typing is  
> probably not for you. That's sort of the whole point behind duck typing:  
> you defer typing decisions to runtime. If you need compiler breakage for  
> something like that, use interfaces.

No, duck typing is compile-time.  Essentially, it goes like this:

void foo(T)(T duck)
{
   duck.quack();
}

You can only call this functions on T types that can quack.  If you try to  
call it on something else, the compiler refuses to build it.

It's very similar to interfaces, except you don't have to declare what  
your interface is, you just pass in an object that can compile with the  
function, and you are done.

Where it can get you into trouble is:

1. a function may have the same name and usage, but have a completely  
different meaning.  Human languages are funny that way.  This means, your  
function could accept a type as a parameter and use it in a very wrong  
way.  Most of the time, this is a non issue, because you use duck typing  
with clear function names (hard to imagine another meaning for quack for  
instance).

2. The error might not be the function call, but in the type itself --  
e.g. you spelled quack wrong.  But the error does not appear as a problem  
with the type, just on its usage.  Comparing this to interfaces, you  
declare to the compiler that your object implements a certain interface,  
and it errors when you don't.

-Steve


More information about the Digitalmars-d-learn mailing list