Hi, On Fri, Jan 1, 2021 at 1:41 PM Markus Heukelom <markus.heuke...@gain.pro> wrote:
> One thing that comes to mind that is not supported by the current proposal > is the ability to express that T must be (any) struct. > […] > Another example is where you write a library that creates an RPC service > from any function that you provide: > Personally, given that in both of these cases you still need to use `reflect` and there's still a lot of type-errors that can happen, I feel the wins here are relatively minor. There definitely are some and if they could be added more or less "for free", I'd definitely support that. But I don't see, personally, how that could be done. As an example, a similar case is expressing that an argument must be a pointer - for example, for json.Unmarshal. It has a similar level of benefit (json.Unmarshal also still needs to use reflect to actually set fields or values) - but in that case, there is already a "free" way to achieve it with the design (that is, use `func Unmarshal[type T any](b []byte, p *T) error`). > On the other hand, I don't see a lot of cases myself where I would want to > call some method on T in a generic function, mainly because there's already > interfaces and helper function for this in Go if you need it. For example, > you could say that a generic priority queue must call a method Priority() > on T, but that could be done in an equally type-safe way by asking for a > helper function to be provided with T (ie. func (T) int) with the > container. There's the graph example in the generics proposal but I think > that that can have a likewise type-safe solution that doesn't need the > ability to call a method on T. > You could argue, that you don't actually *need* methods or interfaces at all. Instead of passing an `io.Reader`, you could pass a `func(p []byte) (int, error)`. And instead of passing an `io.ReadCloser` you could pass that func and a `func() error`. At the end of the day, an interface is just a table of functions. But I hope we can agree that the method and interface mechanism provide a convenient way to package up data and code in a way usable by the callee. On the other hand I agree that an "interface" in its meaning of a > "declaration of a method set" applies equally well to compile time and > runtime. So the current argument is (I think) that generics is just the > application of interfaces at compile time instead of runtime. > I think the argument is rather "we want a way to constrain types and interfaces already provide a familiar way to express such constraints". It's just about re-using a familiar mechanic, instead of introducing a new one (in fact, the previous incarnation of contracts *would* have introduced a new mechanic and that was one of the main criticisms of it). > The issue I have with this is that it complicates (at least) the language > around the concept of "interface" at lot (just think about all the > documentation around interface that needs to be rewritten, and if someone > asks a question on a interface you first need to address if it's used > runtime or compile time, etc). > I do think interfaces change, but only to accommodate type-lists. I'm not a huge fan of that aspect of the design myself. I don't think the documentation around interfaces need to change at all apart from that. Their usage to express constraints is quite orthogonal to their usage as types and personally, I don't predict much confusion happening around that. > A second issue is that, in my opinion, it does not agree very well with > the idea of "one way of doing things" / orthogonality in Go (as explained > above). > > >> The third use-case I see for generics is to catch bugs by being able to > express more complicated type-invariants in code. An example of that would > be type-safety for context.Value > <https://blog.merovius.de/2020/07/20/parametric-context.html> (or, > similarly but subtly different, optional i > > The context.Value example is maybe an example of something that to me > feels (at least initially) as a suspicious application of generics. If > context.Context is made generic (if this is what is meant) then all > functions that use it, such as in the sql package, are forced to be generic > too: > > func (c *Conn) QueryContext[T any](ctx context.Context[T], query > string, args ...interface{}) (*Rows, error) > <https://golang.org/pkg/database/sql/#Conn.QueryContext> > > Before you know it everything is generic.... On the other hand, maybe > this is something that you just need to get used to and be very happy with > after. My initial reaction would be that the right choice here would be to > make context not generic as Value is only a "extra" customer user value > that is not part of its main functionality/purpose. However, it would > possibly be tempting to factor interface{} into a T if you don't think too > much about it. > I definitely agree that, especially as I presented it, Context.Value is not a good use of generics. I was really just interested in exploring the possibility, to come to that conclusion. Context.Value is widely criticized as not being type-safe and generics are widely advertised as solving type-safety issues - so I thought it would be useful, to look at the costs involved in using generics to solve a type-safety issue (that isn't just limited to containers). My general feeling, right now, is that there aren't a lot of type-safety issues generics (or at least this generics design) *can* solve, that aren't containers or generic algorithms (as in "things you'd find in an algorithms text book"). But I'd be interested to be proven wrong :) > > -Markus > > > -- > 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. > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/28dfab48-9413-4658-9272-bcc79f73153fn%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/28dfab48-9413-4658-9272-bcc79f73153fn%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfEXJUz%3D47nUDFykHVr-zv7W0ajs37c%3D5q1VUipciioxoQ%40mail.gmail.com.