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. 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.