[generics] some questions

106 views
Skip to first unread message

T L

unread,
Jun 18, 2020, 5:28:25 AM6/18/20
to golang-nuts
How to declare a generic functions which converting a slice with type Ta to a slice with type Tb. Like
func ConvertSlice(type Ta, Tb constraint)(ins []Ta) []Tb {...}

How to constraint a type parameter must be of an interface type?

Is it possible to define generic unnamed types?
If it is impossible, then how to define a generic map type which elements must be an unnamed integer slice?

Axel Wagner

unread,
Jun 18, 2020, 5:53:28 AM6/18/20
to T L, golang-nuts


On Thu, Jun 18, 2020, 11:28 T L <tapi...@gmail.com> wrote:
How to declare a generic functions which converting a slice with type Ta to a slice with type Tb. Like
func ConvertSlice(type Ta, Tb constraint)(ins []Ta) []Tb {...}

How to constraint a type parameter must be of an interface type?

I don't think you can. Why would you need to? Note that there will always be constraints that you can't express.


Is it possible to define generic unnamed types?

No. It also would be useless. You can't refer to a generic, uninstantiated type. So a generic type either needs a name to be referred by to instantiate it, or be instantiated right immediately in its declaration (and thus wouldn't need to be generic).

If it is impossible, then how to define a generic map type which elements must be an unnamed integer slice?

type numeric interface {
    type int, int8, int16, int32, ...
}

type MyMap(type K comparable, T numeric) map[K][]T

--
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/f02971c4-7e16-4f33-b919-93e7569d6571o%40googlegroups.com.

T L

unread,
Jun 18, 2020, 7:20:38 AM6/18/20
to golang-nuts


On Thursday, June 18, 2020 at 5:53:28 AM UTC-4, Axel Wagner wrote:


On Thu, Jun 18, 2020, 11:28 T L <tapi...@gmail.com> wrote:
How to declare a generic functions which converting a slice with type Ta to a slice with type Tb. Like
func ConvertSlice(type Ta, Tb constraint)(ins []Ta) []Tb {...}


 
For example, I need a ConvertSlice function which will do
* Convert []int to []int64, and the inverse
* Convert string to []byte, and the inverse
* Convert between several struct types with the same field set, except their field tags are different.
* more generally, Convert []Ta to []Tb, and the inverse, where Ta can be converted to Tb.

 
How to constraint a type parameter must be of an interface type?

I don't think you can. Why would you need to? Note that there will always be constraints that you can't express.

One need is the same as the above Convert case, there should be more.

func ConvertSlice(type T, I constraint)(ins []T) []I {...}

Where I must/may be some special interface types.



Is it possible to define generic unnamed types?

No. It also would be useless. You can't refer to a generic, uninstantiated type. So a generic type either needs a name to be referred by to instantiate it, or be instantiated right immediately in its declaration (and thus wouldn't need to be generic).

If it is impossible, then how to define a generic map type which elements must be an unnamed integer slice?

type numeric interface {
    type int, int8, int16, int32, ...
}

type MyMap(type K comparable, T numeric) map[K][]T

Sorry, here I meant "... must be of a slice with an unnamed element type".
Sometimes, the map element slice type itself might be required to be shown as a type parameter.
One of the case is still related to slice conversions.
 

--
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 golan...@googlegroups.com.

T L

unread,
Jun 18, 2020, 7:22:51 AM6/18/20
to golang-nuts
Another question, how to make the following code compile:

package main

type IntSlice interface {
    type []int
}

func Foo(type T IntSlice) (T) {}

func main() {
    type MyInt int
    Foo([]int(nil))
    Foo([]MyInt(nil)) // []MyInt does not satisfy IntSlice ([]MyInt not found in []int)
}

T L

unread,
Jun 18, 2020, 7:45:52 AM6/18/20
to golang-nuts
It looks the generic type argument must share the underlying type of a type in the constraint type list.

But the following code also fails to compile, bug?

package main

type Int interface {
    type int
}

func Foo(type T Int) ([]T) {} // undefined: MyInt


func main() {
    type MyInt int
    Foo([]MyInt(nil))
}

T L

unread,
Jun 18, 2020, 7:47:48 AM6/18/20
to golang-nuts
It looks, in most cases, the current rules recommends the types shown in the constraint definition must be the elementary types.

Axel Wagner

unread,
Jun 18, 2020, 8:01:22 AM6/18/20
to T L, golang-nuts


On Thu, Jun 18, 2020, 13:21 T L <tapi...@gmail.com> wrote:


On Thursday, June 18, 2020 at 5:53:28 AM UTC-4, Axel Wagner wrote:


On Thu, Jun 18, 2020, 11:28 T L <tapi...@gmail.com> wrote:
How to declare a generic functions which converting a slice with type Ta to a slice with type Tb. Like
func ConvertSlice(type Ta, Tb constraint)(ins []Ta) []Tb {...}


 
For example, I need a ConvertSlice function which will do
* Convert []int to []int64, and the inverse
* Convert string to []byte, and the inverse
* Convert between several struct types with the same field set, except their field tags are different.
* more generally, Convert []Ta to []Tb, and the inverse, where Ta can be converted to Tb.

None of these are interface types. I think I don't understand your question. Was there a typo and you meant "integer"? In that case, the answer is here:
You mention four very different use cases. I don't understand how to unify them into one question.


 
How to constraint a type parameter must be of an interface type?

I don't think you can. Why would you need to? Note that there will always be constraints that you can't express.

One need is the same as the above Convert case, there should be more.

func ConvertSlice(type T, I constraint)(ins []T) []I {...}

Where I must/may be some special interface types.

You still haven't said *why* you need it to be an interface type. What does knowing it's an interface allow you to do? Why would it break if someone passed a concrete type?





Is it possible to define generic unnamed types?

No. It also would be useless. You can't refer to a generic, uninstantiated type. So a generic type either needs a name to be referred by to instantiate it, or be instantiated right immediately in its declaration (and thus wouldn't need to be generic).

If it is impossible, then how to define a generic map type which elements must be an unnamed integer slice?

type numeric interface {
    type int, int8, int16, int32, ...
}

type MyMap(type K comparable, T numeric) map[K][]T

Sorry, here I meant "... must be of a slice with an unnamed element type".

I don't think that's possible. And the same question as above applies: Why is that an important constraint to be able to express?

I'm sorry, but I just don't understand what you are trying to ask.

Sometimes, the map element slice type itself might be required to be shown as a type parameter.
One of the case is still related to slice conversions.
 

--
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 golan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f02971c4-7e16-4f33-b919-93e7569d6571o%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/0ef1456d-8d8c-4d74-a36a-82e2b3337765o%40googlegroups.com.

Harald Weidner

unread,
Jun 18, 2020, 8:17:22 AM6/18/20
to T L, golang-nuts
Hello,

> But the following code also fails to compile, bug?
>
> package main
>
> type Int interface {
> type int
> }
>
> func Foo(type T Int) ([]T) {} // undefined: MyInt
>
> func main() {
> type MyInt int
> Foo([]MyInt(nil))
> }

It compiles if you move "type MyInt int" out of the func main scope. See
https://go2goplay.golang.org/p/_sWi72-0rD1

Harald

Bryan C. Mills

unread,
Jun 18, 2020, 10:38:26 AM6/18/20
to golang-nuts
On Thursday, June 18, 2020 at 7:20:38 AM UTC-4 tapi...@gmail.com wrote:
On Thursday, June 18, 2020 at 5:53:28 AM UTC-4, Axel Wagner wrote:
On Thu, Jun 18, 2020, 11:28 T L <tapi...@gmail.com> wrote:
How to declare a generic functions which converting a slice with type Ta to a slice with type Tb. Like
func ConvertSlice(type Ta, Tb constraint)(ins []Ta) []Tb {...}


 
For example, I need a ConvertSlice function which will do
* Convert []int to []int64, and the inverse
* Convert string to []byte, and the inverse
* Convert between several struct types with the same field set, except their field tags are different.
* more generally, Convert []Ta to []Tb, and the inverse, where Ta can be converted to Tb.

