Paving the on-ramp
Kevin Bourrillion
kevinb at google.com
Thu Sep 29 00:37:47 UTC 2022
Again, big fan of getting to a streamlined main() source file.
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.
And it sounds virtuous. But... is it? Really?
Take a language that has this pretty streamlined already (I'll use the one
I know):
```
fun main() {
...
}
```
As my program grows and gets more complex, I will make changes like
* use more other libraries
* add args to main()
* add helper methods
* add constants
* create new classes and use them from here
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?
If I need those other qualities, then I create a class to get them, maybe
even right below main(), and I use it. I'm already going to be regularly
needing to do that anyway just as my code grows.
A quick clarification:
On Wed, Sep 28, 2022 at 12:49 PM Kevin Bourrillion <kevinb at google.com>
wrote:
Because excessive use of `static` is considered a code smell, many
>> educators encourage the pattern of "all the static `main` method does is
>> instantiate an instance and call an instance `main` method" anyway.
>>
>
> Heavy groan. In my opinion, some ideas are too misguided to take seriously.
>
> The value in that practice is if instance `main` accepts parameters like
> `PrintStream` and `Console`, and static main passes in `System.out` and
> `System.console()`. That makes all your actual program logic unit-testable.
> Great! This actually strikes directly at the heart of what the entire
> problem with `static` is! But this isn't the case you're addressing.
>
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.)
(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.)
To resume with the original text...
On Wed, Sep 28, 2022 at 10:57 AM Brian Goetz <brian.goetz at oracle.com> wrote:
## Unnamed classes
>
> In a simple program, the `class` declaration often doesn't help either,
> because
> other classes (if there are any) are not going to reference it by name,
> and we
> don't extend a superclass or implement any interfaces.
>
How do I tell `java` which class file to load and call main() on? Class
name based on file name, I guess?
Tiny side benefit of dropping all the `static`s: then if you also use an
unnamed class you can still make method references to your own helper
methods.
If we say an "unnamed
> class" consists of member declarations without a class header, then our
> Hello
> World program becomes:
>
> ```
> void main() {
> System.out.println("Hello World");
> }
> ```
>
One or more class annotations could appear below package/imports?
Such source files can still have fields, methods, and even nested classes,
>
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?
Students need
>
not confront the confusing distinction between instance and static methods
> yet;
> indeed, if not forced to confront static members on day 1, it might be a
> while
> before they do have to learn this distinction.
>
Well, they'll confront it from the calling side, `str.length()` looks quite
different from unqualified calls and classname-qualified calls. They'd
ideally get a chance to understand that first before making their own
classes.
This is my notion of a natural progression:
1. Write procedural code: calling static methods, using existing data
types, soon calling their instance methods
2. Proceed to creating your own types (from simple data types onward) and
using them too
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
> The fact that there is a
> receiver lurking in the background will come in handy later,
>
(My claim up above is "I don't think it will.")
--
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-spec-observers/attachments/20220928/88942e1c/attachment-0001.htm>
More information about the amber-spec-observers
mailing list