proposal: Generics — Assertions and Conversions

197 views
Skip to first unread message

cxr

unread,
Sep 19, 2021, 12:20:44 AM9/19/21
to golang-nuts
```go
// Generics definitions. Keyword interface also ok, generic better.
generic MyGen(It, *St, ...) {
    // type assertions
    It.(type) int, MyInt     // only one type no need
    
    // interface assertions
    St.(interface) io.Reader // one or more
    
    // method assertions
     (St) Get() It // value receiver
    (*St) Set(It)  // pointer receiver
    
    // generic assertions
    YourGen(St, It)

    // kind assertions, lower reflect.Kind
    //St.(kind)   struct  // can by inferred
    St.F.(kind) int, uint // struct St's field F's kind
    
    // operator assertions
    It.(operator) ==
    It.(operator) +, Add(It) It // one operator and one method, method precedence
    
    // Because no operator overloading, type and kind assertions should be enough;
    // or reflect.Operator declare the operator name and the method prototype.
}

// Anonymous generics. No assertions.
generic(...) type ...
generic(...) func ...

// Anonymous generics. Inline assertions.
generic(...)
    assertions...
type ...
generic(...)
    assertions...
func ...

// Named generics.
generic Name type ...
generic Name func ...
generic Name(...) type ... // alias parameters
generic Name(...) func ... // alias parameters

// Named generics. Keyword can be omitted.
Name type ...
Name func ...
Name(...) type ... // alias parameters
Name(...) func ... // alias parameters

// Keep parameters simple and stupid.

//// Constraints or nests so ugly.
//generic(G1(C), G2(X, R)) type ...
//generic(C G1, X, R G2) func (...) M(...) (...)

// Always flat.
generic G(C, X, R) {
    G1(C)
    G2(X, R)
    G3(C, R)
}

G type ...
G func ...

// Generics all in conversions, highest precedence.
generic G(I, S) {
    I.(kind) int, uint
    S.(type) string, []byte
}

G type T struct{
    a []I
    m map[I]S
    p *(I, S)T // generic type conversion
}

G func Func(a []I, m map[I]S) (v (I, S)T) {
    v.a = a
    v.m = m
    v.p = &v
    return
}

G func (v (I, S)T) Method() (n I) {
    for _, i := range a {
        if _, ok := m[i]; ok {
            n++
        }
    }
    return
}

// Alias generic type conversion.
G type GT = (I, S)T

G type T struct{
    a []I
    m map[I]S
    p *GT
}

G func Func(a []I, m map[I]S) (v GT) {
    v.a = a
    v.m = m
    v.p = &v
    return
}

G func (v GT) Method() (n I) {
    for _, i := range a {
        if _, ok := m[i]; ok {
            n++
        }
    }
    return
}

func main() {
    a := []int{1, 2, 3}
    m := map[int]string{1: "a", 2: "b"}
    
    type t (int, string)T  // generic type converted to concrete type
    f := (int, string)Func // generic func converted to concrete func
    
    // These function calls are equivalent.
    v := f(a, m)
    v = (int, ``)Func(a, m)
    v = Func(a, m) // can by inferred
    
    v.(type) == t  // true
    
    // These invocations are equivalent.
    n := v.Method()
    n = t.Method(v)
}

generic Addable(T) {
    T.(operator) +, Add(T) T
}

Addable func Sum(a ...T) (x T) {
    for _, v := range a {
        x += v
        // or
        x = x.Add(v)
    }
    return
}

generic Graph(Node, Edge) {
    (Node) Edges() []Edge
    (Edge) Nodes() []Node
}

generic(T) type List struct {
    elem T
    next *(T)List
}
```

*CHEN Xianren*\
*2021/9/19*

Ian Lance Taylor

unread,
Sep 19, 2021, 10:43:22 PM9/19/21
to cxr, golang-nuts
Thanks, but we have an accepted proposal for adding generics to the
language: https://golang.org/s/generics-proposal.

Ian
Reply all
Reply to author
Forward
0 new messages