I attempted to write a similar function using assignability rather than conversion.¹
Neither constraint is possible in the current draft.

However, I believe that it would be possible (and coherent with the design) to add built-in interface types for “assignable to T” and “convertible to T” (but not “assignable from T” or “convertible from T”).

¹ My use-cases are the same as those described in:

T L

unread,
Jun 18, 2020, 11:28:47 AM6/18/20
to golang-nuts


On Thursday, June 18, 2020 at 8:01:22 AM UTC-4, Axel Wagner wrote:


On Thu, Jun 18, 2020, 13:21 T L <tapi...@gmail.com> wrote:


On Thursday, June 18, 2020 at 5:53:28 AM UTC-4, Axel Wagner wrote:


On Thu, Jun 18, 2020, 11:28 T L <tapi...@gmail.com> wrote:
How to declare a generic functions which converting a slice with type Ta to a slice with type Tb. Like
func ConvertSlice(type Ta, Tb constraint)(ins []Ta) []Tb {...}


 
For example, I need a ConvertSlice function which will do
* Convert []int to []int64, and the inverse
* Convert string to []byte, and the inverse
* Convert between several struct types with the same field set, except their field tags are different.
* more generally, Convert []Ta to []Tb, and the inverse, where Ta can be converted to Tb.

None of these are interface types. I think I don't understand your question. Was there a typo and you meant "integer"? In that case, the answer is here:
You mention four very different use cases. I don't understand how to unify them into one question.


 
How to constraint a type parameter must be of an interface type?

I don't think you can. Why would you need to? Note that there will always be constraints that you can't express.

One need is the same as the above Convert case, there should be more.

func ConvertSlice(type T, I constraint)(ins []T) []I {...}

Where I must/may be some special interface types.

You still haven't said *why* you need it to be an interface type. What does knowing it's an interface allow you to do? Why would it break if someone passed a concrete type?

For examples, I want to convert a []int value "vs" to a []interface{} value so that it can be passed to the fmt.Println(Convert(int, interface{})(vs)...).
But I don't need a Convert generic function which can convert []int to []interface{} specifically.
What I need is a common generic function which can convert []Ta value to []Tb if Ta values can be converted to Tb.

That means, the above two questions are the same question.
 





Is it possible to define generic unnamed types?

No. It also would be useless. You can't refer to a generic, uninstantiated type. So a generic type either needs a name to be referred by to instantiate it, or be instantiated right immediately in its declaration (and thus wouldn't need to be generic).

If it is impossible, then how to define a generic map type which elements must be an unnamed integer slice?

type numeric interface {
    type int, int8, int16, int32, ...
}

type MyMap(type K comparable, T numeric) map[K][]T

Sorry, here I meant "... must be of a slice with an unnamed element type".

I don't think that's possible. And the same question as above applies: Why is that an important constraint to be able to express?

I'm sorry, but I just don't understand what you are trying to ask.

Sometimes, the map element slice type itself might be required to be shown as a type parameter.
One of the case is still related to slice conversions.
 

--
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 golan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f02971c4-7e16-4f33-b919-93e7569d6571o%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 golan...@googlegroups.com.

T L

unread,
Jun 18, 2020, 11:30:06 AM6/18/20
to golang-nuts
So, it is really a bug. I will report it.

T L

unread,
Jun 18, 2020, 11:34:34 AM6/18/20
to golang-nuts
It is a little hard to describe it clearly. I will continue this question when I sort it out.
 

--
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 golan...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/f02971c4-7e16-4f33-b919-93e7569d6571o%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 golan...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages