views:

285

answers:

2

In language design circles there used to be a long-running debate over whether languages should use structural equivalence or name equivalence. Languages like ALGOL or ML or Modula-3 used structural equivalence while ... well, pretty much most programming languages employ named equivalence (including Modula-2).

What are the typical arguments in favour of structural equivalence? What are the typical arguments in opposition to it? What are the typical arguments in favour of name equivalence? What are the typical arguments in opposition to it?

+4  A: 

I think the advantage of structural type systems is that they encourage you to create fine-grained interfaces oriented towards what the user of the interface needs, rather than what the implementer provides.

In a nominative type system you need a common dependency on the interface. In a structural type system that requirement is eliminated: you can build a loosely coupled system without needing to create that common library where you put all the interfaces. Each client can independently declare the interface it expects from a collaborator.

The disadvantage of structural type systems is that they match up classes to interfaces which may not really implement the correct contract. For example, if you have this interface:

public interface IBananaProvider
{
   /// Returns a banana, never null.
   Banana GetBanana();
}

then the following class will implicitly be considered to implement IBananaProvider in a structural type system. However, the class violates the post condition that the returned banana is never null:

public class SomeBananaProvider
{
    // returns a banana or null if we're all out
    public Banana GetBanana()
    {
        if (bananas.Count > 0)
        {
            return bananas.RemoveLast();
        }
        else
        {
            return null;
        }
    }
} 

This could be fixed if the contract was somehow specified formally and considered part of the type structure. I think things are moving in that direction, e.g. System.Diagnostics.Contracts in .NET 4.0.

Wim Coenen
Just for clarification's sake: structural equivalence's advantages are similar to duck typing's advantages, then, but require full interfaces to be implemented so are less flexible, but for that more likely to be properly typed?
JUST MY correct OPINION
I don't understand what you mean by "require full interfaces to be implemented so are less flexible". Structural typing allows you to define the absolute minimal interface for each collaborator, without implementers needing to know all those minimal interfaces. Therefore I'd say the opposite: structural typing eliminates the need to implement useless interface members, because each required member is one that is actually used by the client.
Wim Coenen
In duck typing if I have an "interface" with elements A and B and I know that a given user of it only ever accesses A I can pass in an "implementer" of that interface that only provides A (a mock object for testing, say) -- the "type" is checked only at point of use and only for the specific element being used. In Modula-3 (a structural equivalence language) I can't do that. The compiler statically checks the structure for equivalence so I can't pass in something that provides a subset of the functionality even if I know that this one specific client (or portion thereof) only uses that subset.
JUST MY correct OPINION
+2  A: 

One good argument in favour of strict name equivalence (as available in Ada for example) is that it makes it possible for the compiler to reject code that accidentally mixes different units, like for example centimeters and inches, or celsius and fahrenheit.

In a language with strict name equivalence you could have two types

type celsius based on float; type fahrenheit based on float;

var c : celsius; var f : fahrenheit;

c := f; /* compile time error: incompatible types */

While, in a language with lose name equivalence and in one with structural equivalence ...

type celsius is float; type fahrenheit is float;

c := f; /* no error and no warning here */

... you would end up with a miscalculation that will lead to unpredictable behaviour, depending on the type of application and system this could lead to serious financial loss or even death. Such a logical bug is also very difficult to track down without strict name equivalence in place.

trijezdci
So you're saying NASA would prefer strict name equivalence? ;)
JUST MY correct OPINION