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

2711 remove not null assertions #2744

Open
wants to merge 25 commits into
base: master
Choose a base branch
from

Conversation

patrickguenther
Copy link

@patrickguenther patrickguenther commented May 6, 2023

tests fixed

jbrains and others added 16 commits May 6, 2023 17:20
This change removed all the explicit null checks using Objects.requireNonNull().
It does not yet address the changes in tests. I am waiting for feedback from
the project maintainers regarding their preferred strategy for changing the
newly-failing tests.
…, as long as it never needs to invoke that operator.
default <R> Iterator<R> collect(PartialFunction<? super T, ? extends R> partialFunction) {
if (!hasNext()) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is adheres to coding guidelines.
If partialFunction == null should not throw when empty, this additional check is required, because the expression partialFunction::isDefinedAt will otherwise throw immediately.

@szarnekow
Copy link
Contributor

What is the reasoning behind this change? At first glance it seems to cloak a lot of programming mistakes by shifting away from fail-early-at-root-cause to fail-at-random-point-in-time.

@patrickguenther
Copy link
Author

patrickguenther commented May 6, 2023

@szarnekow see discussion in #2711
But also: the whole shift we see in the last couple of years for programming languages becoming more functional is because we, the software developer community, have figured out that the best solution to avoid NPEs is to completely eradicate the use of the nullpointer itself.
If that goal is reached, however, all code for checking nulls just becomes obsolete boilerplate.

The other argument, you brought up: "Throwing close to the source" is maybe only valid when the potential throwing of the NPE and the injection point of the null value are in completely different execution stacks. For that, I would support placing some null checks in strategic places like Futures, where an uncaught NPE might even lead it to never terminate.
Otherwise IDEs usually highlight your own classes in the stack trace or when looking at the stacktrace in a terminal or textfile you anyway quickly scan the trace for your own namespace.

@ezoerner
Copy link

ezoerner commented May 6, 2023

What is the reasoning behind this change? At first glance it seems to cloak a lot of programming mistakes by shifting away from fail-early-at-root-cause to fail-at-random-point-in-time.

See the discussion of this in #2711. Evidently the reasoning is that it is for performance reasons that the null checks are being removed. Ideally null checks should not be needed in a functional library as nulls have no business being in functional code—but unfortunately in Java that minefield always lurks under the surface. Personally I think it’s ok to remove the null checks because 1) there shouldn’t be any nulls when your code properly protects against them coming from 3rd party libraries, and 2) a resulting NPE almost always provides enough locality info to quickly determine where the null came from.

For me the compelling reason is to keep the code cleaner by removing the null-check noise; I am skeptical about performance being a compelling reason to remove them.

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

Successfully merging this pull request may close these issues.

None yet

4 participants