-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Open
Labels
ProposalProposal-HoldTypeInferenceIssue is related to generic type inferenceIssue is related to generic type inference
Milestone
Description
Author background
- Experienced Go Engineer, over 8 years experience
- Rust, C, Zig
Related proposals
- I am not sure if this idea has been proposed before
- This idea does not effect error handling
- This proposal is about generics
Proposal
- The proposed change is to allow for better type inference when working with generic referencing interfaces
- This proposal helps anyone who uses generics in a factory or generator pattern. Additionally, anyone writing data structures
- The purpose of this proposal is to allow for interface types referencing generics
type MyInterface[T] interface { *T }to be inferred better - The ability to infer types for interfaces targeting a pointer value of a generic type
- Allow for pointer types of structs to be inferred more easily by Golang generics
- The change is backward compatible
- This change does not affect existing features
- This change is not a performance improvement
Costs
- This would not affect the learning scale of Go as it's a deeper subject. For more experienced Engineers, it should make generics more simple to work with
- More work on the compiler to perform stronger inferring
- gopls would be affected
- Negligible, but a slight performance cost
- No runtime cost
- A use-case for this feature is available here
- No prototype is available for the implementation of this feature
Example - Current Requirement
package main
import (
"strconv"
)
func main() {
c := New[testType]()
c.Txn(func(txn Txn[testType, *testType]) {
txn.New(testType{val: "1"})
txn.Update("0", func(tt testType) (out testType) {
return
})
})
}
func New[T any, U Value[T]]() *Controller[T, U] {
var c Controller[T, U]
c.m = make(map[string]T)
return &c
}
type Controller[T any, U Value[T]] struct {
idx int
m map[string]T
}
func (c *Controller[T, U]) Txn(fn func(Txn[T, U])) {
var txn Txn[T, U]
txn.c = c
fn(txn)
}
type Txn[T any, U Value[T]] struct {
c *Controller[T, U]
}
func (txn *Txn[T, U]) New(t T) {
u := U(&t)
u.SetID(strconv.Itoa(txn.c.idx))
txn.c.idx++
}
func (txn *Txn[T, U]) Update(key string, fn func(T) T) {
v, ok := txn.c.m[key]
if !ok {
return
}
txn.c.m[key] = fn(v)
}
type testType struct {
id string
val string
}
func (t *testType) SetID(id string) {
t.id = id
}
type Value[T any] interface {
*T
SetID(string)
}Example - Proposal
package main
import (
"strconv"
)
func main() {
c := New[testType]()
c.Txn(func(txn Txn[testType]) {
txn.New(testType{val: "1"})
txn.Update("0", func(tt testType) (out testType) {
return
})
})
}
func New[T any, U Value[T]]() *Controller[T, U] {
var c Controller[T, U]
c.m = make(map[string]T)
return &c
}
type Controller[T any, U Value[T]] struct {
idx int
m map[string]T
}
func (c *Controller[T, U]) Txn(fn func(Txn[T, U])) {
var txn Txn[T, U]
txn.c = c
fn(txn)
}
type Txn[T any, U Value[T]] struct {
c *Controller[T, U]
}
func (txn *Txn[T, U]) New(t T) {
u := U(&t)
u.SetID(strconv.Itoa(txn.c.idx))
txn.c.idx++
}
func (txn *Txn[T, U]) Update(key string, fn func(T) T) {
v, ok := txn.c.m[key]
if !ok {
return
}
txn.c.m[key] = fn(v)
}
type testType struct {
id string
val string
}
func (t *testType) SetID(id string) {
t.id = id
}
type Value[T any] interface {
*T
SetID(string)
}dhalman-milc, marlonjames71, claudiofelber and eonianmonkDeedleFake
Metadata
Metadata
Assignees
Labels
ProposalProposal-HoldTypeInferenceIssue is related to generic type inferenceIssue is related to generic type inference
Type
Projects
Status
Hold