Skip to content

Commit 928f487

Browse files
authored
feat: remove star projection and use-site variance (#597)
### Summary of Changes There is currently no use-case for star projections and use-site variance, so they are not worth the effort to implement. Moreover, these concepts are difficult to explain.
1 parent b3d786c commit 928f487

File tree

8 files changed

+16
-71
lines changed

8 files changed

+16
-71
lines changed

docs/language/common/types.md

+2-42
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,7 @@ When we use this [class][classes] as a named type, we need to specify the value
6767

6868
In the case of positional type arguments, they are mapped to [type parameters][type-parameters] by position, i.e. the first type argument is assigned to the first [type parameter][type-parameters], the second type argument is assigned to the second [type parameter][type-parameters] and so forth.
6969

70-
If a positional type argument is used, we just write down its value. The value is either
71-
72-
- a [type projection](#type-projection), or
73-
- a [star projection](#star-projection).
70+
If a positional type argument is used, we just write down its value, which is a [type projection](#type-projection).
7471

7572
For example, if we expect a list of integers, we could use the following type:
7673

@@ -98,7 +95,7 @@ These are the syntactic elements:
9895
- A named type argument (here `T = Int`). This in turn consists of
9996
- The name of the [type parameter][type-parameters] (here `T`)
10097
- An equals sign.
101-
- The value of the type argument, which is still either a [type projection](#type-projection), or a [star projection](#star-projection).
98+
- The value of the type argument, which is still a [type projection](#type-projection).
10299
- A closing angle bracket.
103100

104101
Within a list of type arguments both positional and named type arguments can be used. However, after the first named type arguments all type arguments must be named.
@@ -136,43 +133,6 @@ SomeSpecialList<Int>
136133

137134
The value of the type argument is just another named type (here `Int`).
138135

139-
###### Use-Site Variance
140-
141-
It is also possible to set the [variance][variance] of a [type parameter][type-parameters] at the use-site, i.e. where we use the containing declaration as a named type. This is only possible, however, if we did not [specify the variance at the declaration-site][declaration-site-variance].
142-
143-
Covariance is denoted by the keyword `out`. If the variance of a [type parameter][type-parameters] is set to `out`, we can only access methods of the class that only use the [type parameter][type-parameters] in the out-position, i.e. as [results][results]. Methods that use the [type parameter][type-parameters] in the in-position, i.e. as [parameters][parameters] are hidden. Here is an example for the syntax:
144-
145-
```txt
146-
SomeSpecialList<out Int>
147-
```
148-
149-
The key element here is the keyword `out` that is added to the type argument. This essentially creates a list of integers that can be read from but that cannot be written to.
150-
151-
Contravariance is denoted by the keyword `in`. If the variance of a [type parameter][type-parameters] is set to `in`, we can only access methods of the class that only use the [type parameter][type-parameters] in the in-position, i.e. as [parameters][parameters]. Methods that use the [type parameter][type-parameters] in the out-position, i.e. as [results][results] are hidden. Here is an example of the syntax:
152-
153-
```txt
154-
SomeSpecialList<in Int>
155-
```
156-
157-
The key element here is the keyword `in` that is added to the type argument. Here we essentially create a list of integers that can be written to but not read from.
158-
159-
##### Star Projection
160-
161-
If we do not want to specify a value for a [type parameter][type-parameters] and just accept everything, we can use a _star projection_. Here is the syntax:
162-
163-
```txt
164-
SomeSpecialList<*>
165-
```
166-
167-
It consists only of the `*`, which we use as the value of the type argument.
168-
169-
The star projection is usually equivalent to the type projections
170-
171-
- `out Any?` (`Any?` is the supertype of everything), or
172-
- `in Nothing` (`Nothing` is the subtype of everything).
173-
174-
If the [type parameter][type-parameters] has [bounds][type-parameter-bounds], however, the star projection denotes that any type within the [bounds][type-parameter-bounds] is acceptable.
175-
176136
### Member Types
177137

178138
A member type is essentially the same as a [named type](#named-types) with the difference that the declaration we refer to is nested inside [classes][classes] or [enums][enums].

docs/language/common/variance.md

+7-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
**Note:** This is an advanced section. Feel free to skip it initially.
44

5-
Variance deals with the question which generic types are compatible with each other. We explain this concept using the following [class][classes]:
5+
Variance deals with the question, which generic types are compatible with each other. We explain this concept using the following [class][classes]:
66

77
```txt
88
class Stack<T>(vararg initialElements: T) {
@@ -64,20 +64,17 @@ class Stack<in T> {
6464

6565
## Specifying Variance
6666

67-
The variance of a [type parameter][type-parameters] can either be declared at its [declaration site][declaration-site-variance] or its [use site][use-site-variance]. If it is specified already at the [declaration site][declaration-site-variance], however, [use-site variance][use-site-variance] is no longer available.
67+
The variance of a [type parameter][type-parameters] can only be declared at its [declaration site][declaration-site-variance], using the syntax shown in the following table:
6868

69-
The following table sums up the syntax of [declaration-site variance][declaration-site-variance], where the [class][classes] declaration is changed, and [use-site variance][use-site-variance], where the [type arguments][type-arguments] passed by the [named type][named-types] Refer to the linked documents for more details.
70-
71-
| Desired Variance | Declaration Site | Use Site |
72-
|------------------|----------------------|----------------|
73-
| Invariant | `class Stack<T>` | `Stack<T>` |
74-
| Covariant | `class Stack<out T>` | `Stack<out T>` |
75-
| Contravariant | `class Stack<in T>` | `Stack<in T>` |
69+
| Desired Variance | Declaration Site |
70+
|------------------|----------------------|
71+
| Invariant | `class Stack<T>` |
72+
| Covariant | `class Stack<out T>` |
73+
| Contravariant | `class Stack<in T>` |
7674

7775
[types]: types.md
7876
[named-types]: types.md#named-types
7977
[type-arguments]: types.md#type-arguments
80-
[use-site-variance]: types.md#use-site-variance
8178
[parameters]: parameters.md
8279
[results]: results.md
8380
[classes]: ../stub-language/classes.md

src/language/formatting/safe-ds-formatter.ts

-8
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,6 @@ export class SafeDsFormatter extends AbstractFormatter {
173173
this.formatSdsTypeArgumentList(node);
174174
} else if (ast.isSdsTypeArgument(node)) {
175175
this.formatSdsTypeArgument(node);
176-
} else if (ast.isSdsTypeProjection(node)) {
177-
this.formatSdsTypeProjection(node);
178176
}
179177

180178
// -----------------------------------------------------------------------------
@@ -858,12 +856,6 @@ export class SafeDsFormatter extends AbstractFormatter {
858856
formatter.keyword('=').surround(oneSpace());
859857
}
860858

861-
private formatSdsTypeProjection(node: ast.SdsTypeProjection) {
862-
const formatter = this.getNodeFormatter(node);
863-
864-
formatter.property('variance').append(oneSpace());
865-
}
866-
867859
/**
868860
* Returns whether the type is considered complex and requires special formatting like placing the associated
869861
* parameter on its own line.

src/language/grammar/safe-ds.langium

+1-5
Original file line numberDiff line numberDiff line change
@@ -957,16 +957,12 @@ SdsTypeArgument returns SdsTypeArgument:
957957

958958
interface SdsTypeArgumentValue extends SdsObject {}
959959

960-
interface SdsStarProjection extends SdsTypeArgumentValue {}
961-
962960
interface SdsTypeProjection extends SdsTypeArgumentValue {
963-
variance?: string
964961
^type: SdsType
965962
}
966963

967964
SdsTypeArgumentValue returns SdsTypeArgumentValue:
968-
{SdsStarProjection} '*'
969-
| {SdsTypeProjection} variance=SdsTypeParameterVariance? ^type=SdsType
965+
{SdsTypeProjection} ^type=SdsType
970966
;
971967

972968

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
segment mySegment(
2-
x: Int < * , in Number , out Number , T = Number > ?
2+
x: Int < Number , T = Number > ?
33
) {}
44

55
// -----------------------------------------------------------------------------
66

77
segment mySegment(
8-
x: Int<*, in Number, out Number, T = Number>?
8+
x: Int<Number, T = Number>?
99
) {}
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
segment mySegment(
2-
x: Int < * , in Number , out Number , T = Number>
2+
x: Int < Number , T = Number>
33
) {}
44

55
// -----------------------------------------------------------------------------
66

77
segment mySegment(
8-
x: Int<*, in Number, out Number, T = Number>
8+
x: Int<Number, T = Number>
99
) {}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// $TEST$ no_syntax_error
22

33
segment mySegment(
4-
x: Int<*, in Number, out Number, T = Number>?
4+
x: Int<Number, T = Number>?
55
) {}
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// $TEST$ no_syntax_error
22

33
segment mySegment(
4-
x: Int<*, in Number, out Number, T = Number>
4+
x: Int<Number, T = Number>
55
) {}

0 commit comments

Comments
 (0)