<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Hi,<div class=""><br class=""></div><div class="">I propose adding multiline string literals to Swift 3.</div><div class=""><br class=""></div><div class="">I have written up a proposal as a Github Gist, here:</div><div class=""><a href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd" class="">https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd</a></div><div class=""><br class=""></div><div class="">Can someone with write-access push it to the swift-evolution repository, please?</div><div class=""><br class=""></div><div class="">Thanks..</div><div class=""><br class=""></div><div class="">Regards,</div><div class="">Michael</div><div class=""><br class=""></div><div class=""><h1 class="">Multiline String literals</h1>
<ul class="">
<li class="">Proposal: SE-NNNN</li>
<li class="">Author: <a href="https://www.github.com/michaelpeternell" class="">Michael Peternell</a></li>
<li class="">Status: <a href="https://github.com/apple/swift-evolution/blob/master/0000-template.md#rationale" class="">Awaiting review</a></li>
<li class="">Review manager: TBD</li>
</ul>
<h1 class=""><a id="user-content-introduction" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#introduction" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Introduction</h1><p class="">Multi-line string literals allow text that may be multiple lines
long, to be included verbatim into a string literal. The string may even
contain quote characters (<code class="">"</code> or <code class="">'</code>), and they don't have to be especially escaped.</p>
<h1 class=""><a id="user-content-motivation" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#motivation" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Motivation</h1><p class="">Including many lines of text in a program often looks not so well, e.g. a JSON-string where every quote needs to be escaped: <code class="">"{\"response\":{\"result\":\"OK\"}}"</code>. With multi-line string literals, we can write <code class="">"""{"response":{"result":"OK"}}"""</code> - note that every valid JSON can be pasted as-is into a <code class="">"""3-quote string literal"""</code>, because 3 quotes (<code class="">"""</code>)
cannot appear in a valid JSON. (Why would you want to have a
JSON-string in a program? Maybe you are writing unit tests for a JSON
parser.) Another usage example is below.</p><p class="">Some people had concerns that a string block may break the indentation of the code. E.g.</p>
<pre class=""><code class=""> // some deeply indented code
doSomeStuff(2, 33.1)
print("""Usage: \(program_name) <PARAM-X> <PARAM-Y> filename
Example: \(program_name) 3 1 countries.csv
This will print the 1st column of the 3rd non-empty non-header line from
countries.csv
""")
exit(2)
</code></pre><p class="">First, you don't have to use them. You can still use the former way
of using normal double quote characters. But in order to fix the problem
with multiline strings, you may use a HEREDOC-syntax. The example can
be rewritten as:</p>
<pre class=""><code class=""> // some deeply indented code
doSomeStuff(2, 33.1)
print(<<USAGE_END)
Example: \(program_name) 3 1 countries.csv
This will print the 1st column of the 3rd non-empty
non-header line from countries.csv
USAGE_END
exit(2)
</code></pre><p class="">This works unambiguously, as long as you don't mix tabs and spaces in your source code file.</p>
<h1 class=""><a id="user-content-proposed-solution" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#proposed-solution" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Proposed solution</h1><p class="">This proposal introduces four new forms of a String literal:</p>
<h2 class=""><a id="user-content-the-python-like-string-literal" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#the-python-like-string-literal" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>The Python-like string literal</h2><p class="">Everything between <code class="">"""</code> and <code class="">"""</code> belongs to the string. Escape sequences (<code class="">\n</code>, <code class="">\t</code>, <code class="">\\</code>, etc.) and string interpolation work as usual. The rules are the same as for a normal double quoted (<code class="">"</code>) string literal. However, a single <code class="">"</code> doesn't need to be escaped, and therefore a string literal like <code class="">"""<a href="#" onclick="openABCWindow(22);return false">details</a>"""</code> would be valid Swift. Newline, spaces and tabs are not treated in any special way, so the following string</p>
<pre class=""><code class="">"""
test
test"""
</code></pre><p class="">could also be written as <code class="">"\n test\n test"</code>.</p>
<h2 class=""><a id="user-content-the-heredoc-with-string-interpolation" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#the-heredoc-with-string-interpolation" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>The HEREDOC with string interpolation</h2><p class="">The HEREDOC starts with a <code class=""><<</code>, followed by an
identifier. The string literal starts in the next line and ends in the
line that contains the HEREDOC identifier. Example:</p>
<pre class=""><code class="">print(<<USAGE)
funnyProgram [-v] [-h]
This program tells a joke. Possible options:
-v | --version ... Shows version information
-h | --help ...... Shows this list of options
USAGE
exit(2)
</code></pre><p class="">This string literal does not contain a trailing newline character.
Otherwise, it would not be possible to create a HEREDOC-literal without
trailing newline (The <code class="">print()</code>-function will add a newline
though.) In the example above, each line is indented by 4 spaces. If you
want to strip leading spaces on each line you have to indent the ending
identifier with the same amount of whitespace. Thus, a better example
would look like this:</p>
<pre class=""><code class="">print(<<USAGE)
funnyProgram [-v] [-h]
This program tells a joke. Possible options:
-v | --version ... Shows version information
-h | --help ...... Shows this list of options
USAGE
exit(2)
</code></pre><p class="">The leading indentation has to be all-spaces or all-tabs, but never a mixture of them.</p>
<h2 class=""><a id="user-content-the-heredoc-without-string-interpolation" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#the-heredoc-without-string-interpolation" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>The HEREDOC without string interpolation</h2><p class="">To have no string interpolation or escape sequences at all, you can add single quotes around the HEREDOC-identifier. Example:</p>
<pre class=""><code class="">print(<<'USAGE')
funnyProgram [-v] [-h]
This program tells a joke. Possible options:
-v | --version ... Shows version information
-h | --help ...... Shows this list of options
\( ^^ don't worry, be happy :-)
USAGE
exit(2)
</code></pre><p class="">In all other regards, this string literal behaves the same as the HEREDOC with string interpolation.</p>
<h2 class=""><a id="user-content-guillemets-and-english-typographical-quotes" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#guillemets-and-english-typographical-quotes" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>«Guillemets» and English “typographical quotes”</h2><p class="">Swift already allows emojis in names of all sort. The following code is valid Swift:</p>
<pre class=""><code class="">for 🐟 in sea {
🐟.makeSushi()
}
</code></pre><p class="">Swift is a playful language. Allowing «Guillemets» and “typographical
quotes” is the next logical step. To allow for both strings with
interpolation and strings without interpolation, one should allow string
interpolation and escape sequences while the other should not. I
propose that «Guillemets» are used for strings without interpolation, so
<code class="">«\»</code> is a valid string literal consisting of one escape character. <code class="">“"\(localizedName)"”</code> is a string containing a double quote character (<code class="">"</code>) followed by whatever the contents of <code class="">localizedName</code> is, followed by another double quote character (<code class="">"</code>). (Note that the reverse is already possible: <code class="">"“\(localizedName)”"</code>.)</p><p class="">These literals behave the same as the Python-like string literal above.</p>
<h1 class=""><a id="user-content-detailed-design" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#detailed-design" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Detailed design</h1><p class="">Python-strings, Guillemets and English typographical quotes are
already described in detail above. The only thing that may cause
misunderstandings are the HEREDOCs.</p><p class="">The following code should be invalid:</p>
<pre class=""><code class=""> print(<<EOT)
hello world
is this a proper string literal?
EOT
</code></pre><p class="">because the ending <code class="">EOT</code> has more indentation than one of the lines in the string literal.</p><p class="">The following code is valid though:</p>
<pre class=""><code class=""> // I replaced spaces with _underscores_ below:
____print(<<EOT)
________hello world
____
________is this a valid string?
________EOT
</code></pre><p class="">Although the second line has less indentation than the other lines, this is not a problem because the line is empty.</p><p class="">The following string literal contains 3 spaces in the second line, and it ends with a single newline character:</p>
<pre class=""><code class=""> // I replaced spaces with _underscores_ below:
____print(<<EOT)
________hello world
___________
________is this a valid string?
________EOT
</code></pre><p class="">The following string literal is invalid:</p>
<pre class=""><code class=""> // I replaced spaces with _underscores_ below.
// I replaced tab characters with TAB! below.
____print(<<EOT)
________hello world
____
TAB!____is this a valid string
________EOT
// => no
</code></pre><p class="">With tabs configured to look exactly like 4 spaces, the code above
looks valid but it is not. There is no sane way to decide wether (TAB + 4
spaces) is (less than, the same amount, or more than) 8 spaces. Such
code should be discarded.</p><p class="">The authors opinion is that tabs and spaces should not be mixed, and that this will not be a problem in almost all use cases.</p><p class="">The following HEREDOC is also invalid, although the amount of whitespace is consistent:</p>
<pre class=""><code class=""> // I replaced spaces with _underscores_ below.
// I replaced tab characters with TAB! below.
____print(<<EOT)
____TAB!hello world
____TAB!
____TAB!is this a valid string?
____TAB!__good question.
____TAB!EOT
</code></pre><p class="">Tabs and spaces just shouldn't be mixed. The following snippet is fine though, although inconsistent in it's tab/spaces use:</p>
<pre class=""><code class=""> // I replaced spaces with _underscores_ below:
// I replaced tab characters with TAB! below.
____print(<<EOT)
________hello world
________
________is this a valid string?
________TAB!Yes, indeed, even though this line started with a tab
________EOT
</code></pre><p class="">In the example above, the leading space on each line consists of 8
spaces. Everything after these 8 spaces should become part of the string
literal as-is.</p>
<h1 class=""><a id="user-content-impact-on-existing-code" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#impact-on-existing-code" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Impact on existing code</h1><p class="">This is an add-on feature. Code that uses these multi-line string
literals didn't even compile with previous versions of Swift, so no
existing code can break because of this change.</p>
<h1 class=""><a id="user-content-alternatives-consiedered" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#alternatives-consiedered" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Alternatives consiedered</h1>
<ol class="">
<li class=""><p class="">Introduce just the """Python-like string literal"""</p></li>
<li class=""><p class="">Do nothing.</p></li>
</ol>
<h1 class=""><a id="user-content-rationale" class="anchor" href="https://gist.github.com/michaelpeternell/a4da4185de78808f4575a836c50debbd#rationale" aria-hidden="true"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path></svg></a>Rationale</h1><p class="">...</p></div></body></html>