Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I’ve just watched this talk by Daniel Spiewak where he talks about the advantages of structural typing as compared to Scala’s ans Java’s nominal typing. One example for this difference would be the following Java code

public interface Foo {
  public int length();
}
public interface Bar {
  public int length();
}

Foo f = ...;
Bar b = f;

which of course would not compile because type compatibility between Foo and Bar is determined by name.

A structural type system on the other hand could declare both types being equal or compatible and thus, amongst other things, allow for checked duck typing.

Now I think I do understand most of the advantages of a structural type system but I wonder if it would not invalidate type safety from examples like the following

class Foo {
  class Bar { /* ... */ }
  def takeBar(b: Bar) = { /* ... */ }
  def getBar: Bar = new Bar
}

val foo1 = new Foo
val foo2 = new Foo
foo1.takeBar(foo1.getBar) // should compile
foo1.takeBar(foo2.getBar) // should not compile

Is my understanding correct that in a structural type system the last line would compile as well and if so, wouldn’t this be a disadvantage with respect to type safety?

share|improve this question

migrated from stackoverflow.com Nov 7 '11 at 14:23

This question came from our site for professional and enthusiast programmers.

    
Could you explain why the last line shouldn't compile? I don't see the type incompatibility. –  Sam Goldberg Nov 7 '11 at 14:37
    
It’s a Scala path-dependent type. –  Debilski Nov 7 '11 at 14:45
    
Actually, I wanted to discuss this from the Scala type system point of view. It just happened that the one example given in the talk was in Java. –  Debilski Nov 7 '11 at 14:50
    
Got it. Thanks. –  Sam Goldberg Nov 8 '11 at 15:56
add comment

1 Answer

up vote 6 down vote accepted

Actually, path-dependent types are orthogonal to structural vs nominal typing. It's not really clear what an inner class means in the context of a simple structurally-typed language. It is, however, very possible to define this. If you were to define inner classes in a structurally typed context, you would need to ensure that cases like the one you listed would be rejected (for precisely the same reasons that Scala rejects them).

You would reject such cases by doing the same thing that Scala does: model the path-dependent type as an existential type. The same pack/unpack procedure surrounding object access would hold, and the results would look almost identical to what Scala does. The results may seem like a nominal type equality, but it would still be a structural type system since the question of type compatibility will still be decided on interface rather than name.

Structural typing does have a lot of implications, but (perhaps surprisingly) most of the same concepts we all know and love from nominal type systems do carry over into structural. Structural typing is nothing more than a different way of defining type compatibility.

share|improve this answer
    
Interesting. Many thanks for clarification. –  Debilski Nov 8 '11 at 15:32
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.