JEP proposed to target JDK 11: 330: Launch Single-File Source-Code Programs
Brian Goetz
brian.goetz at oracle.com
Thu May 24 00:41:20 UTC 2018
> On 21/05/18 16:41, Brian Goetz wrote:
>> I think this is mostly a "glass 5% empty" argument. Let's retrace our
>> steps.
> Before we 'retrace' may I ask: was that meant to be 5% or 50%?
I did mean 5%. The small number was not intended to minimize Roman's
concern, but to minimize the place of the shebang feature in this JEP
itself. In setting our goals for the project, shebang support was
always a pretty small, and entirely optional, part of the picture (a
"stretch goal"). So if a small part of the whole is somewhat smaller
than some might prefer, the difference is, necessarily, pretty small.
(If we hadn't found a reasonably stable place to draw the line (I think
we were kind of lucky to have done so), we would have been perfectly
fine to have no shebang support, but I do think the status quo is much
better than that.)
> It certainly is not what I
> was expecting and hoping to hear given your use of the word 'retrace'.
OK, let me explain the sense of "retrace" here. As one of the
instigators for this project, I am in a position to speak
authoritatively to motivation, intentions, and goals. While we of
course attempt to lay these out in the JEP and in related
communications, the reality is that one will never capture all the
possible tradeoffs and interpretations in a short document. So, when
someone comes along with a different idea of what the goals of the
project could have been, the sensible first step is to go back to our
motivation, and clarify, in the context of the current relevant
question. (This isn't necessarily a failing of the expression of the
JEP; no one would be served by a 200 page JEP that tries to anticipate
every possible interaction and interpretation, and the cost of producing
such a document would be way out of line with its value.) So by
retrace, I mean "let's go back to the inception of the project, which is
necessarily uncaptured, and look at the thoughts that were in our heads
at that time that might shed light on how we ended up where we did."
Since my first attempt seems to have missed the mark, let me retrace in
slightly more detail.
We have spent countless hours listening to people's concerns about Java;
these come from a wide range of sources, including developers, students,
teachers, etc. A general theme that people have expressed concern over
is "activation energy"; that doing simple things in Java requires too
much fixed work. Examples include:
- you have to download/install a JDK and IDE before you can write
Hello World
- "public static void main"
- You have to compile HelloWorld.java before you run it.
- Many libraries have a large fixed setup cost before you can do anything.
- the list goes on
Obviously, even a small amount of brainstorming along these lines could
generate hundreds of man-years of project work, so we can't do all of
them. So we made subjective choices about which had the best impact,
and we consider both the cost (in multiple dimensions) and benefit (or
our subjective estimates of the benefits) when making these choices.
One example of a project aimed, at least in part, at this problem was
JShell. I think this was very successful (but it was surely
expensive.) JEP 330 has both a smaller cost and a smaller benefit, but
the balance seemed in line, and the cost was in budget. So the goal
here was to simplify approachability and streamline simple tasks that
are perceived to have a high subjective activation energy. That's the
backdrop behind why we undertook this in the first place -- it provides
some relief in the activation energy department, as long as it has a
reasonable balance of cost and benefit.
Actually, the step-retracing goes much farther back than this. When we
did jshell, we considered whether jshell should also serve as a "batch
script runner", and this issue has been brought up plenty of times
since. But from the very beginning of the jshell project, we felt
strongly that this would be asking jshell to serve two masters; jshell
is intended as an interactive tool, and many decisions were made in
favor of a better interactive experience. If people want to just run a
single Java file in source form, a more principled approach would be to
teach the launchers about source files -- which was entirely practical,
and a much better fit for "I just want to run a 'script' file that is
written in Java." So the seeds of this project were sown several years
ago, and over those years, there have been many discussions (in many
places) about how to address this particular use case.
When we first started discussing this feature, we were thinking mostly
in terms of a more streamlined means of execution, but it didn't take
long to ask the question about packaging. If people want to write
"scripty" programs in Java, once developed, they're going to want to
package and install them, and this is also a high-activation-energy
aspect of Java (JARs, build scripts, etc). Shebang is a very
low-overhead form of packaging, and -- as long as it didn't perturb the
main goal or drive the cost or complexity over budget -- seemed to offer
pretty reasonable incremental benefit for a not-terrible incremental cost.
But, one can go too far, and turning this into a language feature would
have been taking it too far. The Java Language and VM try very hard to
be platform-neutral; shebang is definitively not platform-neutral. And,
anything having to do with the language spec incurs greater costs (I'm
not just talking development costs) and complexity. So, this isn't a
language feature, it's a platform integration feature. Which is why the
launcher is the right vehicle here -- this is where the Java platform
meets the underlying platform.
Volker raised this question early on. We had already thought about the
implications of this (we generally think pretty deeply about the many
possible roads one could take before we propose a project), and we
didn't like them -- because, as mentioned above, this is a platform
integration issue, not a language issue. I don't deny that it would be
nice in certain situations if we made no distinction between "Java
source file" and "scripts that happen to contain Java source code" --
and that might be a perfectly reasonable choice for some other languages
-- but the goal was never "Java as a scripting language". So, while
"why not go all the way with shebang" is a reasonable question to ask,
it seemed (and still seems) the wrong match for Java. When the question
came up again (as they always do in a large community), no new
information had come to light to cause us to come to a different
conclusion.
Jon's distinction here between "Java source file", and a separate notion
of "script that contains Java code" or "platform-specific executable
script", is a good one; we'd implicitly been thinking of these as two
different things, but its clear that this is confusing to people, and
making the distinction explicit should dispel some of that confusion.
Sure, they _could_ be merged, but highlighting this distinction seems
much more in keeping with the spirit of the platform than blurring the
distinction (though that might be a fine choice for other languages.)
So, +1 to Jon's suggestion.
So, what can be done here? We could:
- move forward with the feature, as is.
- clarify the distinction between "Java source file" and "script
containing Java", and tweak accordingly, as Jon suggests.
- drop the JEP entirely.
- drop the shebang support and keep the rest.
What does not seem like a reasonable choice is to turn the Java Language
into a platform-dependent thing, for all the reasons Jon mentioned, and
more.
> I am afraid that adopting pejorative terms like 'infecting' doesn't
> really make your case stronger.
I'm sorry if you were offended by my use of this term. I take the Java
Language very seriously, and defend its boundaries vigorously!
Cheers,
-Brian
More information about the jdk-dev
mailing list