On Sun, Nov 4, 2018 at 10:14 PM roger peppe <rogpe...@gmail.com> wrote:
> This code, for example: https://play.golang.org/p/eaLHBbUJT-d > What might your generated code look like for that? > A bit ad-hoc, but WAI: https://play.golang.org/p/vuCHY2RRxIR In practice, of course, most of these wouldn't be actually generated exactly that way - instead you would use unsafe.Pointers and directly access the field of the rtype from the interface value. But it still show that it works. If someone writes to the slice, you'd obviously pass more functions to it >> for those operations and the compiler can create appropriate closures to >> pass. >> > > That's the problem I have with the solutions you're suggesting. The set of > required operation arguments is open ended and depends on all the generic > data structures that are used within the function and all generic functions > that that are called by it. > As you can see above, all operations that are needed are either a) explicit in the contract, b) explicit in the type-constructors used in the function signature or c) are pretty universal and can be implemented via reflection. The code we've been using for an example is naively simple - any real code > would be much more complex. For example, your code is passing in a closure > that allows the code to get the index of one particular slice. But what if > the code creates another slice for itself? Presumably that would require > another operation function to be passed in. A slice of slices? That's > different and would require a different operation function, I think. > Sure, all of that is true. But… so what? I mean, yes, that is implied by the fact that we have a dynamic implementation of generics. FTR, I am certain that most of these don't actually need to be passed - you should be able to get along with exactly one interface/itable per composite type in the signature and then use the passed *rtype to generate unsafe ops for the rest. But even if that's not the case - this is implicitly generated code, I don't see a problem with that, as both the list of operations necessary and the actually used itable have to be statically known. So this just comes down to passing a very large interface, with a statically allocated method table. It's not even expensive. What if it defines a new type and puts a value in it? Another operation. > Taking the address of a value, calling a function value, putting a value > into a map, copying a value, ...? All different operations requiring their > own entry points. As the complexity of the generic code rises, so does the > number of closures that must be created to allow that code to do all the > things that it needs to do. I don't see that as a viable implementation > strategy. > That's fair. We'll see how viable it is in practice - AFAIK something like that (though likely a lot more clever) is the plan, at least initially. Perhaps you might want to have a go at trying to translate a slightly more > substantial piece of generic code. For example, this generic implementation > of Dijkstra's algorithm: https://play.golang.org/p/BsktFSFVU0D. I'd be > interested to see what you end up with. > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.