[Accepted] SE-0168: Multi-Line String Literals

To clarify, the core team's decision is that one trailing newline should be elided before the closing delimiter. This maintains one consistent rule for both ends of the literal, so """\n and \n""" can be mentally understood as balanced delimiters. as Xiaodi noted, it would otherwise be impossible to write a literal without a trailing newline without scope-creeping the design with additional features.

-Joe

···

On Apr 19, 2017, at 3:27 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Wed, Apr 19, 2017 at 5:24 PM, Joe Groff <jgroff@apple.com <mailto:jgroff@apple.com>> wrote:

> On Apr 19, 2017, at 3:16 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>
> We had a very full debate about which way was superior during review; it was proposed to behave one way and the core team decided on the other. We have to let settled decisions be settled: that's the only way Swift Evolution will continue to work.

I'm asking the core team for clarification on the point of the closing newline.

Cool, thanks. Please do remind them, though, that not stripping the closing newline (which is what was originally proposed) *and* not having the option of using `\` to elide newlines (which is contrary to what was originally proposed) would mean that all multi-line strings would mandatorily end in a newline.

The multi-line string literal as it’s accepted right now only allows pretty code generation with smaller lines. The literal itself is not reserved for JSON, XML and similar syntaxes only, which automatically implies the existence of conventions with longer lines. For whatever reasons a developer might have, it’s essential to allow manual line wrapping without injecting a new line into the resulting string. Not everyone uses the same editor width nor the same editor with exact the same settings. You simply cannot and really should not rely on any editor or linter for that matter, nor do I vision it as a strong argument against having the ability to escape the new line injection. I don’t think we should ever expect the average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
    
   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """
The string concatenation uses optimization magic behind the scenes which is not obvious for everyone. I personally think that every operation involved in concatenation or any operation in-general adds a performance overhead and theoretically needs more time to resolve the expression at runtime, which is the natural way of thinking without any knowledge about the optimization the compiler is able to do for you. A string literal is able to solve that issue during compile time is simply the perfect place for that.

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """
This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to include any whitespace characters at the end of each line unless there is a visible annotation provided for precision. Providing a warning for trailing whitespace characters would be ideal solution right now and the trailing backslash becomes additive but not impossible to add later.

A few people already argued that the core team decided not to include a new line at the end of each multi-line string, where you yourself said that the absence of a trailing backslash will produce a string which always ends with a new line. That behavior would be really strange and painful to prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds more flexibility to the literal model, which results in better readability if the precision is desired for code formatting!

···

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor and a linter, or an IDE and no linter, etc., and in any of these scenarios you can already choose whether or not you want trailing newlines stripped. Why should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string literal and be 100% sure of what glyphs are involved. We should be clear that such a criterion cannot and should not be a design goal. If it supports Unicode and is really literal, then confusables and invisibles will make it impossible to be sure of what you see; you would have to either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of as a multiline string literal. It sounds like what you want isn't multiline (in fact, you want a new way to write a very long single-line string) and it isn't literal (you want to use newlines in your code that do not represent a literal newline). If there is something extremely critical about a particular string, where you simply must start half of it on a separate line to help the readers of your code understand what you are doing, you can already do this by writing "foo" + [newline] "bar". Or you could just let your editor soft-wrap your long string. Making your single-line string wrap the same way in every IDE just doesn't seem like it's related to or worth complicating the syntax for multiline string literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
True, but this is not about IDEs or editors. The feature itself doesn’t know what an editor is and what it capable of, nor should be ever rely on that. Not everyone uses the same settings and you cannot be 100% sure to expect the same string from looking at it, which was written in a different editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently accepted version, but we’ll have to warn about them if we decide to add the trailing backspace. As currently accepted we still have a hole to fill for coding styles, we do not support multi-lined string literals for code formatting only, nor do we have trailing precision for the same matter. (That’s what the backslash was meant for.) That said, I cannot break up a really long hardcoded string, which in my IDE is softly wrapped, into a multi-line string literal so that it looks in every editor the same and still expect the same result and be precise about the trailing whitespace characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by default, so even if Swift doesn't warn about it, you might still need to satisfy other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about it? If it's harmful, you'll have other tools in the pipeline to flag it for you.

Cosigned. We already have an Xcode setting to strip trailing whitespace, a Git setting to flag it, and linter settings to remove it. (For instance, SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

The multi-line string literal as it’s accepted right now only allows
pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow
(with the unavoidable exception of some escape sequences) code written
inside the quotations marks to be exactly as pretty as the resulting string
itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes only,

which automatically implies the existence of conventions with longer lines.
For whatever reasons a developer might have, it’s essential to allow manual
line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is essential.
What are the "whatever reasons" for a developer to need this feature? It is
critical enough to be worth complicating the design for something like
literal syntax, which should be as lightweight, straightforward, and simple
as possible?

Not everyone uses the same editor width nor the same editor with exact the

same settings.

Do you think it is a common use case that someone will want to have text
that looks the same only to people reading the code, but not to people
reading the resulting string? Do you think someone might want to put code
inside a string literal, then wrap the literal using 80-character lines,
but write the code inside to wrap using 120-character lines? These seem
like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for

that matter,

If you are going to view a Swift file, you're going to do it through some
program or other. Is it reasonable to add features to Swift because some
hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to

escape the new line injection. I don’t think we should ever expect the
average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors
cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """

------------------------------

The string concatenation uses optimization magic behind the scenes which
is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any
operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks due
to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime,
which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without any
knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string
literal is able to solve that issue during compile time is simply the
perfect place for that.

------------------------------

Some words about the trailing precision. Joe said that we could use \("")
as workaround, but if I recall correctly literals are banned from the
interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """

This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to
include any whitespace characters at the end of each line unless there is a
visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current
accepted design. Why should I expect literal whitespace to be visibly
annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal

···

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev < adrian.zubarev@devandartist.com> wrote:

solution right now and the trailing backslash becomes additive but not
impossible to add later.
------------------------------

A few people already argued that the core team decided not to include a
new line at the end of each multi-line string, where you yourself said that
the absence of a trailing backslash will produce a string which always ends
with a new line. That behavior would be really strange and painful to
prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds
more flexibility to the literal model, which results in better readability
if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor and
a linter, or an IDE and no linter, etc., and in any of these scenarios you
can already choose whether or not you want trailing newlines stripped. Why
should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string
literal and be 100% sure of what glyphs are involved. We should be clear
that such a criterion cannot and should not be a design goal. If it
supports Unicode and is really literal, then confusables and invisibles
will make it impossible to be sure of what you see; you would have to
either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of
as a multiline string literal. It sounds like what you want isn't multiline
(in fact, you want a new way to write a very long single-line string) and
it isn't literal (you want to use newlines in your code that do not
represent a literal newline). If there is something extremely critical
about a particular string, where you simply must start half of it on a
separate line to help the readers of your code understand what you are
doing, you can already do this by writing "foo" + [newline] "bar". Or you
could just let your editor soft-wrap your long string. Making your
single-line string wrap the same way in every IDE just doesn't seem like
it's related to or worth complicating the syntax for multiline string
literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

True, but this is not about IDEs or editors. The feature itself doesn’t
know what an editor is and what it capable of, nor should be ever rely on
that. Not everyone uses the same settings and you cannot be 100% sure to
expect the same string from looking at it, which was written in a different
editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently accepted
version, but we’ll have to warn about them if we decide to add the trailing
backspace. As currently accepted we still have a hole to fill for coding
styles, we do not support multi-lined string literals for code formatting
only, nor do we have trailing precision for the same matter. (That’s what
the backslash was meant for.) That said, I cannot break up a really long
hardcoded string, which in my IDE is softly wrapped, into a multi-line
string literal so that it looks in every editor the same and still expect
the same result and be precise about the trailing whitespace characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (
swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution < >> swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by default,

so even if Swift doesn't warn about it, you might still need to satisfy
other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about it?
If it's harmful, you'll have other tools in the pipeline to flag it for you.

Cosigned. We already have an Xcode setting to strip trailing whitespace,
a Git setting to flag it, and linter settings to remove it. (For instance,
SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle
every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Exactly, thank you for the clarification. That is the correct decision IMO. :)

Here is the formatted version of the example from my last reply:

···

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 18:58:07, Joe Groff via swift-evolution (swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:27 PM, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Wed, Apr 19, 2017 at 5:24 PM, Joe Groff <jgroff@apple.com> wrote:

On Apr 19, 2017, at 3:16 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

We had a very full debate about which way was superior during review; it was proposed to behave one way and the core team decided on the other. We have to let settled decisions be settled: that's the only way Swift Evolution will continue to work.

I'm asking the core team for clarification on the point of the closing newline.

Cool, thanks. Please do remind them, though, that not stripping the closing newline (which is what was originally proposed) *and* not having the option of using `\` to elide newlines (which is contrary to what was originally proposed) would mean that all multi-line strings would mandatorily end in a newline.

To clarify, the core team's decision is that one trailing newline should be elided before the closing delimiter. This maintains one consistent rule for both ends of the literal, so """\n and \n""" can be mentally understood as balanced delimiters. as Xiaodi noted, it would otherwise be impossible to write a literal without a trailing newline without scope-creeping the design with additional features.

-Joe
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

<https://github.com/apple/swift/blob/master/CHANGELOG.md#swift-21&gt;

* Expressions interpolated in strings may now contain string literals.
  For example, `My name is \(attributes["name"]!)` is now a valid expression.
  **(14050788)**

-- Ben

···

On 20 Apr 2017, at 17:48, Adrian Zubarev wrote:

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """
This is a very dirty and tedious solution for that problem.

Dear Xiaodi Wu, why do you always have to be offensive in a way of questioning every single word another person says and not letting others to have their own opinion?! I do not want to have a discussion with you that will and up you asking me why is the banana crooked. I expect a focused and a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be different from yours and you’ll have to bear with that, because I’ve got my own opinion. If you’d like me to see things differently, try to convince me instead of being unfocused and questioning every single word I’m saying. That won’t lead use to anywhere.

I expect the model to solve two major problems. The first one is already solved by the accepted version. The second one is the ability to escape new lines when needed (notice, I do not want to escape them all the time, but only where it’s desired). The accepted version adds more possibilities to the language and will definitely fix a lot of pain with string literals some developer had. I’m happy to see that. However from my personal standpoint, I do not write any code generators created from string literals as it was a heavily overused example in the proposal and during the discussion. I often need the ability to wrap very long strings into multiple lines for readability, but keep the result string intact. In my last response I showed a sample on how it might look like and that it’s really painful to read such a string on Git, because it does not provide any soft-wrapping like other tools might do. That is why I keep saying that the multi-line string literal should not rely on editors to solve that problem. Otherwise the bare existence of the such literal could be questioned and we could fully fall back to editor features like soft-wrapping or let the editor also wrap strings when it finds a new line character \n to mimic the proposed behavior. I also do not like the argument of using string concatenation to solve my particular issue, because the strings are very long and it quickly becomes were tedious. Furthermore, the multi-line string literal should not be only reserved for solving the problems you’ve mentioned. A trailing backslash does not add any complexity, and you personally don’t need that feature it does not mean that others won’t need it. It’s an additional feature which is lightweight and which won’t harm the copy-paste phenomenon most of you wanted. If you really think it adds complexity than you should also justify your thoughts to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access modifier in Swift the model would be really simple but not flexible. Not that we have a bunch of them the model become complex but on the other hand it also become way more flexible.

···

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 21:50:27, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:
The multi-line string literal as it’s accepted right now only allows pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow (with the unavoidable exception of some escape sequences) code written inside the quotations marks to be exactly as pretty as the resulting string itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes only, which automatically implies the existence of conventions with longer lines. For whatever reasons a developer might have, it’s essential to allow manual line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is essential. What are the "whatever reasons" for a developer to need this feature? It is critical enough to be worth complicating the design for something like literal syntax, which should be as lightweight, straightforward, and simple as possible?

Not everyone uses the same editor width nor the same editor with exact the same settings.

Do you think it is a common use case that someone will want to have text that looks the same only to people reading the code, but not to people reading the resulting string? Do you think someone might want to put code inside a string literal, then wrap the literal using 80-character lines, but write the code inside to wrap using 120-character lines? These seem like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for that matter,

If you are going to view a Swift file, you're going to do it through some program or other. Is it reasonable to add features to Swift because some hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to escape the new line injection. I don’t think we should ever expect the average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
     
   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """
The string concatenation uses optimization magic behind the scenes which is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks due to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime, which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without any knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string literal is able to solve that issue during compile time is simply the perfect place for that.

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """
This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to include any whitespace characters at the end of each line unless there is a visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current accepted design. Why should I expect literal whitespace to be visibly annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal solution right now and the trailing backslash becomes additive but not impossible to add later.

A few people already argued that the core team decided not to include a new line at the end of each multi-line string, where you yourself said that the absence of a trailing backslash will produce a string which always ends with a new line. That behavior would be really strange and painful to prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds more flexibility to the literal model, which results in better readability if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor and a linter, or an IDE and no linter, etc., and in any of these scenarios you can already choose whether or not you want trailing newlines stripped. Why should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string literal and be 100% sure of what glyphs are involved. We should be clear that such a criterion cannot and should not be a design goal. If it supports Unicode and is really literal, then confusables and invisibles will make it impossible to be sure of what you see; you would have to either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of as a multiline string literal. It sounds like what you want isn't multiline (in fact, you want a new way to write a very long single-line string) and it isn't literal (you want to use newlines in your code that do not represent a literal newline). If there is something extremely critical about a particular string, where you simply must start half of it on a separate line to help the readers of your code understand what you are doing, you can already do this by writing "foo" + [newline] "bar". Or you could just let your editor soft-wrap your long string. Making your single-line string wrap the same way in every IDE just doesn't seem like it's related to or worth complicating the syntax for multiline string literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
True, but this is not about IDEs or editors. The feature itself doesn’t know what an editor is and what it capable of, nor should be ever rely on that. Not everyone uses the same settings and you cannot be 100% sure to expect the same string from looking at it, which was written in a different editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently accepted version, but we’ll have to warn about them if we decide to add the trailing backspace. As currently accepted we still have a hole to fill for coding styles, we do not support multi-lined string literals for code formatting only, nor do we have trailing precision for the same matter. (That’s what the backslash was meant for.) That said, I cannot break up a really long hardcoded string, which in my IDE is softly wrapped, into a multi-line string literal so that it looks in every editor the same and still expect the same result and be precise about the trailing whitespace characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by default, so even if Swift doesn't warn about it, you might still need to satisfy other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about it? If it's harmful, you'll have other tools in the pipeline to flag it for you.

Cosigned. We already have an Xcode setting to strip trailing whitespace, a Git setting to flag it, and linter settings to remove it. (For instance, SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Dear Xiaodi Wu, why do you always have to be offensive in a way of questioning every single word another person says and not letting others to have their own opinion?! I do not want to have a discussion with you that will and up you asking me why is the banana crooked. I expect a focused and a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be different from yours and you’ll have to bear with that, because I’ve got my own opinion. If you’d like me to see things differently, try to convince me instead of being unfocused and questioning every single word I’m saying. That won’t lead use to anywhere.

Hi Adrian. For what it's worth, I did not detect any offense in Xiaodi’s questions. I think he was just asking questions to point parts of your opinion which he did not understand or was missing some reasoning.

I expect the model to solve two major problems. The first one is already solved by the accepted version. The second one is the ability to escape new lines when needed (notice, I do not want to escape them all the time, but only where it’s desired). The accepted version adds more possibilities to the language and will definitely fix a lot of pain with string literals some developer had. I’m happy to see that. However from my personal standpoint, I do not write any code generators created from string literals as it was a heavily overused example in the proposal and during the discussion. I often need the ability to wrap very long strings into multiple lines for readability, but keep the result string intact. In my last response I showed a sample on how it might look like and that it’s really painful to read such a string on Git, because it does not provide any soft-wrapping like other tools might do. That is why I keep saying that the multi-line string literal should not rely on editors to solve that problem. Otherwise the bare existence of the such literal could be questioned and we could fully fall back to editor features like soft-wrapping or let the editor also wrap strings when it finds a new line character \n to mimic the proposed behavior. I also do not like the argument of using string concatenation to solve my particular issue, because the strings are very long and it quickly becomes were tedious. Furthermore, the multi-line string literal should not be only reserved for solving the problems you’ve mentioned. A trailing backslash does not add any complexity, and you personally don’t need that feature it does not mean that others won’t need it. It’s an additional feature which is lightweight and which won’t harm the copy-paste phenomenon most of you wanted. If you really think it adds complexity than you should also justify your thoughts to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access modifier in Swift the model would be really simple but not flexible. Not that we have a bunch of them the model become complex but on the other hand it also become way more flexible.

But for what its worth, I agree with Adrian. Let me try to expose the use-case the proposal is not addressing:

A group of people (me included) don’t wrap lines in their editor (by choice) but make sure that lines of code don’t extend over a certain limit (80, 100, 120, whatever). This allows us to keep code readable and control the wrapping behaviour by manually applying it.

For those people, writing long prose which extends over our limit (like is the case in some error/assert/precondition messages), we won’t be able to use the multi-line string proposal and we will have to stay with string concatenation:

Taking the following piece of code:

func myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, “Variables `aVariable` and `anotherVariable` are outside their expected range. Please check that your are not calling this function around midnight”)
}

I currently write it using string concatenation:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, "Variables `aVariable` and `anotherVariable` " +
        "are outside their expected range. Please check that your are not calling this function " +
        "around midnight")
}

But writing it using the multi-line string syntax:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable`
  are outside their expected range. Please check that your are not calling this function
  around midnight
        """)
}

will inject unwanted newlines. I think what we would like to be able to do is:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable` \
  are outside their expected range. Please check that your are not calling this function \
  around midnight
        """)
}

