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.

Reply via email to