<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Apr 27, 2016 at 9:08 AM, Vladimir.S via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I expect to be able to have multiline text exactly *&quot;as-is&quot;* in my source file. No escaping, no interpolation, etc. I believe this should be a target of the proposal.<br></blockquote><div><br></div><div>I also see this as one of the most important goals of any multi-line string-handling proposal. The &quot;no escapes required&quot; syntax doesn&#39;t have to be the only way to handle multi-line strings, but it should be one of the available ways.</div><div><br></div><div>-John</div><div><br></div><div>P.S. - Secondarily (and broader than just multi-line strings) I think there should also be a way to avoid backslash-itis in strings of all kinds by providing some flexibility in string delimiters. But that&#39;s for another thread…</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
Otherwise, I reject to see any reason to introduce anything new at this area - we already can concatenate strings and place them on next line and escape special characters.<br>
<br>
In your proposal, you have to escape characters in your text, you need to carefully modify the copy-pasted text to be allowed as correct multi-line string. Also, what if I need to have spaces *at the end of string* ? Editor can just trimmed them, and we can&#39;t clearly see them.<br>
<br>
Personally I need to be able to have this(in some way) in my code:<br>
(note this &quot;\tuttorial&quot; and &quot;\(edition&quot; - this is just text, I want to have inside my xml)<br>
<br>
let xml = ... // some marker to start the multi-line str<span class=""><br>
&lt;?xml version=&quot;1.0&quot;?&gt;<br>
&lt;catalog&gt;<br></span><span class="">
    &lt;book id=&quot;myid&quot; empty=&quot;&quot;&gt;<br>
        &lt;author&gt;myAuthor&lt;/author&gt;<br>
        &lt;title&gt;myTitle \tutorial 1\(edition 2)&lt;/title&gt;<br>
    &lt;/book&gt;<br>
&lt;/catalog&gt;<br></span>
... // some marker here to stop multi-line str<br>
<br>
It seems like we need some markers for end-of-the-line to be able to keep spaces/tabs in the end of line.<br>
<br>
What about something like this. Two suported variants : first when we need to keep spaces in the end of line, and second when we don&#39;t need spaced(will be trimmed by parser)<br>
<br>
#1 (parser should just take the text between first and last quote *as-is*)<br>
<br>
let xml = &quot;\<br>
&quot;&lt;?xml version=&quot;1.0&quot;?&gt;     &quot; // yes, *I need* these spaces at the end<span class=""><br>
&quot;&lt;catalog&gt;&quot;<br>
&quot;    &lt;book id=&quot;myid&quot; empty=&quot;&quot;&gt;&quot;<br>
&quot;        &lt;author&gt;myAuthor&lt;/author&gt;&quot;<br>
&quot;        &lt;title&gt;myTitle \tutorial 1\(edition 2)&lt;/title&gt;&quot;<br>
&quot;    &lt;/book&gt;&quot;<br>
&quot;&lt;/catalog&gt;&quot;<br>
&quot;<br>
<br></span>
#2 in this case we don&#39;t need any spaces/tabs in the end of lines(don&#39;t care):<br>
(parser takes all that is after | as-is but trims any trailing spaces/tabs in lines to be clear in behaviour)<span class=""><br>
<br>
let xml = &quot;\<br>
|&lt;?xml version=&quot;1.0&quot;?&gt;<br>
|&lt;catalog&gt;<br></span><span class="">
|    &lt;book id=&quot;myid&quot; empty=&quot;&quot;&gt;<br>
|        &lt;author&gt;myAuthor&lt;/author&gt;<br>
|        &lt;title&gt;myTitle \tutorial 1\(edition 2)&lt;/title&gt;<br>
|    &lt;/book&gt;<br>
|&lt;/catalog&gt;<br>
&quot;<br>
<br></span>
Or these two could be combined in one(as-is between |..|) but I&#39;m not sure:<br>
<br>
let xml = &quot;\<br>
|&lt;?xml version=&quot;1.0&quot;?&gt;     | // yes, I need these spaces<br>
|&lt;catalog&gt;| // we have to have closing symbol in this case in other lines<span class=""><br>
|    &lt;book id=&quot;myid&quot; empty=&quot;&quot;&gt;|<br>
|        &lt;author&gt;myAuthor&lt;/author&gt;|<br>
|        &lt;title&gt;myTitle \tutorial 1\(edition 2)&lt;/title&gt;|<br>
|    &lt;/book&gt;|<br>
|&lt;/catalog&gt;|<br>
&quot;<br>
<br>
<br>
</span><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br><span class="">
Gist: &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f</a>&gt;<br>
<br>
<br>
  Multiline string literals<br>
<br></span>
  * Proposal: SE-NNNN<br>
    &lt;<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" rel="noreferrer" target="_blank">https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md</a>&gt;<br>
  * Author(s): Brent Royal-Gordon &lt;<a href="https://github.com/brentdax" rel="noreferrer" target="_blank">https://github.com/brentdax</a>&gt;<br>
  * Status: First Draft<br>
  * Review manager: TBD<br>
<br>
<br>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction</a>&gt;Introduction<span class=""><br>
<br>
In Swift 2.2, the only means to insert a newline into a string literal is<br>
the |\n| escape. String literals specified in this way are generally ugly<br>
and unreadable. We propose a multiline string feature inspired by English<br>
punctuation which is a straightforward extension of our existing string<br>
literals.<br>
<br>
Swift-evolution thread: multi-line string literals.<br></span>
&lt;<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html" rel="noreferrer" target="_blank">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html</a>&gt;<br>
<br>
<br>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes</a>&gt;Draft<br>
    Notes<br>
<br>
  *<span class=""><br>
<br>
    This draft differs from the prototypes being thrown around on the list<br>
    in that it specifies that comments should be treated as whitespace, and<br>
    that whitespace-only lines in the middle of a multiline string should<br>
    be ignored. I&#39;m not sure if this is feasible from a parsing standpoint,<br>
    and I&#39;d like feedback from implementers on this point.<br>
<br></span>
  *<span class=""><br>
<br>
    This draft also specifies diagnostics which should be included.<br>
    Feedback on whether these are good choices would be welcome.<br>
<br></span>
  *<span class=""><br>
<br>
    I am considering allowing you to put a backslash before the newline to<br></span>
    indicate it should /not/ be included in the literal. In other words,<span class=""><br>
    this code:<br>
<br>
    print(&quot;foo\<br>
    &quot;bar&quot;)<br>
<br>
    Would print |&quot;foobar&quot;|. However, I think this should probably be<br>
    proposed separately, because there may be a better way to do it.<br>
<br></span>
  *<span class=""><br>
<br>
    I&#39;ve listed only myself as an author because I don&#39;t want to put anyone<br>
    else&#39;s name to a document they haven&#39;t seen, but there are others who<br>
    deserve to be listed (John Holdsworth at least). Let me know if you<br>
    think you should be included.<br>
<br>
<br></span>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation</a>&gt;Motivation<span class=""><br>
<br>
As Swift begins to move into roles beyond app development, code which needs<br>
to generate text becomes a more important use case. Consider, for instance,<br>
generating even a small XML string:<br>
<br>
let xml = &quot;&lt;?xml version=\&quot;1.0\&quot;?&gt;\n&lt;catalog&gt;\n\t&lt;book id=\&quot;bk101\&quot;<br>
empty=\&quot;\&quot;&gt;\n\t\t&lt;author&gt;\(author)&lt;/author&gt;\n\t&lt;/book&gt;\n&lt;/catalog&gt;&quot;<br>
<br>
The string is practically unreadable, its structure drowned in escapes and<br>
run-together characters; it looks like little more than line noise. We can<br>
improve its readability somewhat by concatenating separate strings for each<br>
line and using real tabs instead of |\t| escapes:<br>
<br>
let xml = &quot;&lt;?xml version=\&quot;1.0\&quot;?&gt;\n&quot; +<br>
          &quot;&lt;catalog&gt;\n&quot; +<br>
          &quot; &lt;book id=\&quot;bk101\&quot; empty=\&quot;\&quot;&gt;\n&quot; +<br>
          &quot; &lt;author&gt;\(author)&lt;/author&gt;\n&quot; +<br>
          &quot; &lt;/book&gt;\n&quot; +<br>
          &quot;&lt;/catalog&gt;&quot;<br>
<br>
However, this creates a more complex expression for the type checker, and<br>
there&#39;s still far more punctuation than ought to be necessary. If the most<br>
important goal of Swift is making code readable, this kind of code falls<br>
far short of that goal.<br>
<br>
<br></span>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution</a>&gt;Proposed<span class=""><br>
    solution<br>
<br>
We propose that, when Swift is parsing a string literal, if it reaches the<br>
end of the line without encountering an end quote, it should look at the<br>
next line. If it sees a quote mark there (a &quot;continuation quote&quot;), the<br>
string literal contains a newline and then continues on that line.<br>
Otherwise, the string literal is unterminated and syntactically invalid.<br>
<br>
Our sample above could thus be written as:<br>
<br>
let xml = &quot;&lt;?xml version=\&quot;1.0\&quot;?&gt;<br>
&quot;&lt;catalog&gt;<br>
          &quot; &lt;book id=\&quot;bk101\&quot; empty=\&quot;\&quot;&gt;<br>
&quot;     &lt;author&gt;\(author)&lt;/author&gt;<br>
          &quot; &lt;/book&gt;<br>
&quot;&lt;/catalog&gt;&quot;<br>
<br>
(Note that GitHub is applying incorrect syntax highlighting to this code<br>
sample, because it&#39;s applying Swift 2 rules.)<br>
<br>
This format&#39;s unbalanced quotes might strike some programmers as strange,<br>
but it attempts to mimic the way multiple lines are quoted in English<br>
prose. As an English Stack Exchange answer illustrates<br></span>
&lt;<a href="http://english.stackexchange.com/a/96613/64636" rel="noreferrer" target="_blank">http://english.stackexchange.com/a/96613/64636</a>&gt;:<span class=""><br>
<br>
    “That seems like an odd way to use punctuation,” Tom said. “What harm<br>
    would there be in using quotation marks at the end of every paragraph?”<br>
<br>
    “Oh, that’s not all that complicated,” J.R. answered. “If you closed<br>
    quotes at the end of every paragraph, then you would need to reidentify<br>
    the speaker with every subsequent paragraph.<br>
<br>
    “Say a narrative was describing two or three people engaged in a<br>
    lengthy conversation. If you closed the quotation marks in the previous<br>
    paragraph, then a reader wouldn’t be able to easily tell if the<br>
    previous speaker was extending his point, or if someone else in the<br>
    room had picked up the conversation. By leaving the previous<br>
    paragraph’s quote unclosed, the reader knows that the previous speaker<br>
    is still the one talking.”<br>
<br>
    “Oh, that makes sense. Thanks!”<br>
<br>
Similarly, omitting the ending quotation mark tells the code&#39;s reader (and<br>
compiler) that the literal continues on the next line, while including the<br>
continuation quote reminds the reader (and compiler) that this line is part<br>
of a string literal.<br>
<br>
<br></span>
      &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes</a>&gt;Benefits<span class=""><br>
      of continuation quotes<br>
<br>
It would be simpler to not require continuation quotes, so why are they<br>
required by this proposal? There are three reasons:<br>
<br></span>
 1.<br>
<br>
    *They help the compiler pinpoint errors in string literal<br>
    delimiting.* If continuation quotes were not required, then a missing<span class=""><br>
    end quote would be interpreted as a multiline string literal. This<br>
    string literal would continue until the compiler encountered either<br>
    another quote mark—perhaps at the site of another string literal or in<br>
    a comment—or the end of the file. In either case, the compiler could at<br>
    best only indicate the start of the runaway string literal; in<br>
    pathological cases (for instance, if the next string literal<br>
    was |&quot;+&quot;|), it might not even be able to do that properly.<br>
<br>
    With continuation quotes required, if you forget to include an end<br>
    quote, the compiler can tell that you did not intend to create a<br>
    multiline string and flag the line that actually has the problem. It<br>
    can also provide immediately actionable fix-it assistance. The fact<br>
    that there is a redundant indication on each line of the programmer&#39;s<br>
    intent to include that line in a multiline quote allows the compiler to<br>
    guess the meaning of the code.<br>
<br></span>
 2.<br>
<br>
    *They separate indentation from the string&#39;s contents.* Without<span class=""><br>
    continuation quotes, there would be no obvious indication of whether<br>
    whitespace at the start of the line was intended to indent the string<br>
    literal so it matched the surrounding code, or whether that whitespace<br>
    was actually meant to be included in the resulting string. Multiline<br>
    string literals would either have to put subsequent lines against the<br>
    left margin, or apply error-prone heuristics to try to guess which<br>
    whitespace was indentation and which was string literal content.<br>
<br></span>
 3.<br>
<br>
    *They improve the ability to quickly recognize the literal.* The |&quot;| on<span class=""><br>
    each line serves as an immediately obvious indication that the line is<br>
    part of a string literal, not code, and the row of |&quot;| characters in a<br>
    well-formatted file allows you to quickly scan up and down the file to<br>
    see the extent of the literal.<br>
<br>
<br></span>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design</a>&gt;Detailed<span class=""><br>
    design<br>
<br>
When Swift is parsing a string literal and reaches the end of a line<br>
without finding a closing quote, it examines the next line, applying the<br>
following rules:<br>
<br></span>
 1.<span class=""><br>
<br>
    If the next line is all whitespace, it is ignored; Swift moves on to<br>
    the line afterward, applying these rules again.<br>
<br></span>
 2.<span class=""><br>
<br>
    If the next line begins with whitespace followed by a continuation<br>
    quote, then the string literal contains a newline followed by the<br>
    contents of the string literal starting on that line. (This line may<br>
    itself have no closing quote, in which case the same rules apply to the<br>
    line which follows.)<br>
<br></span>
 3.<span class=""><br>
<br>
    If the next line contains anything else, Swift raises a syntax error<br>
    for an unterminated string literal. This syntax error should offer two<br>
    fix-its: one to close the string literal at the end of the current<br>
    line, and one to include the next line in the string literal by<br>
    inserting a continuation quote.<br>
<br>
Rules 1 and 2 should treat comments as though they are whitespace; this<br>
allows you to comment out individual lines in a multiline string literal.<br>
(However, commenting out the last line of the string literal will still<br>
make it unterminated, so you don&#39;t have a completely free hand in commenting.)<br>
<br>
<br></span>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code</a>&gt;Impact<span class=""><br>
    on existing code<br>
<br>
Failing to close a string literal before the end of the line is currently a<br>
syntax error, so no valid Swift code should be affected by this change.<br>
<br>
<br></span>
    &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered</a>&gt;Alternatives<br>
    considered<br>
<br>
<br>
      &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character</a>&gt;Requiring<span class=""><br>
      no continuation character<br>
<br>
The main alternative is to not require a continuation quote, and simply<br>
extend the string literal from the starting quote to the ending quote,<br>
including all newlines between them. For example:<br>
<br>
let xml = &quot;&lt;?xml version=\&quot;1.0\&quot;?&gt;<br>
&lt;catalog&gt;<br>
&lt;book id=\&quot;bk101\&quot; empty=\&quot;\&quot;&gt;<br>
&lt;author&gt;\(author)&lt;/author&gt;<br>
&lt;/book&gt;<br>
&lt;/catalog&gt;&quot;<br>
<br>
This has several advantages:<br>
<br></span>
 1.<br>
<br>
    It is simpler.<br>
<br>
 2.<span class=""><br>
<br>
    It is less offensive to programmers&#39; sensibilities (since there are no<br>
    unmatched |&quot;| characters).<br>
<br></span>
 3.<span class=""><br>
<br>
    It does not require that you edit the string literal to insert a<br>
    continuation quote in each line.<br>
<br>
Balanced against the advantages, however, is the loss of the improved<br>
diagnostics, code formatting, and visual affordances mentioned in the<br>
&quot;Benefits of continuation quotes&quot; section above.<br>
<br>
In practice, we believe that editor support (such as &quot;Paste as String<br>
Literal&quot; or &quot;Convert to String Literal&quot; commands) can make adding<br>
continuation quotes less burdensome, while also providing other<br>
conveniences like automatic escaping. We believe the other two factors are<br>
outweighed by the benefits of continuation quotes.<br>
<br>
<br></span>
      &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings</a>&gt;Use<div><div class="h5"><br>
      a different delimiter for multiline strings<br>
<br>
The initial suggestion was that multiline strings should use a different<br>
delimiter, |&quot;&quot;&quot;|, at the beginning and end of the string, with no<br>
continuation characters between. This solution was rejected because it has<br>
the same issues as the &quot;no continuation character&quot; solution, and because it<br>
was mixing two orthogonal issues (multiline strings and alternate delimiters).<br>
<br>
Another suggestion was to support a heredoc syntax, which would allow you<br>
to specify a placeholder string literal on one line whose content begins on<br>
the next line, running until some arbitrary delimiter. For instance, if<br>
Swift adopted Perl 5&#39;s syntax, it might support code like:<br>
<br>
connection.sendString(&lt;&lt;&quot;END&quot;)<br>
&lt;?xml version=&quot;1.0&quot;?&gt;<br>
&lt;catalog&gt;<br>
    &lt;book id=&quot;bk101&quot; empty=&quot;&quot;&gt;<br>
        &lt;author&gt;\(author)&lt;/author&gt;<br>
    &lt;/book&gt;<br>
&lt;/catalog&gt;<br>
END<br>
<br>
In addition to the issues with the |&quot;&quot;&quot;| syntax, heredocs are complicated<br>
both to explain and to parse, and are not a natural extension of Swift&#39;s<br>
current string syntax.<br>
<br>
Both of these suggestions address interesting issues with string literals,<br>
solving compelling use cases. They&#39;re just not that good at fixing the<br>
specific issue at hand. We might consider them in the future to address<br>
those problems to which they are better suited.<br>
<br>
<br></div></div>
      &lt;<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues</a>&gt;Fixing<span class=""><br>
      other string literal readability issues<br>
<br>
This proposal is narrowly aimed at multiline strings. It intentionally<br>
doesn&#39;t tackle several other problems with string literals:<br>
<br></span>
  *<span class=""><br>
<br>
    Reducing the amount of double-backslashing needed when working with<br>
    regular expression libraries, Windows paths, source code generation,<br>
    and other tasks where backslashes are part of the data.<br>
<br></span>
  *<span class=""><br>
<br>
    Alternate delimiters or other strategies for writing strings<br>
    with |&quot;| characters in them.<br>
<br></span>
  *<span class=""><br>
<br>
    String literals consisting of very long pieces of text which are best<br>
    represented completely verbatim.<br>
<br>
These are likely to be subjects of future proposals, though not necessarily<br>
during Swift 3.<br>
<br>
This proposal also does not attempt to address regular expression literals.<br>
The members of the core team who are interested in regular expression<br>
support have ambitions for that feature which put it out of scope for Swift 3.<br>
<br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
<br>
<br>
<br></span><span class="">
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
</span></blockquote><div class=""><div class="h5">
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br></div></div>