My actual use case involves a code generator, where lib1 and lib2 (and possibly dozens of additional libraries) are all outputs of the same generator with slightly different arguments, generated by various different teams and therefore entirely outside of my control.
The generator in question reads a schema file and outputs a library of Go structs for all the data types defined by the schema. There are more than a thousand such data types; they have getters and setters for their attributes, and they're all nested in a giant tree, so e.g. code could call
root := &lib1.Root{}
root.GetFoo().GetBar().GetBaz().GetQux().GetFleem().SetName("hello")
The problem is that various users of the code generator have their own schemas, which are generally made by taking a common standard schema and adding extra fields needed by whatever specific project the users are working on. So for example one project might add a .GetSpoo() method to the Foo type, while another adds GetAlias to Fleem, etc.
What I really want to do is be able to write a helper like:
package examplehelper
func SetFleemName(root ???, name string) {
root.GetFoo().GetBar().GetBaz().GetQux().GetFleem().SetName(name)
}
such that any project can have its own generated library and can call `examplehelper.SetFleemName(root, "foo")` on a Root{} from their own generated library, as long as the Root has GetFoo(), the Foo has GetBar(), etc. down to the Fleem having a SetName(string).
This is technically possible with generics, but not practical, because it requires writing e.g.:
x := lib1.Root{}
helper.SetFleemName[*lib1.Fleem, *lib1.Qux, *lib1.Baz, *lib1.Bar, *lib1.Foo](x, "foo")
and in my real use case that list of type parameters would have more than a thousand types in it.
Right now I'm experimenting with whether it's reasonable to use code generation to solve this - a code generator could either just copy a helper library and replace all the imports with a specific generated library, or could build a generated-library-specific "bridge" library that defines a bunch of
var SetFleemName = generichelper.SetFleemName[*lib1.Fleem, *lib1.Qux, ...<a thousand more types>]
But there's a lot of overhead to having everything go through a generator, and it makes the code harder to read, harder to debug, and harder to use in IDEs. I am hoping that there's some Golang feature I'm just not aware of that would allow me to do this in the language itself, but I haven't been able to find one so far.
Thanks,
Dan