<html><head><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></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="bloop_markdown"><p>One last pitch, can we allow comments in multi-line strings if the string is broken up by a backslash?</p>
<pre><code class="swift">
let myString = """
text text
text text text \ // Comment allowed in the current line here, but not in the line above it
text text text \ /* this type of comment is fine too */
text text\// notice whitespace can be ignored
"""
</code></pre>
<p>You might have some interpolation and want to comment around it.</p>
<pre><code class="swift">let foo = """
bar bar bar
bar \(x) bar\ // `x` does some magic
"""
</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_1491994413280799744" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">-- <br>Adrian Zubarev<br>Sent with Airmail</div></div> <br><p class="airmail_on">Am 12. April 2017 um 12:48:57, Adrian Zubarev (<a href="mailto:adrian.zubarev@devandartist.com">adrian.zubarev@devandartist.com</a>) schrieb:</p> <blockquote type="cite" class="clean_bq"><span><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div></div><div>
<title></title>
<div class="bloop_markdown">
<p>Actually I’m fine with such a compromise. Such a model has
everything we’ve asked for, it’s easy, it has both leading and
trailing precision and implicit new lines where needed.</p>
</div>
<div class="bloop_original_html">
<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_1491994049751838976" class="bloop_sign">
<div style="font-family:helvetica,arial;font-size:13px">
-- <br>
Adrian Zubarev<br>
Sent with Airmail</div>
</div>
<br>
<p class="airmail_on">Am 12. April 2017 um 12:42:17, Vladimir.S via
swift-evolution (<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>)
schrieb:</p>
<blockquote type="cite" class="clean_bq">
<div>
<div><span>On 12.04.2017 13:16, Thorsten Seitz via swift-evolution
wrote:<br>
>> Am 12.04.2017 um 10:11 schrieb Adrian Zubarev via
swift-evolution<br>
>> <swift-evolution@swift.org
<mailto:swift-evolution@swift.org>>:<br>
>><br>
>> Great explanation thank you Brent. I’m convinced about the
closing delimiter now. =)<br>
>><br>
>>
-------------------------------------------------------------------------------------<br>
>><br>
>> If I understood correctly what Xiaodi Wu meant in his
reply, then we could simplify<br>
>> the whole multi-line string literal and also remove the
need of disabling the<br>
>> stripping algorithm.<br>
>><br>
>> We should ban these examples completely:<br>
>><br>
>> |"""Hello·world!"""|<br>
>><br>
><br>
> Being able to use ""“ for single line strings containing lots
of " is useful in<br>
> itself and explained in the motivational section of the
proposal:<br>
> "Tripled string literals can also do double duty as a syntax
for handling short<br>
> string literals with many internal quotation marks“<br>
><br>
> -Thorsten<br>
<br>
Yes, I also think the single line string can be very useful and we
should not<br>
disallow it.<br>
<br>
But I agree that we should disallow multi-line cases when we have
text on the same<br>
line with leading or trailing """ because this complicates the
mental modal and adds<br>
confusion points.<br>
<br>
I.e. I suggest to allow only two forms:<br>
1. Single line: """this is "just" text""" (no line end will be
inserted)<br>
2. Multiline, where leading and trailing """ has no text
after/before them and *all*<br>
the text is in lines *between* triple quotes:<br>
"""<br>
first line<br>
second line<br>
"""<br>
<br>
One can use backslash at the line end to emulate all other needed
cases. Like:<br>
<br>
"""<br>
first line \<br>
second line\<br>
"""<br>
<br>
will produce "first line second line"<br>
<br>
><br>
>> |"""Hello↵ world!""" |<br>
>> |"""Hello↵ world!↵ """ |<br>
>> |"""↵ Hello↵ world!""" |<br>
>><br>
>> Instead an empty multi-line string literal would look like
this:<br>
>><br>
>> |"""↵ """ |<br>
>><br>
>> To fix the above example you’d need to write it like
this:<br>
>><br>
>> |"""↵ Hello·world!\↵ """ |<br>
>> |"""↵ Hello↵ world!\↵ """ |<br>
>><br>
>> * Each line in between the delimiters would add implicit
new lines if not<br>
>> disabled by a backslash.<br>
>> * The trailing precision is also handled by the
backslash.<br>
>> * The indent is handled by the closing delimiter.<br>
>> * It’s easier to learn/teach.<br>
>> * It’s easier to read, because most of the time the line
where the starting<br>
>> delimiter is, is filled with some other code.<br>
>><br>
>> |let myString = """↵ ⇥ ⇥ Hello↵ ⇥ ⇥ world!\↵ ⇥ ⇥ """
|<br>
>><br>
>> Now that would be a true multi-line string literal which
needs at least two lines<br>
>> of code. If you’d need a single line literal,|""|is the
obvious pick.<br>
>><br>
>><br>
>><br>
>><br>
>> --<br>
>> Adrian Zubarev<br>
>> Sent with Airmail<br>
>><br>
>> Am 12. April 2017 um 02:32:33, Brent Royal-Gordon
(brent@architechies.com<br>
>> <mailto:brent@architechies.com>) schrieb:<br>
>><br>
>>><br>
>>>> On Apr 11, 2017, at 8:08 AM, Adrian Zubarev via
swift-evolution<br>
>>>> <swift-evolution@swift.org
<mailto:swift-evolution@swift.org>> wrote:<br>
>>>><br>
>>>> That’s also the example that kept me thinking for
a while.<br>
>>>><br>
>>>>
-------------------------------------------------------------------------------------<br>
>>>><br>
>>>> Overall the proposal is a great compromise to some
issues I had with the first<br>
>>>> version. However I have a few more
questions:<br>
>>>><br>
>>>> * Why can’t we make it consistent and let the
compiler add a new line after the<br>
>>>> starting delimiter.<br>
>>>><br>
>>>> |
let string = """↵ Swift↵ """ // result ↵Swift↵
|<br>
>>>><br>
>>>> If one would would the behavior from the proposal
it’s really easy to add a<br>
>>>> backslash after the starting delimiter.<br>
>>>><br>
>>>> |
let string = """\↵ Swift\↵ """ // result Swift
|<br>
>>>><br>
>>>> This would be consistent and less confusing to
learn.<br>
>>>><br>
>>> That would mean that code like this:<br>
>>><br>
>>> print("""<br>
>>> A whole bunch of<br>
>>> multiline text<br>
>>> """)<br>
>>> print("""<br>
>>> A whole bunch more<br>
>>> multiline text<br>
>>> """)<br>
>>><br>
>>> Will print (with - to indicate blank lines):<br>
>>><br>
>>> -<br>
>>> A whole bunch of<br>
>>> multiline text<br>
>>> -<br>
>>> -<br>
>>> A whole bunch more<br>
>>> multiline text<br>
>>> -<br>
>>><br>
>>> This is, to a first approximation, never what you
actually want the computer to do.<br>
>>>><br>
>>>> * Can’t we make the indent algorithm work like
this instead?<br>
>>>><br>
>>>> |let string = """\↵ ····<tag>↵ ······content
text↵ ····</tag>""" // Indent starts<br>
>>>> with the first non space character // result
<tag>↵ ··content text↵ </tag> |<br>
>>>><br>
>>>> The line where the closing delimiter is trims all
space chapters and the indent<br>
>>>> for the whole multi-line string is starting at the
point where the first<br>
>>>> non-space chapters is in that line.<br>
>>>><br>
>>> We could; I discuss that briefly in the very last
section, on alternatives to the<br>
>>> indentation stripping we specify:<br>
>>><br>
>>> • Stripping indentation to match the depth of the
least indented line: Instead of<br>
>>> removing indentation to match the end delimiter, you
remove indentation to match<br>
>>> the least indented line of the string itself. The
issue here is that, if all lines<br>
>>> in a string should be indented, you can't use
indentation stripping. Ruby 2.3 does<br>
>>> this with its heredocs, and Python's dedent function
also implements this behavior.<br>
>>><br>
>>> That doesn't quite capture the entire breadth of the
problem with this algorithm,<br>
>>> though. What you'd like to do is say, "all of these
lines are indented four<br>
>>> columns, so we should remove four columns of
indentation from each line". But you<br>
>>> don't have columns; you have tabs and spaces, and
they're incomparable because the<br>
>>> compiler can't know what tab stops you set. So we'd
end up calculating a common<br>
>>> prefix of whitespace for all lines and removing that.
But that means, when someone<br>
>>> mixes tabs and spaces accidentally, you end up
stripping an amount of indentation<br>
>>> that is unrelated to anything visible in your code. We
could perhaps emit a<br>
>>> warning in some suspicious circumstances (like "every
line has whitespace just<br>
>>> past the end of indentation, but some use tabs and
others use spaces"), but if we<br>
>>> do, we can't know which one is supposed to be correct.
With the proposed design,<br>
>>> we know what's correct—the last line—and any deviation
from it can be flagged *at<br>
>>> the particular line which doesn't match our
expectation*.<br>
>>><br>
>>> Even without the tabs and spaces issue, consider the
case where you accidentally<br>
>>> don't indent a line far enough. With your algorithm,
that's indistinguishable from<br>
>>> wanting the other lines to be indented more than that
one, so we generate a result<br>
>>> you don't want and we don't (can't!) emit a warning to
point out the mistake. With<br>
>>> the proposed algorithm, we can notice there's an error
and point to the line at fault.<br>
>>><br>
>>> Having the closing delimiter always be on its own line
and using it to decide how<br>
>>> much whitespace to strip is better because it gives
the compiler a firm baseline<br>
>>> to work from. That means it can tell you what's wrong
and where, instead of doing<br>
>>> the dumb computer thing and computing a result that's
technically correct but useless.<br>
>>>><br>
>>>> PS: If we’d get this feature in Swift, it would be
nice if Xcode and other IDEs<br>
>>>> which supports Swift could show space characters
that are inside a string literal<br>
>>>> (not other space character <- which is already
supported), so it would be easier<br>
>>>> to tell what’s part of the string and what is
not.<br>
>>>><br>
>>> That would be very nice indeed. The prototype's
tokenizer simply concatenates<br>
>>> together and computes the string literal's contents
after whitespace stripping,<br>
>>> but in principle, I think it could probably preserve
enough information to tell<br>
>>> SourceKit where the indentation ends and the literal
content begins. (The<br>
>>> prototype is John's department, though, not mine.)
Xcode would then have to do<br>
>>> something with that information, though, and
swift-evolution can't make the Xcode<br>
>>> team do so. But I'd love to see a faint reddish
background behind tripled string<br>
>>> literal content or a vertical line at the indentation
boundary.<br>
>>><br>
>>> In the meantime, this design *does* provide an
unambiguous indicator of how much<br>
>>> whitespace will be trimmed: however much is to the
left of the closing delimiter.<br>
>>> You just have to imagine the line extending upwards
from there. I think that's an<br>
>>> important thing to have.<br>
>>><br>
>>> --<br>
>>> Brent Royal-Gordon<br>
>>> Architechies<br>
>>><br>
>><br>
>> _______________________________________________<br>
>> swift-evolution mailing list<br>
>> swift-evolution@swift.org
<mailto:swift-evolution@swift.org><br>
>>
https://lists.swift.org/mailman/listinfo/swift-evolution<br>
><br>
><br>
><br>
> _______________________________________________<br>
> swift-evolution mailing list<br>
> swift-evolution@swift.org<br>
> https://lists.swift.org/mailman/listinfo/swift-evolution<br>
><br>
_______________________________________________<br>
swift-evolution mailing list<br>
swift-evolution@swift.org<br>
https://lists.swift.org/mailman/listinfo/swift-evolution<br></span></div>
</div>
</blockquote>
</div>
<div class="bloop_markdown"></div>
</div></div></span></blockquote></div><div class="bloop_markdown"><p></p></div></body></html>