Notice how the space at the end of the line is also quite obvious now.

···

On 21 Apr 2017, at 11:32, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 21:50:27, Xiaodi Wu (xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>) schrieb:

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev <adrian.zubarev@devandartist.com <mailto:adrian.zubarev@devandartist.com>> wrote:
The multi-line string literal as it’s accepted right now only allows pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow (with the unavoidable exception of some escape sequences) code written inside the quotations marks to be exactly as pretty as the resulting string itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes only, which automatically implies the existence of conventions with longer lines. For whatever reasons a developer might have, it’s essential to allow manual line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is essential. What are the "whatever reasons" for a developer to need this feature? It is critical enough to be worth complicating the design for something like literal syntax, which should be as lightweight, straightforward, and simple as possible?

Not everyone uses the same editor width nor the same editor with exact the same settings.

Do you think it is a common use case that someone will want to have text that looks the same only to people reading the code, but not to people reading the resulting string? Do you think someone might want to put code inside a string literal, then wrap the literal using 80-character lines, but write the code inside to wrap using 120-character lines? These seem like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for that matter,

If you are going to view a Swift file, you're going to do it through some program or other. Is it reasonable to add features to Swift because some hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to escape the new line injection. I don’t think we should ever expect the average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
     
   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """
The string concatenation uses optimization magic behind the scenes which is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks due to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime, which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without any knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string literal is able to solve that issue during compile time is simply the perfect place for that.

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """
This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to include any whitespace characters at the end of each line unless there is a visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current accepted design. Why should I expect literal whitespace to be visibly annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal solution right now and the trailing backslash becomes additive but not impossible to add later.

