Skip to content

Commit 951312f

Browse files
committed
Split Structural Types in 2 pages
1 parent 1e67d21 commit 951312f

File tree

2 files changed

+101
-99
lines changed

2 files changed

+101
-99
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
layout: doc-page
3+
title: "Programmatic Structural Types - More Details"
4+
---
5+
6+
## Syntax
7+
8+
```
9+
SimpleType ::= ... | Refinement
10+
Refinement ::= ‘{’ RefineStatSeq ‘}’
11+
RefineStatSeq ::= RefineStat {semi RefineStat}
12+
RefineStat ::= ‘val’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl
13+
```
14+
15+
## Implementation of structural types
16+
17+
The standard library defines a trait `Selectable` in the package
18+
`scala`, defined as follows:
19+
20+
```scala
21+
trait Selectable extends Any {
22+
def selectDynamic(name: String): Any
23+
def selectDynamicMethod(name: String, paramClasses: ClassTag[_]*): Any =
24+
new UnsupportedOperationException("selectDynamicMethod")
25+
}
26+
```
27+
28+
An implementation of `Selectable` that relies on Java reflection is
29+
available in the standard library: `scala.reflect.Selectable`. Other
30+
implementations can be envisioned for platforms where Java reflection
31+
is not available.
32+
33+
`selectDynamic` takes a field name and returns the value associated
34+
with that name in the `Selectable`. Similarly, `selectDynamicMethod`
35+
takes a method name, `ClassTag`s representing its parameters types and
36+
will return the function that matches this
37+
name and parameter types.
38+
39+
Given a value `v` of type `C { Rs }`, where `C` is a class reference
40+
and `Rs` are refinement declarations, and given `v.a` of type `U`, we
41+
consider three distinct cases:
42+
43+
- If `U` is a value type, we map `v.a` to the equivalent of:
44+
```scala
45+
v.a
46+
--->
47+
(v: Selectable).selectDynamic("a").asInstanceOf[U]
48+
```
49+
50+
- If `U` is a method type `(T1, ..., Tn) => R` with at most 7
51+
parameters and it is not a dependent method type, we map `v.a` to
52+
the equivalent of:
53+
```scala
54+
v.a
55+
--->
56+
(v: Selectable).selectDynamic("a", CT1, ..., CTn).asInstanceOf[(T1, ..., Tn) => R]
57+
```
58+
59+
- If `U` is neither a value nor a method type, or a dependent method
60+
type, or has more than 7 parameters, an error is emitted.
61+
62+
We make sure that `r` conforms to type `Selectable`, potentially by
63+
introducing an implicit conversion, and then call either
64+
`selectDynamic` or `selectMethodDynamic`, passing the name of the
65+
member to access and the class tags of the formal parameters, in the
66+
case of a method call. These parameters could be used to disambiguate
67+
one of several overload variants in the future, but overloads are not
68+
supported in structural types at the moment.
69+
70+
## Limitations of structural types
71+
72+
- Methods with more than 7 formal parameters cannot be called via
73+
structural call.
74+
- Dependent methods cannot be called via structural call.
75+
- Overloaded methods cannot be called via structural call.
76+
- Refinements do not handle polymorphic methods.
77+
78+
## Differences with Scala 2 structural types
79+
80+
- Scala 2 supports structural types by means of Java reflection. Unlike
81+
Scala 3, structural calls do not rely on a mechanism such as
82+
`Selectable`, and reflection cannot be avoided.
83+
- In Scala 2, structural calls to overloaded methods are possible.
84+
- In Scala 2, mutable `var`s are allowed in refinements. In Scala 3,
85+
they are no longer allowed.
86+
87+
## Migration
88+
89+
Receivers of structural calls need to be instances of `Selectable`. A
90+
conversion from `Any` to `Selectable` is available in the standard
91+
library, in `scala.reflect.Selectable.reflectiveSelectable`. This is
92+
similar to the implementation of structural types in Scala 2.
93+
94+
## Reference
95+
96+
For more info, see [Rethink Structural
97+
Types](https://github.com/lampepfl/dotty/issues/1886).

docs/docs/reference/changed/structural-types.md

Lines changed: 4 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,6 @@ layout: doc-page
33
title: "Programmatic Structural Types"
44
---
55

6-
## Syntax
7-
8-
```
9-
SimpleType ::= ... | Refinement
10-
Refinement ::= ‘{’ RefineStatSeq ‘}’
11-
RefineStatSeq ::= RefineStat {semi RefineStat}
12-
RefineStat ::= ‘val’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl
13-
```
14-
15-
## Motivation
16-
176
Some usecases, such as modelling database access, are more awkward in
187
statically typed languages than in dynamically typed languages: With
198
dynamically typed languages, it's quite natural to model a row as a
@@ -38,92 +27,15 @@ simple dot notation in dynamic contexts without losing the advantages
3827
of static typing. They allow developers to use dot notation and
3928
configure how fields and methods should be resolved.
4029

41-
An [example](#example) is available at the end of this document.
42-
43-
## Implementation of structural types
44-
45-
The standard library defines a trait `Selectable` in the package
46-
`scala`, defined as follows:
47-
48-
```scala
49-
trait Selectable extends Any {
50-
def selectDynamic(name: String): Any
51-
def selectDynamicMethod(name: String, paramClasses: ClassTag[_]*): Any =
52-
new UnsupportedOperationException("selectDynamicMethod")
53-
}
54-
```
55-
56-
An implementation of `Selectable` that relies on Java reflection is
57-
available in the standard library: `scala.reflect.Selectable`. Other
58-
implementations can be envisioned for platforms where Java reflection
59-
is not available.
60-
61-
`selectDynamic` takes a field name and returns the value associated
62-
with that name in the `Selectable`. Similarly, `selectDynamicMethod`
63-
takes a method name, `ClassTag`s representing its parameters types and
64-
will return the function that matches this
65-
name and parameter types.
66-
67-
Given a value `v` of type `C { Rs }`, where `C` is a class reference
68-
and `Rs` are refinement declarations, and given `v.a` of type `U`, we
69-
consider three distinct cases:
70-
71-
- If `U` is a value type, we map `v.a` to the equivalent of:
72-
```scala
73-
v.a
74-
--->
75-
(v: Selectable).selectDynamic("a").asInstanceOf[U]
76-
```
77-
78-
- If `U` is a method type `(T1, ..., Tn) => R` with at most 7
79-
parameters and it is not a dependent method type, we map `v.a` to
80-
the equivalent of:
81-
```scala
82-
v.a
83-
--->
84-
(v: Selectable).selectDynamic("a", CT1, ..., CTn).asInstanceOf[(T1, ..., Tn) => R]
85-
```
86-
87-
- If `U` is neither a value nor a method type, or a dependent method
88-
type, or has more than 7 parameters, an error is emitted.
30+
## Example
8931

90-
We make sure that `r` conforms to type `Selectable`, potentially by
91-
introducing an implicit conversion, and then call either
92-
`selectDynamic` or `selectMethodDynamic`, passing the name of the
93-
member to access and the class tags of the formal parameters, in the
94-
case of a method call. These parameters could be used to disambiguate
95-
one of several overload variants in the future, but overloads are not
96-
supported in structural types at the moment.
32+
<script src="https://scastie.scala-lang.org/Duhemm/HOZFKyKLTs294XOSYPU5Fw.js"></script>
9733

9834
## Extensibility
9935

10036
New instances of `Selectable` can be defined to support means of
10137
access other than Java reflection, which would enable usages such as
102-
the database access example given in the "Motivation" section.
103-
104-
## Limitations of structural types
105-
106-
- Methods with more than 7 formal parameters cannot be called via
107-
structural call.
108-
- Dependent methods cannot be called via structural call.
109-
- Overloaded methods cannot be called via structural call.
110-
- Refinement do not handle polymorphic methods.
111-
112-
## Differences with Scala 2 structural types
113-
114-
- Scala 2 supports structural types by means of Java reflection. Unlike
115-
Scala 3, structural calls do not rely on a mechanism such as
116-
`Selectable`, and reflection cannot be avoided.
117-
- In Scala 2, structural calls to overloaded methods are possible.
118-
- In Scala 2, mutable `var`s are allowed in refinements. In Scala 3,
119-
they are no longer allowed.
120-
121-
## Migration
122-
123-
Receivers of structural calls need to be instances of `Selectable`. A
124-
conversion from `Any` to `Selectable` is available in the standard
125-
library, in `scala.reflect.Selectable.reflectiveSelectable`. This is
126-
similar to the implementation of structural types in Scala 2.
38+
the database access example given at the beginning of this document.
12739

12840
## Relation with `scala.Dynamic`
12941

@@ -146,11 +58,4 @@ differences.
14658
additional argument. `Dynamic` comes with `applyDynamic` and
14759
`updateDynamic` methods, which take actual argument values.
14860

149-
## Example
150-
151-
<script src="https://scastie.scala-lang.org/Duhemm/HOZFKyKLTs294XOSYPU5Fw.js"></script>
152-
153-
## Reference
154-
155-
For more info, see [Rethink Structural
156-
Types](https://github.com/lampepfl/dotty/issues/1886).
61+
[More details](structural-types-spec.html)

0 commit comments

Comments
 (0)