<div dir="ltr">On Thu, Apr 13, 2017 at 4:03 AM, Brent Royal-Gordon <span dir="ltr"><<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>></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><span class="gmail-"><blockquote type="cite"><div>On Apr 12, 2017, at 5:39 PM, Xiaodi Wu <<a href="mailto:xiaodi.wu@gmail.com" target="_blank">xiaodi.wu@gmail.com</a>> wrote:</div><br class="gmail-m_-5253474253423077924Apple-interchange-newline"><div><div dir="ltr">On Wed, Apr 12, 2017 at 5:20 PM, Brent Royal-Gordon <span dir="ltr"><<a href="mailto:brent@architechies.com" target="_blank">brent@architechies.com</a>></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></div></div></div></div></div></blockquote><div><br></div></span><div>You say "this is the example set by `print`", but I don't think anything else actually *follows* that example. No other I/O operation in Swift behaves this way.</div></div></div></blockquote><div><br></div><div>To be more accurate, it's not `print` that specifies this behavior, but rather the standard output stream's implementation of `TextOutputStream.write(_:)`. Swift *explicitly* leaves this choice up to the TextOutputStream-conforming type. That is, the behavior is up to the receiver and not the argument of a call to `TextOutputStream.write(_:)`.</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><div>The underlying `TextOutputStream.write(_:)` doesn't; the I/O in Foundation doesn't; file descriptor I/O doesn't.</div></div></div></blockquote><div><br></div><div><div>And this goes to my point: there is line-oriented I/O, and there is non-line-oriented I/O. After all, why would I/O operations designed to write arbitrary bytes emit trailing newlines by default? It is the I/O operation that determines whether trailing newlines are implied or not, *not* the string.</div></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><div>Concatenation certainly doesn't; nor does anything else you might do to assemble several multiline string literals into a whole.</div></div></div></blockquote><div><br></div><div>And this goes to my other point: it *shouldn't*, because there is nothing about concatenation that is specifically "line-oriented." I am not aware of any language that concatenates with `+` which infers a default separator. Anyone who has ever used `+` has *always* appended their own separator. That is the user expectation, not what you show below.</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><div>So I think `print()` is the exception here, not the rule.</div><div><br></div><div>In my opinion, modulo the "newline after leading delimiter" question, if code like this example:</div><div><br></div><div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span>var xml = """</div><span class="gmail-"><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <?xml version="1.0"?></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <catalog></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> """</div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span></div></span><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span>for (id, author, title, genre, price) in bookTuples {</div><span class="gmail-"><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> xml += """</div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <book id="bk\(id)"></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <author>\(author)</author></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <title>\(title)</title></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <genre>\(genre)</genre></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> <price>\(price)</price></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> </book></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> """</div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span>}</div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span></div></span><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span>xml += """</div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> </catalog></div><div><span class="gmail-m_-5253474253423077924Apple-tab-span" style="white-space:pre-wrap">        </span> """</div><div><br></div><div>Doesn't assemble the kind of string that it's blatantly obvious the user is trying to assemble, I think the syntax has failed.</div></div></div></div></blockquote><div><br></div><div>First, let's be clear that this is an argument against your proposed no-newline-stripping-anywhere rule, so clearly this is not the motivating use case for that proposed design. I see you've moved away from it.</div><div><br></div><div>Second, this is a circular argument, where you are asserting that your proposed no-trailing-newline-stripping is the only blatantly obvious meaning because it is blatantly obvious. On the contrary, it is not at all clear to me that the user obviously wants a newline, not any more so than the following, which clearly does not and should not insert newlines:</div><div><br></div><div><div>```</div><div>var xml = "<?xml version=\"1.0\"?>"</div><div>xml += "<catalog>"</div><div><br></div><div>for (id, _, _, _, _) in bookTuples {</div><div> xml += "<book id=\"bk\(id)\">Book ID: \(id)</book>"</div><div>}</div><div><br></div><div>xml += "</catalog>"</div></div><div>```</div><div><br></div><div>To me, the only blatantly obvious behavior is that if you're going to want a separator and you're using `+` or `+=` for string concatenation, you concatenate the separator yourself. Why would that change just because there's multiline string syntax? The only thing that multiline string syntax should _maybe_ suggest to the reader is that there's a decent chance that there's a newline somewhere in the string, *not* that there's a decent chance that the string ends with one.</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><div><div>`print()` is the outlier. It's an important enough outlier that we should probably help the user notice when they're about to get it wrong, but an outlier it is.</div></div></div><span class="gmail-HOEnZb"><font color="#888888"><br><div>
<span class="gmail-m_-5253474253423077924Apple-style-span" style="border-collapse:separate;font-variant-ligatures:normal;font-variant-east-asian:normal;line-height:normal"><div><div style="font-size:12px">-- </div><div style="font-size:12px">Brent Royal-Gordon</div><div style="font-size:12px">Architechies</div></div></span>
</div>
<br></font></span></div></blockquote></div><br></div></div>