Strange cases of type definitions that use "[]", Go 1.17 and 1.18beta2

335 views
Skip to first unread message

Kamil Ziemian

unread,
Feb 11, 2022, 6:49:25 AM2/11/22
to golang-nuts
Hello,

I should mention that I still don't read Go Language Specification (https://go.dev/ref/spec), due to my decision to first study Unicode and UTF-8, before reading it. It maybe strange thing to do, but I just how I need to deal with Unicode and UTF-8.

Regardless of that I quickly check few sections of it and I still baffled by what I find that compiler accepts. I write this to ask some gophers to help me find a way to think about this. I hope that you forgive me some stupid questions, I have so knowledge of Go, but still very little of "feeling" of Go.

I also have almost no knowledge about compilers. I just compiler front-end user.

In all code examples I use two following versions of Go.
go version go1.17.7 linux/amd64
go version go1.18beta2 linux/amd64

"Type parameters proposal" (https://go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md) add new "[]" in new role. It allows to write
> func someFunction[T Constraint](...) { ... }
> type someType[T Constraint] ...
where "Constraint" is constraint on allowed type parameters and "T"" is a type parameter. (I hope that I didn't mess up names.)

As a byproduct of some obvious mistakes I find that
> type someInt[3] int
work fine in both Go 17 and 18beta2. It defines someInt as new type with underling type [3]int. This looks weird and pouting something like that in the working code is probably a sin, but this is not that big issue.

I'm now trying to play with compilers with this construction.
> type someDifferentInt[float64] int
In Go 1.17 I get this complain
> invalid array bound float64
> type float64 is not an expression
while in Go 1.18beta2 I get
> float64 (type) is not an expression
It probably need be this way, that with using "[T Constraint]" to define (?) type parameters, compiler can't says that it is "invalid array bound float64", but new error message is still less useful. I guess we need to live with that.

> type someOtherInt[float64 float64] int
This is awful thing to write, but I still perplexed by what compilers say.
Go 1.17:
> syntax error: unexpected float64, expecting ]
Go 1.18beta2:
> cannot use a type parameter as constraint

This example is to compare Go compilers with and without generics.
> type someAnotherInt[T any] int
Go 1.17:
> syntax error: unexpected any, expecting ]

Go 1.18beta2: it compile just fine. Can someone explain me, why compiler can't throw an error when it find unused type parameter? I like that in Go unused variable, or import, is compile time error and I would appreciate the same behavior with unused type parameters.

I need to go for a while, I will go back with more questions about what you can get when using "[]" in Go.

Best,
Kamil

Jan Mercl

unread,
Feb 11, 2022, 7:13:51 AM2/11/22
to Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 12:50 PM Kamil Ziemian <kziem...@gmail.com> wrote:

> I need to go for a while, I will go back with more questions about what you can get when using "[]" in Go.

The '[' and ']' is just a pair of tokens with no meaning attached to
it per se. Context is everything. So square brackets in one context
groups a list of type parameter declarations, in another context it
denotes the key type of a map, in another context it defines the size
of an array etc.

Compare this to the '*' token, for example. It can mean multiplying,
dereferencing or specifying a pointer type, all dependent on context
where it appears.

The language specification defines the various contexts for the tokens
using a syntax and attaches the different meanings to those cases.

The differences observed between Go1.17 and Go1.18 reflect the
language specification changed substantially as did the syntax.

Axel Wagner

unread,
Feb 11, 2022, 7:38:44 AM2/11/22
to golang-nuts
On Fri, Feb 11, 2022 at 12:51 PM Kamil Ziemian <kziem...@gmail.com> wrote:
Can someone explain me, why compiler can't throw an error when it find unused type parameter? I like that in Go unused variable, or import, is compile time error and I would appreciate the same behavior with unused type parameters.

I'm not sure it's reason enough, but I do have a case where I want to have unused type-parameters on a type.
Essentially, I have

type ID string
func Call(ctx context.Context, id ID, req Message) (Message, error)

which does an RPC-like call. It's used as

r, err := framework.Call(ctx, somepkg.ID, somepkg,Request{…})
resp := r.(somepkg.Response)

With generics, this would be

