You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ponyc PR #5974 adds type argument inference for generic method and
constructor calls. The tutorial's generics overview now covers the
feature: when it applies, how it interacts with type parameter defaults,
and the cases where explicit type arguments are still required.
Copy file name to clipboardExpand all lines: docs/generics/index.md
+50-1Lines changed: 50 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -25,7 +25,7 @@ The first thing to note here is that the `Foo` class now takes a type parameter
25
25
26
26
In this case, the name is `A`, the constraint is `Any` and the reference capability is `val`. `Any` is used to mean that the type can be any type - it is not constrained. The remainder of the class definition replaces `U32` with the type name `A`.
27
27
28
-
The user of the class must provide a type when referencing the class name. This is done when creating it:
28
+
The user of the class provides a type when referencing the class name, or lets the compiler [infer it from the arguments](#type-argument-inference). Here the type is provided explicitly:
29
29
30
30
```pony
31
31
--8<--
@@ -69,3 +69,52 @@ Methods can be generic too. They are defined in the same way as normal methods b
69
69
This example shows a constraint other than `Any`. The `Stringable` type is any type with a `string()` method to convert to a `String`.
70
70
71
71
These examples show the basic idea behind generics and how to use them. Real world usage gets quite a bit more complex and the following sections will dive deeper into how to use them.
72
+
73
+
## Type Argument Inference
74
+
75
+
When each type argument can be determined from the arguments at the call site, you can omit the type arguments. The generic methods example above includes explicit type arguments:
76
+
77
+
```pony
78
+
--8<-- "generics-generic-methods.pony:7:7"
79
+
```
80
+
81
+
With inference, `A` resolves to `U32` from the argument `U32(10)`, so the type argument can be omitted:
The argument is `U32(10)` rather than the bare `10` from the explicit example — a bare integer literal defaults to `USize`, so `Foo.bar(10)` would resolve `A` to `USize`.
88
+
89
+
The same applies to constructor calls. The `Foo` class from earlier can be constructed without writing the type argument:
When a type parameter has a default and the argument fits the default type, the default is kept. When the argument does not fit, the inferred type replaces the default:
In the first line, `42` fits `USize` (the default), so `A` stays `USize`. In the second line, `F32(1.5)` does not fit `USize`, so `A` becomes `F32`.
108
+
109
+
### When inference does not apply
110
+
111
+
At least one argument must determine each type parameter. When inference fails, the compiler reports an error — write the type arguments explicitly to resolve it. Cases where inference does not apply:
112
+
113
+
- The type parameter does not appear in any parameter type (it only appears in the return type, for example).
114
+
- The argument at the determining position is an array literal or lambda whose own type depends on the type parameter being inferred. This includes type parameters that appear only in a lambda's result type.
115
+
- The parameter type refers to the type parameter through a type alias.
116
+
- The parameter type is a union.
117
+
- The argument is passed with the `where` keyword (named-only arguments).
118
+
- A generic method is called on a type whose own type parameters use defaults and are written without type arguments — add explicit type arguments to either the type or the method.
119
+
120
+
You can always write the type arguments explicitly — inference is a convenience, not a requirement.
0 commit comments