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
Whether to put nullness annotations in their own subpackage #160
Comments
Assumption: "We'll probably never have more than 25 annotations." (Here are some possible future annotations. Note also the possibility of meta-annotations (#101, #109 ( Advantages of
Advantages of
|
I was slightly in favor of subpackages from a purely abstract organizational perspective and also for the discoverability and documentation of related annotations. However, pure abstractions like that are not very important to users. And I don't think a segregated list of related annotations is sufficient documentation, so I would also expect one entry point for documentation of each group of related annotations, and that document is where I would expect users to look, not the package directory file list. (I would expect each related annotation to link to that entry-point document.) So that mitigates that concern. The concern about one-off annotations rings true to me, although I'm not so bothered by one-file packages. Maybe related, if we introduce general-purpose annotations (including but not limited to meta-annotations) that might apply to several different groups, we'd be in the same boat: either put them at the root, elevating their importance, or put them in a So over all I'm happy to leave everything in one package. |
To propose a slightly different rule of thumb: put commonly used things
into the "root" package; consider separate packages for rarer things
(including meta-annotations...) or if there are somehow a lot of related
annotations/enums/etc. (again something that may be true for
meta-annotations). I sort of feel that that is how `java.time` was
structured, for instance, but that package is of course already about a
particular domain, so maybe not the best comparison.
Another way of saying it is: I feel it would be quite nice for nullness
annotations *in particular* to go into org.jspecify.annotations instead of
a subpackage, for the reason that they will need to be referenced
ubiquitously if used in earnest in any given project. Comparatively, I'd
expect that most other domains we could define annotations for would be
used far less often. Additionally, we don't currently have any other
annotations, so using the root package is sort of the "obvious" choice.
Finally I'll note that `org.jspecify.annotations.nullness.Nullable` and
especially `@org.jspecify.annotations.nullness.Nullable` (where @ and
annotations also imply each other) feel pretty redundant. I could imagine
that to be less so in other domains, but here the package name just doesn't
seem to add any context over the annotation name itself.
Still, elevating nullness in this way is maybe unwarranted, and it's
certainly more logical (and future-proof?) to put each annotation "domain"
into its own package. Plus, by letting "nullness" appear in the package
name we hint to users that we hope to support other domains, which is maybe
nice.
To really (?) make a splash: I feel that if we want to use separate
packages for each annotation domain then we should consider dropping the
"annotations" prefix entirely, and instead use `org.jspecify.nullness`,
etc. At least for me personally, `org.jspecify.annotations` was at least
in part compelling under the assumption that that package would contain a
lot of (if not all) the annotations we define. An advantage of this (3rd)
alternative is that we can put any other nullness-related code we might
decide to make part of the repo (say, a runtime reflection utility) into
reasonably named subpackages (e.g., `org.jspecify.nullness.reflect`), and
it also might help with organize test data etc. for each annotation domain
(by using different source roots, for instance).
|
I am convinced by the arguments for a separate package for each type system (plus one for the common elements if needed). The most compelling arguments (to me) are that it is a logical organization that puts similar things together and separates dissimilar things, and that it is more future-proof. I am not compelled by the arguments for lumping everything in to a single package.
The idea of dropping the "annotations" intermediate package is fine with me, and makes sense if JSpecify is nothing more than annotations. |
Some other thoughts that came up during the meeting just now:
|
As noted in a couple other places, we seem to be converging on: org.jspecify.nullness Things to think about before finalizing that: "nullness"Everyone seems to feel that "nullness" is the right name for that component of the package. I note that this matches the Checker Framework's package, and I didn't immediately see any precedent for other terms like "nullability" (unless you count this jOOQ class). And we seem to be pretty happy with "nullness" over "nullability" in general -- particularly for actual annotation names, like module and artifact namesWe'll also have a JPMS module and Maven artifact to name. Currently, they're set to Thanks for all the discussion on this question, both from people who are fine with whatever and from people who have expressed preferences for the various options. |
Also RE: module and artifact names: When writing the above, I implicitly assumed that all our annotations -- including hypothetical annotations unrelated to nullness (and thus in different packages) -- would live in a single JPMS module and a single Maven artifact. Now, I don't think that But if we were to consider a split, I would be nervous. In particular, if we want our annotations to be adopted nearly universally, we would benefit from making our dependency as low-cost as possible. Ideally, that means one jar. Otherwise, we risk making even "nullness-only" users depend on both a nullness jar and a "meta" jar that it depends on. (They can sometimes get away without the "meta" dependency, but we'd at least be forcing people to consider tradeoffs -- plus some JSpecify-specific tradeoffs around aliases.) And of course we might like those people to also consider (I would be in favor of separate modules/artifacts/jars if we ever need to take on additional dependencies for some of our annotations (not that I think we're likely to even need that). But I think that kind of split is compatible with everything I've said above: Most users would depend on |
I agree a single Jar and module for all annotations regardless of
domain/type system they're part of is desirable, and has been a stated goal
from the start I believe. It's maybe worth assuming that eventually we'll
encounter a case where we do want a separate Jar for some particular family
of annotations.
We should also probably assume that any other code we may wish to publish
will go into a separate Jar. For instance, hypothetical helper code to
facilitate runtime inspection of, or testing with, some of our annotations
should probably go into a separate Jar from the annotations.
|
Working decision is "yes": |
Previously discussed in #1 (here, here, here -- apologies if I missed relevant posts while skimming). Our tentative decision (and the state of the annotation sources that exist in this repo) is to put the annotations directly in
org.jspecify.annotations
. That may well be fine. We just want to consciously decide one way or the other :)[update: We are now leaning toward eliminating the
annotations
component (contrary to #1) and putting nullness annotations inorg.jspecify.nullness
.]The text was updated successfully, but these errors were encountered: