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

3.x Create Combinatorial Function, Consumer interfaces for correct nullability #6687

Closed
6 tasks done
hborders opened this issue Oct 26, 2019 · 7 comments
Closed
6 tasks done

Comments

@hborders
Copy link

Thanks for using RxJava but before you post an issue, please consider the following points:

  • Please include the library version number, including the minor and patch version, in the issue text. In addition, if you'd include the major version in the title (such as 3.x) that would be great.

  • If you think you found a bug, please include a code sample that reproduces the problem. Dumping a stacktrace is usually not enough for us.

  • RxJava has more than 150 operators, we recommend searching the javadoc for keywords of what you try to accomplish.

  • If you have a question/issue about a library/technology built on top of RxJava (such as Retrofit, RxNetty, etc.), please consider asking a question on StackOverflow first (then maybe on their issue list).

  • Questions like "how do I X with RxJava" are generally better suited for StackOverflow (where it may already have an answer).

  • Please avoid cross-posting questions on StackOverflow, this issue list, the Gitter room or the mailing list.

As outlined in #5216 and #5442 (2.x issues), Function, Consumer, etc have varying nullability requirements, and thus can't have nullability annotations. Unfortunately, this requires consumers to move their nullability checks to runtime instead of compile time.

I propose that you include the following combinations of your existing functions package. The naming scheme is not important. For reference, I used R (or required) for @NonNull and O (or optional) for @Nullable.

interface BiConsumerRR<T1, T2> {
  void apply(@NonNull T1 t1, @NonNull T2 t2);
}
interface BiConsumerRO<T1, T2> {
  void apply(@NonNull T1 t1, @Nullable T2 t2);
}
interface BiConsumerOO<T1, T2> {
  void apply(@Nullable T1 t1, @Nullable T2 t2);
}
interface BiConsumerOR<T1, T2> {
  void apply(@Nullable T1 t1, @NonNull T2 t2);
}
interface ConsumerR<T> {
  void accept(@NonNull T t) throws Throwable;
}
interface ConsumerO<T> {
  void accept(@Nullable T t) throws Throwable;
}
interface FunctionR<T, R> {
  @NonNull R apply(@NonNull T t);
}
interface FunctionO<T, R> {
  @Nullable R apply(@NonNull T t);
}
interface SupplierR<T> {
  @NonNull T get() throws Throwable;
}
interface SupplierO<T> {
  @Nullable T get() throws Throwable;
}

BiFunction, BiPredicate, Function3, Function4, Function5, Function6, Function7, Function8, Function9, IntFunction, and Predicate already have complete nullability definitions, so I assume they wouldn't need any combinations.

Then, Maybe could have:

@NonNull 
public static <T> Maybe<T> fromSupplier(@NonNull SupplierO<? extends T> supplier);

And Single could have:

@NonNull
public static <T> Single<T> fromSupplier(final SupplierR<? extends T> supplier);

This is only a cost of 10 extra interfaces to ensure compile-time nullability correctness, and provide better guidance to developers. I hope you'll consider it. If you're interested in this, I'm happy to contribute a PR and track down the various ambiguities.

@akarnokd
Copy link
Member

As I mentioned on twitter, I don't want to bloat the API with combinatorials. When we move to Java 8+, the relevant call sites will receive the specific null annotations.

@hborders
Copy link
Author

Thanks. I just wanted this on the record in the real project. When do you expect to move to Java 8+?

@akarnokd
Copy link
Member

We may just wait out AGP 4, a couple of months.

@JakeWharton
Copy link
Contributor

You can use Java 8 bytecode, lambdas/method references, and type-use annotations today provided you stick to Java 6-ish APIs. This has been supported since AGP 3.0 (released two years ago). AGP 4.0 only adds backporting of new APIs and types which are still interesting, but I don't think strictly required.

@BraisGabin
Copy link
Contributor

So, are we waiting that time before releasing 3.x? I think that proper nullability checks would be great so waiting those months should be worth it.

I'm afraid of launch 3.x and then need to wait for 4.x to get this improvement.

@akarnokd
Copy link
Member

You can use Java 8 bytecode, lambdas/method references, and type-use annotations today provided you stick to Java 6-ish APIs. This has been supported since AGP 3.0 (released two years ago)

The problem from RxJava's build side is that we have to up the compile target to 8, which then breaks AnimalSniffer at some places (javac compiles to JDK 8 API use internally), not to mention the TYPE_USE meta annotation on our @NonNull. Suppressing may be not enough or would have to be scoped too big.

@JakeWharton
Copy link
Contributor

I haven't experienced those problems on other libraries with the same setup.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants