Re: [go-nuts] No Generics - Type Binding on Imports
On Mon, Mar 22, 2021 at 2:10 AM Martin Leiser wrote: > > > What happens if > >I try to import a package that defines that Min function but I set the > >argument type to some that does not support the < operator? > I would simply write two similar packages: one using the above mentioned > enumerated interface of the accepted draft, > and another using the > type Lesser interface {Less(Lesser) Lesser } > The implementation of min with Lesser: >func Min(a, b Lesser) Lesser { if a.Less(b) {return a;} else {return b;}} > The implementation of Min with "ComparableStdType" stolen from the accepted > draft: >func Min(a, b ComparableStdType) ComparableStdType {if a < b {return a; } > else {return b;} Sorry, I didn't phrase my question well. I wasn't asking how I can handle that case. I was asking how the compiler detects an erroneous use of the Min function with a type that does not support the < operator. But I gather that you are suggesting that we use type lists as in the current generics proposal, so that answers that question. If we do that, it seems to me that your proposal is no simpler than the current generics proposal. And I think that in practice it will be somewhat harder to use, because it ties generic type scope closely to package scope. I don't think it's the case that all generic types are logically tied to a package. Forcing them to be associated with packages will force people to break up their programs in unnatural ways in order to use generic types. Ian -- 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/CAOyqgcW-xt__atkt6R%3DmjagXbCRu0pQcMKZ6gfJNxKNwgFXSCg%40mail.gmail.com.
Re: [go-nuts] No Generics - Type Binding on Imports
Am 22.03.2021 um 10:10 schrieb Martin Leiser: Am 21. März 2021 22:01:38 MEZ schrieb Ian Lance Taylor : On Sun, Mar 21, 2021 at 1:02 PM Martin Leiser wrote: ... import "container/list" stringlist type ElementType = string What if I want to have a list of lists of strings? That is a no brainer. The type "list of strings" in the example is: "stringlist.Element". So you add the following line: import "container/list" liststringlist type ElementType = stringlist.Element The really tricky question is in my opinion: What if the binding type is a parameter type itself? type MyElement interface{ String() string } and this is bound to import "container/list" myelementlist type ElementType = MyElement I.e my container type build on the list type for its implementation. This really adds complexity to the implementation, because every import binding "MyElement" also binds the list package parameter type. What if I want to have a list of some unexported type that I defined in this package? That is the "Complicated" part of the proposal. It can be solved and it is not that tricky: - All the compiler really needs to know about the bound type is specified by the bound interface type, plus the storage size. - You have to outrule cyclic definitions, but they are impossible, because it is the implementaion which introduces the cycle. - You may even fall back to the normal implementation of "interface types" behind the scenes when appropriate. Semantically all is solved by the following three program transformations chained together: 1. Make the private Type exported (does not change behaviour as long as you avoid name clashes by consistent renaming) 2. Add an import to the Package defining the binding type in a renamed copy of the generic package 3. replace the definition of the bind type by a type alias with the binding type in the copy of step 2 So steps 2 and 3 have to take place in the proper order and recursively across separate packages in case of parameter types used as binding types. Every binding of "MyElement" type adds another binding to list.ElementType. Complicated but solvable, but perhaps only if cyclic imports our outruled for type binding imports in the first place. Thanks again. Ian Thanks for your quick response. Martin Martin -- 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/26262f4f-41ad-3b4c-5682-17946174cc3a%40gmail.com.
Re: [go-nuts] No Generics - Type Binding on Imports
Am 21. März 2021 22:01:38 MEZ schrieb Ian Lance Taylor : >On Sun, Mar 21, 2021 at 1:02 PM Martin Leiser >wrote: >> >> I think so. But How? Remember we need to do two things: >> >> - A way to define type parameters. >> >> - A way to bind the type parameters to concrete types at compile >time > >Thanks for the note. > >I think that a generics proposal needs to do three things. The third >is that it needs to describe which operations are permitted for a type >parameter. Absolutely correct. Especially if you think about the kind of things you may do with type parameters and type inference in languages like Haskell or ML. The only thing you aktually want to do with binding types of type parameters is: use them as parameters of your package. No difference to the accepted proposal here. The key difference here is the way to define and bind the parameters. All else should be as equal as possible, because the accepted proposal is good. > > >> But after we named it "ElementType" we can get a hold of it and bind >it in the package we intend to use e.G. a "list of strings": >> >> import "container/list" type ElementType string > >This general kind of idea has been suggested quite a few times before. >Here are a few examples: > >https://gist.github.com/PeterRK/41d4d3f54b8db55cd616403fd5a389f3 >https://github.com/dotaheor/unify-Go-builtin-and-custom-generics/blob/master/use-package-as-gen.md >https://groups.google.com/g/golang-nuts/c/xKYXZpsWHus/m/SS4FKMBEAQAJ > >There are others. > yes I know about eg. even older ones like genny https://github.com/cheekybits/genny > >> Last features. If you need two different bindings in one package, say >a list of string and a list of int you may use: >> >> import "container/list" intlist type ElementType = int >> >> import "container/list" stringlist type ElementType = string > >What if I want to have a list of lists of strings? That is a no brainer. The type "list of strings" in the example is: "stringlist.Element". So you add the following line: import "container/list" liststringlist type ElementType = stringlist.Element > >What if I want to have a list of some unexported type that I defined >in this package? That is the "Complicated" part of the proposal. It can be solved and it is not that tricky: - All the compiler really needs to know about the bound type is specified by the bound interface type, plus the storage size. - You have to outrule cyclic definitions, but they are impossible, because it is the implementaion which introduces the cycle. - You may even fall back to the normal implementation of "interface types" behind the scenes when appropriate. Semantically all is solved by the following three program transformations chained together: 1. Make the private Type exported (does not change behaviour as long as you avoid name clashes by consistent renaming) 2. Add an import to the Package defining the binding type in a renamed copy of the generic package 3. replace the definition of the bind type by a type alias with the binding type in the copy of step 2 In my posting I only named the 3. transformation to keep things simple. Steps 2 and 3 have to be done at most once for any binding type in the whole program. All this may be implemented as "source to source" transformations, as you may know from the compiler construction class talking about generics (mine was >30 years age full of examples from LIS and Ada, I am a bit rusty here). And it gets way more complicated when you actually start to do it in reality. But it is this simple to describe here, because I choose to bind on the package level. That is part of the trick. The price are global variables. But can You always apply this transformation? Are there additional limitations required? I do not know yet. I believe you must outrule a import cycle for the type binding import. Which should be of no practical impact. > That seems to require interweaving type definitions >and imports in ways that the language does not currently support. Hmm, do not think so, see above. The result of the program transformation above should be a valid Go 1 program. For every type binding you have to have a way to "instantiate" a copy of the whole package with this binding. And the "stringlist" must only have one instantiation for all packages using the same type binding imports. Doing this efficient and effective, that is the complicated part. Did I mention that there is no big difference in complexity in the implementation of my proposal and the accepted one? Sorry for ommiting that. I actually see an additional risk, when talking about global variables involving the parameter types. (Which makes no sense for practical use, but has to be covered or outruled.) > >With this proposal, how can I write a min function that works for any >integer type, including a user-defined integer type? No. I did not include user-defined types. Buf if You add the enumerated interface types of the
Re: [go-nuts] No Generics - Type Binding on Imports
On Sun, Mar 21, 2021 at 1:02 PM Martin Leiser wrote: > > I think so. But How? Remember we need to do two things: > > - A way to define type parameters. > > - A way to bind the type parameters to concrete types at compile time Thanks for the note. I think that a generics proposal needs to do three things. The third is that it needs to describe which operations are permitted for a type parameter. > But after we named it "ElementType" we can get a hold of it and bind it in > the package we intend to use e.G. a "list of strings": > > import "container/list" type ElementType string This general kind of idea has been suggested quite a few times before. Here are a few examples: https://gist.github.com/PeterRK/41d4d3f54b8db55cd616403fd5a389f3 https://github.com/dotaheor/unify-Go-builtin-and-custom-generics/blob/master/use-package-as-gen.md https://groups.google.com/g/golang-nuts/c/xKYXZpsWHus/m/SS4FKMBEAQAJ There are others. > Last features. If you need two different bindings in one package, say a list > of string and a list of int you may use: > > import "container/list" intlist type ElementType = int > > import "container/list" stringlist type ElementType = string What if I want to have a list of lists of strings? What if I want to have a list of some unexported type that I defined in this package? That seems to require interweaving type definitions and imports in ways that the language does not currently support. With this proposal, how can I write a min function that works for any integer type, including a user-defined integer type? What happens if I try to import a package that defines that Min function but I set the argument type to some that does not support the < operator? Thanks again. Ian -- 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/CAOyqgcURm0uCGWPDQiyX_2FfGAon_snXKjn%3DmA_%3D1W1ScFc1Wg%40mail.gmail.com.