Skip to content

Commit 955a4e2

Browse files
update README.md
1 parent 7406c86 commit 955a4e2

File tree

1 file changed

+62
-9
lines changed

1 file changed

+62
-9
lines changed

README.md

Lines changed: 62 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66

77
This project provides Java annotations that enable fine-grained specification of variance for class generics, improving flexibility in generic programming.
88

9+
> **DISCLAIMER:**
10+
> This project is not intended for production use. It's an incomplete implementation with limited support for certain use cases. It should be viewed as a tool for experimenting with variance in Java.
11+
912
## Table of Contents
1013

1114
- [Installation](#installation)
@@ -92,21 +95,58 @@ Invariance means no substitution is allowed between different generic types, eve
9295
- Example: `List<Animal>` and `List<Dog>` are entirely distinct and incompatible.
9396
- This is the default in many languages, like Java's generics.
9497

98+
### New variance notions introduced in this project
99+
100+
In addition to the traditional variance constructs that exist, some novel constructs are also provided here. These are experimental variances that may or may not make sense in a functional manner, but that can be interesting to experiment with.
101+
102+
#### Depth
103+
104+
Depth refers to the extent to which subtyping relationships are valid within a type hierarchy.
105+
106+
- For **covariance**, depth determines how many levels you can move **down** in the hierarchy to find a valid subtype.
107+
- For **contravariance**, depth specifies how many levels you can move **up** for a valid subtype.
108+
109+
If we define a depth of 2:
110+
111+
- For **covariance**, starting at `Animal`, valid subtypes would include `Mammal`, `Bird`, `Dog`, `Cat`, `Sparrow`, and `Penguin` (two levels down).
112+
- For **contravariance**, starting at `Cat`, valid supertypes would include `Mammal` and `Animal` (two levels up).
113+
114+
For example, consider the following type hierarchy:
115+
116+
`Animal` ├── `Mammal` ├── `Dog`
117+
118+
If we define a depth of 1:
119+
120+
- For **covariance**, starting at `Animal`, a valid sutype would be `Mammal`, while `Dog` would be invalid since it's 2 levels down.
121+
122+
#### Side Variance
123+
124+
Side variance introduces a new concept in type relationships, where subtyping operates **sideways** rather than in the traditional **upward** or **downward** directions within a type hierarchy. This means that any classes on the same level in the hierarchy are considered valid subtypes of one another.
125+
126+
For example, onsider the types `Animal`, `Dog`, and `Cat`, where `Dog` and `Cat` are direct subtypes of `Animal`. With a side-variant `List` type:
127+
128+
- `List<Dog>` would be a subtype of `List<Cat>`.
129+
- Similarly, `List<Cat>` would be a subtype of `List<Dog>`.
130+
95131
## Usage
96132

133+
To specify variance for classes, annotate the relevant type parameters with one of the provided annotations (details on these annotations will follow). Once annotated, you can use your classes as though they conform to the specified variance. Note that your IDE's linter may flag errors if the classes are used in ways that Java does not natively support. These warnings are expected and can be safely ignored.
134+
135+
When you compile the project, a new output directory named `output_javavariance` will be created. In this directory, type arguments are erased, and the necessary casts are inserted to ensure the project runs correctly. At this stage, any previously flagged errors should no longer appear.
136+
97137
### Annotations
98138

99-
There are currently three annotations provided by this project: MyVariance, Covariant and Contravariant. With these you are able to annotate type parameters for classes in order to specify fine grained variance.
139+
There are currently three annotations provided by this project: `MyVariance`, `Covariant` and `Contravariant`. With these you are able to annotate type parameters for classes in order to specify fine grained variance.
100140

101-
### MyVariance
141+
#### MyVariance
102142

103-
MyVariance is the most customizable one, and allows you to experiment with different types of variance. With this one there are several parameters you can provide to specify what variance rules should apply:
143+
MyVariance is the most customizable one, and allows you to experiment with different types of variance. There are several parameters you can provide to specify what variance rules should apply:
104144

105-
| Parameter | Description | Possible values |
106-
| ---------- | ------------------------------- | ----------------------------------------------------------- |
107-
| `variance` | Specifies which variance to use | COVARIANT, CONTRAVARIANT, INVARIANT, BIVARIANT, SIDEVARIANT |
108-
| `depth` | How deep subtyping goes | Integer value ≥ 0 |
109-
| `strict` | Whether | `true`, `false` |
145+
| Parameter | Description | Possible values |
146+
| ---------- | ------------------------------------------------------------- | ----------------------------------------------------------- |
147+
| `variance` | Specifies which variance type to use | COVARIANT, CONTRAVARIANT, INVARIANT, BIVARIANT, SIDEVARIANT |
148+
| `depth` | How deep subtyping goes | Integer value ≥ 0 |
149+
| `strict` | Whether compilation should fail if any errors are encountered | `true`, `false` |
110150

111151
#### Covariant
112152

@@ -119,7 +159,8 @@ Covariant is a specific instance of MyVariance. It's intended to inline with the
119159

120160
```java
121161
public class ImmutableList<@Covariant T> {
122-
List<T> underlyingList = new ArrayList<>();
162+
163+
private List<T> underlyingList = new ArrayList<>();
123164

124165
public ImmutableList(Iterable<T> initial) {
125166
initial.forEach(e -> underlyingList.add(e));
@@ -185,6 +226,18 @@ class Pair<@Contravariant X, @Contravariant Y> {
185226

186227
</details>
187228

229+
### Building and running your project
230+
231+
If you are using Maven, you can compile your project with the following command:
232+
233+
```sh
234+
mvn clean compile
235+
```
236+
237+
If you are not using Maven, simply compile the project as you normally would.
238+
239+
This process will generate a new output folder named `output_javavariance`. The code within this folder is the code you should run. To execute your program, run the main file from this directory as you typically would—whether through your IDE, by using `mvn exec`, or any other method you prefer for running Java applications.
240+
188241
## Contributing
189242

190243
Pull requests and issues that aim to better the project are greatly appreciated.

0 commit comments

Comments
 (0)