[raw-strings] Indentation problem

Guy Steele guy.steele at oracle.com
Mon Feb 5 16:48:19 UTC 2018


While the proposal to use pipe characters in multiline literals is ingenious, I guess I am astonished that the discussion so far has not at least mentioned and compared a solution that has been available in C for more than two decades: implicit concatenation of string literals.

public class Multiline {
static String createHtml(String message) {
  String html = "<html>\n"
                "  <head>\n"
                "    <title>Message</title>\n"
                "  </head>\n"
                "  <body>\n";
  if (message != null) {
    html += "    <p>\n"
            "      Message: "+message+"\n"
            "    </p>\n";
  }
  html += "  </body>\n"
          "</html>\n";
  return html;
}
}

But, wait!  We don’t even have to add that to Java, because we have a string concatenation operator, `+`:

public class Multiline {
static String createHtml(String message) {
  String html = "<html>\n"+
                "  <head>\n"+
                "    <title>Message</title>\n"+
                "  </head>\n"+
                "  <body>\n";
  if (message != null) {
    html += "    <p>\n"+
            "      Message: "+message+"\n"+
            "    </p>\n”;
  }
  html += "  </body>\n"+
          "</html>\n";
  return html;
}
}

It’s dead simple:
Whitespace inside double quotes belongs to the included code snippet. 
Whitespace outside double quotes belongs to the containing program.

No need for a trimming method.  No changes needed to the Java language.

Any IDE smart enough to provide pipe characters in a special pasting operation could just as easily provide the necessary double quotes and newline escapes and plus signs.

And while we are at it, we can get even more creative with the indentation of the containing program to better highlight the relative indentation of the included code snippets:

public class Multiline {
static String createHtml(String message) {
  String html =           "<html>\n"+
                          "  <head>\n"+
                          "    <title>Message</title>\n"+
                          "  </head>\n"+
                          "  <body>\n";
  if (message != null) {
    html +=               "    <p>\n"+
                          "      Message: "+message+"\n"+
                          "    </p>\n”;
  }
  html +=                 "  </body>\n"+
                          "</html>\n";
  return html;
}
}

Does this strategy not meet all the stated desiderata?

—Guy

P.S. I have to admit that all the \n escapes are a big ugly.  In Fortress, we explored having several string concatenation operators, one of which would supply an extra space character and one of which would supply an extra newline character.  Supposing `/` to be a string concatenation operator that adds a space character, and `//` to be a string concatenation operator that adds a newline character (in Fortress, we also allowed it to be a postfix operator that just adds a newline character), then we could write:

public class Multiline {
static String createHtml(String message) {
  String html =           "<html>"                     //
                          "  <head>"                   //
                          "    <title>Message</title>" //
                          "  </head>"                  //
                          "  <body>"                   //;
  if (message != null) {
    html +=               "    <p>"                    //
                          "      Message:" / message   //
                          "    </p>"                   //;
  }
  html +=                 "  </body>"                  //
                          "</html>"                    //;
  return html;
}
}

Or we could be even more clever, and say that the // operator has the additional effect of trimming trailing spaces and tabs from its left-hand operand.  Then we get those trailing double quotes out of the way by writing:

public class Multiline {
static String createHtml(String message) {
  String html =           "<html>                     " //
                          "  <head>                   " //
                          "    <title>Message</title> " //
                          "  </head>                  " //
                          "  <body>                   " //;
  if (message != null) {
    html +=               "    <p>                    " //
                          "      Message:" / message    //
                          "    </p>                   " //;
  }
  html +=                 "  </body>                  " //
                          "</html>                    " //;
  return html;
}
}

I am not advocating adding such operators to the Java language.  I am just pointing out that there are other interesting parts of the design space that might address the indentation-of-nested-snippets problem while requiring either fewer changes to the language (possibly none) or changes that might have broader applicability.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20180205/c50b01e1/attachment-0001.html>


More information about the amber-spec-experts mailing list