A few people already argued that the core team decided not to include a new line at the end of each multi-line string, where you yourself said that the absence of a trailing backslash will produce a string which always ends with a new line. That behavior would be really strange and painful to prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds more flexibility to the literal model, which results in better readability if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com <mailto:xiaodi.wu@gmail.com>) schrieb:

You can use a plain text editor and no linter, or a plain text editor and a linter, or an IDE and no linter, etc., and in any of these scenarios you can already choose whether or not you want trailing newlines stripped. Why should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string literal and be 100% sure of what glyphs are involved. We should be clear that such a criterion cannot and should not be a design goal. If it supports Unicode and is really literal, then confusables and invisibles will make it impossible to be sure of what you see; you would have to either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of as a multiline string literal. It sounds like what you want isn't multiline (in fact, you want a new way to write a very long single-line string) and it isn't literal (you want to use newlines in your code that do not represent a literal newline). If there is something extremely critical about a particular string, where you simply must start half of it on a separate line to help the readers of your code understand what you are doing, you can already do this by writing "foo" + [newline] "bar". Or you could just let your editor soft-wrap your long string. Making your single-line string wrap the same way in every IDE just doesn't seem like it's related to or worth complicating the syntax for multiline string literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
True, but this is not about IDEs or editors. The feature itself doesn’t know what an editor is and what it capable of, nor should be ever rely on that. Not everyone uses the same settings and you cannot be 100% sure to expect the same string from looking at it, which was written in a different editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently accepted version, but we’ll have to warn about them if we decide to add the trailing backspace. As currently accepted we still have a hole to fill for coding styles, we do not support multi-lined string literals for code formatting only, nor do we have trailing precision for the same matter. (That’s what the backslash was meant for.) That said, I cannot break up a really long hardcoded string, which in my IDE is softly wrapped, into a multi-line string literal so that it looks in every editor the same and still expect the same result and be precise about the trailing whitespace characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Other common tools like Git already flag trailing whitespace by default, so even if Swift doesn't warn about it, you might still need to satisfy other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about it? If it's harmful, you'll have other tools in the pipeline to flag it for you.

