<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">Discussion here seems to have
        settled down.  Here's what seem like the possibly-open parts: <br>
        <br>
         - Most of the concerns centered around the imports part, not
        the main part.  We should think some more about alternatives for
        Console IO other than auto-importing a static println method;
        this might mean that their invocation is something more verbose
        than just "println", but better than "System.out.println", and
        possibly more discoverable.  In the meantime, we'll separate off
        the auto-import for STR as part of string templates to decouple
        these trains.  <br>
        <br>
         - The notion of "unnamed class" seems to fill a hole alongside
        "unnamed package" and "unnamed module", but the analogy is
        imperfect, because these classes _will_ have a name, just not
        one visible from _inside_ the class.  The alternative is to view
        these as _implicitly named_ classes, where they have a name,
        just derived from the file system rather than the source code. 
        The distinction might influence whether such simplified class
        declarations can have constructors (if you can't name it, you
        can't name the constructor), whether static methods or fields
        can be accessed from within the class, etc.  (However, these
        influences are weak; we could still reasonably choose to
        disallow constructors and instance initializers even if the name
        is denotable.)  <br>
        <br>
        We could, of course, prevent class access from outside the class
        too, effectively making such classes visible only to the
        launcher.  But this would come at no small cost to prevent such
        accesses, and for limited benefit.  The status-quo proposal
        currently says: the name of the class is not visible from within
        the class, you can't have constructors or instance initializers,
        you get an implicit no-arg constructor like every other
        constructor-less class.  If you want a more complex construction
        protocol, or supertypes, or class declaration annotations, or to
        live in a package, declare a class.  This still seems pretty
        OK.  <br>
        <br>
        <br>
        <br>
      </font></font><br>
    <div class="moz-cite-prefix">On 10/12/2022 7:56 PM, Brian Goetz
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:d8e77325-b6a2-f9ea-92a2-7a4c27573b51@oracle.com">
      
      <font size="4"><font face="monospace">I've gotten some good
          feedback from this writeup, much of it illuminating how
          different people (myself included) make different assumptions
          about how certain things work / what things are for.  <br>
          <br>
          #### Role of main<br>
          <br>
          A main() method can be viewed from two perspectives: it is an
          ordinary method with modifiers, parameters, etc, but it is
          also an externally significant _entry point_ into a program. 
          (We've seen a similar double-duty with method parameters in
          the context of the underscore discussion: a method parameter
          is both a "local" that serves the implementation of the
          method, but its also part of the specification of the method
          (e.g., the name and type bleed into the Javadoc.))  <br>
          <br>
          Java made the choice in 1995 that an entry point is "just" a
          suitably named / structured / accessible method.  This was
          somewhat "un-Java-ish", as identification of main-ness is a
          structural property, and Java (certainly back then) mostly
          avoided such structural techniques where it could.  I think
          its fair to question whether this decision is still serving us
          (Stephen's proposal does exactly that), but I think this was a
          pragmatic choice and I'm inclined to continue to run with it,
          rather than look at it as something "to be fixed".  <br>
          <br>
          So the proposal broadens the structure parameters around "what
          is a main", but ultimately leaves the "some methods are
          special" decision in place.  (Aside: if we'd had annotations
          in Java 1.0, we might well have used an @EntryPoint capture
          the metadata of "this method is externally launchable", and
          let the launcher reflect over the methods of a class to find a
          suitable entry point.  But we didn't, and trying to rewrite
          history in this way is likely a losing game.)  <br>
          <br>
          #### Role of launcher<br>
          <br>
          This raises a secondary question about the role of the
          launcher.  My mental model was one of "the launcher is just
          some out-of-sight code that invokes the main method."  That
          `main` (currently) should be public plays into this, because
          if this out-of-sight code is going to call this method, surely
          accessibility will have a chance to say "can this code call
          this method".  I was surprised, though, to find out that
          others have a different view of this.  Kevin asked whether it
          was a "bug" in the model that, in order for the launcher to be
          able to call a `main` method, then so must other code.  This
          is a form of coupling that I had assumed is pure good (because
          it means there's a unified model of invocation), but is
          reasonable to call it out as a coupling.<br>
          <br>
          In my view, treating the launcher as "just another caller"
          simplifies the story, because we don't have to have a separate
          story for invoking entry points.  If we're doubling down on
          "main is just a method with some special metadata that says
          'start here'", then doubling down on accessibility here as
          well makes sense to me also.  Hence my suggestion to frame the
          launcher as "ordinary code in the unnamed package".  But as
          natural as this seems to me, I recognize that this may seem
          weird to others.  <br>
          <br>
          #### Role of unnamed packages<br>
          <br>
          Another place where there were differing viewpoints is on the
          role of unnamed packages.  Some felt that using the unnamed
          package at all should be reserved for the most transient of
          "run it once and delete it" programs; others felt that it had
          a role beyond mere experiments.  <br>
          <br>
          In part because of the difficulties described in the On Ramp
          document, Java has not found extensive use in scripts, but we
          are hoping that this will become more common over time.  (The
          "Launch Single File Java Programs" JEP was a step towards
          being more script-friendly.)  I would think that the unnamed
          package is the right place for scripts as well, since users
          will want to identify the program by its path in the file
          system, not by setting up a class path and referring to a
          relative position within that.  <br>
          <br>
          Overall, I think the result of this project will be that
          *more* code lives in the unnamed package -- and that's OK,
          because people will write more simple, self-contained programs
          in Java, and the unnamed package is an OK place for these
          things to live.  <br>
          <br>
          #### Instance main and interfaces<br>
          <br>
          Several folks have pointed out that perhaps an instance main
          should be specified by an interface (say, Program), and that
          unnamed classes implicitly implement Program.  This has some
          attraction, since this is generally how we prevent names from
          being magic.  <br>
          <br>
          There are some downsides, though.  We already have two ways to
          spell "main"; we might want more in the future, and having to
          spell them all out in an interface (even with defaults) could
          impede evolution.  More importantly, this is using a different
          mechanism that we use for the main we currently have, which
          means there are two different ways to identify the two kinds
          of main.  This is starting to veer into the sort of "fix
          mistakes of the past" siren song which leaves you with two
          different ways of doing the same thing, which appears to new
          users as more complexity, not less.  <br>
          <br>
          #### Moral hazards<br>
          <br>
          A significant proportion of the negative feedback to the
          proposal amounted to some sort of "moral hazard".  The biggest
          component here was that shortening `System.out.println()` to
          `println()` would encourage people to use console IO more
          often, in places where it was not appropriate, or that it
          would be an impediment to testing.  I didn't find this
          argument very compelling, though; I don't think the number of
          characters required to access console IO is the determining
          factor here in choosing an IO strategy (or even being aware
          that there is such a thing as an IO strategy.)<br>
          <br>
          #### Console IO<br>
          <br>
          There were a variety of opinions on the direction we should go
          with simplifying console IO.  While nearly everyone agrees
          that `System.out.println` is a mouthful, there were a number
          of alternate approaches suggested, such as:<br>
          <br>
           - Expose new classes (e.g., SystemOut) with static methods
          (SystemOut.println) instead of new static methods;<br>
           - Expose a new API for console IO, but don't auto-import
          anything;<br>
           - Auto-import console IO methods only in unnamed classes;<br>
           - others.<br>
          <br>
          #### Auto imports<br>
          <br>
          After some thought, I realize that the auto-import feature is
          trying to serve two separate goals, and maybe is getting
          distorted because of it.  The String Templates JEP defines
          some canned processors (STR and FMT), which are effectively
          part of the language.  At first blush (which is when people
          are often most vocal about peripheral features), people
          already don't like having to type STR-dot (sorry, not changing
          our mind about that), and having to import STR feels like
          adding insult to injury.  STR is effectively part of the
          language, so we don't want to place hoops in the way of using
          it.  But that is a slightly different use case than rescuing
          println, for which there are multiple possible paths.  Maybe
          its best to separate these.  <br>
          <br>
          <br>
          The On Ramp document outlined some (admittedly fuzzy) goals
          which may be helpful for evaluating some of these thoughts. 
          We are not trying to create a "beginner's dialect of Java",
          nor am I particularly interested in using this effort to turn
          back the clock and redesign features that some people wish had
          been designed otherwise.  The goal here is, to the extent
          possible, to make elements of program declaration recede into
          the background until they are actually adding value.  Access
          control, classes, statics, etc, should come into the picture
          when they are needed, and not before.  I'm sure that there are
          other aspects of the language that people would like to have
          recede into the background too, and will attempt to attach to
          this project, but I'm interested in focusing primarily on
          those that are impediments to learning the language.  If we do
          our job right, these will have benefits well beyond the first
          few days of using Java.<br>
          <br>
          My thoughts: <br>
          <br>
           - Java made the choice that "entry points" are specially
          structured methods, and can be called both programmatically
          and via the launcher.  I see no reason to tinker with this
          concept, or to materially change how entry points are declared
          -- just to widen the range of `main` methods that are
          considered entry points.  <br>
          <br>
           - While the JLS doesn't really say what the launcher is (just
          that there is something that launches programs), positioning
          the launcher as some code in the unnamed package seems
          helpful, because familiar concepts of access control apply
          both to programmatic and command line invocation.  <br>
          <br>
           - While I get that some people find the unnamed package to be
          a "smell", I think it is actually fine for a range of
          programs, and I expect that range to broaden over time as
          people start using Java for scripts.  <br>
          <br>
           - I am sympathetic to the argument that people don't want
          "println" and friends to effectively become global; this is
          separate from simplifying the locution.  Where there may be an
          attractive middle ground is:<br>
          <br>
              - Take the new methods for console IO and put them
          somewhere in java.lang, say ConsoleIO;<br>
              - Auto-import ConsoleIO only in unnamed classes.<br>
          <br>
          While this creates a new coupling, it may align well, in that
          the programs who most want access to console IO are those that
          are most likely to be able to be unnamed classes -- and the
          rest can import all the console IO with a single `import
          static ConsoleIO.*`.  Refactoring to a named class would then
          involve adding both the class wrapper and this import.  <br>
          <br>
           - I am open to other approaches for improving the console IO
          story.  Maybe this is Console.println(), which avoids the need
          for auto-static-import at all at the cost of some more words
          (but at least doesn't require understanding static fields, and
          has the advantage that all the console stuff can be in one
          place), or maybe something else.  (A big part of the problem
          with the status quo now is that not only is System.out.println
          undiscoverable, but having found that, you still have no idea
          where "readln" is.)  <br>
          <br>
           - While I get why people are attracted to putting instance
          main in an interface, I don't think I'd like the result.  As
          mentioned above, this implicitly places an impediment in
          future expansion of the launcher protocol, but more
          importantly, means we have two mechanisms for finding main --
          an "old" and "new" one.  I try hard to avoid creating this
          situation, because the benefit is rarely worth the increased
          cognitive load.  <br>
          <br>
          <br>
          <br>
          <br>
        </font></font><br>
      <div class="moz-cite-prefix">On 9/28/2022 1:57 PM, Brian Goetz
        wrote:<br>
      </div>
      <blockquote type="cite" cite="mid:1b6200d3-a7a6-6479-e8ab-d932eedbceb1@oracle.com"> <font size="4"><font face="monospace">At various points, we've
            explored the question of which program elements are most and
            least helpful for students first learning Java.  After
            considering a number of alternatives over the years, I have
            a simple proposal for smoothing the "on ramp" to Java
            programming, while not creating new things to unlearn.  <br>
            <br>
            Markdown source is below, HTML will appear soon at: <br>
            <br>
                <a class="moz-txt-link-freetext" href="https://openjdk.org/projects/amber/design-notes/on-ramp" moz-do-not-send="true">https://openjdk.org/projects/amber/design-notes/on-ramp</a><br>
            <br>
            <br>
            # Paving the on-ramp<br>
            <br>
            Java is one of the most widely taught programming languages
            in the world.  Tens<br>
            of thousands of educators find that the imperative core of
            the language combined<br>
            with a straightforward standard library is a foundation that
            students can<br>
            comfortably learn on.  Choosing Java gives educators many
            degrees of freedom:<br>
            they can situate students in `jshell` or Notepad or a
            full-fledged IDE; they can<br>
            teach imperative, object-oriented, functional, or hybrid
            programming styles; and<br>
            they can easily find libraries to interact with external
            data and services.  <br>
            <br>
            No language is perfect, and one of the most common
            complaints about Java is that<br>
            it is "too verbose" or has "too much ceremony."  And
            unfortunately, Java imposes<br>
            its heaviest ceremony on those first learning the language,
            who need and<br>
            appreciate it the least.  The declaration of a class and the
            incantation of<br>
            `public static void main` is pure mystery to a beginning
            programmer.  While<br>
            these incantations have principled origins and serve a
            useful organizing purpose<br>
            in larger programs, they have the effect of placing
            obstacles in the path of<br>
            _becoming_ Java programmers. Educators constantly remind us
            of the litany of<br>
            complexity that students have to confront on Day 1 of class
            -- when they really<br>
            just want to write their first program.  <br>
            <br>
            As an amusing demonstration of this, in her JavaOne keynote
            appearance in 2019,<br>
            [Aimee Lucido](<a class="moz-txt-link-freetext" href="https://www.youtube.com/watch?v=BkPPFiXUwYk" moz-do-not-send="true">https://www.youtube.com/watch?v=BkPPFiXUwYk</a>)
            talked about when<br>
            she learned to program in Java, and how her teacher
            performed a rap song<br>
            to help students memorize `"public static void main"`.  Our
            hats are off to<br>
            creative educators everywhere for this kind of dedication,
            but teachers<br>
            shouldn't have to do this.<br>
            <br>
            Of course, advanced programmers complain about ceremony
            too.  We will never be<br>
            able to satisfy programmers' insatiable appetite for typing
            fewer keystrokes,<br>
            and we shouldn't try, because the goal of programming is to
            write programs that<br>
            are easy to read and are clearly correct, not programs that
            were easy to type.<br>
            But we can try to better align the ceremony commensurate
            with the value it<br>
            brings to a program -- and let simple programs be expressed
            more simply.  <br>
            <br>
            ## Concept overload<br>
            <br>
            The classic "Hello World" program looks like this in Java:<br>
            <br>
            ```<br>
            public class HelloWorld { <br>
                public static void main(String[] args) { <br>
                    System.out.println("Hello World");<br>
                }<br>
            }<br>
            ```<br>
            <br>
            It may only be five lines, but those lines are packed with
            concepts that are<br>
            challenging to absorb without already having some
            programming experience and<br>
            familiarity with object orientation. Let's break down the
            concepts a student<br>
            confronts when writing their first Java program:<br>
            <br>
              - **public** (on the class).  The `public` accessibility
            level is relevant<br>
                only when there is going to be cross-package access; in
            a simple "Hello<br>
                World" program, there is only one class, which lives in
            the unnamed package.<br>
                They haven't even written a one-line program yet; the
            notion of access<br>
                control -- keeping parts of a program from accessing
            other parts of it -- is<br>
                still way in their future.<br>
            <br>
              - **class**.  Our student hasn't set out to write a
            _class_, or model a<br>
                complex system with objects; they want to write a
            _program_.  In Java, a<br>
                program is just a `main` method in some class, but at
            this point our student<br>
                still has no idea what a class is or why they want one.<br>
            <br>
              - **Methods**.  Methods are of course a key concept in
            Java, but the mechanics<br>
                of methods -- parameters, return types, and invocation
            -- are still<br>
                unfamiliar, and the `main` method is invoked magically
            from the `java`<br>
                launcher rather than from explicit code.  <br>
            <br>
              - **public** (again).  Like the class, the `main` method
            has to be public, but<br>
                again this is only relevant when programs are large
            enough to require<br>
                packages to organize them.  <br>
            <br>
              - **static**.  The `main` method has to be static, and at
            this point, students<br>
                have no context for understanding what a static method
            is or why they want<br>
                one.  Worse, the early exposure to `static` methods will
            turn out to be a<br>
                bad habit that must be later unlearned.  Worse still,
            the fact that the<br>
                `main` method is `static` creates a seam between `main`
            and other methods;<br>
                either they must become `static` too, or the `main`
            method must trampoline<br>
                to some sort of "instance main" (more ceremony!)  And if
            we get this wrong,<br>
                we get the dreaded and mystifying `"cannot be referenced
            from a static<br>
                context"` error.<br>
            <br>
              - **main**.  The name `main` has special meaning in a Java
            program, indicating<br>
                the starting point of a program, but this specialness
            hides behind being an<br>
                ordinary method name.  This may contribute to the sense
            of "so many magic<br>
                incantations."<br>
            <br>
              - **String[]**.  The parameter to `main` is an array of
            strings, which are the<br>
                arguments that the `java` launcher collected from the
            command line.  But our<br>
                first program -- likely our first dozen -- will not use
            command-line<br>
                parameters. Requiring the `String[]` parameter is, at
            this point, a mistake<br>
                waiting to happen, and it will be a long time until this
            parameter makes<br>
                sense.  Worse, educators may be tempted to explain
            arrays at this point,<br>
                which further increases the time-to-first-program.<br>
            <br>
              - **System.out.println**.  If you look closely at this
            incantation, each<br>
                element in the chain is a different thing -- `System` is
            a class (what's a<br>
                class again?), `out` is a static field (what's a
            field?), and `println` is<br>
                an instance method.  The only part the student cares
            about right now is<br>
                `println`; the rest of it is an incantation that they do
            not yet understand<br>
                in order to get at the behavior they want.<br>
            <br>
            That's a lot to explain to a student on the first day of
            class.  There's a good<br>
            chance that by now, class is over and we haven't written any
            programs yet, or<br>
            the teacher has said "don't worry what this means, you'll
            understand it later"<br>
            six or eight times.  Not only is this a lot of _syntactic_
            things to absorb, but<br>
            each of those things appeals to a different concept (class,
            method, package,<br>
            return value, parameter, array, static, public, etc) that
            the student doesn't<br>
            have a framework for understanding yet.  Each of these will
            have an important<br>
            role to play in larger programs, but so far, they only
            contribute to "wow,<br>
            programming is complicated."  <br>
            <br>
            It won't be practical (or even desirable) to get _all_ of
            these concepts out of<br>
            the student's face on day 1, but we can do a lot -- and
            focus on the ones that<br>
            do the most to help beginners understand how programs are
            constructed.<br>
            <br>
            ## Goal: a smooth on-ramp<br>
            <br>
            As much as programmers like to rant about ceremony, the real
            goal here is not<br>
            mere ceremony reduction, but providing a graceful _on ramp_
            to Java programming.<br>
            This on-ramp should be helpful to beginning programmers by
            requiring only those<br>
            concepts that a simple program needs.  <br>
            <br>
            Not only should an on-ramp have a gradual slope and offer
            enough acceleration<br>
            distance to get onto the highway at the right speed, but its
            direction must<br>
            align with that of the highway.  When a programmer is ready
            to learn about more<br>
            advanced concepts, they should not have to discard what
            they've already learned,<br>
            but instead easily see how the simple programs they've
            already written<br>
            generalize to more complicated ones, and both the syntatic
            and conceptual<br>
            transformation from "simple" to "full blown" program should
            be straightforward<br>
            and unintrusive.  It is a definite non-goal to create a
            "simplified dialect of<br>
            Java for students".<br>
            <br>
            We identify three simplifications that should aid both
            educators and students in<br>
            navigating the on-ramp to Java, as well as being generally
            useful to simple<br>
            programs beyond the classroom as well:<br>
            <br>
             - A more tolerant launch protocol<br>
             - Unnamed classes<br>
             - Predefined static imports for the most critical methods
            and fields<br>
            <br>
            ## A more tolerant launch protocol<br>
            <br>
            The Java Language Specification has relatively little to say
            about how Java<br>
            "programs" get launched, other than saying that there is
            some way to indicate<br>
            which class is the initial class of a program (JLS 12.1.1)
            and that a public<br>
            static method called `main` whose sole argument is of type
            `String[]` and whose<br>
            return is `void` constitutes the entry point of the
            indicated class.  <br>
            <br>
            We can eliminate much of the concept overload simply by
            relaxing the<br>
            interactions between a Java program and the `java` launcher:<br>
            <br>
             - 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>
            <br>
             - 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>
            <br>
             - 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>
            <br>
            This small set of changes to the launch protocol strikes out
            five of the bullet<br>
            points in the above list of concepts: public (twice),
            static, method parameters,<br>
            and `String[]`.  <br>
            <br>
            At this point, our Hello World program is now:<br>
            <br>
            ```<br>
            class HelloWorld { <br>
                void main() { <br>
                    System.out.println("Hello World");<br>
                }<br>
            }<br>
            ```<br>
            <br>
            It's not any shorter by line count, but we've removed a lot
            of "horizontal<br>
            noise" along with a number of concepts.  Students and
            educators will appreciate<br>
            it, but advanced programmers are unlikely to be in any hurry
            to make these<br>
            implicit elements explicit either.  <br>
            <br>
            Additionally, the notion of an "instance main" has value
            well beyond the first<br>
            day.  Because excessive use of `static` is considered a code
            smell, many<br>
            educators encourage the pattern of "all the static `main`
            method does is<br>
            instantiate an instance and call an instance `main` method"
            anyway.  Formalizing<br>
            the "instance main" protocol reduces a layer of boilerplate
            in these cases, and<br>
            defers the point at which we have to explain what instance
            creation is -- and<br>
            what `static` is.  (Further, allowing the `main` method to
            be an instance method<br>
            means that it could be inherited from a superclass, which is
            useful for simple<br>
            frameworks such as test runners or service frameworks.)<br>
            <br>
            ## 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.  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>
            <br>
            Such source files can still have fields, methods, and even
            nested classes, so<br>
            that as a program evolves from a few statements to needing
            some ancillary state<br>
            or helper methods, these can be factored out of the `main`
            method while still<br>
            not yet requiring a full class declaration:<br>
            <br>
            ```<br>
            String greeting() { return "Hello World"; }<br>
            <br>
            void main() {<br>
                System.out.println(greeting());<br>
            }<br>
            ```<br>
            <br>
            This is where treating `main` as an instance method really
            shines; the user has<br>
            just declared two methods, and they can freely call each
            other.  Students need<br>
            not confront the confusing distinction between instance and
            static methods yet;<br>
            indeed, if not forced to confront static members on day 1,
            it might be a while<br>
            before they do have to learn this distinction.  The fact
            that there is a<br>
            receiver lurking in the background will come in handy later,
            but right now is<br>
            not bothering anybody.<br>
            <br>
            [JEP 330](<a class="moz-txt-link-freetext" href="https://openjdk.org/jeps/330" moz-do-not-send="true">https://openjdk.org/jeps/330</a>)
            allows single-file programs to be<br>
            launched directly without compilation; this streamlined
            launcher pairs well with<br>
            unnamed classes. <br>
            <br>
            ## Predefined static imports<br>
            <br>
            The most important classes, such as `String` and `Integer`,
            live in the<br>
            `java.lang` package, which is automatically on-demand
            imported into all<br>
            compilation units; this is why we do not have to `import
            java.lang.String` in<br>
            every class.  Static imports were not added until Java 5,
            but no corresponding<br>
            facility for automatic on-demand import of common behavior
            was added at that<br>
            time.  Most programs, however, will want to do console IO,
            and Java forces us to<br>
            do this in a roundabout way -- through the static
            `System.out` and `System.in`<br>
            fields.  Basic console input and output is a reasonable
            candidate for<br>
            auto-static import, as one or both are needed by most simple
            programs.  While<br>
            these are currently instance methods accessed through static
            fields, we can<br>
            easily create static methods for `println` and `readln`
            which are suitable for<br>
            static import, and automatically import them.  At which
            point our first program<br>
            is now down to:<br>
            <br>
            ```<br>
            void main() {<br>
                println("Hello World");<br>
            }<br>
            ```<br>
            <br>
            ## Putting this all together<br>
            <br>
            We've discussed several simplifications:<br>
            <br>
             - Update the launcher protocol to make public, static, and
            arguments optional<br>
               for main methods, and for main methods to be instance
            methods (when a<br>
               no-argument constructor is available); <br>
             - Make the class wrapper for "main classes" optional
            (unnamed classes);<br>
             - Automatically static import methods like `println`<br>
            <br>
            which together whittle our long list of day-1 concepts down
            considerably.  While<br>
            this is still not as minimal as the minimal Python or Ruby
            program -- statements<br>
            must still live in a method -- the goal here is not to win
            at "code golf".  The<br>
            goal is to ensure that concepts not needed by simple
            programs need not appear in<br>
            those programs, while at the same time not encouraging
            habits that have to be<br>
            unlearned as programs scale up. <br>
            <br>
            Each of these simplifications is individually small and
            unintrusive, and each is<br>
            independent of the others.  And each embodies a simple
            transformation that the<br>
            author can easily manually reverse when it makes sense to do
            so: elided<br>
            modifiers and `main` arguments can be added back, the class
            wrapper can be added<br>
            back when the affordances of classes are needed (supertypes,
            constructors), and<br>
            the full qualifier of static-import can be added back.  And
            these reversals are<br>
            independent of one another; they can done in any combination
            or any order.<br>
            <br>
            This seems to meet the requirements of our on-ramp; we've
            eliminated most of the<br>
            day-1 ceremony elements without introducing new concepts
            that need to be<br>
            unlearned. The remaining concepts -- a method is a container
            for statements, and<br>
            a program is a Java source file with a `main` method -- are
            easily understood in<br>
            relation to their fully specified counterparts.  <br>
            <br>
            ## Alternatives<br>
            <br>
            Obviously, we've lived with the status quo for 25+ years, so
            we could continue<br>
            to do so.  There were other alternatives explored as well;
            ultimately, each of<br>
            these fell afoul of one of our goals.<br>
            <br>
            ### Can't we go further?<br>
            <br>
            Fans of "code golf" -- of which there are many -- are surely
            right now trying to<br>
            figure out how to eliminate the last little bit, the `main`
            method, and allow<br>
            statements to exist at the top-level of a program.  We
            deliberately stopped<br>
            short of this because it offers little value beyond the
            first few minutes, and<br>
            even that small value quickly becomes something that needs
            to be unlearned.  <br>
            <br>
            The fundamental problem behind allowing such "loose"
            statements is that<br>
            variables can be declared inside both classes (fields) and
            methods (local<br>
            variables), and they share the same syntactic production but
            not the same<br>
            semantics.  So it is unclear (to both compilers and humans)
            whether a "loose"<br>
            variable would be a local or a field.  If we tried to adopt
            some sort of simple<br>
            heuristic to collapse this ambiguity (e.g., whether it
            precedes or follows the<br>
            first statement), that may satisfy the compiler, but now
            simple refactorings<br>
            might subtly change the meaning of the program, and we'd be
            replacing the<br>
            explicit syntactic overhead of `void main()` with an
            invisible "line" in the<br>
            program that subtly affects semantics, and a new subtle rule
            about the meaning<br>
            of variable declarations that applies only to unnamed
            classes.  This doesn't<br>
            help students, nor is this particularly helpful for all but
            the most trivial<br>
            programs.  It quickly becomes a crutch to be discarded and
            unlearned, which<br>
            falls afoul of our "on ramp" goals.  Of all the concepts on
            our list, "methods"<br>
            and "a program is specified by a main method" seem the ones
            that are most worth<br>
            asking students to learn early.<br>
            <br>
            ### Why not "just" use `jshell`?  <br>
            <br>
            While JShell is a great interactive tool, leaning too
            heavily on it as an onramp<br>
            would fall afoul of our goals.  A JShell session is not a
            program, but a<br>
            sequence of code snippets.  When we type declarations into
            `jshell`, they are<br>
            viewed as implicitly static members of some unspecified
            class, with<br>
            accessibility is ignored completely, and statements execute
            in a context where<br>
            all previous declarations are in scope.  This is convenient
            for experimentation<br>
            -- the primary goal of `jshell` -- but not such a great
            mental model for<br>
            learning to write Java programs.  Transforming a batch of
            working declarations<br>
            in `jshell` to a real Java program would not be sufficiently
            simple or<br>
            unintrusive, and would lead to a non-idiomatic style of
            code, because the<br>
            straightforward translation would have us redeclaring each
            method, class, and<br>
            variable declaration as `static`.  Further, this is probably
            not the direction<br>
            we want to go when we scale up from a handful of statements
            and declarations to<br>
            a simple class -- we probably want to start using classes as
            classes, not just<br>
            as containers for static members. JShell is a great tool for
            exploration and<br>
            debugging, and we expect many educators will continue to
            incorporate it into<br>
            their curriculum, but is not the on-ramp programming model
            we are looking for.  <br>
            <br>
            ### What about "always local"?<br>
            <br>
            One of the main tensions that `main` introduces is that most
            class members are<br>
            not `static`, but the `main` method is -- and that forces
            programmers to<br>
            confront the seam between static and non-static members. 
            JShell answers this<br>
            with "make everything static". <br>
            <br>
            Another approach would be to "make everything local" --
            treat a simple program<br>
            as being the "unwrapped" body of an implicit main method. 
            We already allow<br>
            variables and classes to be declared local to a method.  We
            could add local<br>
            methods (a useful feature in its own right) and relax some
            of the asymmetries<br>
            around nesting (again, an attractive cleanup), and then
            treat a mix of<br>
            declarations and statements without a class wrapper as the
            body of an invisible<br>
            `main` method. This seems an attractive model as well -- at
            first.<br>
            <br>
            While the syntactic overhead of converting back to
            full-blown classes -- wrap<br>
            the whole thing in a `main` method and a `class` declaration
            -- is far less<br>
            intrusive than the transformation inherent in `jshell`, this
            is still not an<br>
            ideal on-ramp.  Local variables interact with local classes
            (and methods, when<br>
            we have them) in a very different way than instance fields
            do with instance<br>
            methods and inner classes: their scopes are different (no
            forward references),<br>
            their initialization rules are different, and captured local
            variables must be<br>
            effectively final.  This is a subtly different programming
            model that would then<br>
            have to be unlearned when scaling up to full classes.
            Further, the result of<br>
            this wrapping -- where everything is local to the main
            method -- is also not<br>
            "idiomatic Java".  So while local methods may be an
            attractive feature, they are<br>
            similarly not the on-ramp we are looking for.<br>
            <br>
            <br>
          </font></font> </blockquote>
      <br>
    </blockquote>
    <br>
  </body>
</html>