From 955a4e2797ef8f8a7ae2005603648a77355886ed Mon Sep 17 00:00:00 2001 From: FelixAnthonisen Date: Sat, 7 Dec 2024 20:29:00 +0100 Subject: [PATCH] update README.md --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 9e0e74b..aeb6af3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ This project provides Java annotations that enable fine-grained specification of variance for class generics, improving flexibility in generic programming. +> **DISCLAIMER:** +> 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. + ## Table of Contents - [Installation](#installation) @@ -92,21 +95,58 @@ Invariance means no substitution is allowed between different generic types, eve - Example: `List` and `List` are entirely distinct and incompatible. - This is the default in many languages, like Java's generics. +### New variance notions introduced in this project + +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. + +#### Depth + +Depth refers to the extent to which subtyping relationships are valid within a type hierarchy. + +- For **covariance**, depth determines how many levels you can move **down** in the hierarchy to find a valid subtype. +- For **contravariance**, depth specifies how many levels you can move **up** for a valid subtype. + +If we define a depth of 2: + +- For **covariance**, starting at `Animal`, valid subtypes would include `Mammal`, `Bird`, `Dog`, `Cat`, `Sparrow`, and `Penguin` (two levels down). +- For **contravariance**, starting at `Cat`, valid supertypes would include `Mammal` and `Animal` (two levels up). + +For example, consider the following type hierarchy: + +`Animal` ├── `Mammal` ├── `Dog` + +If we define a depth of 1: + +- For **covariance**, starting at `Animal`, a valid sutype would be `Mammal`, while `Dog` would be invalid since it's 2 levels down. + +#### Side Variance + +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. + +For example, onsider the types `Animal`, `Dog`, and `Cat`, where `Dog` and `Cat` are direct subtypes of `Animal`. With a side-variant `List` type: + +- `List` would be a subtype of `List`. +- Similarly, `List` would be a subtype of `List`. + ## Usage +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. + +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. + ### Annotations -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. +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. -### MyVariance +#### MyVariance -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: +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: -| Parameter | Description | Possible values | -| ---------- | ------------------------------- | ----------------------------------------------------------- | -| `variance` | Specifies which variance to use | COVARIANT, CONTRAVARIANT, INVARIANT, BIVARIANT, SIDEVARIANT | -| `depth` | How deep subtyping goes | Integer value ≥ 0 | -| `strict` | Whether | `true`, `false` | +| Parameter | Description | Possible values | +| ---------- | ------------------------------------------------------------- | ----------------------------------------------------------- | +| `variance` | Specifies which variance type to use | COVARIANT, CONTRAVARIANT, INVARIANT, BIVARIANT, SIDEVARIANT | +| `depth` | How deep subtyping goes | Integer value ≥ 0 | +| `strict` | Whether compilation should fail if any errors are encountered | `true`, `false` | #### Covariant @@ -119,7 +159,8 @@ Covariant is a specific instance of MyVariance. It's intended to inline with the ```java public class ImmutableList<@Covariant T> { -List underlyingList = new ArrayList<>(); + + private List underlyingList = new ArrayList<>(); public ImmutableList(Iterable initial) { initial.forEach(e -> underlyingList.add(e)); @@ -185,6 +226,18 @@ class Pair<@Contravariant X, @Contravariant Y> { +### Building and running your project + +If you are using Maven, you can compile your project with the following command: + +```sh +mvn clean compile +``` + +If you are not using Maven, simply compile the project as you normally would. + +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. + ## Contributing Pull requests and issues that aim to better the project are greatly appreciated.