<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div>+1</div><div><br>On 13 Apr 2017, at 11:28, Adrian Zubarev via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}

h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}

h1 {
        color: #000000;
        font-size: 28pt;
}

h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}

h3 {
        font-size: 18px;
}

h4 {
        font-size: 16px;
}

h5 {
        font-size: 14px;
}

h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}

hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
    display: inherit;
}

p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}

a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}

#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}

button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}

code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}

code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}

pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}

pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}

#ws { background-color: #f8f8f8; }


.bloop_markdown table {
border-collapse: collapse;  
font-family: Helvetica, arial, freesans, clean, sans-serif;  
color: rgb(51, 51, 51);  
font-size: 15px; line-height: 25px;
padding: 0; }

.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
     
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }

.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }

.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

.bloop_markdown blockquote{
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

code, pre, #ws, #message {
    word-break: normal;
    word-wrap: normal;
}

hr {
    display: inherit;
}

.bloop_markdown :first-child {
    -webkit-margin-before: 0;
}

code, pre, #ws, #message {
    font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}


.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style><div class="bloop_markdown"><p>Now that I had some sleep I actually revise my opinion about the last line. I took a few hours to sum my thoughts together in a gist, here is a formatted version of it: <a href="https://gist.github.com/DevAndArtist/dae76d4e3d4e49b1fab22ef7e86a87a9">https://gist.github.com/DevAndArtist/dae76d4e3d4e49b1fab22ef7e86a87a9</a></p>

<hr>

<h3 id="simplemulti-linestringliteralmodel">Simple ‘multi-line string literal’ model</h3>

<h4 id="corefeatures:">Core features:</h4>

<ol>
<li>Omitting of (most) backslashes for <code>"</code>.</li>
<li>Altering the string with implicit new line injection at the end of the line.</li>
</ol>

<h4 id="consequencesof1:">Consequences of #1:</h4>

