4 ms·
What could you do with row polymorphism that you couldn’t do with generic functions that take slices in Go?
by skybrian 1y ago
What could you do with row polymorphism that you couldn’t do with generic functions that take slices in Go?
- tines 1y agoI think Go interfaces are row-polymorphic aren't they? I'm also wondering what the difference between row-polymorphism and ad-hoc polymorphism (a la C++ templates) is.
- wavemode 1y agoYes, Go interfaces are row-polymorphic, in the sense that they allow you to write functions that operate on any struct which has a field with a certain name and type. This utilizes the fact that structs implement interfaces implicitly in Go, rather than explicitly. > I'm also wondering what the difference between row-polymorphism and ad-hoc polymorphism (a la C++ templates) is C++ templates can also be row-polymorphic. They're a lot more flexible than just row polymorphism, though, because they essentially allow you to be polymorphic over any type for which a given expression is valid syntax. Concepts were an attempt to allow developers to rein in some of that flexibility, since it actually became a pain.
- skybrian 1y agoIs this new with generics? I thought Go interfaces were just method sets?
- jerf 1y ago"Go interfaces are row-polymorphic, in the sense that they allow you to write functions that operate on any struct which has a field with a certain name and type." It doesn't have it yet. Go is headed strongly in that direction which is why I add the "yet", but see https://github.com/golang/go/issues/70128 https://github.com/golang/go/issues/70128 , especially the "future directions" note about issue #48522 which is not implemented. Prepatory work has been done but the change is not in yet. You can embed something like compile-time row types into Go if you implement it in terms of accessor methods that can be included in an interface, rather than direct struct field access, which has its pros and cons. But if you're reading this in 2026 or beyond, check in with Go, this may not be true anymore.
- ryandv 1y ago[flagged]
- aatd86 1y agohighfalutin... I didn't know that word :D I actually believe otherwise, AI risks fossilizing our programming languages expressiveness and developper experience, shunting any possibility of improvements that is not envoded in its data set. I think that for tools made for human consumption, AI is always going to be limited (even AGI). A case of "for us by us" is necessary. Unless humans completely delegate the machine coding to machines and we only remain with a few legacy systems, never inspecting new machine instruction corpus. Inthe future that is.
- jerf 1y agoAs long as AIs are finite, they will need good concepts to help reduce the complexity of the world they are dealing with too. They may need and/or prefer different ones than we do, but this stuff isn't going to go away. Your need to understand it may, but then, most programmers don't understand this and do OK anyhow.
- aatd86 1y agoWhen you want to abstract on structs "having" a given field (by name) of a given type, I think. Although that may come in Go at some point.
- tines 1y agoI'm not a Go expert but that's exactly what interfaces are, aren't they? In Go a struct automatically implements an interface if it contains all the required fields (duck-typing).
- deleted 1y ago[deleted]
- sparkie 1y agoThey're both a form of structural typing - the static equivalent of duck typing. A difference with row types is that they don't have to be declared up front like an interface - they're basically anonymous types. You declare the row types in the type signature. For example, a function taking some structural subtype of `Foo` and returning some structural subtype of `Bar` would be written in Go as: type Foo interface { baz Baz } type Bar interface { qux Qux } func (x Foo) f() Bar { ... } In OCaml, you'd just inline the row types - there are no `Foo` or `Bar`: val f : < baz : Baz.t; .. > -> < qux : Qux.t; .. > let f x = ... You can typedef row types though type foo = < baz : Baz.t; .. > type bar = < qux : Qux.t; .. > val f : foo -> bar Rows can be declared to have an exact set of members. For example, the types `< bar : Baz.t >` and `< bar : Baz.t; ..>` are two different types. The latter can have members besides `bar`, but the former can only have the member `bar`. A type containing the fields `bar` and `qux` would be a subtype of `< bar : Bar.t; .. >`, but it would not be a subtype of `< bar : Bar.t >`. OCaml has another form of structural typing in its module system, closer to interfaces where a `module type` is declared up-front, and can be specified as the argument for a functor (parameterized module) - but this is incompatible with the row types in the object system.
- logicchains 1y ago