Few questions regarding Generics

157 views
Skip to first unread message

Khosrow Afroozeh

unread,
Feb 22, 2021, 9:03:53 AM2/22/21
to golang-nuts
I was playing with the go2go playground, and while implementing a toy List type, came across a few issues (Sorry if these have been discussed before, my cursory search didn't turn out to find anything). Given the type

type List[T any] []T

1. The current go2go implementation does not allow one to do this:

func ToList[T any](v []T) List[T] {
        return List(v)
}

with the error: List(v) is not a type

Is this a bug, shortcoming of the current implementation, or by design? This would be a deal breaker if type-casting doesn't work for generics.

2. It seems impossible to implement a type-safe Map function. The following code:

func (l List[T]) Map(f func[U any](v T) U) List[U] {
    return nil
}

will not compile, with the error: function type cannot have type parameters
Judging by the error message this seems to be by design, but it will significantly reduce the usability of generics for any transformation method. What is the reasoning behind this limitation?

Thanks,

Matt KØDVB

unread,
Feb 22, 2021, 9:39:09 AM2/22/21
to Khosrow Afroozeh, golang-nuts
Make Map a function not a method (not sure it can be made a method they way you’re trying):

package main

import (
"fmt"
"strconv"
)

type List[T any] []T

func ToList[T any](v []T) List[T] {
return List[T](v)
}

func Map[T, U any](l List[T], f func(v T) U) List[U] {
r := make(List[U], len(l))
for i, x := range l {
r[i] = f(x)
}
return r
}

func main() {
x := []int{1, 2, 3}
y := ToList(x)
fmt.Println(y)
fmt.Printf("%q\n", Map(y, strconv.Itoa))
}




--
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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/2aa1c2cb-e7bc-438e-81a9-e4a2904af21cn%40googlegroups.com.

Axel Wagner

unread,
Feb 22, 2021, 9:52:38 AM2/22/21
to Khosrow Afroozeh, golang-nuts
On Mon, Feb 22, 2021 at 3:04 PM Khosrow Afroozeh <kh.af...@gmail.com> wrote:
2. It seems impossible to implement a type-safe Map function. The following code:

func (l List[T]) Map(f func[U any](v T) U) List[U] {
    return nil
}

will not compile, with the error: function type cannot have type parameters
Judging by the error message this seems to be by design, but it will significantly reduce the usability of generics for any transformation method. What is the reasoning behind this limitation?

You are correct that it reduces expressive power. That has been deemed acceptable, for now. Some of the reasoning is in the design doc:
This is also related to the restriction that generic functions and types can't be used without instantiation, which is very hard to figure out with reflection existing, the requirement to not generate code at runtime and the strong preference not to force certain implementation options (specifically boxing).

If you could add type-parameters to methods, you could effectively achieve the same result though, by doing (making up syntax for generic methods)

type F struct {}

func (F) DoSomething[T any](v T) {
}

func main() {
    var f F
}

`f` now is effectively an uninstantiated generic function - you just have to write the call as `f.DoSomething(v)`, not `f(v)`.
The corollary is, that all the semantic and implementation difficulties arising from uninstantiated generic functions and types *also* arise from allowing additional type-parameters on methods.

No one argues it wouldn't be useful. But it's hard to do.

Volker Dobler

unread,
Feb 22, 2021, 12:25:26 PM2/22/21
to golang-nuts
On Monday, 22 February 2021 at 15:03:53 UTC+1 Khosrow Afroozeh wrote:
type List[T any] []T

1. The current go2go implementation does not allow one to do this:

func ToList[T any](v []T) List[T] {
        return List(v)
}

with the error: List(v) is not a type

Is this a bug, shortcoming of the current implementation, or by design? This would be a deal breaker if type-casting doesn't work for generics.

Given that there are no type casts in Go this is absolutely to be expected ;-)
And type conversions need a type and List isn't (but List[T] would be one).

V. 

Khosrow Afroozeh

unread,
Feb 22, 2021, 1:08:20 PM2/22/21
to golang-nuts
aha, thanks for your help! One problem down.

The error message is pretty cryptic though, I’d assumed the type inference would automatically take care of it, or complain about instantiation.

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/NUDZ7gL-IIM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/8c2a7b7d-ff11-4c8c-8dd4-2971ba6ab922n%40googlegroups.com.

roger peppe

unread,
Feb 22, 2021, 1:40:24 PM2/22/21
to Khosrow Afroozeh, golang-nuts
On Mon, 22 Feb 2021 at 18:07, Khosrow Afroozeh <kh.af...@gmail.com> wrote:
aha, thanks for your help! One problem down.

The error message is pretty cryptic though, I’d assumed the type inference would automatically take care of it, or complain about instantiation.

I think it should probably work, but currently I think that type inference only works for function calls, not for type conversions.

The proposal doesn't allow closures or methods with their own type parameters, so you'll need to define Map as a function rather than a method.


On Feb 22, 2021, at 6:25 PM, Volker Dobler <dr.volke...@gmail.com> wrote:

On Monday, 22 February 2021 at 15:03:53 UTC+1 Khosrow Afroozeh wrote:
type List[T any] []T

1. The current go2go implementation does not allow one to do this:

func ToList[T any](v []T) List[T] {
        return List(v)
}

with the error: List(v) is not a type

Is this a bug, shortcoming of the current implementation, or by design? This would be a deal breaker if type-casting doesn't work for generics.

Given that there are no type casts in Go this is absolutely to be expected ;-)
And type conversions need a type and List isn't (but List[T] would be one).

V. 

--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/NUDZ7gL-IIM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/8c2a7b7d-ff11-4c8c-8dd4-2971ba6ab922n%40googlegroups.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...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/2C15FD0D-933F-4CF7-AA88-686D232D38E0%40gmail.com.
Reply all
Reply to author
Forward
0 new messages