-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
spec: provide some way to refer to a generic function without instantiation #52654
Comments
Related, #46477 |
CC @griesemer |
A variable to which an uninstantiated generic functions is assigned would need generic function type. Presumably a different generic function (with the same signature) could be assigned to that variable. One would need to be able to instantiate and invoke the generic function stored in that variable. I'm not sure that we know how to do this (if we can, we could probably also have type parameters on methods). I think the spec changes and type checking would be fairly straight-forward; the problems seem to be on the implementation/translation side. An alias mechanism for functions might be more tenable, but we don't have anything like this yet. |
How would: var Clip = slices.Clip
func init() {
impl := os.Getenv("IMPLEMENTATION")
if impl != "" {
var ok bool
Clip, ok = implementations[impl]
if !ok {
panic(fmt.Errorf("Implementation %q not found", impl))
}
}
} Compile ? I think using this instead is clearer and fixes most of the complexity issues: const Clip = slices.Clip |
A function declaration is already effectively a constant declaration with function value, except that we use func Clip = slices.Clip (same effect but making it clear that we're talking about a function). So this would be a function alias declaration. |
@griesemer Actually, the general concept of function aliases with the syntax you propose would be useful for non generic functions as well. So I am in favor of this. |
Function aliases would also be useful for fixes like in CL 211617.
Calls to
It would be nice to be able to do
In which case |
This also appears to impact type aliases which makes it seem like it's not possible to type alias generic types. https://go.dev/play/p/HwjOUsIfmhq I'll get this error when I attempt to run the code: package main
import "fmt"
type A[T any] struct {
V T
}
func (a *A[T]) Value() T {
return a.V
}
type B = A
func main() {
a := &B[int]{V: 2}
fmt.Println(a.Value())
}
|
I was searching for a solution to assign a generic type struct to a variable defined on the package level but without instantiating the generic struct with a concrete type, but it seems like that this is not really possible at the moment. This would be needed for example when we would like to instantiate a new struct only once like in the singleton pattern. The most straightforward way would be to guard the struct instantiation with a local variable which holds the generic struct type. But this unfortunately is not possible. type node[T any] struct {
data T
next *node[T]
}
var once sync.Once
var n = node /// <== error: cannot use generic type without instantiation.
func NewNode[T any](data T) *node[T] {
once.Do(func() {
n = &node[T]{
data: data,
next: &node[T]{},
}
})
return n
} |
FWIW I found this issue because I'm genuinely curious about use-cases for this that are not solved by the function-alias idea discussed above. I understand why we don't allow it (yet) and it seems the primary blocker for having generic methods to me. But I'd be interested in use cases for the feature of allowing to pass around uninstantiated functions/types itself. @esimov In your code, what would this do? func main() {
n1 := yourpkg.NewNode(42)
n2 := yourpkg.NewNode("foobar")
fmt.Printf("%T, %T, %#v, %#v", n1, n2, n1, n2)
} |
The motivation behind type aliases was the ability to refer under a new name to a thing that exists elsewhere. Prior to generics, functions can be easily re-referred to using assignment:
However, doing the same thing with a generic function fails with error message "cannot use generic function F without instantiation". It is possible to define a wrapper function, but that requires copy/pasting the entire function signature.
It'd be nice if the plain assignment worked.
I understand that this probably raises non-trivial spec difficulties. I just wanted to flag it as a useful thing.
I imagine this is a dupe, but I couldn't find it.
cc @ianlancetaylor @dsnet
The text was updated successfully, but these errors were encountered: