Regards (From mobile)
On Apr 27, 2016, at 10:52 AM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote: >> If you agree that these are all orthogonal pieces, then treat them as such: >> I’d suggest that you provide a proposal that just tackles the continuation >> string literals. This seems simple, and possible to get in for Swift 3. > > I've gone ahead and drafted this proposal, with some small extensions and > adjustments. See the "Draft Notes" section for details of what I've changed > and what concerns I have. > > Gist: <https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f> > > Multiline string literals > Proposal: SE-NNNN > Author(s): Brent Royal-Gordon > Status: First Draft > Review manager: TBD > Introduction > > In Swift 2.2, the only means to insert a newline into a string literal is the > \n escape. String literals specified in this way are generally ugly and > unreadable. We propose a multiline string feature inspired by English > punctuation which is a straightforward extension of our existing string > literals. > > Swift-evolution thread: multi-line string literals. > > Draft Notes > > This draft differs from the prototypes being thrown around on the list in > that it specifies that comments should be treated as whitespace, and that > whitespace-only lines in the middle of a multiline string should be ignored. > I'm not sure if this is feasible from a parsing standpoint, and I'd like > feedback from implementers on this point. > > This draft also specifies diagnostics which should be included. Feedback on > whether these are good choices would be welcome. > > I am considering allowing you to put a backslash before the newline to > indicate it should not be included in the literal. In other words, this code: > > print("foo\ > "bar") > Would print "foobar". However, I think this should probably be proposed > separately, because there may be a better way to do it. > > I've listed only myself as an author because I don't want to put anyone > else's name to a document they haven't seen, but there are others who deserve > to be listed (John Holdsworth at least). Let me know if you think you should > be included. > > Motivation > > As Swift begins to move into roles beyond app development, code which needs > to generate text becomes a more important use case. Consider, for instance, > generating even a small XML string: > > let xml = "<?xml version=\"1.0\"?>\n<catalog>\n\t<book id=\"bk101\" > empty=\"\">\n\t\t<author>\(author)</author>\n\t</book>\n</catalog>" > The string is practically unreadable, its structure drowned in escapes and > run-together characters; it looks like little more than line noise. We can > improve its readability somewhat by concatenating separate strings for each > line and using real tabs instead of \t escapes: > > let xml = "<?xml version=\"1.0\"?>\n" + > "<catalog>\n" + > " <book id=\"bk101\" empty=\"\">\n" + > " <author>\(author)</author>\n" + > " </book>\n" + > "</catalog>" > However, this creates a more complex expression for the type checker, and > there's still far more punctuation than ought to be necessary. If the most > important goal of Swift is making code readable, this kind of code falls far > short of that goal. > > Proposed solution > > We propose that, when Swift is parsing a string literal, if it reaches the > end of the line without encountering an end quote, it should look at the next > line. If it sees a quote mark there (a "continuation quote"), the string > literal contains a newline and then continues on that line. Otherwise, the > string literal is unterminated and syntactically invalid. > > Our sample above could thus be written as: > > let xml = "<?xml version=\"1.0\"?> > "<catalog> > " <book id=\"bk101\" empty=\"\"> > " <author>\(author)</author> > " </book> > "</catalog>" Somehow I find the fundamental asymetry of this syntax disturbing for the eye (many years of programming have created this silent but real expectation that " should match). The thought that it might be trying to mimic "english prose" does not make it suddenly look pretty or likeable. But again I probably have no taste as I used to find heredoc in perl/shell, if not pretty, at least practical. I think what I find surprising is what I perceive as a what-we-give-with-the-left-hand (the promise of a convenient way to insert existing external text), we-take-back-with-the-right: yes you can insert text, but you will have to massage it so much that you are going to be detered from using it for anything past 10 lines. > (Note that GitHub is applying incorrect syntax highlighting to this code > sample, because it's applying Swift 2 rules.) > > This format's unbalanced quotes might strike some programmers as strange, but > it attempts to mimic the way multiple lines are quoted in English prose. As > an English Stack Exchange answer illustrates: > > “That seems like an odd way to use punctuation,” Tom said. “What harm would > there be in using quotation marks at the end of every paragraph?” > > “Oh, that’s not all that complicated,” J.R. answered. “If you closed quotes > at the end of every paragraph, then you would need to reidentify the speaker > with every subsequent paragraph. > > “Say a narrative was describing two or three people engaged in a lengthy > conversation. If you closed the quotation marks in the previous paragraph, > then a reader wouldn’t be able to easily tell if the previous speaker was > extending his point, or if someone else in the room had picked up the > conversation. By leaving the previous paragraph’s quote unclosed, the reader > knows that the previous speaker is still the one talking.” > > “Oh, that makes sense. Thanks!” > Similarly, omitting the ending quotation mark tells the code's reader (and > compiler) that the literal continues on the next line, while including the > continuation quote reminds the reader (and compiler) that this line is part > of a string literal. > I certainly lack imagination as a missing quote does not make my mind immediately scream 'of course, it will be on the next line, or the one after, or maybe later... keep looking for it'. > Benefits of continuation quotes > > It would be simpler to not require continuation quotes, so why are they > required by this proposal? There are three reasons: > > They help the compiler pinpoint errors in string literal delimiting. If > continuation quotes were not required, then a missing end quote would be > interpreted as a multiline string literal. This string literal would continue > until the compiler encountered either another quote mark—perhaps at the site > of another string literal or in a comment—or the end of the file. In either > case, the compiler could at best only indicate the start of the runaway > string literal; in pathological cases (for instance, if the next string > literal was "+"), it might not even be able to do that properly. > > With continuation quotes required, if you forget to include an end quote, the > compiler can tell that you did not intend to create a multiline string and > flag the line that actually has the problem. It can also provide immediately > actionable fix-it assistance. The fact that there is a redundant indication > on each line of the programmer's intent to include that line in a multiline > quote allows the compiler to guess the meaning of the code. > > They separate indentation from the string's contents. Without continuation > quotes, there would be no obvious indication of whether whitespace at the > start of the line was intended to indent the string literal so it matched the > surrounding code, or whether that whitespace was actually meant to be > included in the resulting string. Multiline string literals would either have > to put subsequent lines against the left margin, or apply error-prone > heuristics to try to guess which whitespace was indentation and which was > string literal content. > > They improve the ability to quickly recognize the literal. The " on each line > serves as an immediately obvious indication that the line is part of a string > literal, not code, and the row of " characters in a well-formatted file > allows you to quickly scan up and down the file to see the extent of the > literal. > > Detailed design > > When Swift is parsing a string literal and reaches the end of a line without > finding a closing quote, it examines the next line, applying the following > rules: > > If the next line is all whitespace, it is ignored; Swift moves on to the line > afterward, applying these rules again. > > If the next line begins with whitespace followed by a continuation quote, > then the string literal contains a newline followed by the contents of the > string literal starting on that line. (This line may itself have no closing > quote, in which case the same rules apply to the line which follows.) > > If the next line contains anything else, Swift raises a syntax error for an > unterminated string literal. This syntax error should offer two fix-its: one > to close the string literal at the end of the current line, and one to > include the next line in the string literal by inserting a continuation quote. > > Rules 1 and 2 should treat comments as though they are whitespace; this > allows you to comment out individual lines in a multiline string literal. > (However, commenting out the last line of the string literal will still make > it unterminated, so you don't have a completely free hand in commenting.) > > Impact on existing code > > Failing to close a string literal before the end of the line is currently a > syntax error, so no valid Swift code should be affected by this change. > > Alternatives considered > > Requiring no continuation character > > The main alternative is to not require a continuation quote, and simply > extend the string literal from the starting quote to the ending quote, > including all newlines between them. For example: > > let xml = "<?xml version=\"1.0\"?> > <catalog> > <book id=\"bk101\" empty=\"\"> > <author>\(author)</author> > </book> > </catalog>" > This has several advantages: > > It is simpler. > > It is less offensive to programmers' sensibilities (since there are no > unmatched " characters). > > It does not require that you edit the string literal to insert a continuation > quote in each line. > > Balanced against the advantages, however, is the loss of the improved > diagnostics, code formatting, and visual affordances mentioned in the > "Benefits of continuation quotes" section above. > > In practice, we believe that editor support (such as "Paste as String > Literal" or "Convert to String Literal" commands) can make adding > continuation quotes less burdensome, while also providing other conveniences > like automatic escaping. We believe the other two factors are outweighed by > the benefits of continuation quotes. > > Use a different delimiter for multiline strings > > The initial suggestion was that multiline strings should use a different > delimiter, """, at the beginning and end of the string, with no continuation > characters between. This solution was rejected because it has the same issues > as the "no continuation character" solution, and because it was mixing two > orthogonal issues (multiline strings and alternate delimiters). > > Another suggestion was to support a heredoc syntax, which would allow you to > specify a placeholder string literal on one line whose content begins on the > next line, running until some arbitrary delimiter. For instance, if Swift > adopted Perl 5's syntax, it might support code like: > > connection.sendString(<<"END") > <?xml version="1.0"?> > <catalog> > <book id="bk101" empty=""> > <author>\(author)</author> > </book> > </catalog> > END > In addition to the issues with the """ syntax, heredocs are complicated both > to explain and to parse, and are not a natural extension of Swift's current > string syntax. > > Both of these suggestions address interesting issues with string literals, > solving compelling use cases. They're just not that good at fixing the > specific issue at hand. We might consider them in the future to address those > problems to which they are better suited. > > Fixing other string literal readability issues > > This proposal is narrowly aimed at multiline strings. It intentionally > doesn't tackle several other problems with string literals: > > Reducing the amount of double-backslashing needed when working with regular > expression libraries, Windows paths, source code generation, and other tasks > where backslashes are part of the data. > > Alternate delimiters or other strategies for writing strings with " > characters in them. > > String literals consisting of very long pieces of text which are best > represented completely verbatim. > > These are likely to be subjects of future proposals, though not necessarily > during Swift 3. > > This proposal also does not attempt to address regular expression literals. > The members of the core team who are interested in regular expression support > have ambitions for that feature which put it out of scope for Swift 3. > > -- > Brent Royal-Gordon > Architechies > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution