<div dir="ltr"><div dir="ltr">On Wed, Sep 28, 2022 at 1:10 PM Brian Goetz <<a href="mailto:brian.goetz@oracle.com">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><blockquote type="cite">
      <div dir="ltr">
        <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><font size="4"><font face="monospace"> - Relax the
                  requirement that the class, and `main` method, be
                  public.  Public<br>
                     accessibility is only relevant when access crosses
                  packages; simple programs<br>
                     live in the unnamed package, so cannot be accessed
                  from any other package<br>
                     anyway.  For a program whose main class is in the
                  unnamed package, we can<br>
                     drop the requirement that the class or its `main`
                  method be public,<br>
                     effectively treating the `java` launcher as if it
                  too resided in the unnamed<br>
                     package.<br>
                </font></font></div>
          </blockquote>
          <div><br>
          </div>
          <div>Alternative: drop the requirement altogether. Most main
            methods have no desire to make themselves publicly callable
            as `TheClass.main(args)`, but today they are forced to
            expose that API anyway. I feel like it would still be
            conceptually clean to say that `public` is really about
            whether other *code* can access it, not whether a VM can get
            to it at all.</div>
        </div>
      </div>
    </blockquote>
    I think we're saying the same thing; main need not be public. </div></blockquote><div><br></div><div><br></div><div>You seemed quite clearly to be offering that for classes in the default package only.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite"><div dir="ltr"><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><font size="4"><font face="monospace"> - Make the
                  "args" parameter to `main` optional, by allowing the
                  `java` launcher to<br>
                     first look for a main method with the traditional
                  `main(String[])`<br>
                     signature, and then (if not found) for a main
                  method with no arguments.<br>
                </font></font></div>
          </blockquote>
          <div><br>
          </div>
          <div>This seems to leave users vulnerable to some surprises,
            where the code they think is being called isn't. Why not
            make it a compile-time error to provide both forms?</div></div></div></blockquote>
    Currently, the treatment of methods called "main" is "and also"; it
    is a valid method, *and also* (if it has the right shape) can be
    used as a main entry point.  Making this an error would take some
    valid programs and make them invalid, which seems a shift in the
    interpretation of the magic name "main".  A warning is probably
    reasonable though.<br></div></blockquote><div><br></div><div><br></div><div>Oh, yeah, I have a habit of saying "error" when I am always always perfectly satisfied with a warning. Of course, the warning goes just on the method that isn't gonna get called, and the user should be advised to rename it.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div><blockquote type="cite"><div dir="ltr"><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><font size="4"><font face="monospace">  - Make the
                  `static` modifier on `main` optional, by allowing the
                  `java` launcher to<br>
                     invoke an instance `main` method (of either
                  signature) by instantiating an<br>
                     instance using an accessible no-arg constructor and
                  then invoking the `main`<br>
                     method on it.<br>
                </font></font></div>
          </blockquote>
          <div><br>
          </div>
          On a deep conceptual level... I'd insist that main() *is
          static*. It is *the* single entry point into the program; what
          could be more static than that? But thinking about our
          learner, who wrote some `main`s before learning about static.
          The instant they learn `static` is a keyword a method can
          have, they'll "know" one thing about it already: this is going
          to be something new that's *not* true of main(). But then they
          hear an explanation that fits `main` perfectly?</div></div></blockquote></div></blockquote><div><br></div><div>Sorry, just a quick self-reply of clarification: when I said "main IS static", that was taking Java's model that everything belongs to a class as *given*. It's not commentary against "main is really a free function".</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>
    John likes to say "static has messed up every job we've ever given
    it", and while that seems an exaggeration at first, often turns out
    to be surprisingly accurate.  One subtle thing it messes up here is
    that one cannot effectively inherit a main() method.  But inheriting
    main() is super useful!  Consider a TestCase class in a test
    framework, or an AbstractService class in a services framework.  If
    the abstract class can provide the main() method, then every test
    case or service _is also a program_, one which runs that test case
    or service. </div></blockquote><div><br></div><div><br></div><div>I see that that is "a way" to do a thing. But in my view, implementation inheritance has messed up every job we've ever given it. :-) It will at the *least* take me some time and reflection to convince myself that "inheritable main" isn't horrifying.</div></div><div><br></div><div>Most of the specific counter-arguments I laid out to the non-static main have dropped out of the thread without acknowledgement, so I'm a little concerned they'll be forgotten in the discussion.</div><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div style="line-height:1.5em;padding-top:10px;margin-top:10px;color:rgb(85,85,85);font-family:sans-serif"><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(213,15,37);padding-top:2px;margin-top:2px">Kevin Bourrillion |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(51,105,232);padding-top:2px;margin-top:2px"> Java Librarian |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(0,153,57);padding-top:2px;margin-top:2px"> Google, Inc. |</span><span style="border-width:2px 0px 0px;border-style:solid;border-color:rgb(238,178,17);padding-top:2px;margin-top:2px"> <a href="mailto:kevinb@google.com" target="_blank">kevinb@google.com</a></span></div></div></div></div></div></div></div></div>