Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go2go: anonymous func with generics #39632

Open
mattn opened this issue Jun 17, 2020 · 10 comments
Open

cmd/go2go: anonymous func with generics #39632

mattn opened this issue Jun 17, 2020 · 10 comments
Assignees
Milestone

Comments

@mattn
Copy link
Member

@mattn mattn commented Jun 17, 2020

Anonymous function with generics does not work.

What did you do?

https://go2goplay.golang.org/p/5DSE8QCPltv

package main

import (
    "fmt"
)

func main() {
    x := func(type T interface{type int, string}) (v []T) T {
        max := v[0]
        for _, vv := range v {
            if vv > max {
                max = vv
            }
        }
        return max
    }
    fmt.Println(x([]int{1, 2, 3}))
    fmt.Println(x([]string{"bar", "foo"}))
}

What did you expect to see?

Anonymous function x works well.

What did you see instead?

Compilation error

I'm not sure the spec well but I hope this work.

@mattn mattn changed the title go2:go: anonymous func with generics go2go: anonymous func with generics Jun 17, 2020
@fhs
Copy link
Contributor

@fhs fhs commented Jun 17, 2020

This is the example with the syntax fixed: https://go2goplay.golang.org/p/5DSE8QCPltv
The correct syntax is:

...
    x := func(type T interface{type int, string}) (v []T) T {
...

The error:

prog.go:8:14: function type must have no type parameters
@ianlancetaylor ianlancetaylor changed the title go2go: anonymous func with generics cmd/go2go: anonymous func with generics Jun 17, 2020
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Jun 17, 2020
@mattn
Copy link
Member Author

@mattn mattn commented Jun 17, 2020

@fhs Thanks. Updated summary.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jun 17, 2020

CC @griesemer

My first take on this is that this is a bad error message from the parser. At least at the moment, generic function literals are not supported. It might be nice to support them just for orthogonality. I don't see a convincing reason why we need them, but I also don't see a convincing reason why we can't implement them.

That said, even if we fix the parser and type checker to handle them, they won't be supported by the translation tool.

@griesemer
Copy link
Contributor

@griesemer griesemer commented Jun 17, 2020

Sure, it is easy to accept type parameters in function literal syntax.

Edited: The parser already accepts type parameters in function literals, but then reports an error (that error could perhaps be clearer). For the reasons discussed below we had decided that it's not super useful to permit generic function literals.

@bcmills
Copy link
Member

@bcmills bcmills commented Jun 17, 2020

In this example, since x is a variable in local scope, it should be valid to use as a value.

What would it mean to pass x to some other function as a value of type interface{}? (For example, what would reflect.TypeOf(x) report?)

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Jun 18, 2020

I agree with @bcmills that this does seem fairly problematic. I think the only thing you could do with a generic function literal is instantiate it or call it. That's not completely useless...but it's almost entirely useless.

@dolmen
Copy link

@dolmen dolmen commented Jun 24, 2020

Function literals stored in variables are currently the only way to have function-scoped functions.

I often use function-scoped function variables to reduce code redundancy without polluting the package scope. I would use macros instead if we had that.

Generics are kind of strongly typed macros. I would be sad if I couldn't use generics to define a function inside a function.

@bcmills
Copy link
Member

@bcmills bcmills commented Jun 24, 2020

@dolmen, it would arguably be more consistent to allow a function declaration at local scope, which could then be parameterized. (A function declaration — unlike a function literal — is not a value, so the questions about the type of that value would be moot.)

@leaanthony
Copy link

@leaanthony leaanthony commented Sep 1, 2020

I just encountered this issue and wondering if there has been any movement on this?

My use case is fairly simple: Receive a function that transforms the data given to it and returns the result. My attempt is here:
https://go2goplay.golang.org/p/_JbH_7uPrTX

Is there a workaround for this scenario?

EDIT: I just got this working. Hopefully this will help others: https://go2goplay.golang.org/p/qpZOGSAwxEG

@griesemer
Copy link
Contributor

@griesemer griesemer commented Sep 1, 2020

Yes, that's one way to solve this. Btw., here's the updated example code: https://go2goplay.golang.org/p/mUWfsZPHs5h (now working with the latest type parameter syntax).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
7 participants
You can’t perform that action at this time.