JDK-8224678 : Compiler Support for JEP 355: Text Blocks (Preview)
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 13
  • Submitted: 2019-05-23
  • Updated: 2019-12-16
  • Resolved: 2019-06-04
Related Reports
CSR :  
Relates :  
Relates :  
Description
Summary
-------

Enhance the Java language by introducing _text blocks_, a more intuitive way to represent multi-line strings than string literals.

Problem
-------

In Java, embedding a snippet of HTML, XML, SQL, or JSON in a _string literal_ ([JLS 3.10.5](https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.10.5)) "..." usually requires significant editing with _escape sequences_ ([JLS 3.10.6](https://docs.oracle.com/javase/specs/jls/se10/html/jls-3.html#jls-3.10.6)) and _concatenation_ ([JLS 15.18.1](https://docs.oracle.com/javase/specs/jls/se10/html/jls-15.html#jls-15.18.1)) before the code containing the snippet will compile. The snippet is often difficult to read and arduous to maintain.

More generally, the need to denote short, medium, and long blocks of text in a Java program is near universal, whether the text is code from other programming languages, structured text representing golden files, or messages in natural languages. On the one hand, the Java language recognizes this need by allowing strings of unbounded size and content, but on the other hand, it embodies a design default that strings should be small enough to denote on a single line of a source file, and simple enough to escape easily.

Solution
-------

The Java language can be regularized by accepting that strings may be large enough to span multiple lines of a source file, and by envisaging that escapes in their content may represent formatting and layout operations as well as individual characters.

Accordingly, it would improve both the readability and the writeability of a broad class of Java programs to have a linguistic mechanism for denoting strings more literally than a string literal -- across multiple lines and without the visual clutter of escapes. In essence, a two-dimensional block of text, rather than a one-dimensional sequence of characters.

The following are examples of text blocks:

```
String simple = """
                A simple
                multi-line
                text block
                """;
```

```
String empty = """
               """;
```

```
String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;
```

```
String query = """
               SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
               WHERE `CITY` = 'INDIANAPOLIS'
               ORDER BY `EMP_ID`, `LAST_NAME`;
               """;
```

```
ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
                         function hello() {
                             print('"Hello, world"');
                         }
                         
                         hello();
                         """);
```

Specification
-------

Proposed changes to the Java Language Specification are attached, and also [available online](http://cr.openjdk.java.net/~abuckley/jep355/text-blocks-jls-20190603.html). Because a text block is a constant expression of type `String`, it is acceptable to use a text block anywhere that a string literal could be used, and vice versa.

There are no changes to the JVM Specification. A string in the constant pool of a `class` file ([JVMS 4.4.3](https://docs.oracle.com/javase/specs/jvms/se10/html/jvms-4.html#jvms-4.4.3)) has always been independent of Java language rules for string literals, so it is a suitable compilation target for text blocks. A `class` file does not record whether a string in the constant pool was compiled from a string literal or a text block.
Comments
Moving to Approved.
04-06-2019

Please see the attachment `text-blocks-jls-20190603.html` or the (updated) link to the spec version available online. There was an older attachment `text-blocks-spec.html` which required some admin intervention to delete; it is no longer present.
03-06-2019

Thanks; leaving the old file in place would be fine too.
03-06-2019

[~abuckley] or [~jlaskey], please attach an amended version of the text blocks spec changes before this CSR is finalized; thanks.
03-06-2019

Per https://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-June/001418.html, we are now requiring interning of text blocks. The JEP has been updated to clarify that "A text block is a constant expression of type String", and the JLS changes have been updated to record a must-intern policy in 3.10.6 and to enumerate text blocks in 15.28.
03-06-2019

For the sake of argument, stipulating that not requiring intern for text blocks is reasonable, by my reading the current version of the proposed changes is incomplete with regard to constant expressions. In an example, the proposed spec states: > Text blocks can be used wherever an expression of type String is > allowed, such as in string concatenation (15.18.1), in method > invocation on class String, and in annotations with String elements: Strings in annotation elements must be constant expressions: > T is not an array type, and the type of V is assignment compatible > (��5.2) with T, and: > > - If T is a primitive type or String, then V is a constant expression (��15.28). https://docs.oracle.com/javase/specs/jls/se12/html/jls-9.html#jls-9.7 Therefore, one could infer that text blocks, like string literals, can be constant expressions per JLS (��15.28). If that is the intention, presumably the listing > A constant expression is an expression denoting a value of primitive > type or a String that does not complete abruptly and is composed using > only the following: > > - Literals of primitive type and literals of type String (��3.10.1, ��3.10.2, ��3.10.3, ��3.10.4, ��3.10.5) > - Casts to primitive types and casts to type String (��15.16) > - ... Should be amended to explicitly discuss text blocks and the statement later in that section that > Constant expressions of type String are always "interned" so as to > share unique instances, using the method String.intern. should be amended to discuss the lack of that guarantee for text blocks. Please have constant-ness discussed before this request is finalized.
28-05-2019

The rationale was well discussed in the amber EG and is on record in this thread http://mail.openjdk.java.net/pipermail/amber-spec-experts/2019-May/001378.html .
27-05-2019

JEP 355 used to record an important decision made in the Amber EG about interning of text blocks (in particular, the non-requirement to intern), but that record seems to have been removed. This is an unfortunate turn of events. It means there is no motivation for why the JLS changes say what they do about interning of text blocks, and there is no basis for responding to the fine question about interning from the CSR Group Lead.
25-05-2019

As the interning topic was apparently discussed in the Amber EG, it would seem to be a relevant matter to introducing a new kind of string expression. One could at least contrive of cases where replaced an interned constant string with a non-interned or not-necessarily-interned text block would cause unwanted changes in behavior. The proponents of this work are free to not answer relevant questions from the CSR group lead and, in turn, the CSR group lead is free to not vote to approve requests where relevant questions are not answered.
24-05-2019

Why the changes for interning? What about string constant expressions? "Constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern. " https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.28 Moving to Provisional.
24-05-2019