github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/typeparams/example/generic-go-types.md (about)

     1  <!-- To regenerate the readme, run: -->
     2  <!-- go run golang.org/x/example/gotypes@latest generic-go-types.md -->
     3  
     4  # Updating tools to support type parameters.
     5  
     6  This guide is maintained by Rob Findley (`rfindley@google.com`).
     7  
     8  **status**: this document is currently a work-in-progress. See
     9  [golang/go#50447](https://go.dev/issues/50447) for more details.
    10  
    11  %toc
    12  
    13  # Introduction
    14  
    15  With Go 1.18, Go now supports generic programming via type parameters. This
    16  document is intended to serve as a guide for tool authors that want to update
    17  their tools to support the new language constructs introduced for generic Go.
    18  
    19  This guide assumes some knowledge of the language changes to support generics.
    20  See the following references for more information:
    21  
    22  - The [original proposal](https://go.dev/issue/43651) for type parameters.
    23  - The [addendum for type sets](https://go.dev/issue/45346).
    24  - The [latest language specfication](https://tip.golang.org/ref/spec) (still in-progress as of 2021-01-11).
    25  - The proposals for new APIs in
    26    [go/token and go/ast](https://go.dev/issue/47781), and in
    27    [go/types](https://go.dev/issue/47916).
    28  
    29  It also assumes existing knowledge of `go/ast` and `go/types`. If you're just
    30  getting started,
    31  [x/example/gotypes](https://github.com/golang/example/tree/master/gotypes) is
    32  a great introduction (and was the inspiration for this guide).
    33  
    34  # Summary of new language features and their APIs
    35  
    36  While generic Go programming is a large change to the language, at a high level
    37  it introduces only a few new concepts. Specifically, we can break down our
    38  discussion into the following three broad categories. In each category, the
    39  relevant new APIs are listed (some constructors and getters/setters may be
    40  elided where they are trivial).
    41  
    42  **Generic types**. Types and functions may be _generic_, meaning their
    43  declaration has a non-empty _type parameter list_: as in `type  List[T any]
    44  ...` or `func f[T1, T2 any]() { ... }`. Type parameter lists define placeholder
    45  types (_type parameters_), scoped to the declaration, which may be substituted
    46  by any type satisfying their corresponding _constraint interface_ to
    47  _instantiate_ a new type or function.
    48  
    49  Generic types may have methods, which declare `receiver type parameters` via
    50  their receiver type expression: `func (r T[P1, ..., PN]) method(...) (...)
    51  {...}`.
    52  
    53  _New APIs_:
    54   - The field `ast.TypeSpec.TypeParams` holds the type parameter list syntax for
    55     type declarations.
    56   - The field `ast.FuncType.TypeParams` holds the type parameter list syntax for
    57     function declarations.
    58   - The type `types.TypeParam` is a `types.Type` representing a type parameter.
    59     On this type, the `Constraint` and `SetConstraint` methods allow
    60     getting/setting the constraint, the `Index` method returns the index of the
    61     type parameter in the type parameter list that declares it, and the `Obj`
    62     method returns the object declared in the declaration scope for the type
    63     parameter (a `types.TypeName`).
    64   - The type `types.TypeParamList` holds a list of type parameters.
    65   - The method `types.Named.TypeParams` returns the type parameters for a type
    66     declaration.
    67   - The method `types.Named.SetTypeParams` sets type parameters on a defined
    68     type.
    69   - The function `types.NewSignatureType` creates a new (possibly generic)
    70     signature type.
    71   - The method `types.Signature.RecvTypeParams` returns the receiver type
    72     parameters for a method.
    73   - The method `types.Signature.TypeParams` returns the type parameters for
    74     a function.
    75  
    76  **Constraint Interfaces**: type parameter constraints are interfaces, expressed
    77  via an interface type expression. Interfaces that are only used in constraint
    78  position are permitted new embedded elements composed of tilde expressions
    79  (`~T`) and unions (`A | B | ~C`). The new builtin interface type `comparable`
    80  is implemented by types for which `==` and `!=` are valid. As a special case,
    81  the `interface` keyword may be omitted from constraint expressions if it may be
    82  implied (in which case we say the interface is _implicit_).
    83  
    84  _New APIs_:
    85   - The constant `token.TILDE` is used to represent tilde expressions as an
    86     `ast.UnaryExpr`.
    87   - Union expressions are represented as an `ast.BinaryExpr` using `|`. This
    88     means that `ast.BinaryExpr` may now be both a type and value expression.
    89   - The method `types.Interface.IsImplicit` reports whether the `interface`
    90     keyword was elided from this interface.
    91   - The method `types.Interface.MarkImplicit` marks an interface as being
    92     implicit.
    93   - The method `types.Interface.IsComparable` reports whether every type in an
    94     interface's type set is comparable.
    95   - The method `types.Interface.IsMethodSet` reports whether an interface is
    96     defined entirely by its methods (has no _specific types_).
    97   - The type `types.Union` is a type that represents an embedded union
    98     expression in an interface. May only appear as an embedded element in
    99     interfaces.
   100   - The type `types.Term` represents a (possibly tilde) term of a union.
   101  
   102  **Instantiation**: generic types and functions may be _instantiated_ to create
   103  non-generic types and functions by providing _type arguments_ (`var x T[int]`).
   104  Function type arguments may be _inferred_ via function arguments, or via
   105  type parameter constraints.
   106  
   107  _New APIs_:
   108   - The type `ast.IndexListExpr` holds index expressions with multiple indices,
   109     as occurs in instantiation expressions with multiple type arguments, or in
   110     receivers with multiple type parameters.
   111   - The function `types.Instantiate` instantiates a generic type with type arguments.
   112   - The type `types.Context` is an opaque instantiation context that may be
   113     shared to reduce duplicate instances.
   114   - The field `types.Config.Context` holds a shared `Context` to use for
   115     instantiation while type-checking.
   116   - The type `types.TypeList` holds a list of types.
   117   - The type `types.ArgumentError` holds an error associated with a specific
   118     argument index. Used to represent instantiation errors.
   119   - The field `types.Info.Instances` maps instantiated identifiers to information
   120     about the resulting type instance.
   121   - The type `types.Instance` holds information about a type or function
   122     instance.
   123   - The method `types.Named.TypeArgs` reports the type arguments used to
   124     instantiate a named type.
   125  
   126  # Examples
   127  
   128  The following examples demonstrate the new APIs above, and discuss their
   129  properties. All examples are runnable, contained in subdirectories of the
   130  directory holding this README.
   131  
   132  ## Generic types
   133  
   134  ### Type parameter lists
   135  
   136  Suppose we want to understand the generic library below, which defines a generic
   137  `Pair`, a constraint interface `Constraint`, and a generic function `MakePair`.
   138  
   139  %include findtypeparams/main.go input -
   140  
   141  We can use the new `TypeParams` fields in `ast.TypeSpec` and `ast.FuncType` to
   142  access the syntax of the type parameter list. From there, we can access type
   143  parameter types in at least three ways:
   144   - by looking up type parameter definitions in `types.Info`
   145   - by calling `TypeParams()` on `types.Named` or `types.Signature`
   146   - by looking up type parameter objects in the declaration scope. Note that
   147     there now may be a scope associated with an `ast.TypeSpec` node.
   148  
   149  %include findtypeparams/main.go print -
   150  
   151  This program produces the following output. Note that not every type spec has
   152  a scope.
   153  
   154  %include findtypeparams/main.go output -
   155  
   156  ### Methods on generic types
   157  
   158  **TODO**
   159  
   160  ## Constraint Interfaces
   161  
   162  ### New interface elements
   163  
   164  **TODO**
   165  
   166  ### Implicit interfaces
   167  
   168  **TODO**
   169  
   170  ### Type sets
   171  
   172  **TODO**
   173  
   174  ## Instantiation
   175  
   176  ### Finding instantiated types
   177  
   178  **TODO**
   179  
   180  ### Creating new instantiated types
   181  
   182  **TODO**
   183  
   184  ### Using a shared context
   185  
   186  **TODO**
   187  
   188  # Updating tools while building at older Go versions
   189  
   190  In the examples above, we can see how a lot of the new APIs integrate with
   191  existing usage of `go/ast` or `go/types`. However, most tools still need to
   192  build at older Go versions, and handling the new language constructs in-line
   193  will break builds at older Go versions.
   194  
   195  For this purpose, the `x/exp/typeparams` package provides functions and types
   196  that proxy the new APIs (with stub implementations at older Go versions).
   197  **NOTE**: does not yet exist -- see
   198  [golang/go#50447](https://go.dev/issues/50447) for more information.
   199  
   200  # Further help
   201  
   202  If you're working on updating a tool to support generics, and need help, please
   203  feel free to reach out for help in any of the following ways:
   204   - Via the [golang-tools](https://groups.google.com/g/golang-tools) mailing list.
   205   - Directly to me via email (`rfindley@google.com`).
   206   - For bugs, you can [file an issue](https://github.com/golang/go/issues/new/choose).