On Thu, Apr 13, 2017 at 4:03 AM, Brent Royal-Gordon <[email protected]> wrote:
> On Apr 12, 2017, at 5:39 PM, Xiaodi Wu <[email protected]> wrote: > > On Wed, Apr 12, 2017 at 5:20 PM, Brent Royal-Gordon < > [email protected]> wrote: > >> Wow, maybe I shouldn't have slept. >> >> 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. >> >> 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. >> > > 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()`: > > ``` > print("Hello, world!") // Emits "Hello, world!\n" > ``` > > > 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. > 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(_:)`. The underlying `TextOutputStream.write(_:)` doesn't; the I/O in Foundation > doesn't; file descriptor I/O doesn't. > 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. Concatenation certainly doesn't; nor does anything else you might do to > assemble several multiline string literals into a whole. > 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. So I think `print()` is the exception here, not the rule. > > In my opinion, modulo the "newline after leading delimiter" question, if > code like this example: > > var xml = """ > <?xml version="1.0"?> > <catalog> > """ > for (id, author, title, genre, price) in bookTuples { > xml += """ > <book id="bk\(id)"> > <author>\(author)</author> > <title>\(title)</title> > <genre>\(genre)</genre> > <price>\(price)</price> > </book> > """ > } > xml += """ > </catalog> > """ > > Doesn't assemble the kind of string that it's blatantly obvious the user > is trying to assemble, I think the syntax has failed. > 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. 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: ``` var xml = "<?xml version=\"1.0\"?>" xml += "<catalog>" for (id, _, _, _, _) in bookTuples { xml += "<book id=\"bk\(id)\">Book ID: \(id)</book>" } xml += "</catalog>" ``` 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. `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. > > -- > Brent Royal-Gordon > Architechies > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
