On Tue, Feb 15, 2022 at 11:18 AM Kamil Ziemian <kziemian...@gmail.com> wrote:
> Hello, > > While reading "Type Parameters Proposal" ( > https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md) > I can't find a direct answer to question stated below. I should notice that > I have idea how it works, but I'm not sure if it is correct. > > Consider slightly changed code (https://go.dev/play/p/R1gK9bdLXV0?v=gotip) > from section "Element constraint example" ( > https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#element-constraint-example). > It shows that after passing `sliceMySlice` to the generic function `Double` > it change a type from `MySlice` to `[]int`. My question is, why this change > of type happens? > > Here how I understand this. Function `Double` has signature > `func Double[E MyInteger](s []E) []E` > so calling > `Double(sliceMySlice)` > requires function argument type inference. To do this we need to unify > type of `MySlice` to `[]int`. This can be done because [_For type > unification, two types that don‘t contain any type parameters are > equivalent if they are identical, or if they are channel types that are > identical ignoring channel direction, or if their underlying types are > equivalent._]( > https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#type-unification). > And from my understanding last case is applied here. Which give us `E` -> > `int`. We now need to instantiated function `Double[int]` by replacing in > all palaces type parameter `E` with type argument `int` and compiling such > function. > > In next step we take instantiated function `#Double[int](s []int) []int` > and call `#Double[int](sliceMySlice)`. Assigning value of type `MySlice` to > variable of type `[]int` is permissible in Go, so this is how this change > of type happens. I hope that I correctly understood that `[]int` is unnamed > (?) type. > Yes, your understanding seems correct. I checked proposal for occurrence of word "instatiation", it find 13 > results. Of them 3 referee to instatiation of Go generic function. > > Section "Omissions". "No currying. There is no way to partially > instantiate a generic function or type, other than by using a helper > function or a wrapper type. All type arguments must be either explicitly > passed or inferred at instantiation time.". > > Question "Why not use the syntax F<T> like C++ and Java?". "When parsing > code within a function, such as v := F<T>, at the point of seeing the < > it's ambiguous whether we are seeing a type instantiation or an expression > using the < operator." "Without type information, it is impossible to > decide whether the right hand side of the assignment is a pair of > expressions (w < x and y > (z)), or whether it is a generic function > instantiation and call that returns two result values ((w<x, y>)(z))." > > "Instantiating a function" ( > https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#instantiating-a-function). > "Go normally permits you to refer to a function without passing any > arguments, producing a value of function type. You may not do this with a > function that has type parameters; all type arguments must be known at > compile time. That said, you can instantiate the function, by passing type > arguments, but you don't have to call the instantiation. This will produce > a function value with no type parameters." > > This is the whole text of "Instantiating a function" and it is not to > helpful for me in understanding how it works. Ideas and notations that I > used above come from Robert Griesemer's talk "Typing [Generic] Go" from > GopherCon 2020 (https://www.youtube.com/watch?v=TborQFPY2IM), whiteout it > I would probably have no clue what may happen. I still can understand it > wrongly, but it is my fault. > > I hope this is not too silly question. > > Best, > Kamil > piątek, 11 lutego 2022 o 18:37:48 UTC+1 Kamil Ziemian napisał(a): > >> Hello, >> >> If you don't mind, I have few editorials suggestions to "Type parameters >> proposal". >> >> Last code example in section "Type parameters" ( >> https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#type-parameters) >> have very big and unecesary indentation, it should be removed. >> >> At the end of "The any constraint" ( >> https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#the-constraint) >> I would change "discussed separately)." to "discussed separately.)". This >> placement of dot before bracket is used in other parts of this document. >> >> In first code example in "Mutually referencing type parameters" >> ( >> https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md#mutually-referencing-type-parameters) >> we have function signature >> "func New[Node NodeConstraint[Edge], Edge EdgeConstraint[Node]] (nodes >> []Node) *Graph[Node, Edge]". >> It would be more consistent with Go style as I know it, if we remove >> white space placed before "(nodes []Node)". >> >> Best, >> Kamil >> niedziela, 6 lutego 2022 o 12:20:54 UTC+1 Kamil Ziemian napisał(a): >> >>> Thank you so much, about explanation. This is the first time that I hear >>> about named type and unnamed type in Go. >>> >>> Thank you even more for giving my another reason to learn Go Spec. I try >>> it before, but then I was lost in section about runes, so I go to learn >>> UTF-8. But soon enough I understand that to learn UTF-8 I need to go learn >>> about Unicode and I try to find time for it. >>> >>> Best regards, >>> Kamil >>> niedziela, 6 lutego 2022 o 03:47:36 UTC+1 Ian Lance Taylor napisał(a): >>> >>>> On Sat, Feb 5, 2022 at 4:27 PM Kamil Ziemian <kziem...@gmail.com> >>>> wrote: >>>> > >>>> > On the other hand this code compiled >>>> > > package main >>>> > > >>>> > > import "fmt" >>>> > > >>>> > > type Stringer interface { >>>> > > String() string >>>> > > } >>>> > > >>>> > > type StringableVector[T Stringer] []T >>>> > > >>>> > > type someFloat float64 >>>> > > >>>> > > func (sF someFloat) String() string { >>>> > > return fmt.Sprintf("someFloat: %v", float64(sF)) >>>> > > } >>>> > > >>>> > > func main() { >>>> > > var varStringer Stringer = someFloat(7) >>>> > > sliceSomeFloat := make([]someFloat, 3) >>>> > > >>>> > > var varStringableVector StringableVector[someFloat] = >>>> sliceSomeFloat >>>> > > >>>> > > fmt.Printf("varStringer type: %T\n", varStringer) >>>> > > fmt.Printf("sliceSomeFloat type: %T\n", sliceSomeFloat) >>>> > > fmt.Printf("varStringableVector type: %T\n", varStringableVector) >>>> > > } >>>> > >>>> > and produced result >>>> > >>>> > > stringerVar type: main.someFloat >>>> > > sliceScomeFloat type: []main.someFloat >>>> > > stringableVectorVar type: main.StringableVector[main.someFloat] >>>> > >>>> > Variable stringableVectorVar is not of interface type, because in >>>> such case its type printed by fmt.Printf should be []main.someFloat. So, it >>>> looks like to me as []main.someFloat is implicitly conversed to >>>> main.StringableVector[main.someFloat]. >>>> > >>>> > Answer to my previous questions was that []stupidFloat/[]someFloat is >>>> not of type StringableVector[stupidFloat] so it doesn't have method >>>> String() string. But in my poor understanding of Go, this code shouldn't >>>> compile due to implicit conversion of two types. >>>> > >>>> > Can anyone explain to me, where am I wrong? >>>> >>>> You are not permitted to assign directly from one named type to >>>> another named type. But here you are assigning an unnamed type, >>>> []someFloat, to a named type, StringableVector[someFloat]. Assigning >>>> an unnamed type to a named type is permitted if the underlying type of >>>> the named is identical to the unnamed type, which in this case it is. >>>> The same is true in non-generic Go. The exact rules are at >>>> https://go.dev/ref/spec#Assignability. >>>> >>>> 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/546dbb9e-9868-4791-ac63-953cf067da79n%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/546dbb9e-9868-4791-ac63-953cf067da79n%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/CAEkBMfEjCV-C4ASZZtiuAxuvgVdRTGS7-ZaTt5rzMqBzj4sR5Q%40mail.gmail.com.