Cosigned. We already have an Xcode setting to strip trailing whitespace, a Git setting to flag it, and linter settings to remove it. (For instance, SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution

(Despite Ben's claims...)

Are there no limits on interpolation? I don't see anything about that in the informal addendum to the undetailed proposal. Will multiline strings in interpolations in normal string literals enable them to lexically span multiple lines? Based on Swift 3.0.2 accepting this:

var x = "single line \( "strings are \( "not normally" ) allowed" ) to span multiple lines"

I assume that this would be accepted:

var x = "single line \( """
                        strings are \( "not normally" ) allowed
                        """ ) to span multiple lines"

which seems confusingly excessive.

I have someone implementing a Swift syntax highlighter right now, and we're trying to anticipate support for multiline strings. It's vexing in combination with the following recovery/robustness feature: if you read a lexical newline while in the "-quoted string state, return to the normal code state. (Interpreting " strings as potentially multiline opens the possibility of accidental "inversion" of the remainder of the file in case of a bug, syntax error, or not-yet-supported language feature. Better to mess up one line than many.)

Disallowing """ multiline strings in interpolations seems a very reasonable thing to do.

···

--
Peter Dillinger, Ph.D.
Software Engineering Manager, Coverity Analysis, Software Integrity Group | Synopsys

From: swift-evolution-bounces@swift.org [mailto:swift-evolution-bounces@swift.org] On Behalf Of Ben Rimmington via swift-evolution
Sent: Thursday, April 20, 2017 12:12 PM
To: Adrian Zubarev <adrian.zubarev@devandartist.com>
Cc: swift-evolution <swift-evolution@swift.org>
Subject: Re: [swift-evolution] [Accepted] SE-0168: Multi-Line String Literals

On 20 Apr 2017, at 17:48, Adrian Zubarev wrote:

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """

   <space><space>foo<space><space>\(end)

   """
This is a very dirty and tedious solution for that problem.
<swift/CHANGELOG.md at main · apple/swift · GitHub;

* Expressions interpolated in strings may now contain string literals.
  For example, `My name is \(attributes["name"]!)` is now a valid expression.
  **(14050788)**

-- Ben

Dear Xiaodi Wu, why do you always have to be offensive in a way of
questioning every single word another person says and not letting others to
have their own opinion?! I do not want to have a discussion with you that
will and up you asking me why is the banana crooked. I expect a focused and
a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be
different from yours and you’ll have to bear with that, because I’ve got my
own opinion. If you’d like me to see things differently, try to convince me
instead of being unfocused and questioning every single word I’m saying.
That won’t lead use to anywhere.

Hi Adrian. For what it's worth, I did not detect any offense in Xiaodi’s
questions. I think he was just asking questions to point parts of your
opinion which he did not understand or was missing some reasoning.

Yes, that was my intention.

I expect the model to solve two major problems. The first one is already
solved by the accepted version. The second one is the ability to escape new
lines when needed (notice, I do not want to escape them all the time, but
only where it’s desired). The accepted version adds more possibilities to
the language and will definitely fix a lot of pain with string literals
some developer had. I’m happy to see that. However from my personal
standpoint, I do not write any code generators created from string literals
as it was a heavily overused example in the proposal and during the
discussion. I often need the ability to wrap very long strings into
multiple lines for readability, but keep the result string intact. In my
last response I showed a sample on how it might look like and that it’s
really painful to read such a string on Git, because it does not provide
any soft-wrapping like other tools might do. That is why I keep saying that
the multi-line string literal should not rely on editors to solve that
problem. Otherwise the bare existence of the such literal could be
questioned and we could fully fall back to editor features like
soft-wrapping or let the editor also wrap strings when it finds a new line
character \n to mimic the proposed behavior. I also do not like the
argument of using string concatenation to solve my particular issue,
because the strings are very long and it quickly becomes were tedious.
Furthermore, the multi-line string literal should not be only reserved for
solving the problems you’ve mentioned. A trailing backslash does not add
any complexity, and you personally don’t need that feature it does not mean
that others won’t need it. It’s an additional feature which is lightweight
and which won’t harm the copy-paste phenomenon most of you wanted. If you
really think it adds complexity than you should also justify your thoughts
to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access
modifier in Swift the model would be really simple but not flexible. Not
that we have a bunch of them the model become complex but on the other hand
it also become way more flexible.

But for what its worth, I agree with Adrian. Let me try to expose the
use-case the proposal is not addressing:

A group of people (me included) don’t wrap lines in their editor (by
choice) but make sure that lines of code don’t extend over a certain limit
(80, 100, 120, whatever). This allows us to keep code readable and control
the wrapping behaviour by manually applying it.

For those people, writing long prose which extends over our limit (like is
the case in some error/assert/precondition messages), we won’t be able to
use the multi-line string proposal and we will have to stay with string
concatenation:

But the key questions I asked are still unanswered:

- What is wrong with string concatenation? Why is that not the ideal
solution? A key motivation for this particular proposal was that it will
allow you to copy and paste content with newlines into a string. But here,
you are explicitly wrapping a string without newlines for the purposes of
formatting your own code. Surely, that can be just as easily done by
writing `"+"` as it is by writing `\`, no?

- What does this use case have to do with _multiline_ strings? Put another
way, why are you in support of a syntax for line continuation, but only for
_multiline_ string literals? [Looking back, I guess this echoes one of the
core team's issues with it as well.] In your examples, you're demonstrating
that it's very useful for generating _single-line_ strings. If this is a
common use and important use case, shouldn't we be designing a way to make
this work with _single-line string literals_?

One argument left unsaid here, but which I guess I'll state explicitly: in
the decisions that they have taken on review, the core team has, afaict,
shown that they want to design "multiline string literals" in such a way
that a multiline (string literal) is the preferred way of spelling a
(multiline string) literal, and that the latter should be the principal use
for the former. I think this is both wise and worthy of preservation,
unless there is some very strong countervailing reason.

But anyway, we are getting far afield here. I don't feel particularly
strongly about `\` as a feature here. But I do believe that making trailing
whitespaces at the end of a line a compiler warning or error is not the way
to go. Either your style is to strip those out and you already have tools
to enforce that, or it isn't your style and the compiler shouldn't force
you to. The idea that it must be possible to visually inspect a string and
know what characters are contained in it is not only unhelpful but
dangerous: with Unicode, this "inspectability" can never be guaranteed, and
making gestures at solving only one particular example of the issue would
encourage users to rely on visual inspection of strings when they
absolutely should not.

Taking the following piece of code:

···

On Fri, Apr 21, 2017 at 8:45 AM, David Hart <david@hartbit.com> wrote:

On 21 Apr 2017, at 11:32, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

func myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, “Variables `aVariable`
and `anotherVariable` are outside their expected range. Please check that
your are not calling this function around midnight”)
}

I currently write it using string concatenation:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, "Variables `aVariable`
and `anotherVariable` " +
        "are outside their expected range. Please check that your are not
calling this function " +
        "around midnight")
}

But writing it using the multi-line string syntax:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables
`aVariable` and `anotherVariable`
are outside their expected range. Please check that your are not calling
this function
around midnight
        """)
}

will inject unwanted newlines. I think what we would like to be able to do
is:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables
`aVariable` and `anotherVariable` \
are outside their expected range. Please check that your are not calling
this function \
around midnight
        """)
}

Notice how the space at the end of the line is also quite obvious now.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 21:50:27, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev <adrian.zubarev@ > devandartist.com> wrote:

The multi-line string literal as it’s accepted right now only allows
pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow
(with the unavoidable exception of some escape sequences) code written
inside the quotations marks to be exactly as pretty as the resulting string
itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes

only, which automatically implies the existence of conventions with longer
lines. For whatever reasons a developer might have, it’s essential to allow
manual line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is essential.
What are the "whatever reasons" for a developer to need this feature? It is
critical enough to be worth complicating the design for something like
literal syntax, which should be as lightweight, straightforward, and simple
as possible?

Not everyone uses the same editor width nor the same editor with exact the

same settings.

Do you think it is a common use case that someone will want to have text
that looks the same only to people reading the code, but not to people
reading the resulting string? Do you think someone might want to put code
inside a string literal, then wrap the literal using 80-character lines,
but write the code inside to wrap using 120-character lines? These seem
like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for

that matter,

If you are going to view a Swift file, you're going to do it through some
program or other. Is it reasonable to add features to Swift because some
hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to

escape the new line injection. I don’t think we should ever expect the
average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors
cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """

------------------------------

The string concatenation uses optimization magic behind the scenes which
is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any
operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks due
to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime,
which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without
any knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string
literal is able to solve that issue during compile time is simply the
perfect place for that.

------------------------------

Some words about the trailing precision. Joe said that we could use \("")
as workaround, but if I recall correctly literals are banned from the
interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """

This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to
include any whitespace characters at the end of each line unless there is a
visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current
accepted design. Why should I expect literal whitespace to be visibly
annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal

solution right now and the trailing backslash becomes additive but not
impossible to add later.
------------------------------

A few people already argued that the core team decided not to include a
new line at the end of each multi-line string, where you yourself said that
the absence of a trailing backslash will produce a string which always ends
with a new line. That behavior would be really strange and painful to
prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds
more flexibility to the literal model, which results in better readability
if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor and
a linter, or an IDE and no linter, etc., and in any of these scenarios you
can already choose whether or not you want trailing newlines stripped. Why
should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string
literal and be 100% sure of what glyphs are involved. We should be clear
that such a criterion cannot and should not be a design goal. If it
supports Unicode and is really literal, then confusables and invisibles
will make it impossible to be sure of what you see; you would have to
either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of
as a multiline string literal. It sounds like what you want isn't multiline
(in fact, you want a new way to write a very long single-line string) and
it isn't literal (you want to use newlines in your code that do not
represent a literal newline). If there is something extremely critical
about a particular string, where you simply must start half of it on a
separate line to help the readers of your code understand what you are
doing, you can already do this by writing "foo" + [newline] "bar". Or you
could just let your editor soft-wrap your long string. Making your
single-line string wrap the same way in every IDE just doesn't seem like
it's related to or worth complicating the syntax for multiline string
literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution < >> swift-evolution@swift.org> wrote:

True, but this is not about IDEs or editors. The feature itself doesn’t
know what an editor is and what it capable of, nor should be ever rely on
that. Not everyone uses the same settings and you cannot be 100% sure to
expect the same string from looking at it, which was written in a different
editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently
accepted version, but we’ll have to warn about them if we decide to add the
trailing backspace. As currently accepted we still have a hole to fill for
coding styles, we do not support multi-lined string literals for code
formatting only, nor do we have trailing precision for the same matter.
(That’s what the backslash was meant for.) That said, I cannot break up a
really long hardcoded string, which in my IDE is softly wrapped, into a
multi-line string literal so that it looks in every editor the same and
still expect the same result and be precise about the trailing whitespace
characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (
swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution < >>> swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by default,

so even if Swift doesn't warn about it, you might still need to satisfy
other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about
it? If it's harmful, you'll have other tools in the pipeline to flag it for
you.

Cosigned. We already have an Xcode setting to strip trailing whitespace,
a Git setting to flag it, and linter settings to remove it. (For instance,
SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle
every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

I totally agree with Adrian and David. Being able to hard wrap long strings without newlines and without breaking indentation due to softwrapping is important while keeping trailing spaces visible (like they are in a normal string). All this is fulfilled by the trailing backslash.

-Thorsten

···

Am 21.04.2017 um 15:45 schrieb David Hart via swift-evolution <swift-evolution@swift.org>:

On 21 Apr 2017, at 11:32, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

Dear Xiaodi Wu, why do you always have to be offensive in a way of questioning every single word another person says and not letting others to have their own opinion?! I do not want to have a discussion with you that will and up you asking me why is the banana crooked. I expect a focused and a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be different from yours and you’ll have to bear with that, because I’ve got my own opinion. If you’d like me to see things differently, try to convince me instead of being unfocused and questioning every single word I’m saying. That won’t lead use to anywhere.

Hi Adrian. For what it's worth, I did not detect any offense in Xiaodi’s questions. I think he was just asking questions to point parts of your opinion which he did not understand or was missing some reasoning.

I expect the model to solve two major problems. The first one is already solved by the accepted version. The second one is the ability to escape new lines when needed (notice, I do not want to escape them all the time, but only where it’s desired). The accepted version adds more possibilities to the language and will definitely fix a lot of pain with string literals some developer had. I’m happy to see that. However from my personal standpoint, I do not write any code generators created from string literals as it was a heavily overused example in the proposal and during the discussion. I often need the ability to wrap very long strings into multiple lines for readability, but keep the result string intact. In my last response I showed a sample on how it might look like and that it’s really painful to read such a string on Git, because it does not provide any soft-wrapping like other tools might do. That is why I keep saying that the multi-line string literal should not rely on editors to solve that problem. Otherwise the bare existence of the such literal could be questioned and we could fully fall back to editor features like soft-wrapping or let the editor also wrap strings when it finds a new line character \n to mimic the proposed behavior. I also do not like the argument of using string concatenation to solve my particular issue, because the strings are very long and it quickly becomes were tedious. Furthermore, the multi-line string literal should not be only reserved for solving the problems you’ve mentioned. A trailing backslash does not add any complexity, and you personally don’t need that feature it does not mean that others won’t need it. It’s an additional feature which is lightweight and which won’t harm the copy-paste phenomenon most of you wanted. If you really think it adds complexity than you should also justify your thoughts to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access modifier in Swift the model would be really simple but not flexible. Not that we have a bunch of them the model become complex but on the other hand it also become way more flexible.

But for what its worth, I agree with Adrian. Let me try to expose the use-case the proposal is not addressing:

A group of people (me included) don’t wrap lines in their editor (by choice) but make sure that lines of code don’t extend over a certain limit (80, 100, 120, whatever). This allows us to keep code readable and control the wrapping behaviour by manually applying it.

For those people, writing long prose which extends over our limit (like is the case in some error/assert/precondition messages), we won’t be able to use the multi-line string proposal and we will have to stay with string concatenation:

Taking the following piece of code:

func myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, “Variables `aVariable` and `anotherVariable` are outside their expected range. Please check that your are not calling this function around midnight”)
}

I currently write it using string concatenation:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, "Variables `aVariable` and `anotherVariable` " +
        "are outside their expected range. Please check that your are not calling this function " +
        "around midnight")
}

But writing it using the multi-line string syntax:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable`
  are outside their expected range. Please check that your are not calling this function
  around midnight
        """)
}

will inject unwanted newlines. I think what we would like to be able to do is:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable` \
  are outside their expected range. Please check that your are not calling this function \
  around midnight
        """)
}

