Hacker News new | ask | show | jobs
by camus2 3218 days ago
> This is an assertion, not an argument. It's not how the literature sees it. Plus, you can even have it from Rob Pike himself if you don't believe me: https://twitter.com/rob_pike/status/546973312543227904

The hell with your "assertion". Structural typing =/= structural subtyping, just like the presence of classes in a language in no way means that language supports inheritance.

> I didn't say that this piece of code constituted subtyping. I was refuting your specific claim that `f` cannot be written in Go.

It cannot since you had to add an interface to the mix, unlike with your OCaml example, which proves that go structs and OCaml classes are not similar in any way. Go structs do not support any kind of polymorphism unlike OCaml classes.

1 comments

> Structural typing =/= structural subtyping, just like the presence of classes in a language in no way means that language supports inheritance.

Well, structural typing is used for two things, type equivalence and subtyping [1]. If it isn't subtyping, then the consequence would be that Rob Pike talked about type identity only, which doesn't make sense.

Let's pull in the definition of subtyping again:

> [S]ubtyping (also subtype polymorphism or inclusion polymorphism) is a form of type polymorphism in which a subtype is a datatype that is related to another datatype (the supertype) by some notion of substitutability, meaning that program elements, typically subroutines or functions, written to operate on elements of the supertype can also operate on elements of the subtype.

Now, one misunderstanding seems to be that you assume that I'm saying that B is or should be a subtype of A. Note that I never actually said that and it's not relevant; neither inheritance nor delegation necessarily create a subtype relationship. See "Inheritance is not subtyping" by Cook et al., a seminal paper in programming language theory [2].

Structural vs. nominative or nominal subtyping revolves around the definition of substitutability. With nominative subtyping, we have the case where a subtype relationship is constructed based on explicitly specified relationships between types identified by their names; structural subtyping exists when the type signature of the subtype conforms to the type signature of the supertype.

The latter is the case in Go. Somewhat simplified, the type of a struct (strictly speaking, of a pointer to an instance of that struct [3]) is the subtype of the type of any interface it matches.

> It cannot since you had to add an interface to the mix, unlike with your OCaml example, which proves that go structs and OCaml classes are not similar in any way.

This is because `#a` is a short-hand for "the interface of `a`". So, yes, the OCaml example does the same thing. You can reproduce it by removing the inheritance from OCaml, and it'll still work (or, without the `#`, still won't):

  class a = object method foo = 0 end
  class b = object method foo = 0 method bar = 1 end

  let f (x: #a) = ()
  let () = f (new b)
Note that the classes are completely independent; there is no inheritance at all. It's just that the interface of `b` conforms to the interface of `a`, and hence instances of `b` can be passed to functions expecting `#a`.

[1] E.g. http://wiki.c2.com/?NominativeAndStructuralTyping

[2] http://dl.acm.org/citation.cfm?id=96721

[3] C++ and many other OO languages make a similar distinction, as runtime polymorphism does not work well for value types.