<div dir="ltr"><div class="markdown-here-wrapper" style=""><p style="margin:1.2em 0px!important">On Thu, 10 Dec 2015 at 21:45, Travis Tilley via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</p>
<p style="margin:1.2em 0px!important"></p><div class="markdown-here-exclude"><p></p><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif">The ruby &lt;&lt;- heredoc syntax, unlike the &lt;&lt; heredoc syntax, will strip indentation if necessary. Technically, it searches for the &quot;least indented line&quot; in the whole string, and removes exactly that amount from each line. So yes, the indentation problem -is- solved in ruby (though it might break entirely if you have empty lines, since the least indented line has no indentation).</div></div></blockquote><p></p></div><p style="margin:1.2em 0px!important"></p>
<p style="margin:1.2em 0px!important">To my mind, the rules should be:</p>
<ol style="margin:1.2em 0px;padding-left:2em">
<li style="margin:0.5em 0px">The indentation level is set from the least indented line that is not the first line and is not empty.</li>
<li style="margin:0.5em 0px">A leading empty line is removed.</li>
<li style="margin:0.5em 0px">The leading line, if there is any text in it, is not subject to de-indentation.</li>
</ol>
<p style="margin:1.2em 0px!important">I genuinely believe these three rules taken together address all the errors and infelicities to which triple quotes and HEREDOCs subject us. Here are some examples:</p>
<pre style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;font-size:1em;line-height:1.2em;margin:1.2em 0px"><code class="hljs language-python" style="font-size:0.85em;font-family:Consolas,Inconsolata,Courier,monospace;margin:0px 0.15em;padding:0px 0.3em;white-space:pre-wrap;border:1px solid rgb(234,234,234);border-radius:3px;display:inline;background-color:rgb(248,248,248);white-space:pre;overflow:auto;border-radius:3px;border:1px solid rgb(204,204,204);padding:0.5em 0.7em;display:block!important;display:block;overflow-x:auto;padding:0.5em;color:rgb(51,51,51);background:rgb(248,248,248)">text = <span class="hljs-string" style="color:rgb(221,17,68)">&quot;&quot;&quot;
    Some

  Features
    Are
    Discussed
&quot;&quot;&quot;</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (1): The indentation is taken from the third line below `text`, so it&#39;s 2.</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (2): First line is: &quot;\n&quot; so it is removed.</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (3): No effect.</span>

text = <span class="hljs-string" style="color:rgb(221,17,68)">&quot;&quot;&quot;  Some

          Features
            Are
            Discussed
&quot;&quot;&quot;</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (1): The indentation is taken again from the line reading &quot;Features&quot;. Here it is 10.</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (2): No effect.</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (3): The leading whitespace in `  Some` is preserved.</span>
</code></pre>
<p style="margin:1.2em 0px!important">Do you all think these rules pass muster?</p>
<p style="margin:1.2em 0px!important">A fourth rule — one which seems advisable but also less necessary than the others — is that a string constructed in this way always ends with a newline. It is a rule that perhaps leads to surprises and inconsistencies.</p>
<p style="margin:1.2em 0px!important">Best Regards,</p><p style="margin:1.2em 0px!important">Jason</p>
<div title="MDH:PGRpdiBjbGFzcz0iZ21haWxfcXVvdGUiPjxkaXYgZGlyPSJsdHIiPk9uIFRodSwgMTAgRGVjIDIw
MTUgYXQgMjE6NDUsIFRyYXZpcyBUaWxsZXkgdmlhIHN3aWZ0LWV2b2x1dGlvbiAmbHQ7PGEgaHJl
Zj0ibWFpbHRvOnN3aWZ0LWV2b2x1dGlvbkBzd2lmdC5vcmciIHRhcmdldD0iX2JsYW5rIj5zd2lm
dC1ldm9sdXRpb25Ac3dpZnQub3JnPC9hPiZndDsgd3JvdGU6PGJyPjwvZGl2PjxibG9ja3F1b3Rl
IGNsYXNzPSJnbWFpbF9xdW90ZSIgc3R5bGU9Im1hcmdpbjowIDAgMCAuOGV4O2JvcmRlci1sZWZ0
OjFweCAjY2NjIHNvbGlkO3BhZGRpbmctbGVmdDoxZXgiPjxkaXYgZGlyPSJsdHIiPjxkaXYgY2xh
c3M9ImdtYWlsX2RlZmF1bHQiIHN0eWxlPSJmb250LWZhbWlseTp2ZXJkYW5hLHNhbnMtc2VyaWYi
PlRoZSBydWJ5ICZsdDsmbHQ7LSBoZXJlZG9jIHN5bnRheCwgdW5saWtlIHRoZSAmbHQ7Jmx0OyBo
ZXJlZG9jIHN5bnRheCwgd2lsbCBzdHJpcCBpbmRlbnRhdGlvbiBpZiBuZWNlc3NhcnkuIFRlY2hu
aWNhbGx5LCBpdCBzZWFyY2hlcyBmb3IgdGhlICJsZWFzdCBpbmRlbnRlZCBsaW5lIiBpbiB0aGUg
d2hvbGUgc3RyaW5nLCBhbmQgcmVtb3ZlcyBleGFjdGx5IHRoYXQgYW1vdW50IGZyb20gZWFjaCBs
aW5lLiBTbyB5ZXMsIHRoZSBpbmRlbnRhdGlvbiBwcm9ibGVtIC1pcy0gc29sdmVkIGluIHJ1Ynkg
KHRob3VnaCBpdCBtaWdodCBicmVhayBlbnRpcmVseSBpZiB5b3UgaGF2ZSBlbXB0eSBsaW5lcywg
c2luY2UgdGhlIGxlYXN0IGluZGVudGVkIGxpbmUgaGFzIG5vIGluZGVudGF0aW9uKS48L2Rpdj48
L2Rpdj48L2Jsb2NrcXVvdGU+PGRpdj48YnI+PC9kaXY+PGRpdj5UbyBteSBtaW5kLCB0aGUgcnVs
ZXMgc2hvdWxkIGJlOjwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+MS4gVGhlIGluZGVudGF0aW9u
IGxldmVsIGlzIHNldCBmcm9tIHRoZSBsZWFzdCBpbmRlbnRlZCBsaW5lIHRoYXQgaXMgbm90IHRo
ZSBmaXJzdCBsaW5lIGFuZCBpcyBub3QgZW1wdHkuPC9kaXY+PGRpdj4yLiBBIGxlYWRpbmcgZW1w
dHkgbGluZSBpcyByZW1vdmVkLjwvZGl2PjxkaXY+My4gVGhlIGxlYWRpbmcgbGluZSwgaWYgdGhl
cmUgaXMgYW55IHRleHQgaW4gaXQsIGlzIG5vdCBzdWJqZWN0IHRvIGRlLWluZGVudGF0aW9uLjxi
cj48YnI+SSBnZW51aW5lbHkgYmVsaWV2ZSB0aGVzZSB0aHJlZSBydWxlcyB0YWtlbiB0b2dldGhl
ciBhZGRyZXNzIGFsbCB0aGUgZXJyb3JzIGFuZCBpbmZlbGljaXRpZXMgdG8gd2hpY2ggdHJpcGxl
IHF1b3RlcyBhbmQgSEVSRURPQ3Mgc3ViamVjdCB1cy4gSGVyZSBhcmUgc29tZSBleGFtcGxlczo8
L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PmBgYHB5dGhvbjwvZGl2PjxkaXY+dGV4dCA9ICIiIjwv
ZGl2PjxkaXY+Jm5ic3A7ICZuYnNwOyBTb21lPC9kaXY+PGRpdj48YnI+PC9kaXY+PGRpdj4mbmJz
cDsgRmVhdHVyZXM8L2Rpdj48ZGl2PiZuYnNwOyAmbmJzcDsgQXJlPC9kaXY+PGRpdj4mbmJzcDsg
Jm5ic3A7IERpc2N1c3NlZDwvZGl2PjxkaXY+IiIiPC9kaXY+PGRpdj4jIEZyb20gKDEpOiBUaGUg
aW5kZW50YXRpb24gaXMgdGFrZW4gZnJvbSB0aGUgdGhpcmQgbGluZSBiZWxvdyBgdGV4dGAsIHNv
IGl0J3MgMi48L2Rpdj48ZGl2PiMgRnJvbSAoMik6IEZpcnN0IGxpbmUgaXM6ICJcbiIgc28gaXQg
aXMgcmVtb3ZlZC48L2Rpdj48ZGl2PiMgRnJvbSAoMyk6IE5vIGVmZmVjdC48L2Rpdj48ZGl2Pjxi
cj48L2Rpdj48ZGl2PnRleHQgPSAiIiIgJm5ic3A7U29tZTwvZGl2PjxkaXY+PGJyPjwvZGl2Pjxk
aXY+Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBGZWF0dXJlczwvZGl2PjxkaXY+
Jm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgQXJlPC9kaXY+PGRpdj4m
bmJzcDsgJm5ic3A7ICZuYnNwOyAmbmJzcDsgJm5ic3A7ICZuYnNwOyBEaXNjdXNzZWQ8L2Rpdj48
ZGl2PiIiIjwvZGl2PjxkaXY+IyBGcm9tICgxKTogVGhlIGluZGVudGF0aW9uIGlzIHRha2VuIGFn
YWluIGZyb20gdGhlIGxpbmUgcmVhZGluZyAiRmVhdHVyZXMiLiBIZXJlIGl0IGlzIDEwLjwvZGl2
PjxkaXY+IyBGcm9tICgyKTogTm8gZWZmZWN0LjwvZGl2PjxkaXY+IyBGcm9tICgzKTogVGhlIGxl
YWRpbmcgd2hpdGVzcGFjZSBpbiBgICZuYnNwO1NvbWVgIGlzIHByZXNlcnZlZC48L2Rpdj48ZGl2
PmBgYDwvZGl2PjxkaXY+PGJyPjwvZGl2PjxkaXY+RG8geW91IGFsbCB0aGluayB0aGVzZSBydWxl
cyBwYXNzIG11c3Rlcj88L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2PkEgZm91cnRoIHJ1bGUgLS0g
b25lIHdoaWNoIHNlZW1zIGFkdmlzYWJsZSBidXQgYWxzbyBsZXNzIG5lY2Vzc2FyeSB0aGFuIHRo
ZSBvdGhlcnMgLS0gaXMgdGhhdCBhIHN0cmluZyBjb25zdHJ1Y3RlZCBpbiB0aGlzIHdheSBhbHdh
eXMgZW5kcyB3aXRoIGEgbmV3bGluZS4gSXQgaXMgYSBydWxlIHRoYXQgcGVyaGFwcyBsZWFkcyB0
byBzdXJwcmlzZXMgYW5kIGluY29uc2lzdGVuY2llcy48L2Rpdj48ZGl2Pjxicj48L2Rpdj48ZGl2
PkJlc3QgUmVnYXJkcyw8L2Rpdj48ZGl2PiZuYnNwOyBKYXNvbjwvZGl2PjwvZGl2Pg==" style="height:0;width:0;max-height:0;max-width:0;overflow:hidden;font-size:0em;padding:0;margin:0">​</div></div></div>