3 ms·
Two thoughts: 1) The failure of func (t *fishTank) fishCount() string { return fmt.Sprintf("How many fishies? %d!", t.size()) } to work has not
by morelisp 4y ago
Two thoughts:
1) The failure of
func (t *fishTank) fishCount() string {
return fmt.Sprintf("How many fishies? %d!", t.size())
}
to work has nothing to do with generics; methods are always "removed" from types defined this way. If you want you can cast `t` to a `*container[fish]` and call it, but this is also where I would ask why "extend" rather than compose - are you gaining anything by ensuring identical layouts?
2) The bigger issue, that interfaces cannot require their implementations to be comparable, is https://github.com/golang/go/issues/52614 https://github.com/golang/go/issues/52614 and linked tickets.
- hiptobecubic 4y agoBut why (1)? If a `fishTank` is a `container[fish]` what is the benefit of requiring it to be cast again?
- morelisp 4y agoWhen people say Go is not an OO language, this is what they mean. Concrete type declarations define storage, not is-a hierarchies. A fishTank is not a container[fish], any more or less than it is any other `{ string, []fish }`.
- sidlls 4y agoAnd yet OO-isms are replete throughout implementations in go. `interface{}` all the things is another of the worst things about go. It practically begs for engineers to engage in all the worst practices of OO-ism and unit test zealotry.
- throwaway894345 4y agointerface{} isn’t pervasive in Go, it doesn’t tend to get abused often in practice, it has nothing to do with OO at all, and it doesn’t lead to any particular ideology about unit testing. It seems like you are mistaken on all counts.
- masklinn 4y ago> But why (1)? If a `fishTank` is a `container[fish]` But a `fishTank` is not a `container[fish]`. In common parlance type T Thing is newtyping. T has the same implementation as the underlying type, and Go allows conversions back and forth, but they are otherwise unrelated, and the new type does not share the interface (method set) of the original. It is, in a way, a shorthand for type T struct { _0 Thing }
- hiptobecubic 4y agoOh I misunderstood `type T Thing` to be an alias and not a haskell-style newtype. $ ghci GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help Prelude> class HasField a where { field1 :: a -> Int } Prelude> data Foo = Foo Prelude> instance HasField Foo where { field1 f = 2 } Prelude> field1 Foo 2 Prelude> newtype Bar = Bar Foo Prelude> :t Bar Bar :: Foo -> Bar Prelude> field1 (Bar Foo) <interactive>:7:1: error: • No instance for (HasField Bar) arising from a use of ‘field1’ • In the expression: field1 (Bar Foo) In an equation for ‘it’: it = field1 (Bar Foo) Prelude> type Baz = Foo Prelude> field1 (Foo :: Baz) 2
- morelisp 4y agoThere's an unfortunately-close syntax that does define type aliases in Go, type T = Thing
- tapirl 4y agoThe answer is complete. I just make some additional explanations here. 1) is totally generics unrelated. package main type T1 int func (T1) M() {} type T2 T1 func main() { var t2 T2 t2.M() // t2.M undefined } The fishTank should be defined as type fishTank struct { container[fish] } instead. 2) is a temporary restriction, among many in the Go 1.18. Some of the restrictions will be removed from future Go versions. ref: * https://go101.org/generics/101.html https://go101.org/generics/101.html * https://github.com/golang/go/issues/50646#issuecomment-1023706545 https://github.com/golang/go/issues/50646#issuecomment-10237... * https://github.com/golang/go/issues/51257 https://github.com/golang/go/issues/51257 * https://github.com/golang/go/issues/51338 https://github.com/golang/go/issues/51338 * https://github.com/golang/go/issues/52474 https://github.com/golang/go/issues/52474 * https://github.com/golang/go/issues/52509 https://github.com/golang/go/issues/52509 * https://github.com/golang/go/issues/52531 https://github.com/golang/go/issues/52531 * https://github.com/golang/go/issues/52614 https://github.com/golang/go/issues/52614
- morelisp 4y agoRe. "temporary restriction": Although there's agreement something should improve around `comparable`, there's no concrete design approved to solve it. It may persist for many versions, or indefinitely. (Vs. e.g re-enabling better type inference where the goal is known and it's "just" implementation work.)
- tapirl 4y agoThere will be some permanent restrictions in Go custom design, but I think the `comparalbe` one is not one of them. My personal prediction is it will be solved before Go 1.21.
- timbray 4y agoThanks. But why are methods removed from types defined this way? Is there a good discussion about this somewhere?
- 4y ago
- masklinn 4y agoI think Tim got confused between typedef (`type T Thing`, aka newtyping) and aliasing (`type T = Thing`).