<div dir="ltr"><div>Hello expert,</div><div><br></div><div>One more design space point that allows beginner friendly arrangement of concepts is to extend the Java compilation unit to always allow top-level method declarations.</div><div><br></div><div>Top-level methods are always static and can not be public.</div><div><div></div><div>There is still a value for advanced java-developers:
 these methods allow a succinct way to write private static 
utility-methods to be used from the normal class.</div></div><div><br></div><div>It's not hard to imagine that normal Java code inside the my/company/pkg/Test.java file can contain:<br></div><div><br></div><div>````<br></div><div>package my.company.pkg;</div><div><br></div><div>import ...;</div><div>import ...;</div><div><br></div><div>void helper1(HiddenClass hiddenClass) {</div><div>   ...<br></div><div>}</div><div><br></div><div><div>void helper2() {</div><div>   ...<br></div><div>}</div><div><br><br></div></div><div>public class Test {</div><div>    record NormalInnerDeclaration() {}<br></div><div>}</div><div>class HiddenClass {</div><div>}<br></div><div>````<br></div><div><br></div><div><div>The semantics of this is that only the code inside the compilation unit can call `helper1` or `helper2`, nobody else can.</div></div><div>Semantically there is no enclosing class, there is no name that can be used to disambiguate method name: Test.helper1() is not the top level method and can not be used to reference `helper1` method, only the stand-alone name `helper1` can.</div><div></div><div><br></div><div>For the beginners this means that they can write a file with the `.java` suffix and use the unnamed package and they should never care about class names or exact file name.<br></div><div><br></div><div>````</div><div>void main() {</div><div>   ...<br></div><div>}</div><div><br></div><div>void quicksort() {</div><div>}</div><div><br></div><div>record MyRecord {</div><div>}<br></div><div>````<br></div><div><br></div><div>We can extend the Java mechanism to run a single file to look up top-level static methods. Having some `excersise1.java` we can execute it with the simple</div><div><br></div><div>````</div><div>    $ java excersise1.java</div><div>````<br></div><div><br></div><div>Technically in JVM this method can be implemented as something like a companion Utility class in the same nest. For the `my/company/pkg/Test.java` source file we may get `my/company/pkg/Test.class` and `my/company/pkg/Test$utilitycompanion.class` or something like this.<br></div><div><br></div><div>When a beginner progresses towards large-scale organization of code, they still don't need to unlearn to use top-level methods, they will stay always available.</div><div><br></div><div>--</div><div><div dir="ltr" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Victor Nazarov<br></div></div></div></div></div></div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Sep 29, 2022 at 3:37 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" target="_blank">brian.goetz@oracle.com</a>> wrote:<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>
    <br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div>
          <div>A major design goal of yours seems clear: to get there
            without rendering Java source files
            explicitly bimorphic ("class" source files all look like
            this, "main" source files all look like that). Instead you
            have a set of independent features that can compose to get
            you there in a "smooth ramp". The design looks heavily
            influenced by that goal.</div>
        </div>
      </div>
    </blockquote>
    <br>
    Yes, I sometimes call this "telescoping", because there's a chain of
    "x is short for y is short for z".  For example, with lambdas:<br>
    <br>
        x -> e<br>
    <br>
    is-short-for<br>
    <br>
        (x) -> e     <br>
    <br>
    is-short-for<br>
    <br>
        (var x) -> e  <br>
    <br>
    is-short-for<br>
    <br>
        (int x) -> e  // or whatever the arg is<br>
    <br>
    As a design convention, it enables a mental model where there is
    really just one form, with varying things you could leave out. 
    Early in the Lambda days, we saw articles like "there are N forms of
    lambda expressions", and that stuff infuriates me, it is as if
    people go out of their way to find more complex mental models than
    necessary.  <br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div>
          <div>As my program grows and gets more complex, I will make
            changes like</div>
          <div><br>
          </div>
          <div>* use more other libraries</div>
          <div>* add args to main()</div>
          <div>* add helper methods</div>
          <div>* add constants</div>
          <div>* create new classes and use them from here<br>
          </div>
          <div><br>
          </div>
          <div>But: when and why would I be motivated to change *this*
            code *itself* to "become" a class, become instantiable,
            acquire instance state, etc. etc.? I don't imagine ever
            having that urge. main() is just main()! It's just a way in.
            Isn't it literally just a way to (a) transfer control back
            and forth and (b) hand me args?</div>
        </div>
      </div>
    </blockquote>
    <br>
    This doesn't seem like such a leap to me.  You might start out
    hardcoding a file path that will be read.  Then you might decide to
    let that be passed in (so you add the args parameter to main).  Then
    you might want to treat the filename to be read as a field so it can
    be shared across methods, so you turn it into a constructor
    parameter.  One could imagine "introduce X" refactorings to do all
    of these.  The process of hardcoding to main() parameter to
    constructor argument is a natural sedimentation of things finding
    their right level.  (And even if you don't do all of this, knowing
    that its an ordinary class (like an enum or a record) just with a
    concise syntax means you don't have to learn new concepts.  I don't
    want Foo classes and Bar classes.)<br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div>
          <div class="gmail_quote"><br>
            <div>Note I was only reacting to "static bad!" here. I would
              be happy if *that* argument were dropped, but you do still
              have another valid argument: that `static` is another
              backward default, and the viral burden of putting it not
              just on main() but every helper method you factor out is
              pure nuisance. (I'd suggest mentioning the viral nature of
              this particular burden higher/more prominently in the doc,
              as it's currently out of place under the "unnamed classes"
              section.)</div>
            <div><br>
            </div>
            <div>(That doesn't mean "so let's do it"; I still hope to
              see that benefit carefully measured against the drawbacks.
              Btw, *some* of those drawbacks might be eased by
              disallowing an explicit constructor... and jeez, please
              disallow type parameters too... I'm leaving the exact
              meaning of "disallow" undefined here.)</div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    Indeed, I intend that there are no explicit constructors or instance
    initializers here.  (There can't be constructors, because the class
    is unnamed!)  I think I said somewhere "such classes can contain
    ..." and didn't list constructors, but I should have been more
    explicit.  <br>
    <br>
    <blockquote type="cite">
      <div dir="ltr"><br>
        <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">## Unnamed
                  classes<br>
                  <br>
                  In a simple program, the `class` declaration often
                  doesn't help either, because<br>
                  other classes (if there are any) are not going to
                  reference it by name, and we<br>
                  don't extend a superclass or implement any interfaces.</font></font></div>
          </blockquote>
          <div><br>
          </div>
          <div>How do I tell `java` which class file to load and call
            main() on? Class name based on file name, I guess?</div>
        </div>
      </div>
    </blockquote>
    <br>
    Sadly yes.  More sad stories coming on this front, Jim can tell.  <br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote"><br>
          <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">If we say an
                  "unnamed<br>
                  class" consists of member declarations without a class
                  header, then our Hello<br>
                  World program becomes:<br>
                  <br>
                  ```<br>
                  void main() { <br>
                      System.out.println("Hello World");<br>
                  }<br>
                  ```<br>
                </font></font></div>
          </blockquote>
          <div><br>
          </div>
          <div><br>
          </div>
          <div>One or more class annotations could appear below
            package/imports?<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    No package statement (unnamed classes live in the unnamed package),
    but imports are OK.  No class annotations.  No type variables.  No
    superclasses.  <br>
    <br>
    <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"> Such source
                  files can still have fields, methods, and even nested
                  classes, </font></font></div>
          </blockquote>
          <div><br>
          </div>
          <div>Do those get compiled to real nested classes, nested
            inside an unnamed class? So if I edit a "regular" `Foo.java`
            file, go down below the last `}` and add a `main` function
            there, does that cause the whole `Foo` class above to be
            reinterpreted as "nested inside an unnamed class" instead of
            top-level?</div>
        </div>
      </div>
    </blockquote>
    <br>
    To be discussed!<br>
    <br>
    <blockquote type="cite">
      <div dir="ltr">
        <div class="gmail_quote">This is my notion of a natural
          progression:
          <div><br>
          </div>
          <div>1. Write procedural code: calling static methods, using
            existing data types, soon calling their instance methods</div>
          <div>2. Proceed to creating your own types (from simple data
            types onward) and using them too</div>
          <div>3. One day learn that your main() function is actually a
            method of an instantiable type too... at pub trivia night,
            then promptly forget it</div>
        </div>
      </div>
    </blockquote>
    <br>
    Right.<br>
    <br>
    <br>
    <br>
  </div>

</blockquote></div>