<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4" face="monospace">I just want to point out that
      there's a sort of "syntax error" in your proposal.  <br>
      <br>
      Java provides annotations as a means of "structured comments" on
      declarations and type uses, but the Java language does not, and
      will not, impart any semantics to programs on the basis of
      annotations.  If you are talking about writing a static analysis
      tool, perhaps a pluggable checker in the Checkers framework, then
      (as Ethan points out) you can use existing annotations with APs
      and do so, and the compiler is merely a conduit for ferrying the
      annotations to where an AP can find them.  (In fact, there is
      already a checker for "fake enums", where you say that a given
      `int` is really one of the enumerated set 1, 2, 3, 4, which is a
      restriction type.)<br>
      <br>
      If you mean that the compiler actually is going to get into the
      act, though, then this is not an annotation-driven feature, this
      is a full-blown language feature and should be thought of
      accordingly.  I know its tempting to view annos as a "shortcut" to
      language features, but if something has semantics, its part of the
      language, and sadly that means no shortcuts.  That's not to say it
      isn't a worthwhile idea with a good cost-to-benefit ratio. 
      (Indeed, as we get further into the type classes work, the logic
      of a `newtype` mechanism becomes even more compelling as then it
      becomes possible to affect behavior with restrictions such as
      `CaseInsensitveString`, which doesn't actually restrict the value
      set of the type, but allows you to define `Ord
      CaseInsentiveString` separate from `Ord String`.)<br>
      <br>
      <br>
    </font><br>
    <div class="moz-cite-prefix">On 10/13/2025 3:17 PM, Archie Cobbs
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CANSoFxtmH7BiMXMWKc-P81XNoxvjZKWDNf94ZGJuAEKxgenzCw@mail.gmail.com">
      
      <div dir="ltr">
        <div dir="ltr">
          <div dir="ltr">
            <div dir="ltr">
              <div dir="ltr">
                <div dir="ltr">
                  <div>Ethan McCue <<a href="mailto:ethan@mccue.dev" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">ethan@mccue.dev</a>>
                    wrote:</div>
                  <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">However
                    there is nothing conceptually preventing the tools
                    validating @NonNull usage from also emitting an
                    error until you have inserted a known precheck.<br>
                    ...<br>
                    But for other single-value invariants, like your
                    @PhoneNumber example, it seems fairly practical.
                    Especially since, as a general rule, arbitrary cost
                    computations really shouldn't be invisible. How
                    would one know if (@B A) is going to thread
                    invocations of some validation method everywhere?</blockquote>
                  <div><br>
                  </div>
                  <div>This is why 3rd party tools aren't as good as
                    having the compiler handle it, because the compiler
                    is in a position to provide both stronger and more
                    efficient guarantees - think generic types and
                    runtime erasure. Compiler-supported typing allows
                    the developer to move the burden of proof from the
                    method receiving a parameter to the code invoking
                    that method, and onward back up the call chain, so
                    that validations tend to occur "early", when they
                    are first known to be true, instead of "late" at the
                    (many more) points in the code where someone
                    actually cares that they are true.</div>
                  <div><br>
                  </div>
                  <div>So if phone numbers are central to your
                    application, and they are passed around and used all
                    over the place as type<span style="font-family:monospace"> @PhoneNumber String</span>,
                    then they will only need to actually be validated at
                    a few application entry points, not at the start of
                    every method that has a phone number as a parameter.
                    In other words, the annotation is ideally not a
                    "to-do" list but rather an "it's already done" list.</div>
                  <div><br>
                  </div>
                  <div>The guarantee that the compiler would then
                    provide is ideally on the same level as with
                    generics: while it's being provided by the compiler,
                    not the JVM, so you can always get around it if you
                    try hard enough (native code, reflection, class file
                    switcheroo, etc.), as long as you "follow the rules"
                    you get the guarantee - or if not, an error or at
                    least a warning.</div>
                  <br>
                  <div>Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
                    wrote:</div>
                  <div class="gmail_quote">
                    <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                      <div>I think the best bet for making this usable
                        would be some mechanism like a "view", likely
                        only on value types, that would erase down to
                        the underlying wrapped type, but interpose
                        yourself on construction, and provided a
                        conversion from T to RefinedT that verified the
                        requirement.  But this is both nontrivial and
                        presumes a lot of stuff we don't even have
                        yet...</div>
                    </blockquote>
                    <div><br>
                    </div>
                    <div>I think that is close to what I was imagining.
                      It seems like it could be done with fairly minimal
                      impact/disruption...? No need for wrappers or
                      views.</div>
                    <div><br>
                    </div>
                    <div>But first just to be clear, what I'm getting at
                      here is a fairly narrow idea, i.e., what
                      relatively simple thing might the compiler do,
                      with a worthwhile cost/benefit ratio, to make it
                      easier for developers to reason about the
                      correctness of their code when "type restriction"
                      is being used, either formally or informally
                      (meaning, if you're using an int to pass around
                      the size of collection, you're doing informal type
                      restriction).</div>
                    <div><br>
                    </div>
                    <div>What's the benefit? Type restriction is fairly
                      pervasive, and yet because Java doesn't make it
                      very easy to do, it's often not being done at all,
                      and this ends up adding to the amount of manual
                      work developers must do to prove to themselves
                      their code is correct. The more of this burden the
                      compiler could take on, the bigger the benefit
                      would be.</div>
                    <div><br>
                    </div>
                    <div>What's the cost? That depends on the solution
                      of course.</div>
                    <br>
                  </div>
                  <div class="gmail_quote">To me the giant poster-child
                    for this kind of pragmatic language addition is
                    generics. It had all kinds of minor flaws from the
                    point of view of language design, but the problem it
                    addressed was so pervasive, and the new tool it
                    provided to developers for verifying the correctness
                    of their code was so powerful, that nobody thinks it
                    wasn't worth the trade-off.</div>
                  <div class="gmail_quote"><br>
                  </div>
                  <div class="gmail_quote">OK let me throw out two
                    straw-man proposals. I'll just assume these are
                    stupid/naive ideas with major flaws. Hopefully they
                    can at least help map out the usable territory - if
                    any exists.</div>
                  <div class="gmail_quote">
                    <div>
                      <div><br>
                      </div>
                      <b>Proposal #1</b></div>
                    <div><br>
                    </div>
                    <div>This one is very simple, but provides a weaker
                      guarantee.</div>
                    <div>
                      <div>
                        <ol>
                          <li>The compiler recognizes and tracks "type
                            restriction annotations", which are type
                            annotations having the<span style="font-family:monospace"></span>
                            meta-annotation <span style="font-family:monospace">@TypeRestriction</span></li>
                          <li>For all operations assigning some value v
                            of type S to type T:</li>
                          <ol>
                            <li>If a type restriction annotation A is
                              present on T but not S, the compiler
                              generates a warning in the new lint
                              category <span style="font-family:monospace">"type-restriction"</span></li>
                          </ol>
                        </ol>
                      </div>
                      That's it. A cast like<span style="font-family:monospace"> var pn =
                        (@PhoneNumber String)input </span>functions
                      simply as a developer assertion that the type
                      restriction has been verified, but the compiler
                      does not actually check this. There is no change
                      to the generated bytecode. If the developer
                      chooses to write a validation method that takes a
                      string, validates it (or throws an exception), and
                      then returns the validated string, that method
                      will need to be annotated with<span style="font-family:monospace">
                        @SuppressWarnings("type-restriction") </span><span style="font-family:arial,sans-serif">because of
                        the cast in front of the return statement.</span>
                      <div><br>
                      </div>
                      <div>Guarantee provided: Proper type restriction
                        as long as "type-restriction" warnings are
                        enabled and not emitted. However, this is a
                        "fail slow" guarantee: it's easy to defeat (just
                        cast!). So if you write a method that takes a<span style="font-family:monospace"> @PhoneNumber
                          String </span>parameter that is passed an
                        invalid value, you won't find out until
                        something goes wrong later down the line (or
                        never). In other words, <i>your</i> code will
                        be correct, but you have to be trusting of any
                        code that <i>invokes</i> your code, which in
                        practice is not always a sound strategy.</div>
                      <div><br>
                      </div>
                      <div><b>Proposal #2</b></div>
                    </div>
                    <div><br>
                    </div>
                    <div>
                      <div>This is proposal is more complex but provides
                        a stronger guarantee:</div>
                    </div>
                  </div>
                  <div>
                    <ol>
                      <li>The compiler recognizes and tracks "type
                        restriction annotations", which have the<span style="font-family:monospace"></span>
                        meta-annotation <span style="font-family:monospace">@TypeRestriction</span></li>
                      <ol>
                        <li><span style="font-family:arial,sans-serif">The
                            annotation specifies a user-supplied
                            "constructor" class providing a user-defined
                            construction/validation method </span><span style="font-family:monospace">validate(v)</span></li>
                        <li>We add <span style="font-family:monospace">class
                            TypeRestrictionException extends
                            RuntimeException</span> and encourage <span style="font-family:monospace">validate()</span>
                          methods to throw (some subclass of) it</li>
                      </ol>
                      <li>For all operations assigning some value v of
                        type S to type T:</li>
                      <ol>
                        <li>If a type restriction annotation A is
                          present on T but not S, the compiler generates
                          a <span style="font-family:monospace">"type-restriction"</span> warning
                          AND adds an implicit cast added (see next
                          step)</li>
                      </ol>
                      <li>For every cast like  <span style="font-family:monospace">var pn =
                          (@PhoneNumber String)"+15105551212" </span> the
                        compiler inserts bytecode to invoke the
                        appropriate enforcer<span style="font-family:monospace"> validate(v) </span>method</li>
                      <li><span style="font-family:arial,sans-serif">The
                          JLS rules for method resolution, type
                          inference, etc., do not change (that would be
                          way over-complicating things)</span></li>
                      <ol>
                        <li>Two methods<span style="font-family:monospace"> void
                            dial(String pn) </span>and<span style="font-family:monospace"> void
                            dial(@PhoneNumber String pn) </span>will
                          still collide</li>
                      </ol>
                    </ol>
                  </div>
                  <div>
                    <div>Guarantee provided: Proper type restriction
                      unless you are going to extremes (native code,
                      reflection, runtime classfile switcheroo, etc.).
                      This is a "fail fast" guarantee: errors are caught
                      at the moment an invalid value is assigned to a
                      type-restricted variable. If your method
                      parameters have the annotation, you don't have to
                      trust 3rd party code that calls those methods (as
                      long as it was compiled properly). I.e., same
                      level of guarantee as generics.</div>
                  </div>
                  <div><br>
                  </div>
                  <div>These are by no means complete or
                    particularly elegant solutions from a language
                    design point of view. They are pragmatic and
                    relatively unobtrusive add-ons, using existing
                    language concepts, to get us most of what we want,
                    which is:</div>
                  <div>
                    <ul>
                      <li>User-defined "custom" type restrictions with
                        compile-time checking/enforcement</li>
                      <ul>
                        <li>As with generics, the goal is not language
                          perfection, but rather making it easier for
                          developers to reason about correctness</li>
                      </ul>
                      <li>Compile-time guarantees that type restricted
                        values in source files will be actually type
                        restricted at runtime</li>
                      <li>Efficient implementation</li>
                      <ul>
                        <li>Validation only happens "when necessary"</li>
                        <li>No JVM changes needed (erasure)</li>
                      </ul>
                      <li>No changes to language syntax; existing source
                        files are 100% backward compatible</li>
                    </ul>
                  </div>
                  <div>
                    <div>The developer side of me says that the
                      cost/benefit ratio of something like this would be
                      worthwhile, in spite of its pragmatic nature,
                      simply because the problem being addressed seems
                      so pervasive. I felt the same way about generics
                      (which was a much bigger change addressing a
                      much bigger pervasive problem).</div>
                    <div><br>
                    </div>
                    <div>But I'm sure there are things I'm missing... ?<br>
                      <div><br>
                      </div>
                      <div>-Archie</div>
                    </div>
                  </div>
                </div>
                <div dir="ltr"><span class="gmail_signature_prefix"><br>
                  </span></div>
                <div dir="ltr"><span class="gmail_signature_prefix">-- </span><br>
                  <div dir="ltr" class="gmail_signature">Archie L. Cobbs<br>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>