<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 <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> 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 <<- heredoc syntax, unlike the << heredoc syntax, will strip indentation if necessary. Technically, it searches for the "least indented line" 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)">"""
Some
Features
Are
Discussed
"""</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's 2.</span>
<span class="hljs-comment" style="color:rgb(153,153,136);font-style:italic"># From (2): First line is: "\n" 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)">""" Some
Features
Are
Discussed
"""</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 "Features". 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>