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
Copy file name to clipboardExpand all lines: docs/docs/reference/changed-features/structural-types-spec.md
+25-4
Original file line number
Diff line number
Diff line change
@@ -100,12 +100,19 @@ conversion that can turn `v` into a `Selectable`, and the selection methods coul
100
100
valb: { defput(x: String):Unit } = a // error
101
101
b.put("abc") // looks for a method with a `String` parameter
102
102
```
103
-
The second to last line is not well-typed, since the erasure of the parameter type of `put` in class `Sink` is `Object`, but the erasure of `put`'s parameter in the type of `b` is `String`. This additional condition is necessary, since we will have to resort to reflection to call a structural member like `put` in the type of `b` above. The condition ensures that the statically known parameter types of the refinement correspond up to erasure to the parameter types of the selected call target at runtime.
104
-
105
-
The usual reflection dispatch algorithms need to know exact erased parameter types. For instance, if the example above would typecheck, the call
103
+
The second to last line is not well-typed,
104
+
since the erasure of the parameter type of `put` in class `Sink` is `Object`,
105
+
but the erasure of `put`'s parameter in the type of `b` is `String`.
106
+
This additional condition is necessary, since we will have to resort
107
+
to some (as yet unknown) form of reflection to call a structural member
108
+
like `put` in the type of `b` above. The condition ensures that the statically
109
+
known parameter types of the refinement correspond up to erasure to the
110
+
parameter types of the selected call target at runtime.
111
+
112
+
Most reflection dispatch algorithms need to know exact erased parameter types. For instance, if the example above would typecheck, the call
106
113
`b.put("abc")` on the last line would look for a method `put` in the runtime type of `b` that takes a `String` parameter. But the `put` method is the one from class `Sink`, which takes an `Object` parameter. Hence the call would fail at runtime with a `NoSuchMethodException`.
107
114
108
-
One might hope for a "more intelligent" reflexive dispatch algorithm that does not require exact parameter type matching. Unfortunately, this can always run into ambiguities. For instance, continuing the example above, we might introduce a new subclass `Sink1` of `Sink` and change the definition of `a` as follows:
115
+
One might hope for a "more intelligent" reflexive dispatch algorithm that does not require exact parameter type matching. Unfortunately, this can always run into ambiguities, as long as overloading is a possibility. For instance, continuing the example above, we might introduce a new subclass `Sink1` of `Sink` and change the definition of `a` as follows:
@@ -116,6 +123,20 @@ conversion that can turn `v` into a `Selectable`, and the selection methods coul
116
123
types `Object` and `String`, respectively. Yet dynamic dispatch still needs to go
117
124
to the first `put` method, even though the second looks like a better match.
118
125
126
+
For the cases where we can in fact implement reflection without knowing precise parameter types (for instance if static overloading is replaced by dynamically dispatched multi-methods), there is an escape hatch. For types that extend `scala.Selectable.WithoutPreciseParameterTypes` the signature check is omitted. Example:
0 commit comments