Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Java 21 #345

Closed
Luro02 opened this issue Dec 21, 2023 · 1 comment · Fixed by #503
Closed

Update to Java 21 #345

Luro02 opened this issue Dec 21, 2023 · 1 comment · Fixed by #503
Labels
D-easy Easy to implement. enhancement New feature or request low-priority
Milestone

Comments

@Luro02
Copy link
Collaborator

Luro02 commented Dec 21, 2023

Description

Has some nice language features

@Luro02 Luro02 added enhancement New feature or request low-priority labels Dec 21, 2023
@Luro02 Luro02 added this to the v0.6 milestone Jan 13, 2024
@Luro02 Luro02 added the D-easy Easy to implement. label Feb 7, 2024
@Luro02
Copy link
Collaborator Author

Luro02 commented Feb 8, 2024

As an example for what will be possible: A common problem in the codebase is the null return value. When null is returned, it is easy to forget, which would result in a crash. Therefore, in most cases Optional is returned.

Optional is a pain to work with and it might take forever to be usable (https://mail.openjdk.org/pipermail/amber-spec-experts/2024-January/003976.html). In many parts of the code, you will therefore find a .orElse(null).

With Java 21 we can write a better Optional that is similar to what rust provides (Option<T>).

Here is the proof of concept implementation:

`Option.java`
import java.util.Iterator;
import java.util.function.Function;
import java.util.stream.Stream;

public sealed interface Option<T> extends Iterable<T> permits Some, None {
  static <T> Option<T> ofNullable(T value) {
      return value == null ? new None<>() : new Some<>(value);
  }

  default T unwrap() {
      return switch (this) {
          case Some<T> (var value) -> value;
          case None<T> ignored -> throw new IllegalStateException("Expected Some value, but got None.");
      };
  }

  default boolean isSome() {
      return this instanceof Some;
  }

  default <U> Option<U> map(Function<T, U> function) {
      return switch (this) {
          case Some<T>(var value) -> new Some<>(function.apply(value));
          case None<T> ignored -> new None<>();
      };
  }

  /**
   * Returns the value if it is present or null if it is not.
   *
   * @return the value or null
   */
  default T nullable() {
      return switch (this) {
          case Some<T>(var value) -> value;
          case None<T> ignored -> null;
      };
  }

  default Stream<T> stream() {
      return switch (this) {
          case Some<T>(var value) -> Stream.of(value);
          case None<T> ignored -> Stream.empty();
      };
  }

  @Override
  default Iterator<T> iterator() {
      return stream().iterator();
  }
}
`Some.java`
public record Some<T>(T value) implements Option<T> {
}
`None.java`
public record None<T>() implements Option<T> {
}

Luro02 added a commit to Luro02/autograder that referenced this issue Apr 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
D-easy Easy to implement. enhancement New feature or request low-priority
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant