Initial discussion of solutions for issues presented in amber-dev/2022-May/007322

Julian Waters tanksherman27 at gmail.com
Thu May 19 04:32:39 UTC 2022


Hi all,

Previously a list of issues were laid out in a previous posting to help
visualize the problem and (try to help) guide future attempts at tackling
it. I'd thought I'd just throw a few wild ideas out here at the moment to
keep things going for now in the background as work on Amber continues.

As mentioned, a significant amount of Java boilerplate stems from code that
is written procedurally- Functionally if you will. These usually take the
form of final classes with constructors that throw exceptions, which only
contain static methods. An initial naive approach could be to allow methods
to be defined in packages themselves without an enclosing class; This "top
level" code is intuitively appealing to modern developers and cuts
boilerplate for simple programs down to virtually zero. Of course, there is
the problem that Java ultimately compiles down to classfiles, and having
free floating methods in the JVM would probably require a significant
amount of effort to add with diminishing returns. However, at runtime the
developer has no care for whether their code compiles to classes, and
classes in the metaspace are already excellent (static) method containers.
It would seem a little wasteful to not reuse this and simply compile
package level code into an anonymous class when javac is run.

This approach does raise the interesting question of whether an entirely
new class type should be introduced for this purpose so javac can utilize
it when compiling "package level methods" (I'll give it the arbitrary name
of ACC_PACKAGE for now); They would only allow static members, and no
constructors (or anything object related) whatsoever, to be defined. Far
from just being more syntactical sugar, this could possibly let us have a
new minimal Klass type in the JVM with all the support for creating objects
(vtable index, subclass and superclass support, and everything else object
related that's defined in the base Klass that every other klass type
inherits from) removed entirely. I may be entirely wrong here, but to me it
would seem that the resulting tighter packing in the metaspace would result
in, at the very least, improvement of memory consumption for classes that
will never need it.

Of course, it wouldn't hurt to allow manually defining an "ACC_PACKAGE"
class (eg public package Util {}) either, such as if the developer wishes
not to take up an entire package namespace for just a few utility methods.
An obvious thing to do is have all methods and fields defined in these
special classes be static by default without requiring the "static" keyword
(In fact it would be an error for them to *not* be static at all). What
would be up for discussion is whether to allow defining them differently in
a way that would avoid the typical "class XXX {}" declaration (Much like
what is already done with records. Maybe we could merge package and class
declarations for these special classes?).

There's obviously many more things to address (Should we allow nesting
these classes, or nesting *in* these classes? What should the default
access level be now that we don't have to be worried about
subclass/protected access? Should defining package level methods be allowed
in a file that also contains a regular class? And so on), but hopefully
this is a good first start as a whole.

(Special thanks to Mariell Hoversholm for helping out with certain areas in
a private conversation)

best regards,
Julian


More information about the amber-dev mailing list