Notice how the space at the end of the line is also quite obvious now.

Dear Xiaodi Wu, why do you always have to be offensive in a way of questioning every single word another person says and not letting others to have their own opinion?! I do not want to have a discussion with you that will and up you asking me why is the banana crooked. I expect a focused and a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be different from yours and you’ll have to bear with that, because I’ve got my own opinion. If you’d like me to see things differently, try to convince me instead of being unfocused and questioning every single word I’m saying. That won’t lead use to anywhere.

Hi Adrian. For what it's worth, I did not detect any offense in Xiaodi’s questions. I think he was just asking questions to point parts of your opinion which he did not understand or was missing some reasoning.

Yes, that was my intention.

I expect the model to solve two major problems. The first one is already solved by the accepted version. The second one is the ability to escape new lines when needed (notice, I do not want to escape them all the time, but only where it’s desired). The accepted version adds more possibilities to the language and will definitely fix a lot of pain with string literals some developer had. I’m happy to see that. However from my personal standpoint, I do not write any code generators created from string literals as it was a heavily overused example in the proposal and during the discussion. I often need the ability to wrap very long strings into multiple lines for readability, but keep the result string intact. In my last response I showed a sample on how it might look like and that it’s really painful to read such a string on Git, because it does not provide any soft-wrapping like other tools might do. That is why I keep saying that the multi-line string literal should not rely on editors to solve that problem. Otherwise the bare existence of the such literal could be questioned and we could fully fall back to editor features like soft-wrapping or let the editor also wrap strings when it finds a new line character \n to mimic the proposed behavior. I also do not like the argument of using string concatenation to solve my particular issue, because the strings are very long and it quickly becomes were tedious. Furthermore, the multi-line string literal should not be only reserved for solving the problems you’ve mentioned. A trailing backslash does not add any complexity, and you personally don’t need that feature it does not mean that others won’t need it. It’s an additional feature which is lightweight and which won’t harm the copy-paste phenomenon most of you wanted. If you really think it adds complexity than you should also justify your thoughts to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access modifier in Swift the model would be really simple but not flexible. Not that we have a bunch of them the model become complex but on the other hand it also become way more flexible.

But for what its worth, I agree with Adrian. Let me try to expose the use-case the proposal is not addressing:

A group of people (me included) don’t wrap lines in their editor (by choice) but make sure that lines of code don’t extend over a certain limit (80, 100, 120, whatever). This allows us to keep code readable and control the wrapping behaviour by manually applying it.

For those people, writing long prose which extends over our limit (like is the case in some error/assert/precondition messages), we won’t be able to use the multi-line string proposal and we will have to stay with string concatenation:

But the key questions I asked are still unanswered:

- What is wrong with string concatenation? Why is that not the ideal solution? A key motivation for this particular proposal was that it will allow you to copy and paste content with newlines into a string. But here, you are explicitly wrapping a string without newlines for the purposes of formatting your own code. Surely, that can be just as easily done by writing `"+"` as it is by writing `\`, no?

The reason I'm bothered about string concatenation is that it's not as easily maintainable. For example, imagine I modify some text in one of the segments (before the last). I have to re-evaluate where the separation will go and do more editing than with \.

- What does this use case have to do with _multiline_ strings? Put another way, why are you in support of a syntax for line continuation, but only for _multiline_ string literals? [Looking back, I guess this echoes one of the core team's issues with it as well.] In your examples, you're demonstrating that it's very useful for generating _single-line_ strings. If this is a common use and important use case, shouldn't we be designing a way to make this work with _single-line string literals_?

The only link with multi-line string with my example is that we are choosing to format it over multiple lines of source code. But of course, I wouldn't be against a special syntax of single-line strings to solve the same problem:

assert(condition, "A single-line string over multiple lines
    could look like this - new lines are ignored")

···

On 21 Apr 2017, at 20:20, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Apr 21, 2017 at 8:45 AM, David Hart <david@hartbit.com> wrote:

On 21 Apr 2017, at 11:32, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

One argument left unsaid here, but which I guess I'll state explicitly: in the decisions that they have taken on review, the core team has, afaict, shown that they want to design "multiline string literals" in such a way that a multiline (string literal) is the preferred way of spelling a (multiline string) literal, and that the latter should be the principal use for the former. I think this is both wise and worthy of preservation, unless there is some very strong countervailing reason.

But anyway, we are getting far afield here. I don't feel particularly strongly about `\` as a feature here. But I do believe that making trailing whitespaces at the end of a line a compiler warning or error is not the way to go. Either your style is to strip those out and you already have tools to enforce that, or it isn't your style and the compiler shouldn't force you to. The idea that it must be possible to visually inspect a string and know what characters are contained in it is not only unhelpful but dangerous: with Unicode, this "inspectability" can never be guaranteed, and making gestures at solving only one particular example of the issue would encourage users to rely on visual inspection of strings when they absolutely should not.

Taking the following piece of code:

func myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, “Variables `aVariable` and `anotherVariable` are outside their expected range. Please check that your are not calling this function around midnight”)
}

I currently write it using string concatenation:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, "Variables `aVariable` and `anotherVariable` " +
        "are outside their expected range. Please check that your are not calling this function " +
        "around midnight")
}

But writing it using the multi-line string syntax:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable`
  are outside their expected range. Please check that your are not calling this function
  around midnight
        """)
}

will inject unwanted newlines. I think what we would like to be able to do is:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable` \
  are outside their expected range. Please check that your are not calling this function \
  around midnight
        """)
}

Notice how the space at the end of the line is also quite obvious now.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 21:50:27, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

The multi-line string literal as it’s accepted right now only allows pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow (with the unavoidable exception of some escape sequences) code written inside the quotations marks to be exactly as pretty as the resulting string itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes only, which automatically implies the existence of conventions with longer lines. For whatever reasons a developer might have, it’s essential to allow manual line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is essential. What are the "whatever reasons" for a developer to need this feature? It is critical enough to be worth complicating the design for something like literal syntax, which should be as lightweight, straightforward, and simple as possible?

Not everyone uses the same editor width nor the same editor with exact the same settings.

Do you think it is a common use case that someone will want to have text that looks the same only to people reading the code, but not to people reading the resulting string? Do you think someone might want to put code inside a string literal, then wrap the literal using 80-character lines, but write the code inside to wrap using 120-character lines? These seem like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for that matter,

If you are going to view a Swift file, you're going to do it through some program or other. Is it reasonable to add features to Swift because some hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to escape the new line injection. I don’t think we should ever expect the average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
     
   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """
The string concatenation uses optimization magic behind the scenes which is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks due to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime, which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without any knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string literal is able to solve that issue during compile time is simply the perfect place for that.

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """
This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to include any whitespace characters at the end of each line unless there is a visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current accepted design. Why should I expect literal whitespace to be visibly annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal solution right now and the trailing backslash becomes additive but not impossible to add later.

