Java 13 Text Blocks, Switch Update, Micronaut, Quarkus

CodeFX Occasionally #72 — 7th of June 2019

Nicolai Parlog
nipafx news
Published in
7 min readJun 11, 2019

--

Hi everyone,

there’s been some new development on Java 13 and I recently experimented a little with the new, hot, and blazing fast web frameworks Quarkus and Micronaut, so I thought it’s time for another newsletter. Without further ado…

I send this newsletter out some Fridays. Or other days. Sometimes not for weeks. But as an actual email. So, subscribe!

Text blocks in Java 13

Good news, everyone, we got another shot at multiline strings, now called text blocks, in Java 13! Here you go:

String html = """
Hello, world
""";

Here are a few interesting details:

  • the opening delimiter is not just """, but includes the line terminator - yes there has to be a new line!
  • the closing delimiter can be on the last line or on its own line, depending on whether the string should end with a line terminator or not
  • incidental white space is removed and there’s some complexity in identifying which white space is incidental and which isn’t — the position of the closing """ plays a critical role here
  • these blocks are not raw, i.e. escape sequences like \t and \n are evaluated
  • best way to embed variables is something like String::format (there's neither interpolation nor are text blocks easy to concatenate)
  • this will be a regular String that, at run time, is indistinguishable from one created from a string literal

For more, read the JEP (or wait for the inevitable Twitch stream, blog post, YouTube video, etc. 😉).

Update: The inevitable stream happened and a post was published.

Micro-update to switch expressions in Java 13

The youngest Java language feature is the extension of switch from statement to expression, which was introduced in Java 12 as a preview feature. Good thing about those previews is that it's far easier to experiment with them and gather experience that can be acted on before the change gets set into stone.

And this is exactly what happened here. The question was: How can a switch expression branch complete and denote its result:

boolean result = switch (ternaryBoolean) {
case TRUE -> {
System.out.println("Bool true");
// what do we replace "..." with?
... true;
}
// [...]
};

Maybe the most obvious, return, doesn't work because it would cause confusion as to whether we're ending the switch expression or the entire surrounding method:

Digression: What’s so terrible about “return”, any why is it OK for lambdas but not OK for switches?

While we could of course define “return” to mean whatever we want, But, in imperative languages with the concept of “methods” or “procedures”, including Java, return has always had a clear meaning: unwind the current call frame, and yield the designated value to the caller. Lambda expressions are effectively method bodies (lambdas are literals for functional interfaces, which are single method interfaces), and so return (barely) fits. But switch expressions are most definitely not methods, and are not associated with call frames. Asking users to look at the enclosing context when they see a “return” in the middle of a method, to know whether it returns from the method or merely transfers control within the method, is a lot to ask. (Yes, I know lambdas ask this as well; this is why this was an uncomfortable choice, and having made this hole, I’m not anxious to expand it dramatically. If anything I’d prefer to close it, but that’s another bikeshed.).

(end digression)

[Brian Goetz]

In Java 12, the answer was break, but not everybody liked it:

The overloading of break creates uncomfortable interactions. There is the obvious ambiguity between “break value” and “break label”; there is also the slightly less obvious interaction where we cannot permit “break value” inside a loop or statement switch inside an expression switch. While both of these can be “specified around”, they create distortions in the spec, which in turn creates complexity in the user model; these are a sign that we may be pushing something a bit too far. Further, historically “break” has been a straight transfer of control; this muddies up what “break” means.

[Brian Goetz]

Ok, so no break. What then? For a while it seemed to be break-with. Keyword management is a problem and hyphenated keywords may be a solution, but, hell, for now they look weird as fuck. But that's not the only concern:

We could surely take “break-with” and move on; it feels sufficiently “switchy”. But let’s look ahead a little bit. We’ve now confronted the same problem twice [with lambdas and switch]: an expression form that, in a minority use case, needed a way to express “stop computing this expression, because I’m done, and here’s its value.” (And, unfortunately, we have two different syntactic ways to express the same basic concept.) Let’s call these “structured expressions.”

We have two structured expression forms, and of the three numbers in computer science, “two” is not one of them. Which suggests we are going to face this problem again some day […] Let’s say for sake of argument that we might someway want to extend ternary expressions to support the same kind of “restricted block expressions” as expression switches. […]

String s = (foo != null) ? s : { println("null again at line" + __LINE__); break-with "null"; };

Such an expression needs a way to say “I’m done, here’s my value”, just as lambda and switch did before it. Clearly “return” is not the right thing here any more than it is for switches. And I don’t think “break-with” is all that great here either! It’s not terrible, but outside of a loop or switch, it starts to feel kind of forced. And it would be terrible to solve this problem twice with one-time solutions, and have no general story, and then have to come up with YET ANOTHER way of expressing the same basic concept. So regardless of what we expect for future expression forms, let’s examine what our options are that are not tied to call frames (return) or direct transfer of control (switches and loops.).

[Brian Goetz]

Long discussion ensues… with yield as the result in Java 13:

boolean result = switch (ternaryBoolean) {
case TRUE -> {
System.out.println("Bool true");
yield true;
}
// [...]
};

With this change, switch expressions will remain in preview for another release and I expect it to become final in March 2020 with Java 14.

Micronaut and Quarkus

I recently played around with Micronaut and Quarkus and was impressed by how easy it is to get started. The Hello World Fallacy is a real thing, of course, so getting started fast doesn’t really mean a whole lot, but considering how young some of the involved tools are (particularly Graal), it’s still impressive.

In case you never heard about Micronaut and Quarkus, let me quickly introduce them. Both are frameworks for Java backends that promise fast startup and response times and low memory footprint. Both work well with Graal’s ahead of time compilation to a native image, which results in blazing fast startup times. Quarkus’ Hello World takes about 3 ms to launch on my five-year-old laptop. 3 fraking milliseconds! Amazing!

Here are a few differences I discovered in the two hours I spent with the frameworks:

  • Micronaut supports more than just Java, namely also Groovy and Kotlin
    [Update: I was wrong: Quarkus also supports Kotlin — thank Gunnar for pointing this out.]
  • Quarkus has the nicer site, but seems a little less refined than Micronaut
  • both rely on specialized dependency injection frameworks because they need to avoid reflection at run time (reflection is bad for performance and doesn’t work well with Graal AOT)
  • Quarkus’ Hello World compiled faster than Micronaut’s and launched an order of magnitude faster
  • I saw no difference in response times between them

When starting to work on the site for my courses (yes, that’s still a thing), I went with Spring Boot. Now I’m considering to go with one of these two instead. Better performance is always nice, less memory footprint means lower cost, but most importantly, if I learn a technology that’s new to me, why not pick one that’s actually new. 😁

As it stands, I’d probably go with Micronaut because of its Kotlin support, but since I want to relaunch my online presence before continuing working on the courses, I have some time before I need to pick one of the two.

What I’ve been up to

As mentioned recently, I want to do a better job of letting you know about my various activities. Here’s my first shot at that — a new segment listing what I’ve done. I’d be thrilled to get your feedback on this, so let me know what you think, e.g. by mail to nipa@codefx.org.

CW20:

CW21:

CW22:

CW23:

I want to do one thing per week, but I’m hoping for two. Worked out so far. 😁

Long shots

Here are three great reads, but they are a little longer:

so long … Nicolai

PS: Don’t forget to subscribe or recommend! :)

Image by Claire GIRAL from Pixabay

--

--

Nicolai Parlog
nipafx news

Nicolai is a #Java enthusiast with a passion for learning and sharing — in posts & books; in videos & streams; at conferences & in courses. https://nipafx.dev