<ul>
<li><p>To omit escaping the quote character, the delimiter characters for the <strong>multi-line string literal</strong> will be <em>tripled quotes</em> <code>"""</code>, also similar to other programming languages.</p></li>
<li><p>When a standard string literal contains at least 5 quotes, then the usage of a <strong>multi-line string literal</strong> will be shorter.</p></li>
</ul>

<pre><code class="swift">"&lt;a href=\"\(url)\" id=\"link\(i)\" class=\"link\"&gt;"    // With escapes
"""&lt;a href="\(url)" id="link\(i)" class="link"&gt;"""      // With tripled literals
</code></pre>

<h4 id="consequencesof2:">Consequences of #2:</h4>

<ul>
<li><p>To fully support this feature, we need to compromise the design for simplicity and intuitivity.</p>

<ul>
<li>This feature needs precision for leading and trailing spaces.</li>
<li>Alternatively one would need a way to disable new line injection to also support code formatting.</li>
</ul></li>
</ul>

<h4 id="twowaysofwritingamulti-linestringliteral:">Two ways of writing a multi-line string literal:</h4>

<ul>
<li><p>Single line version <code>"""abc"""</code> is trivial and already was shown above.</p></li>
<li><p>The multi-line version comes with a few compromises for simplicity of rules:</p></li>
</ul>

<pre><code class="swift">"""   // DS (delimiter start)
foo   // s0
foo   // s1
foo   // s2
"""   // DE (delimiter end)
</code></pre>

<ul>
<li><p>The string content is always written between the lines <code>DS</code> and <code>DE</code> (delimiter lines). </p></li>
<li><p>To not to go the <strong>continuation quotes</strong> path, the left (or leading) precision is handled by the <em>closing delimiter</em> (<strong>1. compromise</strong>). The closing delimiter is also responsible for the indent algorithm, which will calculate the stripping prefix in line <code>DE</code> and apply stripping to lines <code>s0</code> to <code>sn</code>.</p></li>
<li><p>Right (or trailing) precision of each line from <code>s0</code> to <code>sn</code> (notice n equals 2 in the example above) is handled by a backslash character (<strong>2. compromise</strong>).</p></li>
<li><p>The right precision comes at a price of losing the implicit new line injection, however this was also a requested feature (<strong>3. compromise</strong>). That means that the backslash serves two jobs simultaneously.</p></li>
<li><p>New line injection happens only on lines <code>s0</code> to <code>s(n - 1)</code> (<strong>4. and last compromise</strong> of the design). The last line <code>sn</code> (or <code>s2</code> above) does not inject a new line into the final string. This implies that in this line a backslash character handles only right precision, or one could say it’s reduced to one functionality.</p></li>
</ul>

<hr>

<h4 id="important:">Important:</h4>

<p>Because whitespace is important to these examples, it is explicitly indicated: <code>·</code> is a space, <code>⇥</code> is a tab, and <code>↵</code> is a newline.</p>

<h5 id="leadingtrailingprecisionandindent1.and2.compromise:">Leading/trailing precision and indent (1. and 2. compromise):</h5>

<pre><code class="swift">// Nothing to strip in this example (no ident).
let str_1 = """↵  
foo↵
"""

// No right precision (no backslash) -&gt; whitespaces will be stripped.
let str_2 = """↵  
foo··↵
"""

// Same as `str_2`
let str_3 = """↵  
foo····↵
"""

// Line `DE` of the closing delimiter calculates the indent prefix  
// `··` and strips it from `s0` (left precision).
let str_4 = """↵  
··foo↵
··"""

// Line `DE` of the closing delimiter calculates the indent prefix  
// `····` and strips it from `s0` (left precision).
// No right precision (no backslash) -&gt; whitespaces will be stripped.
let str_5 = """↵  
····foo··↵
····"""

// Line `DE` of the closing delimiter calculates the indent prefix  
// `⇥ ⇥ ` and strips it from `s0` (left precision).
// Right precision is applied (backslash). In this case the literal
// contains only a single line of content, which happens to be   
// also the last line before `DE` -&gt; backslash only serves precision.
let str_6 = """↵  
⇥ ⇥ foo\↵
⇥ ⇥ """

// Line `DE` of the closing delimiter calculates the indent prefix  
// `·⇥ ·⇥ ` and strips it from `s0` (left precision).
// No right precision (no backslash) -&gt; whitespaces will be stripped.
let str_7 = """↵  
·⇥ ·⇥ foo··↵
·⇥ ·⇥ """

let string_1 = "foo"

str_1 == string_1   // =&gt; true
str_2 == string_1   // =&gt; true
str_3 == string_1   // =&gt; true
str_4 == string_1   // =&gt; true
str_5 == string_1   // =&gt; true
str_6 == string_1   // =&gt; true
str_7 == string_1   // =&gt; true
</code></pre>

<p>A false multi-line string literal, which compiles but emits a warning and proves a <code>fix-it</code>:</p>

<pre><code class="swift">let str_8 = """↵  
··foo↵
····"""

str_8 == string_1   // =&gt; true
</code></pre>

<pre><code>warning: missing indentation in multi-line string literal
  ··foo!
    ^  
  Fix-it: Insert "··"
</code></pre>

<ul>
<li><p>The stripping algorithm calculates the prefix indent from the closing delimiter line <code>DE</code> and tries to strip it in lines <code>s0</code> to <code>sn</code> if possible, otherwise each line, which could not be handled correctly will emit an individual warning and a <code>fix-it</code>.</p></li>
<li><p>The stripping algorithm removes every whitespace on the end of each line from <code>s0</code> to <code>sn</code> iff there is no right precision, annotated through a backslash like <code>··foo··\↵</code>. This behavior is essential and aligns well with the precision behavior of a standard string literal <code>" "</code>, otherwise a <strong>multi-line string literal</strong> like</p></li>
</ul>

<pre><code class="swift">"""
foo
"""
</code></pre>

<p>can contain 3 characters or 10 characters or even 1000 characters, but the developer couldn’t tell or even approximately guess.</p>

<p>The correct way of fixing this, as already mentioned above, is by striping all white spaces after the last non-space character of the line, unless the right precision is explicitly annotated with a backslash.</p>

<pre><code class="swift">"""
foo   \
"""
</code></pre>

<h5 id="disablingnewlineinjection3.compromise:">Disabling new line injection (3. compromise):</h5>

<p>The examples we’ve used so far had only a single content line, so we couldn’t showcase the behavior yet. New lines are only injected into a multi-line string if it has at least two content lines.</p>

<pre><code class="swift">let str_9 = """↵  
····foo↵
····bar↵
····"""

let str_10 = """↵  
····foo↵
····bar↵
····baz↵
····"""

let string_2 = "foo\nbar"
let string_3 = "foor\nbar\nbaz"

str_9 == string_2  // =&gt; true
str_10 == string_3 // =&gt; true
</code></pre>

<p>To disable new line injection one would need to use the backslash for right precision.</p>

<pre><code class="swift">let str_11 = """↵  
····foo\↵
····bar↵
····"""

let str_12 = """↵  
····foo\↵
····bar\↵
····baz↵
····"""

str_11 == string_2    // =&gt; false
str_12 == string_3    // =&gt; false

str_11 == "foorbar"   // =&gt; true
str_12 == "foobarbaz" // =&gt; true
</code></pre>

<p>Remember that the last content line <code>sn</code> does not automatically inject a new line into the final string!</p>

<h5 id="newlineinjectionexceptforthelastline4.compromise:">New line injection except for the last line (4. compromise):</h5>

<p>The standard string literal like <code>"foo"</code> only contains its string content from the starting delimiter to the closing delimiter. The discussion on the mailing list suggests that the <strong>multi-line string literal</strong> should also go that route and not inject a new line for the last content line <code>sn</code>. <code>str_9</code> is a good example for that behavior. </p>

<p>Now if one would want a new line at the end of the string, there are a few options to achieve this:</p>

<pre><code class="swift">// Natural way:
let str_13 = """↵  
····foo↵
····bar↵
····↵
····"""

// Remember the last content line does not inject a `\n` character by default
// so there is no need for `\n\` here (but it's possible as well)!
let str_14 = """↵  
····foo↵
····bar\n↵
····"""

str_13 == "foo\nbar\n" // =&gt; true
</code></pre>

<p>At first glance the behavior in <code>str_13</code> seems odd and inconsistent, however it actually mimics perfectly the natural way of writing text paragraphs.</p>

<pre><code>[here is a blank line]↵
text text text tex text↵
text text text tex text↵
[here is a blank line]
</code></pre>

<p>This is easily expressed with the literal model expressed above:</p>

<pre><code class="swift">let myParagraph = """↵
····↵
····text text text tex text↵
····text text text tex text↵
····↵
····"""
</code></pre>

<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div> <br> <div id="bloop_sign_1492075149230121216" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev<br>Sent with Airmail</div></div> <br><p class="airmail_on">Am 13. April 2017 um 02:39:51, Xiaodi Wu (<a href="mailto:xiaodi.wu@gmail.com">xiaodi.wu@gmail.com</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div><div></div><div>


<title></title>


<div dir="ltr">On Wed, Apr 12, 2017 at 5:20 PM, Brent Royal-Gordon
<span dir="ltr">&lt;<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>&gt;</span> wrote:<br>
<div class="gmail_extra">
<div class="gmail_quote">
<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">
<div style="word-wrap:break-word">
<div>Wow, maybe I shouldn't have slept.</div>
<div><br></div>
<div>Okay, let's deal with trailing newline first. I'm *very*
confident that trailing newlines should be kept by default. This
opinion comes from lots of practical experience with multiline
string features in other languages. In practice, if you're
generating files in a line-oriented way, you're usually generating
them a line at a time. It's pretty rare that you want to generate
half a line and then add more to it in another statement; it's more
likely you'll interpolate the data. I'm not saying it doesn't
happen, of course, but it happens a lot less often than you would
think just sitting by the fire, drinking whiskey and musing over
strings.</div>
<div><br></div>
<div>I know that, if you're pushing for this feature, it's not
satisfying to have the answer be "trust me, it's not what you
want". But trust me, it's not what you want.</div>
</div>
</blockquote>
<div><br></div>
<div>This is not a very good argument. If you are generating files
in a line-oriented way, it is the function _emitting_ the string
that handles the line-orientedness, not the string itself. That is
the example set by `print()`:</div>
<div><br></div>
<div>```</div>
<div>print("Hello, world!") // Emits "Hello, world!\n"</div>
<div>```</div>
<div><br></div>
<div>Once upon a time, if I recall, this function was called
`println`, but it was renamed. This particular example demonstrates
why keeping trailing newlines by default is misguided:</div>
<div><br></div>
<div>```</div>
<div>print(</div>
<div>&nbsp; """</div>
<div>&nbsp; Hello, world!</div>
<div>&nbsp; """</div>
<div>)</div>
<div>```</div>
<div><br></div>
<div>Under your proposed rules, this emits "Hello, world!\n\n". It
is almost certainly not what you want. Instead, it is a misguided
attempt by the designers of multiline string syntax to do the job
that the designers of `print()` have already accounted for.</div>
<div><br></div>
<div>If we were to buy your line of reasoning and adapt it for
single-line strings, we would arrive at a rather absurd result. If
you're emitting multiple single-line strings, you almost certainly
want a space to separate them. Again this is exemplified by the
behavior of `print()`:</div>
<div><br></div>
<div>```</div>
<div>print("Hello", "Brent!")</div>
<div>```</div>
<div><br></div>
<div>This emits "Hello Brent!" (and not "HelloBrent!"). But we do
not take that reasoning and demand that "This is my string" end
with an default trailing space, nor do we have `+` concatenate
strings by default with a separating space.</div>
<div><br></div>
<div><br></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">
<div style="word-wrap:break-word">
<div>Moving to the other end, I think we could do a leading newline
strip *if* we're willing to create multiline and non-multiline
modes—that is, newlines are _not allowed at all_ unless the opening
delimiter ends its line and the closing delimiter starts its line
(modulo indentation). But I'm reluctant to do that because, well,
it's weird and complicated. I also get the feeling that, if there's
a single-line mode and a multi-line mode, we ought to treat them as
truly orthogonal features and allow `"`-delimited strings to use
multi-line mode, but I'm really not convinced that's a good
idea.</div>
<div><br></div>
<div>(Note, by the way, that heredocs—a *really* common multiline
string design—always strip the leading newline but not the trailing
one.)</div>
<div><br></div>
<div>Adrian cited this example, where I agree that you really don't
want the string to be on the same line as the leading
delimiter:</div>
<div><br></div>
<div>
<div>let myReallyLongXMLConstantName = """&lt;?xml
version="1.0"?&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;&lt;catalog&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &lt;book id="bk101" empty=""&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;&lt;author&gt;John
Doe&lt;/author&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;&lt;title&gt;XML Developer's
Guide&lt;/title&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp;
&nbsp;&lt;genre&gt;Computer&lt;/genre&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;&lt;price&gt;44.95&lt;/price&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &lt;/book&gt;</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;&lt;/catalog&gt;\</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp;""" &nbsp; &nbsp; &nbsp; &nbsp;</div>
<br class="gmail-m_-4413069624854317166Apple-interchange-newline">
But there are lots of places where it works fine. Is there a good
reason to force an additional newline in this?</div>
<div><br></div>
<div>
<div>case .isExprSameType(let from, let to):</div>
</div>
<div>
<div>return """checking a value with optional type \(from) against
dynamic type \(to) \</div>
<div>&nbsp; &nbsp; &nbsp;&nbsp;succeeds whenever the value is
non-'nil'; did you mean to use '!= nil'?\</div>
<div>&nbsp; &nbsp; &nbsp;&nbsp;"""</div>
</div>
<div><br></div>
<div>I mean, we certainly could, but I'm not convinced we should.
At least, not yet.</div>
<div><br></div>
<div>In any case, trailing newline definitely stays. Leading
newline, I'm still thinking about.</div>
<div><br></div>
<div>As for other things:</div>
<div><br></div>
<div>* I see zero reason to fiddle with trailing whitespace. If
it's there, it might be significant or it might not be. If we strip
it by default and we shouldn't, the developer has no way to protect
it. Let's trust the developer. (And their tooling—Xcode, I believe
Git, and most linters already have trailing whitespace features. We
don't need them too.)</div>
<div><br></div>
<div>* Somebody asked about `"""`-delimited heredocs. I think it's
a pretty syntax, but it's not compatible with single-line use of
`"""`, and I think that's probably more important. We can always
add heredocs in another way if we decide we want them. (I think
`#to(END)` is another very Swifty syntax we could use for
heredocs--less lightweight, but it gives us a Google-able
keyword.)</div>
<div><br></div>
<div>* Literal spaces and tabs cannot be backslashed. This is
really important because, if you see a backslash after the last
visible character in a line, you can't tell just by looking whether
the next character is a space, tab, or newline. So the solution is,
if it's not a newline, it's not valid at all.</div>
<div><br></div>
<div>I'll respond to Jarod separately.</div>
<br>
<div>
<blockquote type="cite">
<div>On Apr 12, 2017, at 12:07 PM, John Holdsworth &lt;<a href="mailto:mac@johnholdsworth.com" target="_blank">mac@johnholdsworth.com</a>&gt; wrote:</div>
<br class="gmail-m_-4413069624854317166Apple-interchange-newline">
<div>
<div style="word-wrap:break-word">
<div>Finally.. a&nbsp;<a href="http://johnholdsworth.com/swift-LOCAL-2017-04-12-a-osx.tar.gz" target="_blank">new Xcode toolchain</a>&nbsp;is available largely
in sync with the proposal as is.</div>
<div>(You need to restart Xcode after selecting the toolchain to
restart SourceKit)</div>
<div><br></div>
<div>I personally am undecided whether to remove the first line if
it is empty. The new</div>
<div>rules are more consistent but somehow less practical. A blank
initial line is almost</div>
<div>never what a user would want and I would tend towards removing
it automatically.</div>
<div>This is almost what a user would it expect it to do.</div>
<div><br></div>
<div>I’m less sure the same applies to the trailing newline. If
this is a syntax for</div>
<div>multi-line strings, I'd argue that they should normally be
complete lines -</div>
<div>particularly since the final newline can so easily be
escaped.</div>
<div><span class="gmail-"><br></span></div>
<div><span class="gmail-"><span style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures">
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</span><span style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures;color:rgb(186,45,162)">let</span>
<span style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures">
longstring = ""</span><span style="font-family:menlo;font-size:11px;font-variant-ligatures:no-common-ligatures;color:rgb(209,47,27)">"\</span></span></div>
<div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Lorem ipsum dolor sit amet,
consectetur adipiscing elit, sed do eiusmod \</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, \</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo
consequat.\</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "</span><span style="font-variant-ligatures:no-common-ligatures">""</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;min-height:13px">
<br></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp;</span> <span style="font-variant-ligatures:no-common-ligatures;color:rgb(62,30,129)">print</span><span style="font-variant-ligatures:no-common-ligatures">(
""</span><span style="font-variant-ligatures:no-common-ligatures;color:rgb(209,47,27)">"\</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Usage: myapp
&lt;options&gt;</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27);min-height:13px">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;</span><br class="gmail-m_-4413069624854317166webkit-block-placeholder"></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Run myapp to do
mything</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27);min-height:13px">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;&nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp;</span><br class="gmail-m_-4413069624854317166webkit-block-placeholder"></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Options:</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; -myoption - an
option</span></div>
<div style="margin:0px;font-size:11px;line-height:normal;font-family:menlo;color:rgb(209,47,27)">
<span style="font-variant-ligatures:no-common-ligatures">&nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "</span><span style="font-variant-ligatures:no-common-ligatures">"" )</span></div>
</div>
<div><span style="font-variant-ligatures:no-common-ligatures"><br></span></div>
<div>(An explicit “\n" in the string should never be stripped
btw)</div>
<div><br></div>
<div>Can we have a straw poll for the three alternatives:</div>
<div><span class="gmail-"><br></span></div>
<div><span class="gmail-">1) Proposal as it stands &nbsp;- no magic
removal of leading/training blank lines.</span></div>
<div><span class="gmail-">2) Removal of a leading blank line when
indent stripping is being applied.</span></div>
<div><span class="gmail-">3) Removal of leading blank line and
trailing newline when indent stripping is being
applied.</span></div>
<div><span class="gmail-"><br></span></div>
<div>My vote is for the pragmatic path: 2)</div>
<div><br></div>
<div>(The main intent of this revision was actually removing the
link between how the</div>
<div>string started and whether indent stripping was applied which
was unnecessary.)</div>
<br>
<div>
<blockquote type="cite">
<div>On 12 Apr 2017, at 17:48, Xiaodi Wu via swift-evolution
&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div>
<br class="gmail-m_-4413069624854317166Apple-interchange-newline">
<div><span style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline">
Agree. I prefer the new rules over the old, but considering common
use cases, stripping the leading and trailing newline makes for a
more pleasant experience than not stripping either of
them.</span><br style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<br style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">

<span style="font-family:helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;float:none;display:inline">
I think that is generally worth prioritizing over a simpler
algorithm or even accommodating more styles. Moreover, a user who
wants a trailing or leading newline merely types an extra one if
there is newline stripping, so no use cases are made difficult,
only a very common one is made more ergonomic.</span></div>
</blockquote>
</div>
<br></div>
</div>
</blockquote>
</div>
<span class="gmail-HOEnZb"><font color="#888888"><br></font></span>
<div>
<div>
<div style="font-size:12px"><span class="gmail-HOEnZb"><font color="#888888">--&nbsp;</font></span></div>
<div style="font-size:12px"><span class="gmail-HOEnZb"><font color="#888888">Brent Royal-Gordon</font></span></div>
<div style="font-size:12px"><span class="gmail-HOEnZb"><font color="#888888">Architechies</font></span></div>
</div>
</div>
<span class="gmail-HOEnZb"><br></span></div>
</blockquote>
</div>
<br></div>
</div>


</div></div></span></blockquote></div><div class="bloop_markdown"><p></p></div></div></blockquote><blockquote type="cite"><div><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>