A few people already argued that the core team decided not to include a new line at the end of each multi-line string, where you yourself said that the absence of a trailing backslash will produce a string which always ends with a new line. That behavior would be really strange and painful to prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds more flexibility to the literal model, which results in better readability if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor and a linter, or an IDE and no linter, etc., and in any of these scenarios you can already choose whether or not you want trailing newlines stripped. Why should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string literal and be 100% sure of what glyphs are involved. We should be clear that such a criterion cannot and should not be a design goal. If it supports Unicode and is really literal, then confusables and invisibles will make it impossible to be sure of what you see; you would have to either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of as a multiline string literal. It sounds like what you want isn't multiline (in fact, you want a new way to write a very long single-line string) and it isn't literal (you want to use newlines in your code that do not represent a literal newline). If there is something extremely critical about a particular string, where you simply must start half of it on a separate line to help the readers of your code understand what you are doing, you can already do this by writing "foo" + [newline] "bar". Or you could just let your editor soft-wrap your long string. Making your single-line string wrap the same way in every IDE just doesn't seem like it's related to or worth complicating the syntax for multiline string literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
True, but this is not about IDEs or editors. The feature itself doesn’t know what an editor is and what it capable of, nor should be ever rely on that. Not everyone uses the same settings and you cannot be 100% sure to expect the same string from looking at it, which was written in a different editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently accepted version, but we’ll have to warn about them if we decide to add the trailing backspace. As currently accepted we still have a hole to fill for coding styles, we do not support multi-lined string literals for code formatting only, nor do we have trailing precision for the same matter. (That’s what the backslash was meant for.) That said, I cannot break up a really long hardcoded string, which in my IDE is softly wrapped, into a multi-line string literal so that it looks in every editor the same and still expect the same result and be precise about the trailing whitespace characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by default, so even if Swift doesn't warn about it, you might still need to satisfy other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about it? If it's harmful, you'll have other tools in the pipeline to flag it for you.

