Hacker News new | ask | show | jobs
by camus2 3224 days ago
> Go has automated delegation, and as we know, (automated) delegation IS inheritance [1, 2]. Some implementations of delegation are a bit more limited, some are a bit more expressive, but fundamentally they have the same purpose.

No it is not inheritance, and Go doesn't have automated delegation, it has type embedding.

Given struct A, if a function requires A, you can't pass any type B that embeds A, you must pass A.

    type A struct {
        Foo int
    }

    type B struct {
        A
    }
func acceptA(a A}{} // you can't pass B here
1 comments

> No it is not inheritance, and Go doesn't have automated delegation, it has type embedding.

Different names for the same thing.

> func acceptA(a A}{} // you can't pass B here

This says that the function isn't polymorphic in its argument, not that the types aren't polymorphic. Function resolution that is not polymorphic is not limited to Go, but occurs in inheritance-based languages, too. Example in OCaml:

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

  let f (x: a) = ()
  let () = f (new b)
You will get an error that the type of `new b` (= `b`) is not compatible with `a`, because they're not identical, even though `b` is a subclass of `a`.

If you replace the declaration of `f` with:

  let f (x: #a) = ()
it'll work, because `#a` denotes a polymorphic type, matching `a` or any subclass of `a` (same as though you'd specify an interface in Go [1]). You can also cast the type explicitly to `a` to work around the error.

[1] Like Go, OCaml uses structural subtyping.

> Different names for the same thing.

No, different names for completely different concepts.

> This says that the function isn't polymorphic in its argument, not that the types aren't polymorphic. Function resolution that is not polymorphic is not limited to Go, but occurs in inheritance-based languages, too. Example in OCaml:

Struct types in Go are not polymorphic in anyway period, the only way to achieve polymorphism in Go is through interfaces which are not concrete types, unlike classes.

> [1] Like Go, OCaml uses structural subtyping.

No it doesn't. There is no subtyping in Go. There is only type conversion and type assertion.

Whatever you wrote with OCaml is completely irrelevant to the discussion as the type systems are fundamentally different. but let's pretend it is.

It's interesting that you didn't bother try writing the equivalent of `let f (x: #a) = ()` in Go, because you CANNOT. An interface IS NOT a substitute for OCaml inheritance, as the later is more precise and specialized.

So no, Go doesn't support inheritance at its core. That's a false assertion. Go interfaces do not give a damn about what the actual implementation is, unlike OCaml sub classes.

> There is no subtyping in Go.

There is. Go simply has structural subtyping [1] rather than nominal subtyping.

> It's interesting that you didn't bother try writing the equivalent of `let f (x: #a) = ()` in Go, because you CANNOT.

You forget that OCaml also uses structural subtyping. Writing `#a` is effectively the shorthand for the inferred interface. So you can write it also as:

  let f (x: < foo: int; .. > ) = ()
where

  < foo: int; .. >
is the interface of any class implementing at least a method `foo` of type `int`, i.e. what you'd write as

  interface {
    foo() int
  }
in Go. You just don't in practice, because `#a` is both more convenient and readable.

And the corresponding Go function would be:

  func f(x interface { foo() int }) {
  }
[1] https://en.wikipedia.org/wiki/Structural_type_system
> There is. Go simply has structural subtyping [1] rather than nominal subtyping.

No there is not, period.

  interface {
    foo() int
  }
is not sub typing. but it's interesting how you move the goal post on each comment. You go from inheritance to sub typing to "structural subtyping". You're not interested in a serious discussion.
> No there is not, period.

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

> is not sub typing. but it's interesting how you move the goal post on each comment.

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

> You go from inheritance to sub typing to "structural subtyping".

This is not how the thread went. I added a reference to structural subtyping as a purely explanatory footnote to illustrate a well-known similarity between OCaml and Go; subtyping had not been mentioned at all so far. Starting at that footnote, you introduced a digression by claiming that Go does not have subtyping at all.

> 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.