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

Reply via email to