type ID string
func Call[Req, Resp Message](context.Context, ID, Req) (Resp, error)

But this requires writing

resp, err := framework.Call[somepkg.Request, somepkg.Response](ctx, somepkg.ID, somepkg.Request{…})

as return types can't be inferred. Instead, I plan to do

type ID[Req, Resp Message] string // unused type-parameters
func Call[Req, Resp Message](context.Context, ID[Req, Resp], Req) (Resp, error)

which allows `somepkg` to declare

var ID = framework.ID[MyRequest, MyResponse]("my-name")

letting the client write

resp, err := framework.Call(ctx, somepkg.ID, somepkg.Request)

Now somepkg.ID carries both types and is in an argument, so both types can be inferred.

As I said, I'm not 100% yet on whether this is a good idea and much less if that would be enough reason to keep allowing unused type parameters. But there is at least some potential benefit to allowing it.
 

I need to go for a while, I will go back with more questions about what you can get when using "[]" in Go.

Best,
Kamil

--
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/b085b991-e59e-4225-a4d6-36b2391e1dc2n%40googlegroups.com.

Axel Wagner

unread,
Feb 11, 2022, 7:51:52 AM2/11/22
to Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 12:51 PM Kamil Ziemian <kziem...@gmail.com> wrote:
I'm now trying to play with compilers with this construction.
> type someDifferentInt[float64] int
In Go 1.17 I get this complain
> invalid array bound float64
> type float64 is not an expression
while in Go 1.18beta2 I get
> float64 (type) is not an expression
It probably need be this way, that with using "[T Constraint]" to define (?) type parameters, compiler can't says that it is "invalid array bound float64", but new error message is still less useful. I guess we need to live with that.

I can't see why the parser can't see that this should (if anything) be interpreted as an array type declaration. To me, this seems like a regression. I'd suggest maybe filing an issue.
 
> type someOtherInt[float64 float64] int
This is awful thing to write, but I still perplexed by what compilers say.
Go 1.17:
> syntax error: unexpected float64, expecting ]
Go 1.18beta2:
> cannot use a type parameter as constraint

This error message seems reasonably clear to me. You are declaring a type parameter `float64` with constraint `float64`. It tells you that you can't use type parameters as constraints.
 

This example is to compare Go compilers with and without generics.
> type someAnotherInt[T any] int
Go 1.17:
> syntax error: unexpected any, expecting ]

Go 1.18beta2: it compile just fine. Can someone explain me, why compiler can't throw an error when it find unused type parameter? I like that in Go unused variable, or import, is compile time error and I would appreciate the same behavior with unused type parameters.

I need to go for a while, I will go back with more questions about what you can get when using "[]" in Go.

Best,
Kamil

--

Kamil Ziemian

unread,
Feb 11, 2022, 7:56:54 AM2/11/22
to golang-nuts
Thank you Jan Marcel. I see now that I wasn't precise enough. I understand that '[' and ']' are just tokens, even I have only intuitive understanding of concept of token. My problem is that as Ian Lance Taylor and other people said many times: adding generics will make Go more complicated. My problem is not in understanding why it is more complicated, but to accept disturbing cases of it becoming so. It less question of intellectually understanding, more about "feeling of Go". Which is of course hard to defined.

I copied compilations errors, because in many cases I don't find Go compilers errors very useful. Don't get me wrong, in many cases there are fine, but messages as
> type someDifferentInt[float64] int
> error: float64 (type) is not an expression
are not something that I understand. I often end up ignoring the message and just stare for few minutes in the line where the error was found, compare it to working examples, tweak code a little bit and find what happens. I hope that someone give me some advise how to deal with that, that Go errors are going to be even harder to me to read. Even if this advise is "Just accept it and carry on", it will be valuable.

Best,
Kamil

Kamil Ziemian

unread,
Feb 11, 2022, 8:47:07 AM2/11/22
to golang-nuts
Axel I agree that "But there is at least some potential benefit to allowing it.". But, by my humble understanding, true question is "Would Go still feel likes Go after this?". This question is one of the reasons why generics was so long, decade or even more, in the making. Somewhere on GitHub there is a discussion about unused type of arguments in the function. I think they agree that with benefits of hindsight you should be force to write func f(_ int) ... for any unused argument, that is need for function signature or some similar reason. But, now this will be to much breaking of backward compatibility with to little benefit. So I think it is worth pondering now, even if we it is already to late to change anything in Go 1.18.

"As I said, I'm not 100% yet on whether this is a good idea and much less if that would be enough reason to keep allowing unused type parameters." I like your approach. As I understand your code, because type inference works only on types of arguments, not on types of return values, you define a somepkg.ID to be just a string, that carries information about two additional types. This allows Go type inference algorithm infer type of return value from ID value and put it into place of return type of particular instantiation of generic function. Am I right?

You are almost surly more experience Go programmer than me, so anything that I write next may be just silly. Ian Lance Taylor give us one Go-proverb-like advice about generics in Go: "Write code, don't design types". Was your code created according to this rule? It doesn't look like that to me, but I'm in no case someone who should judge it. Better gophers should look at it and decide if this is legitimate use of type parameters.

My guts tell me that is not what I want to work with. It is some workaround of type interference algorithm, by putting too much information in one humble string-under-the-hood type. Dave Cheney said once that "Zen of Python" is also valid in Go and maybe better followed by Go programmers than by Python programmers. And this seems to be a breaking of rule "Explicit is better implicit" and, more importantly, of Go proverb "Clear is better than clever". But, again, so true gopher should judge your code, not me. I just write this to start some discussion about that and I remember that you yourself have doubts about it.

Best,
Kamil
Message has been deleted

Kamil Ziemian

unread,
Feb 11, 2022, 9:12:18 AM2/11/22
to golang-nuts
"> type someDifferentInt[float64] int

I can't see why the parser can't see that this should (if anything) be interpreted as an array type declaration. To me, this seems like a regression. I'd suggest maybe filing an issue."

I think I know the reason. You can write
> type someArrayWithThreeInt [3]int
which is proper definition of new type that under the hood is just array of three int. Due to Go rules about names, white spaces and how Go parser work, this is equivalent (I think so) to
> type someArrayWithThreeInt[3] int

I check this last code in simple example and it seems to work "as you might think". It defines type which under the hood is, again, array of three ints. But writing such thing is probably a sin.

I don't know if I should filing the issue. There is already 5k+ issues and a lot of work for Go developers, I don't want to add another if there is not good enough reasons. Since this can possible break some code, I heisted about that. Better gophers should look at that.

Even if writing "type someArrayWithThreeInt[3] int" is evil, wicked thing, we know that everything can broke something to someone (https://xkcd.com/1172/) and Go backward compatibility police is quite strong. I want to write another 5k+ issue about thing that cannot be improved.

Best,
Kamil

Jan Mercl

unread,
Feb 11, 2022, 9:37:59 AM2/11/22
to Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 3:13 PM Kamil Ziemian <kziem...@gmail.com> wrote:

> "> type someDifferentInt[float64] int
> I can't see why the parser can't see that this should (if anything) be interpreted as an array type declaration. To me, this seems like a regression. I'd suggest maybe filing an issue."
>
> I think I know the reason. You can write
> > type someArrayWithThreeInt [3]int
> which is proper definition of new type that under the hood is just array of three int. Due to Go rules about names, white spaces and how Go parser work, this is equivalent (I think so) to
> > type someArrayWithThreeInt[3] int
>
> I check this last code in simple example and it seems to work "as you might think". It defines type which under the hood is, again, array of three ints. But writing such thing is probably a sin.

Why is it a sin? It's a perfectly normal type definition. Quite
common, because useful for attaching methods to a type. One cannot
attach a method to type [3]int.

> I don't know if I should filing the issue.

I wonder what problem is perceived in `type name [expression]T` that
would be the essence of the issue?

White space between tokens, once the lexer injects the semicolons
according to the specified rules, becomes insignificant above
separating adjacent tokens, as also defined in the language
specification.

Kamil Ziemian

unread,
Feb 11, 2022, 10:00:06 AM2/11/22
to golang-nuts
"Why is it a sin? It's a perfectly normal type definition. Quite common, because useful for attaching methods to a type. One cannotattach a method to type [3]int."
To write it with such white spaces
> type typeName[3] int
looks like sinful thing to me. It should be
> type typeName [3]int
No problem with that. But, from what I see, both examples works.

Best,
Kamil

Kamil Ziemian

unread,
Feb 11, 2022, 10:02:42 AM2/11/22
to golang-nuts
I'm seriously lost here. Code below works in both Go 1.17 and Go 1.18beta2

> package main
>
> import "fmt"
>
> type someInterface[3] interface {
>         SomeMethod()
> }
>
> func main() {
>         var varSI someInterface
>
>         fmt.Printf("varSI value: %v\n", varSI)
>         fmt.Printf("varSI type:  %T\n", varSI)
> }

and give in both cases result
> varSI value: [<nil> <nil> <nil>]
> varSI type:  main.someInterface

I didn't find any way to assign some new value to "varSI", but this is already disturbing to me.

Best,
Kamil

Axel Wagner

unread,
Feb 11, 2022, 10:44:15 AM2/11/22
to Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 2:48 PM Kamil Ziemian <kziem...@gmail.com> wrote:
Somewhere on GitHub there is a discussion about unused type of arguments in the function. I think they agree that with benefits of hindsight you should be force to write func f(_ int) ... for any unused argument, that is need for function signature or some similar reason.

It would work fine, for my case, to be required to name unused type parameters `_`. Though I think the code would be less clear. With `type ID[Req, Resp Message] string` it is clear what the type parameters are and what they should be instantiated with. That's not the case with `type ID[_, _ Message] string`.

I think there is arguably a difference between generic functions and generic type declarations. In the former case, an argument name is rarely needed for the documentation, whereas in the latter case it's probably always needed. Though I'm not sure, really.

As I understand your code, because type inference works only on types of arguments, not on types of return values, you define a somepkg.ID to be just a string, that carries information about two additional types. This allows Go type inference algorithm infer type of return value from ID value and put it into place of return type of particular instantiation of generic function. Am I right?

Yes.
 
You are almost surly more experience Go programmer than me, so anything that I write next may be just silly. Ian Lance Taylor give us one Go-proverb-like advice about generics in Go: "Write code, don't design types". Was your code created according to this rule?

It is non-generic code currently used in production and I would like it to benefit from generics. The issue with type-inference came up when thinking about that. So, no, this is not something that I made up to have an example or anything like that. I thought about a couple alternative ways to do it and they all don't work for one reason or another.

I feel pretty confident that this is not an instance of "designing types".

My guts tell me that is not what I want to work with. It is some workaround of type interference algorithm, by putting too much information in one humble string-under-the-hood type.

Believe it or not, but I agree. It's just the least bad solution I could come up with, so far.
 

Axel Wagner

unread,
Feb 11, 2022, 11:00:12 AM2/11/22
to Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 3:14 PM Kamil Ziemian <kziem...@gmail.com> wrote:
"> type someDifferentInt[float64] int
I can't see why the parser can't see that this should (if anything) be interpreted as an array type declaration. To me, this seems like a regression. I'd suggest maybe filing an issue."

I think I know the reason. You can write
> type someArrayWithThreeInt [3]int
which is proper definition of new type that under the hood is just array of three int. Due to Go rules about names, white spaces and how Go parser work, this is equivalent (I think so) to
> type someArrayWithThreeInt[3] int

Yes. It is clear why the parser would try and parse it as an array type declaration.
But as you observed, it doesn't do that in go 1.18 - otherwise it would output the error message of "invalid array bound".
I can't see a syntactical ambiguity, though. The series of tokens `type A [ B ] C` can, AFAICT, only be parsed as an array type declaration, generics or not (if there where *two* identifiers in the brackets, it would be something else, because that could be a generic type declaration. But not with one).

So, to me, this seems like a regression. The parser should parse this as an array declaration and the type checker should output the helpful error message, that the array bounds are invalid.
 
There are some tests for this error message:
This case is not covered by them, which is probably why this change went unnoticed.

I don't know if I should filing the issue. There is already 5k+ issues and a lot of work for Go developers, I don't want to add another if there is not good enough reasons.

This is why I said that this seems like a regression and suggested that you file an issue. We have an error message for this particular mistake. We have tests to see that the right error message is printed when it happens. We clearly care about providing helpful errors. The error message doesn't appear in a case where it seems that it should.

All of these surmise to a good reason to file an issue.

Since this can possible break some code, I heisted about that. Better gophers should look at that.

This is purely about changing the error message from the compiler, not changing whether or not code is being accepted. There is absolutely no question that `type A[3] int` should continue to compile fine. There is no question that `type A[float64] int` shouldn't. It's just that the error for the latter case should include the "invalid array bounds" message.

Also note that `gofmt` will automatically reformat this code to be clear about the intention. So, I wouldn't worry about it being unreadable if people do.
 

Kamil Ziemian

unread,
Feb 11, 2022, 11:02:04 AM2/11/22
to golang-nuts
> type someOtherInt[float64 float64] int
This is awful thing to write, but I still perplexed by what compilers say.
Go 1.17:
> syntax error: unexpected float64, expecting ]
Go 1.18beta2:
> cannot use a type parameter as constraint

"This error message seems reasonably clear to me. You are declaring a type parameter `float64` with constraint `float64`. It tells you that you can't use type parameters as constraints."
I choose this example to be "straight to your face". I can't tell if it was the first example, this is silly code, I would find out what happens easily than in real code that I had. In this original example message wasn't to useful since thing used as a constraint wasn't the type.


"Believe it or not, but I agree. It's just the least bad solution I could come up with, so far."
I can relate somewhat to your situations. We all need to learn how to use type parameters in Go and it will take a while even for the best of us.

Axel Wagner

unread,
Feb 11, 2022, 11:06:48 AM2/11/22
to Kamil Ziemian, golang-nuts
FYI I went ahead and filed https://github.com/golang/go/issues/51145

Kamil Ziemian

unread,
Feb 11, 2022, 11:06:50 AM2/11/22
to golang-nuts
I was myself unable to remember how compilers reacts to various type declarations that uses "[]", so I make this summary. Maybe one find it useful.

> package main
>
> import "fmt"
>
> type someType[float64] int // (1)
>
> func main() {
>         fmt.Println("Hello, world!")
> }

Go 1.17

> invalid array bound float64
> type float64 is not an expression
Go 1.18beta2

> float64 (type) is not an expression

You got the same result if you replace line (1) with
> type someArray[float64] [3]int

If you replace line (1) with
> type someOtherType[int float64] int
you get in Go 1.17

> syntax error: unexpected float64, expecting ]
in Go 1.18beta2
> cannot use a type parameter as RHS in type declaration

Replacing (1) by
> type someAnotherType[uint float64] int
Go 1.17 gives

> syntax error: unexpected float64, expecting ]
In Go1.18beta this bloody nonsense compile!!!

Replacing (1) by
> type someOtherArray[int float64] [3]int
Go 1.17 gives

> syntax error: unexpected float64, expecting ]
In Go1.18beta this bloody nonsense compile!!!

I just tried to implement working example of code implementing generic graph, that is sketched in "Type parameters proposal" and I feel as if I'm find some rabbit hole.

Best,
Kamil Ziemian

Axel Wagner

unread,
Feb 11, 2022, 11:15:51 AM2/11/22
to Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 5:08 PM Kamil Ziemian <kziem...@gmail.com> wrote:
Replacing (1) by
> type someOtherArray[int float64] [3]int
Go 1.17 gives
> syntax error: unexpected float64, expecting ]
In Go1.18beta this bloody nonsense compile!!!

It might be nonsense, but it's reasonable for this to compile under the rules given. It is equivalent to

type C interface { float64 }
type someOtherArray[T C] [3]T

Yes, it is not particularly useful to have a type parameter constraint with only one allowed type. But it is not unreasonable for the compiler to allow that.
Apart from that, the rest of the difference is simply in using different identifiers and being able to shadow predeclared identifiers. This has always been allowed in go (e.g. you can write `type int string`, which is valid code).
Such code is confusing, but it makes the language better to allow it and tell people to not write intentionally obscure code.
 

Jan Mercl

unread,
Feb 11, 2022, 12:38:11 PM2/11/22
to Axel Wagner, Kamil Ziemian, golang-nuts
On Fri, Feb 11, 2022 at 5:06 PM 'Axel Wagner' via golang-nuts
<golan...@googlegroups.com> wrote:

> FYI I went ahead and filed https://github.com/golang/go/issues/51145

I must be missing something because I still don't understand what the
problem is. The syntax `type A[B]C` can be reduced both in Go1.17 and
Go1.18 in only way - it's declaring an array type A, having B elements
of type C. Because B must be a constant expression, which `float64`,
unless redefined, is not, the error message produced is complete and
unambiguous.

Compiler error messages say what the error is, their purpose is not to
explain the specification. The intended reader of the error message is
supposed to understand the message in context of the language
specification, i.e. in this case be aware that the code declares an
array type, and expects an expression where a type `float64` was found
instead.

FTR: To have it explicit, it has nothing to do with type parameters,
they have syntax incompatible with this given example.

Axel Wagner

unread,
Feb 11, 2022, 12:54:24 PM2/11/22
to Jan Mercl, golang-nuts
On Fri, Feb 11, 2022 at 6:35 PM Jan Mercl <0xj...@gmail.com> wrote:
On Fri, Feb 11, 2022 at 5:06 PM 'Axel Wagner' via golang-nuts
<golan...@googlegroups.com> wrote:

> FYI I went ahead and filed https://github.com/golang/go/issues/51145

I must be missing something because I still don't understand what the
problem is. The syntax `type A[B]C` can be reduced both in Go1.17 and
Go1.18 in only way - it's declaring an array type A, having B elements
of type C. Because B must be a constant expression, which `float64`,
unless redefined, is not, the error message produced is complete and
unambiguous.

The error message included "invalid array bounds" in go 1.17.
It does not contain that in go 1.18.
It is thus, clearly, less helpful than it used to be.

Compiler error messages say what the error is, their purpose is not to
explain the specification. The intended reader of the error message is
supposed to understand the message in context of the language
specification, i.e. in this case be aware that the code declares an
array type, and expects an expression where a type `float64` was found
instead.

If that was the intent, the compiler would not have produced the extra "invalid array bounds" message before and it wouldn't produce similar messages in other contexts.


In any case, if the issue gets closed as WAI, then so be it.
 
FTR: To have it explicit, it has nothing to do with type parameters,
they have syntax incompatible with this given example.

I agree. That was exactly my point. There is no syntactic ambiguity, ergo the compiler should know that it has to be an array declaration, ergo it should provide the more specific error message in this case. 
 

Brian Candler

unread,
Feb 12, 2022, 5:12:21 AM2/12/22
to golang-nuts
On Friday, 11 February 2022 at 16:06:50 UTC kziem...@gmail.com wrote:
> type someAnotherType[uint float64] int
Go 1.17 gives
> syntax error: unexpected float64, expecting ]
In Go1.18beta this bloody nonsense compile!!!

Sadly, it's legal to re-use the name of an existing type as a variable name and/or a type name, even in pre-generics Go.

Now you can also use it as a generic type name.

jake...@gmail.com

unread,
Feb 13, 2022, 11:44:30 AM2/13/22
to golang-nuts
On Friday, February 11, 2022 at 10:02:42 AM UTC-5 kziem...@gmail.com wrote:
I'm seriously lost here. Code below works in both Go 1.17 and Go 1.18beta2

> package main
>
> import "fmt"
>
> type someInterface[3] interface {
>         SomeMethod()
> }
>
> func main() {
>         var varSI someInterface
>
>         fmt.Printf("varSI value: %v\n", varSI)
>         fmt.Printf("varSI type:  %T\n", varSI)
> }

and give in both cases result
> varSI value: [<nil> <nil> <nil>]
> varSI type:  main.someInterface

I didn't find any way to assign some new value to "varSI", but this is already disturbing to me.

FWIW, here is code that assigns to varSI in two ways:  https://go.dev/play/p/ypj6rQbpBBl
Note that running this code in the playground will reformat ' type someInterface[3] interface' to the proper ' type someInterface [3]interface'. This is not a change in meaning, just a clarifying white space change made by `go fmt`.

Kamil Ziemian

unread,
Feb 13, 2022, 5:21:24 PM2/13/22
to golang-nuts
"I think there is arguably a difference between generic functions and generic type declarations. In the former case, an argument name is rarely needed for the documentation, whereas in the latter case it's probably always needed. Though I'm not sure, really."

I complain about, to make excuse for my ignorance, that current learning materials are in 75% or more about generic functions and 25% is about generic types. This is estimate based on learning materials, that I watch/red. I don't know if this is accident, or it is more uncharted territory? Either way, we need to learn a lot about using generic types and it is hard to tell anything for sure now.


"So, no, this is not something that I made up to have an example or anything like that. I thought about a couple alternative ways to do it and they all don't work for one reason or another."

Thank you for the information. Do you check if performance of generic code is good? I always want to know if there is regression in performance.


"FWIW, here is code that assigns to varSI in two ways:  https://go.dev/play/p/ypj6rQbpBBl"

From what I understand "type someInterface [3]interface{ SomeMethod() }" define interface array of three elements of "interface{ SomeMethod() }" and as such it should rather be name "someArrayOfInterfaces". Am I right?

Also, can someone give me an example, where it is desired to use such type?

Best,
Kamil

Kamil Ziemian

unread,
Feb 13, 2022, 5:38:11 PM2/13/22
to golang-nuts
"I can't see a syntactical ambiguity, though. The series of tokens `type A [ B ] C` can, AFAICT, only be parsed as an array type declaration, generics or not (if there where *two* identifiers in the brackets, it would be something else, because that could be a generic type declaration. But not with one).

So, to me, this seems like a regression. The parser should parse this as an array declaration and the type checker should output the helpful error message, that the array bounds are invalid."

Thank you. I now understood what you meant. You are much, much better that me in the realms of the compilers and parsers.

Sorry if my response are chaotic. I will try to be more systematic in answering in the future, but for a while my answers will be messy.

Best,
Kamil

Axel Wagner

unread,
Feb 13, 2022, 6:05:04 PM2/13/22
to Kamil Ziemian, golang-nuts
On Sun, Feb 13, 2022 at 11:23 PM Kamil Ziemian <kziem...@gmail.com> wrote:
"So, no, this is not something that I made up to have an example or anything like that. I thought about a couple alternative ways to do it and they all don't work for one reason or another."

Thank you for the information. Do you check if performance of generic code is good? I always want to know if there is regression in performance.

Performance does not matter in ~all cases I'm concerned with so far.

I see no reason why performance would suffer for my case, though, as it currently uses interfaces and reflect. If anything, performance should improve (even if calls are still indirect) as I can completely remove reflect and remove some of the type assertions.

There are certainly cases where performance will suffer, when compared to generated code for a specific types, FWIW. It's just that they are not what I'm talking about here.

"FWIW, here is code that assigns to varSI in two ways:  https://go.dev/play/p/ypj6rQbpBBl"

From what I understand "type someInterface [3]interface{ SomeMethod() }" define interface array of three elements of "interface{ SomeMethod() }" and as such it should rather be name "someArrayOfInterfaces". Am I right?

Also, can someone give me an example, where it is desired to use such type?

Best,
Kamil
niedziela, 13 lutego 2022 o 17:44:30 UTC+1 jake...@gmail.com napisał(a):
On Friday, February 11, 2022 at 10:02:42 AM UTC-5 kziem...@gmail.com wrote:
I'm seriously lost here. Code below works in both Go 1.17 and Go 1.18beta2

> package main
>
> import "fmt"
>
> type someInterface[3] interface {
>         SomeMethod()
> }
>
> func main() {
>         var varSI someInterface
>
>         fmt.Printf("varSI value: %v\n", varSI)
>         fmt.Printf("varSI type:  %T\n", varSI)
> }

and give in both cases result
> varSI value: [<nil> <nil> <nil>]
> varSI type:  main.someInterface

I didn't find any way to assign some new value to "varSI", but this is already disturbing to me.

FWIW, here is code that assigns to varSI in two ways:  https://go.dev/play/p/ypj6rQbpBBl
Note that running this code in the playground will reformat ' type someInterface[3] interface' to the proper ' type someInterface [3]interface'. This is not a change in meaning, just a clarifying white space change made by `go fmt`.

--
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.
Reply all
Reply to author
Forward
Message has been deleted
0 new messages