Cosigned. We already have an Xcode setting to strip trailing whitespace, a Git setting to flag it, and linter settings to remove it. (For instance, SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Dear Xiaodi Wu, why do you always have to be offensive in a way of
questioning every single word another person says and not letting others to
have their own opinion?! I do not want to have a discussion with you that
will and up you asking me why is the banana crooked. I expect a focused and
a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be
different from yours and you’ll have to bear with that, because I’ve got my
own opinion. If you’d like me to see things differently, try to convince me
instead of being unfocused and questioning every single word I’m saying.
That won’t lead use to anywhere.

Hi Adrian. For what it's worth, I did not detect any offense in Xiaodi’s
questions. I think he was just asking questions to point parts of your
opinion which he did not understand or was missing some reasoning.

Yes, that was my intention.

I expect the model to solve two major problems. The first one is already
solved by the accepted version. The second one is the ability to escape new
lines when needed (notice, I do not want to escape them all the time, but
only where it’s desired). The accepted version adds more possibilities to
the language and will definitely fix a lot of pain with string literals
some developer had. I’m happy to see that. However from my personal
standpoint, I do not write any code generators created from string literals
as it was a heavily overused example in the proposal and during the
discussion. I often need the ability to wrap very long strings into
multiple lines for readability, but keep the result string intact. In my
last response I showed a sample on how it might look like and that it’s
really painful to read such a string on Git, because it does not provide
any soft-wrapping like other tools might do. That is why I keep saying that
the multi-line string literal should not rely on editors to solve that
problem. Otherwise the bare existence of the such literal could be
questioned and we could fully fall back to editor features like
soft-wrapping or let the editor also wrap strings when it finds a new line
character \n to mimic the proposed behavior. I also do not like the
argument of using string concatenation to solve my particular issue,
because the strings are very long and it quickly becomes were tedious.
Furthermore, the multi-line string literal should not be only reserved for
solving the problems you’ve mentioned. A trailing backslash does not add
any complexity, and you personally don’t need that feature it does not mean
that others won’t need it. It’s an additional feature which is lightweight
and which won’t harm the copy-paste phenomenon most of you wanted. If you
really think it adds complexity than you should also justify your thoughts
to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access
modifier in Swift the model would be really simple but not flexible. Not
that we have a bunch of them the model become complex but on the other hand
it also become way more flexible.

But for what its worth, I agree with Adrian. Let me try to expose the
use-case the proposal is not addressing:

A group of people (me included) don’t wrap lines in their editor (by
choice) but make sure that lines of code don’t extend over a certain limit
(80, 100, 120, whatever). This allows us to keep code readable and control
the wrapping behaviour by manually applying it.

For those people, writing long prose which extends over our limit (like
is the case in some error/assert/precondition messages), we won’t be able
to use the multi-line string proposal and we will have to stay with string
concatenation:

But the key questions I asked are still unanswered:

- What is wrong with string concatenation? Why is that not the ideal
solution? A key motivation for this particular proposal was that it will
allow you to copy and paste content with newlines into a string. But here,
you are explicitly wrapping a string without newlines for the purposes of
formatting your own code. Surely, that can be just as easily done by
writing `"+"` as it is by writing `\`, no?

The reason I'm bothered about string concatenation is that it's not as
easily maintainable. For example, imagine I modify some text in one of the
segments (before the last). I have to re-evaluate where the separation will
go and do more editing than with \.

Hmm...the difficulty of editing hard-wrapped strings is principally due to
the hard-wrapping and not the delimiters, wouldn't you say? I've manually
re-wrapped my share of hard-wrapped text *without* delimiters, and it's
sufficiently a pain in the butt. Yes, there are three characters in `"+"`
to add or delete instead of the one in `\`, but the crux of the issue is
the hard-wrapping, which you're _choosing_ to do, wouldn't you agree?

- What does this use case have to do with _multiline_ strings? Put another
way, why are you in support of a syntax for line continuation, but only for
_multiline_ string literals? [Looking back, I guess this echoes one of the
core team's issues with it as well.] In your examples, you're demonstrating
that it's very useful for generating _single-line_ strings. If this is a
common use and important use case, shouldn't we be designing a way to make
this work with _single-line string literals_?

The only link with multi-line string with my example is that we are
choosing to format it over multiple lines of source code. But of course, I
wouldn't be against a special syntax of single-line strings to solve the
same problem:

assert(condition, "A single-line string over multiple lines
    could look like this - new lines are ignored")

And this is my point. If this feature is worth having, then whatever syntax
it goes by, it has nothing to do with multiline string literals and should
work for all string literals. It's simply not part and parcel of multiline
string literals.

···

On Fri, Apr 21, 2017 at 1:46 PM, David Hart <david@hartbit.com> wrote:

On 21 Apr 2017, at 20:20, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:
On Fri, Apr 21, 2017 at 8:45 AM, David Hart <david@hartbit.com> wrote:

On 21 Apr 2017, at 11:32, Adrian Zubarev via swift-evolution < >> swift-evolution@swift.org> wrote:

One argument left unsaid here, but which I guess I'll state explicitly: in
the decisions that they have taken on review, the core team has, afaict,
shown that they want to design "multiline string literals" in such a way
that a multiline (string literal) is the preferred way of spelling a
(multiline string) literal, and that the latter should be the principal use
for the former. I think this is both wise and worthy of preservation,
unless there is some very strong countervailing reason.

But anyway, we are getting far afield here. I don't feel particularly
strongly about `\` as a feature here. But I do believe that making trailing
whitespaces at the end of a line a compiler warning or error is not the way
to go. Either your style is to strip those out and you already have tools
to enforce that, or it isn't your style and the compiler shouldn't force
you to. The idea that it must be possible to visually inspect a string and
know what characters are contained in it is not only unhelpful but
dangerous: with Unicode, this "inspectability" can never be guaranteed, and
making gestures at solving only one particular example of the issue would
encourage users to rely on visual inspection of strings when they
absolutely should not.

Taking the following piece of code:

func myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, “Variables `aVariable`
and `anotherVariable` are outside their expected range. Please check that
your are not calling this function around midnight”)
}

I currently write it using string concatenation:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, "Variables `aVariable`
and `anotherVariable` " +
        "are outside their expected range. Please check that your are not
calling this function " +
        "around midnight")
}

But writing it using the multi-line string syntax:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables
`aVariable` and `anotherVariable`
are outside their expected range. Please check that your are not calling
this function
around midnight
        """)
}

will inject unwanted newlines. I think what we would like to be able to
do is:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables
`aVariable` and `anotherVariable` \
are outside their expected range. Please check that your are not calling
this function \
around midnight
        """)
}

Notice how the space at the end of the line is also quite obvious now.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 21:50:27, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev <adrian.zubarev@devand >> artist.com> wrote:

The multi-line string literal as it’s accepted right now only allows
pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow
(with the unavoidable exception of some escape sequences) code written
inside the quotations marks to be exactly as pretty as the resulting string
itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes

only, which automatically implies the existence of conventions with longer
lines. For whatever reasons a developer might have, it’s essential to allow
manual line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is
essential. What are the "whatever reasons" for a developer to need this
feature? It is critical enough to be worth complicating the design for
something like literal syntax, which should be as lightweight,
straightforward, and simple as possible?

Not everyone uses the same editor width nor the same editor with exact

the same settings.

Do you think it is a common use case that someone will want to have text
that looks the same only to people reading the code, but not to people
reading the resulting string? Do you think someone might want to put code
inside a string literal, then wrap the literal using 80-character lines,
but write the code inside to wrap using 120-character lines? These seem
like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for

that matter,

If you are going to view a Swift file, you're going to do it through some
program or other. Is it reasonable to add features to Swift because some
hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to

escape the new line injection. I don’t think we should ever expect the
average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors
cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """

------------------------------

The string concatenation uses optimization magic behind the scenes which
is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any
operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks
due to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime,
which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without
any knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string
literal is able to solve that issue during compile time is simply the
perfect place for that.

------------------------------

Some words about the trailing precision. Joe said that we could use
\("") as workaround, but if I recall correctly literals are banned from
the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """

This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to
include any whitespace characters at the end of each line unless there is a
visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current
accepted design. Why should I expect literal whitespace to be visibly
annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal

solution right now and the trailing backslash becomes additive but not
impossible to add later.
------------------------------

A few people already argued that the core team decided not to include a
new line at the end of each multi-line string, where you yourself said that
the absence of a trailing backslash will produce a string which always ends
with a new line. That behavior would be really strange and painful to
prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds
more flexibility to the literal model, which results in better readability
if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor
and a linter, or an IDE and no linter, etc., and in any of these scenarios
you can already choose whether or not you want trailing newlines stripped.
Why should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string
literal and be 100% sure of what glyphs are involved. We should be clear
that such a criterion cannot and should not be a design goal. If it
supports Unicode and is really literal, then confusables and invisibles
will make it impossible to be sure of what you see; you would have to
either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of
as a multiline string literal. It sounds like what you want isn't multiline
(in fact, you want a new way to write a very long single-line string) and
it isn't literal (you want to use newlines in your code that do not
represent a literal newline). If there is something extremely critical
about a particular string, where you simply must start half of it on a
separate line to help the readers of your code understand what you are
doing, you can already do this by writing "foo" + [newline] "bar". Or you
could just let your editor soft-wrap your long string. Making your
single-line string wrap the same way in every IDE just doesn't seem like
it's related to or worth complicating the syntax for multiline string
literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution < >>> swift-evolution@swift.org> wrote:

True, but this is not about IDEs or editors. The feature itself doesn’t
know what an editor is and what it capable of, nor should be ever rely on
that. Not everyone uses the same settings and you cannot be 100% sure to
expect the same string from looking at it, which was written in a different
editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently
accepted version, but we’ll have to warn about them if we decide to add the
trailing backspace. As currently accepted we still have a hole to fill for
coding styles, we do not support multi-lined string literals for code
formatting only, nor do we have trailing precision for the same matter.
(That’s what the backslash was meant for.) That said, I cannot break up a
really long hardcoded string, which in my IDE is softly wrapped, into a
multi-line string literal so that it looks in every editor the same and
still expect the same result and be precise about the trailing whitespace
characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (
swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution < >>>> swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by

default, so even if Swift doesn't warn about it, you might still need to
satisfy other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about
it? If it's harmful, you'll have other tools in the pipeline to flag it for
you.

Cosigned. We already have an Xcode setting to strip trailing
whitespace, a Git setting to flag it, and linter settings to remove it.
(For instance, SwiftFormat has a --trimwhitespace flag.) Not every tool
needs to handle every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

From Joe's email:

"[...]
Discussion on the list raised the idea of allowing a line to end with \ to "escape" the newline and elide it from the value of the literal; the core team had concerns about only allowing that inside multi-line literals and felt that that could also be considered later as an additive feature.
[...]"

So it sounds that can be considered in a separate proposal to be added to normal and multi-line string literals.

···

On Apr 21, 2017, at 2:57 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

On Fri, Apr 21, 2017 at 1:46 PM, David Hart <david@hartbit.com> wrote:

On 21 Apr 2017, at 20:20, Xiaodi Wu <xiaodi.wu@gmail.com> wrote:

On Fri, Apr 21, 2017 at 8:45 AM, David Hart <david@hartbit.com> wrote:

On 21 Apr 2017, at 11:32, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

Dear Xiaodi Wu, why do you always have to be offensive in a way of questioning every single word another person says and not letting others to have their own opinion?! I do not want to have a discussion with you that will and up you asking me why is the banana crooked. I expect a focused and a constructive discussion if not mentioned otherwise.

My expectation from the model of the multi-lined string literal might be different from yours and you’ll have to bear with that, because I’ve got my own opinion. If you’d like me to see things differently, try to convince me instead of being unfocused and questioning every single word I’m saying. That won’t lead use to anywhere.

Hi Adrian. For what it's worth, I did not detect any offense in Xiaodi’s questions. I think he was just asking questions to point parts of your opinion which he did not understand or was missing some reasoning.

Yes, that was my intention.

I expect the model to solve two major problems. The first one is already solved by the accepted version. The second one is the ability to escape new lines when needed (notice, I do not want to escape them all the time, but only where it’s desired). The accepted version adds more possibilities to the language and will definitely fix a lot of pain with string literals some developer had. I’m happy to see that. However from my personal standpoint, I do not write any code generators created from string literals as it was a heavily overused example in the proposal and during the discussion. I often need the ability to wrap very long strings into multiple lines for readability, but keep the result string intact. In my last response I showed a sample on how it might look like and that it’s really painful to read such a string on Git, because it does not provide any soft-wrapping like other tools might do. That is why I keep saying that the multi-line string literal should not rely on editors to solve that problem. Otherwise the bare existence of the such literal could be questioned and we could fully fall back to editor features like soft-wrapping or let the editor also wrap strings when it finds a new line character \n to mimic the proposed behavior. I also do not like the argument of using string concatenation to solve my particular issue, because the strings are very long and it quickly becomes were tedious. Furthermore, the multi-line string literal should not be only reserved for solving the problems you’ve mentioned. A trailing backslash does not add any complexity, and you personally don’t need that feature it does not mean that others won’t need it. It’s an additional feature which is lightweight and which won’t harm the copy-paste phenomenon most of you wanted. If you really think it adds complexity than you should also justify your thoughts to convince your conversation partner.

IMHO ‘complexity’ creates ‘flexibility’. If we’d only had one access modifier in Swift the model would be really simple but not flexible. Not that we have a bunch of them the model become complex but on the other hand it also become way more flexible.

But for what its worth, I agree with Adrian. Let me try to expose the use-case the proposal is not addressing:

A group of people (me included) don’t wrap lines in their editor (by choice) but make sure that lines of code don’t extend over a certain limit (80, 100, 120, whatever). This allows us to keep code readable and control the wrapping behaviour by manually applying it.

For those people, writing long prose which extends over our limit (like is the case in some error/assert/precondition messages), we won’t be able to use the multi-line string proposal and we will have to stay with string concatenation:

But the key questions I asked are still unanswered:

- What is wrong with string concatenation? Why is that not the ideal solution? A key motivation for this particular proposal was that it will allow you to copy and paste content with newlines into a string. But here, you are explicitly wrapping a string without newlines for the purposes of formatting your own code. Surely, that can be just as easily done by writing `"+"` as it is by writing `\`, no?

The reason I'm bothered about string concatenation is that it's not as easily maintainable. For example, imagine I modify some text in one of the segments (before the last). I have to re-evaluate where the separation will go and do more editing than with \.

Hmm...the difficulty of editing hard-wrapped strings is principally due to the hard-wrapping and not the delimiters, wouldn't you say? I've manually re-wrapped my share of hard-wrapped text *without* delimiters, and it's sufficiently a pain in the butt. Yes, there are three characters in `"+"` to add or delete instead of the one in `\`, but the crux of the issue is the hard-wrapping, which you're _choosing_ to do, wouldn't you agree?

- What does this use case have to do with _multiline_ strings? Put another way, why are you in support of a syntax for line continuation, but only for _multiline_ string literals? [Looking back, I guess this echoes one of the core team's issues with it as well.] In your examples, you're demonstrating that it's very useful for generating _single-line_ strings. If this is a common use and important use case, shouldn't we be designing a way to make this work with _single-line string literals_?

The only link with multi-line string with my example is that we are choosing to format it over multiple lines of source code. But of course, I wouldn't be against a special syntax of single-line strings to solve the same problem:

assert(condition, "A single-line string over multiple lines
    could look like this - new lines are ignored")

And this is my point. If this feature is worth having, then whatever syntax it goes by, it has nothing to do with multiline string literals and should work for all string literals. It's simply not part and parcel of multiline string literals.

One argument left unsaid here, but which I guess I'll state explicitly: in the decisions that they have taken on review, the core team has, afaict, shown that they want to design "multiline string literals" in such a way that a multiline (string literal) is the preferred way of spelling a (multiline string) literal, and that the latter should be the principal use for the former. I think this is both wise and worthy of preservation, unless there is some very strong countervailing reason.

But anyway, we are getting far afield here. I don't feel particularly strongly about `\` as a feature here. But I do believe that making trailing whitespaces at the end of a line a compiler warning or error is not the way to go. Either your style is to strip those out and you already have tools to enforce that, or it isn't your style and the compiler shouldn't force you to. The idea that it must be possible to visually inspect a string and know what characters are contained in it is not only unhelpful but dangerous: with Unicode, this "inspectability" can never be guaranteed, and making gestures at solving only one particular example of the issue would encourage users to rely on visual inspection of strings when they absolutely should not.

Taking the following piece of code:

func myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, “Variables `aVariable` and `anotherVariable` are outside their expected range. Please check that your are not calling this function around midnight”)
}

I currently write it using string concatenation:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, "Variables `aVariable` and `anotherVariable` " +
        "are outside their expected range. Please check that your are not calling this function " +
        "around midnight")
}

But writing it using the multi-line string syntax:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable`
  are outside their expected range. Please check that your are not calling this function
  around midnight
        """)
}

will inject unwanted newlines. I think what we would like to be able to do is:

fun myFunction() {
    assert(aVariable > 10 && anotherVariable < 50, """Variables `aVariable` and `anotherVariable` \
  are outside their expected range. Please check that your are not calling this function \
  around midnight
        """)
}

Notice how the space at the end of the line is also quite obvious now.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 21:50:27, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

On Thu, Apr 20, 2017 at 11:48 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

The multi-line string literal as it’s accepted right now only allows pretty code generation with smaller lines.

This statement does not make sense to me. Multiline string literals allow (with the unavoidable exception of some escape sequences) code written inside the quotations marks to be exactly as pretty as the resulting string itself. That is why it's a literal.

The literal itself is not reserved for JSON, XML and similar syntaxes only, which automatically implies the existence of conventions with longer lines. For whatever reasons a developer might have, it’s essential to allow manual line wrapping without injecting a new line into the resulting string.

You keep re-stating instead of explaining why you think this is essential. What are the "whatever reasons" for a developer to need this feature? It is critical enough to be worth complicating the design for something like literal syntax, which should be as lightweight, straightforward, and simple as possible?

Not everyone uses the same editor width nor the same editor with exact the same settings.

Do you think it is a common use case that someone will want to have text that looks the same only to people reading the code, but not to people reading the resulting string? Do you think someone might want to put code inside a string literal, then wrap the literal using 80-character lines, but write the code inside to wrap using 120-character lines? These seem like rather implausible use cases.

You simply cannot and really should not rely on any editor or linter for that matter,

If you are going to view a Swift file, you're going to do it through some program or other. Is it reasonable to add features to Swift because some hypothetical text editors might not be able to wrap lines?

nor do I vision it as a strong argument against having the ability to escape the new line injection. I don’t think we should ever expect the average Swift developer sitting in-front of an ultra wide monitor.

Consider this example:

// Currently it would look like this:

let myLongString = "Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.\n\nNam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.\n\nDuis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis."

// With the accepted version of the proposal it becomes a little bit better, but still to long,
// because we can only replace `\n` characters with lines and that's it.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.

   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis.
   """

// This is how it should ideally look like and be editor/IDE/linter independent.
// The string produces the same result as above and does not rely on any
// soft-wrapping functionality

Why should one not rely on editors being able to soft wrap? Which editors cannot soft wrap? What is wrong with soft wrapping?

and is written within some smaller line width.
// The trailing precision is a really good tradeoff at this point.

let myLongString = """
   Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit \
   lobortis nisl ut aliquip ex ea commodo consequat. Duis autem vel eum iriure \
   dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore \
   eu feugiat nulla facilisis at vero eros et accumsan et iusto odio dignissim qui \
   blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
     
   Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming \
   id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer \
   adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna \
   aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation \
   ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.

   Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie \
   consequat, vel illum dolore eu feugiat nulla facilisis.
   """
The string concatenation uses optimization magic behind the scenes which is not obvious for everyone.

What is magic about string concatenation?

I personally think that every operation involved in concatenation or any operation in-general adds a performance overhead

In what scenarios have you encountered runtime performance bottlenecks due to concatenation of string literals?

and theoretically needs more time to resolve the expression at runtime, which is the natural way of thinking without any knowledge

Why should we add new features simply because people who "think without any knowledge" might have misunderstandings about existing ones?

about the optimization the compiler is able to do for you. A string literal is able to solve that issue during compile time is simply the perfect place for that.

Some words about the trailing precision. Joe said that we could use \("") as workaround, but if I recall correctly literals are banned from the interpolation itself, which will result in us doing something like this:

let end = ""

let myString = """
   <space><space>foo<space><space>\(end)
   """
This is a very dirty and tedious solution for that problem.

As accepted right now, no one should ever expect the result string to include any whitespace characters at the end of each line unless there is a visible annotation provided for precision.

Why shouldn't they? I expect nothing about line endings with the current accepted design. Why should I expect literal whitespace to be visibly annotated? I expect them to be, um, whitespace.

Providing a warning for trailing whitespace characters would be ideal solution right now and the trailing backslash becomes additive but not impossible to add later.

A few people already argued that the core team decided not to include a new line at the end of each multi-line string, where you yourself said that the absence of a trailing backslash will produce a string which always ends with a new line. That behavior would be really strange and painful to prevent if there is no backslash for escaping it.

The trailing backslash does not add any complexity but instead it adds more flexibility to the literal model, which results in better readability if the precision is desired for code formatting!

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 07:30:29, Xiaodi Wu (xiaodi.wu@gmail.com) schrieb:

You can use a plain text editor and no linter, or a plain text editor and a linter, or an IDE and no linter, etc., and in any of these scenarios you can already choose whether or not you want trailing newlines stripped. Why should the compiler try to enforce any rules here?

Since Unicode is supported, it is never possible to look at a string literal and be 100% sure of what glyphs are involved. We should be clear that such a criterion cannot and should not be a design goal. If it supports Unicode and is really literal, then confusables and invisibles will make it impossible to be sure of what you see; you would have to either stop supporting Unicode or stop being literal.

I'm not sure this "coding style" you describe can properly be thought of as a multiline string literal. It sounds like what you want isn't multiline (in fact, you want a new way to write a very long single-line string) and it isn't literal (you want to use newlines in your code that do not represent a literal newline). If there is something extremely critical about a particular string, where you simply must start half of it on a separate line to help the readers of your code understand what you are doing, you can already do this by writing "foo" + [newline] "bar". Or you could just let your editor soft-wrap your long string. Making your single-line string wrap the same way in every IDE just doesn't seem like it's related to or worth complicating the syntax for multiline string literals. I would be strongly opposed to such a feature.

On Wed, Apr 19, 2017 at 23:42 Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
True, but this is not about IDEs or editors. The feature itself doesn’t know what an editor is and what it capable of, nor should be ever rely on that. Not everyone uses the same settings and you cannot be 100% sure to expect the same string from looking at it, which was written in a different editor if we don’t warn about trailing whitespaces now.

The trailing whitespaces might not do any harm for the currently accepted version, but we’ll have to warn about them if we decide to add the trailing backspace. As currently accepted we still have a hole to fill for coding styles, we do not support multi-lined string literals for code formatting only, nor do we have trailing precision for the same matter. (That’s what the backslash was meant for.) That said, I cannot break up a really long hardcoded string, which in my IDE is softly wrapped, into a multi-line string literal so that it looks in every editor the same and still expect the same result and be precise about the trailing whitespace characters.

--
Adrian Zubarev
Sent with Airmail

Am 20. April 2017 um 00:27:48, Brent Royal-Gordon via swift-evolution (swift-evolution@swift.org) schrieb:

On Apr 19, 2017, at 3:18 PM, Xiaodi Wu via swift-evolution <swift-evolution@swift.org> wrote:

Other common tools like Git already flag trailing whitespace by default, so even if Swift doesn't warn about it, you might still need to satisfy other tools in your pipeline.

Isn't that an equally good argument for Swift *not* warning you about it? If it's harmful, you'll have other tools in the pipeline to flag it for you.

Cosigned. We already have an Xcode setting to strip trailing whitespace, a Git setting to flag it, and linter settings to remove it. (For instance, SwiftFormat has a --trimwhitespace flag.) Not every tool needs to handle every case of questionable style.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Sounds like the solution and would bring strings into line with the precedent in C.
Overall, the multi-line proposal held together better when it included this feature.

···

On 21 Apr 2017, at 20:27, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

From Joe's email:

"[...]
Discussion on the list raised the idea of allowing a line to end with \ to "escape" the newline and elide it from the value of the literal; the core team had concerns about only allowing that inside multi-line literals and felt that that could also be considered later as an additive feature.
[...]"

So it sounds that can be considered in a separate proposal to be added to normal and multi-line string literals.