On Fri, 21 Aug 2020 at 22:46, Ian Lance Taylor <i...@golang.org> wrote:
> Yes, there are various such possibilities. > > What jimmy frasche said above is correct: nothing changes in the case > of a type switch of a type parameter. The code now knows the type > list element that the type argument matched, but it can't do anything > that it couldn't do anyhow. > I suspect that this would make the new type switch construct very much less useful. For example, it wouldn't be possible to specialize a vector operation to use machine-specific operations on a vector without using unsafe. It might be interesting to do a survey of some of the reasons that people would wish to use a type switch on a type parameter and see if the proposed construct would be sufficient. Have you got an example of how it might be used? cheers, rog. > > Ian > > On Fri, Aug 21, 2020 at 2:43 PM Axel Wagner > <axel.wagner...@googlemail.com> wrote: > > > > also, of course, you could still use operators with them, while now also > knowing the exact semantics of those operators (e.g. in regards to > overflow), which might also be useful. > > > > On Fri, Aug 21, 2020 at 11:42 PM Axel Wagner < > axel.wagner...@googlemail.com> wrote: > >> > >> > >> > >> On Fri, Aug 21, 2020 at 11:30 PM roger peppe <rogpe...@gmail.com> > wrote: > >>> > >>> On Fri, 21 Aug 2020 at 22:10, jimmy frasche <soapboxcic...@gmail.com> > wrote: > >>>> > >>>> I'd assume that would fail to compile as you're returning a []T not a > []int > >>> > >>> > >>> If that's the case, then I'm not sure that such a type switch would be > very useful. It would tell you what type the values are, but you can't do > anything with them because all the values would still be of the original > type. > >> > >> > >> You can reasonably convert them to their underlying type and *then* use > them as such. > >> That would make it useful while not allowing what you posit. > >> > >>> I had assumed that the intention was that within the arm of the type > switch, the switched type would take on the specified type. > >>> That would allow (for example) specialising to use underlying machine > operations on []T when T is a known type such as byte. > >> > >> > >> It would, however, prevent you from calling methods on the type or pass > it to a function taking an interface compatible with the constraint. > >> Also, I shudder to even imagine how this could be put into a spec. > >> > >>> > >>> > >>> > >>>> On Fri, Aug 21, 2020 at 2:07 PM roger peppe <rogpe...@gmail.com> > wrote: > >>>> > > >>>> > > >>>> > On Fri, 21 Aug 2020 at 01:28, Ian Lance Taylor <i...@golang.org> > wrote: > >>>> >> > >>>> >> After many discussions and reading many comments, we plan to move > >>>> >> forward with some changes and clarifications to the generics design > >>>> >> draft. > >>>> >> > >>>> >> 1. > >>>> >> > >>>> >> We’re going to settle on square brackets for the generics syntax. > >>>> >> We’re going to drop the “type” keyword before type parameters, as > >>>> >> using square brackets is sufficient to distinguish the type > parameter > >>>> >> list from the ordinary parameter list. To avoid the ambiguity with > >>>> >> array declarations, we will require that all type parameters > provide a > >>>> >> constraint. This has the advantage of giving type parameter lists > the > >>>> >> exact same syntax as ordinary parameter lists (other than using > square > >>>> >> brackets). To simplify the common case of a type parameter that > has > >>>> >> no constraints, we will introduce a new predeclared identifier > “any” > >>>> >> as an alias for “interface{}”. > >>>> >> > >>>> >> The result is declarations that look like this: > >>>> >> > >>>> >> type Vector[T any] []T > >>>> >> func Print[T any](s []T) { … } > >>>> >> func Index[T comparable](s []T, e T) { … } > >>>> >> > >>>> >> We feel that the cost of the new predeclared identifier “any” is > >>>> >> outweighed by the simplification achieved by making all parameter > >>>> >> lists syntactically the same: as each regular parameter always has > a > >>>> >> type, each type parameter always has a constraint (its meta-type). > >>>> >> > >>>> >> Changing “[type T]” to “[T any]” seems about equally readable and > >>>> >> saves one character. We’ll be able to streamline a lot of existing > >>>> >> code in the standard library and elsewhere by replacing > “interface{}” > >>>> >> with “any”. > >>>> >> > >>>> >> 2. > >>>> >> > >>>> >> We’re going to simplify the rule for type list satisfaction. The > type > >>>> >> argument will satisfy the constraint if the type argument is > identical > >>>> >> to any type in the type list, or if the underlying type of the type > >>>> >> argument is identical to any type in the type list. What we are > >>>> >> removing here is any use of the underlying types of the types in > the > >>>> >> type list. This tweaked rule means that the type list can decide > >>>> >> whether to accept an exact defined type, other than a predeclared > >>>> >> type, or whether to accept any type with a matching underlying > type. > >>>> >> > >>>> >> This is a subtle change that we don’t expect to affect any existing > >>>> >> experimental code. > >>>> >> > >>>> >> We think that this definition might work if we permit interface > types > >>>> >> with type lists to be used outside of type constraints. Such > >>>> >> interfaces would effectively act like sum types. That is not part > of > >>>> >> this design draft, but it’s an obvious thing to consider for the > >>>> >> future. > >>>> >> > >>>> >> Note that a type list can mention type parameters (that is, other > type > >>>> >> parameters in the same type parameter list). These will be > checked by > >>>> >> first replacing the type parameter(s) with the corresponding type > >>>> >> argument(s), and then using the rule described above. > >>>> >> > >>>> >> 3. > >>>> >> > >>>> >> We’re going to clarify that when considering the operations > permitted > >>>> >> for a value whose type is a type parameter, we will ignore the > methods > >>>> >> of any types in the type list. The general rule is that the > generic > >>>> >> function can use any operation permitted by every type in the type > >>>> >> list. However, this will only apply to operators and predeclared > >>>> >> functions (such as "len" and "cap"). It won’t apply to methods, > for > >>>> >> the case where the type list includes a list of types that all > define > >>>> >> some method. Any methods must be listed separately in the > interface > >>>> >> type, not inherited from the type list. > >>>> >> > >>>> >> This rule seems generally clear, and avoids some complex reasoning > >>>> >> involving type lists that include structs with embedded type > >>>> >> parameters. > >>>> >> > >>>> >> 4. > >>>> >> > >>>> >> We’re going to permit type switches on type parameters that have > type > >>>> >> lists, without the “.(type)” syntax. The “(.type)” syntax exists > to > >>>> >> clarify code like “switch v := x.(type)”. A type switch on a type > >>>> >> parameter won’t be able to use the “:=” syntax anyhow, so there is > no > >>>> >> reason to require “.(type)”. In a type switch on a type parameter > >>>> >> with a type list, every case listed must be a type that appears in > the > >>>> >> type list (“default” is also permitted, of course). A case will be > >>>> >> chosen if it is the type matched by the type argument, although as > >>>> >> discussed above it may not be the exact type argument: it may be > the > >>>> >> underlying type of the type argument. > >>>> > > >>>> > > >>>> > Here's one interesting implication of this: it allows us to do type > conversions that were not previously possible. > >>>> > > >>>> > For example, if we have "type I int", we can use a type switch to > convert some type []I to type []int: > >>>> > https://go2goplay.golang.org/p/-860Zlz7-cn > >>>> > > >>>> > func F[type T intlike](ts []T) []int { > >>>> > switch T { > >>>> > case int: > >>>> > return ts > >>>> > } > >>>> > return nil > >>>> > } > >>>> > > >>>> > It seems to me that this kind of thing will allow us to perform a > similar conversion (convert some part of the type to its underlying type) > on any type. > >>>> > > >>>> > In the early days of Go, the spec allowed this kind of conversion > as a normal type conversion. I wonder if it might be reasonable to revert > to those more relaxed semantics. I think they're potentially useful, for > example, when dealing with named types obtained from modules with two > different major versions without incurring copies. > >>>> > > >>>> > Although in the above-linked issue Robert talks about runtime costs > such as "possibly re-mapping method tables", I don't see that this would > necessarily be the case. Thoughts? > >>>> > > >>>> > -- > >>>> > 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/CAJhgacjL7p7qck%3DSO0Nz9f%2BKZw6MNcgkD5REXwSNK7_fCTXYQg%40mail.gmail.com > . > >>> > >>> -- > >>> 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/CAJhgacjTm%3DC-6f%2B4%2BA0HCTDT0_U7pQZOmRjShuzigdocDzAcww%40mail.gmail.com > . > -- 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/CAJhgacjmBVUxkT8LE3iS4Ae7Ykeo04y%2BJGg12jfFVCKqo-jLLQ%40mail.gmail.com.