<div dir="ltr">Can this concept be dealt with my allowing a string file to be imported and assigned to a string constant? All happening at compile time and using #include type concept from C? It would tackle at least a reasonable subset of the issue in a way that I think works better for source control, etc.<div><br></div><div>let xml = @stringfile("Foo/Bar/baz.xml");<br><br><div class="gmail_quote"><div dir="ltr">On Wed, Apr 27, 2016 at 9:35 AM John Siracusa via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Apr 27, 2016 at 9:08 AM, Vladimir.S via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<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">I expect to be able to have multiline text exactly *"as-is"* in my source file. No escaping, no interpolation, etc. I believe this should be a target of the proposal.<br></blockquote><div><br></div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>I also see this as one of the most important goals of any multi-line string-handling proposal. The "no escapes required" syntax doesn't have to be the only way to handle multi-line strings, but it should be one of the available ways.</div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>-John</div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>P.S. - Secondarily (and broader than just multi-line strings) I think there should also be a way to avoid backslash-itis in strings of all kinds by providing some flexibility in string delimiters. But that's for another thread…</div></div></div></div><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div> </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">
Otherwise, I reject to see any reason to introduce anything new at this area - we already can concatenate strings and place them on next line and escape special characters.<br>
<br>
In your proposal, you have to escape characters in your text, you need to carefully modify the copy-pasted text to be allowed as correct multi-line string. Also, what if I need to have spaces *at the end of string* ? Editor can just trimmed them, and we can't clearly see them.<br>
<br>
Personally I need to be able to have this(in some way) in my code:<br>
(note this "\tuttorial" and "\(edition" - this is just text, I want to have inside my xml)<br>
<br>
let xml = ... // some marker to start the multi-line str<span><br>
<?xml version="1.0"?><br>
<catalog><br></span><span>
<book id="myid" empty=""><br>
<author>myAuthor</author><br>
<title>myTitle \tutorial 1\(edition 2)</title><br>
</book><br>
</catalog><br></span>
... // some marker here to stop multi-line str<br>
<br>
It seems like we need some markers for end-of-the-line to be able to keep spaces/tabs in the end of line.<br>
<br>
What about something like this. Two suported variants : first when we need to keep spaces in the end of line, and second when we don't need spaced(will be trimmed by parser)<br>
<br>
#1 (parser should just take the text between first and last quote *as-is*)<br>
<br>
let xml = "\<br>
"<?xml version="1.0"?> " // yes, *I need* these spaces at the end<span><br>
"<catalog>"<br>
" <book id="myid" empty="">"<br>
" <author>myAuthor</author>"<br>
" <title>myTitle \tutorial 1\(edition 2)</title>"<br>
" </book>"<br>
"</catalog>"<br>
"<br>
<br></span>
#2 in this case we don't need any spaces/tabs in the end of lines(don't care):<br>
(parser takes all that is after | as-is but trims any trailing spaces/tabs in lines to be clear in behaviour)<span><br>
<br>
let xml = "\<br>
|<?xml version="1.0"?><br>
|<catalog><br></span><span>
| <book id="myid" empty=""><br>
| <author>myAuthor</author><br>
| <title>myTitle \tutorial 1\(edition 2)</title><br>
| </book><br>
|</catalog><br>
"<br>
<br></span>
Or these two could be combined in one(as-is between |..|) but I'm not sure:<br>
<br>
let xml = "\<br>
|<?xml version="1.0"?> | // yes, I need these spaces<br>
|<catalog>| // we have to have closing symbol in this case in other lines<span><br>
| <book id="myid" empty="">|<br>
| <author>myAuthor</author>|<br>
| <title>myTitle \tutorial 1\(edition 2)</title>|<br>
| </book>|<br>
|</catalog>|<br>
"<br>
<br>
<br>
</span><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">
<br><span>
Gist: <<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f</a>><br>
<br>
<br>
Multiline string literals<br>
<br></span>
* Proposal: SE-NNNN<br>
<<a href="https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md" rel="noreferrer" target="_blank">https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md</a>><br>
* Author(s): Brent Royal-Gordon <<a href="https://github.com/brentdax" rel="noreferrer" target="_blank">https://github.com/brentdax</a>><br>
* Status: First Draft<br>
* Review manager: TBD<br>
<br>
<br>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction</a>>Introduction<span><br>
<br>
In Swift 2.2, the only means to insert a newline into a string literal is<br>
the |\n| escape. String literals specified in this way are generally ugly<br>
and unreadable. We propose a multiline string feature inspired by English<br>
punctuation which is a straightforward extension of our existing string<br>
literals.<br>
<br>
Swift-evolution thread: multi-line string literals.<br></span>
<<a href="https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html" rel="noreferrer" target="_blank">https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html</a>><br>
<br>
<br>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes</a>>Draft<br>
Notes<br>
<br>
*<span><br>
<br>
This draft differs from the prototypes being thrown around on the list<br>
in that it specifies that comments should be treated as whitespace, and<br>
that whitespace-only lines in the middle of a multiline string should<br>
be ignored. I'm not sure if this is feasible from a parsing standpoint,<br>
and I'd like feedback from implementers on this point.<br>
<br></span>
*<span><br>
<br>
This draft also specifies diagnostics which should be included.<br>
Feedback on whether these are good choices would be welcome.<br>
<br></span>
*<span><br>
<br>
I am considering allowing you to put a backslash before the newline to<br></span>
indicate it should /not/ be included in the literal. In other words,<span><br>
this code:<br>
<br>
print("foo\<br>
"bar")<br>
<br>
Would print |"foobar"|. However, I think this should probably be<br>
proposed separately, because there may be a better way to do it.<br>
<br></span>
*<span><br>
<br>
I've listed only myself as an author because I don't want to put anyone<br>
else's name to a document they haven't seen, but there are others who<br>
deserve to be listed (John Holdsworth at least). Let me know if you<br>
think you should be included.<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation</a>>Motivation<span><br>
<br>
As Swift begins to move into roles beyond app development, code which needs<br>
to generate text becomes a more important use case. Consider, for instance,<br>
generating even a small XML string:<br>
<br>
let xml = "<?xml version=\"1.0\"?>\n<catalog>\n\t<book id=\"bk101\"<br>
empty=\"\">\n\t\t<author>\(author)</author>\n\t</book>\n</catalog>"<br>
<br>
The string is practically unreadable, its structure drowned in escapes and<br>
run-together characters; it looks like little more than line noise. We can<br>
improve its readability somewhat by concatenating separate strings for each<br>
line and using real tabs instead of |\t| escapes:<br>
<br>
let xml = "<?xml version=\"1.0\"?>\n" +<br>
"<catalog>\n" +<br>
" <book id=\"bk101\" empty=\"\">\n" +<br>
" <author>\(author)</author>\n" +<br>
" </book>\n" +<br>
"</catalog>"<br>
<br>
However, this creates a more complex expression for the type checker, and<br>
there's still far more punctuation than ought to be necessary. If the most<br>
important goal of Swift is making code readable, this kind of code falls<br>
far short of that goal.<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution</a>>Proposed<span><br>
solution<br>
<br>
We propose that, when Swift is parsing a string literal, if it reaches the<br>
end of the line without encountering an end quote, it should look at the<br>
next line. If it sees a quote mark there (a "continuation quote"), the<br>
string literal contains a newline and then continues on that line.<br>
Otherwise, the string literal is unterminated and syntactically invalid.<br>
<br>
Our sample above could thus be written as:<br>
<br>
let xml = "<?xml version=\"1.0\"?><br>
"<catalog><br>
" <book id=\"bk101\" empty=\"\"><br>
" <author>\(author)</author><br>
" </book><br>
"</catalog>"<br>
<br>
(Note that GitHub is applying incorrect syntax highlighting to this code<br>
sample, because it's applying Swift 2 rules.)<br>
<br>
This format's unbalanced quotes might strike some programmers as strange,<br>
but it attempts to mimic the way multiple lines are quoted in English<br>
prose. As an English Stack Exchange answer illustrates<br></span>
<<a href="http://english.stackexchange.com/a/96613/64636" rel="noreferrer" target="_blank">http://english.stackexchange.com/a/96613/64636</a>>:<span><br>
<br>
“That seems like an odd way to use punctuation,” Tom said. “What harm<br>
would there be in using quotation marks at the end of every paragraph?”<br>
<br>
“Oh, that’s not all that complicated,” J.R. answered. “If you closed<br>
quotes at the end of every paragraph, then you would need to reidentify<br>
the speaker with every subsequent paragraph.<br>
<br>
“Say a narrative was describing two or three people engaged in a<br>
lengthy conversation. If you closed the quotation marks in the previous<br>
paragraph, then a reader wouldn’t be able to easily tell if the<br>
previous speaker was extending his point, or if someone else in the<br>
room had picked up the conversation. By leaving the previous<br>
paragraph’s quote unclosed, the reader knows that the previous speaker<br>
is still the one talking.”<br>
<br>
“Oh, that makes sense. Thanks!”<br>
<br>
Similarly, omitting the ending quotation mark tells the code's reader (and<br>
compiler) that the literal continues on the next line, while including the<br>
continuation quote reminds the reader (and compiler) that this line is part<br>
of a string literal.<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes</a>>Benefits<span><br>
of continuation quotes<br>
<br>
It would be simpler to not require continuation quotes, so why are they<br>
required by this proposal? There are three reasons:<br>
<br></span>
1.<br>
<br>
*They help the compiler pinpoint errors in string literal<br>
delimiting.* If continuation quotes were not required, then a missing<span><br>
end quote would be interpreted as a multiline string literal. This<br>
string literal would continue until the compiler encountered either<br>
another quote mark—perhaps at the site of another string literal or in<br>
a comment—or the end of the file. In either case, the compiler could at<br>
best only indicate the start of the runaway string literal; in<br>
pathological cases (for instance, if the next string literal<br>
was |"+"|), it might not even be able to do that properly.<br>
<br>
With continuation quotes required, if you forget to include an end<br>
quote, the compiler can tell that you did not intend to create a<br>
multiline string and flag the line that actually has the problem. It<br>
can also provide immediately actionable fix-it assistance. The fact<br>
that there is a redundant indication on each line of the programmer's<br>
intent to include that line in a multiline quote allows the compiler to<br>
guess the meaning of the code.<br>
<br></span>
2.<br>
<br>
*They separate indentation from the string's contents.* Without<span><br>
continuation quotes, there would be no obvious indication of whether<br>
whitespace at the start of the line was intended to indent the string<br>
literal so it matched the surrounding code, or whether that whitespace<br>
was actually meant to be included in the resulting string. Multiline<br>
string literals would either have to put subsequent lines against the<br>
left margin, or apply error-prone heuristics to try to guess which<br>
whitespace was indentation and which was string literal content.<br>
<br></span>
3.<br>
<br>
*They improve the ability to quickly recognize the literal.* The |"| on<span><br>
each line serves as an immediately obvious indication that the line is<br>
part of a string literal, not code, and the row of |"| characters in a<br>
well-formatted file allows you to quickly scan up and down the file to<br>
see the extent of the literal.<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design</a>>Detailed<span><br>
design<br>
<br>
When Swift is parsing a string literal and reaches the end of a line<br>
without finding a closing quote, it examines the next line, applying the<br>
following rules:<br>
<br></span>
1.<span><br>
<br>
If the next line is all whitespace, it is ignored; Swift moves on to<br>
the line afterward, applying these rules again.<br>
<br></span>
2.<span><br>
<br>
If the next line begins with whitespace followed by a continuation<br>
quote, then the string literal contains a newline followed by the<br>
contents of the string literal starting on that line. (This line may<br>
itself have no closing quote, in which case the same rules apply to the<br>
line which follows.)<br>
<br></span>
3.<span><br>
<br>
If the next line contains anything else, Swift raises a syntax error<br>
for an unterminated string literal. This syntax error should offer two<br>
fix-its: one to close the string literal at the end of the current<br>
line, and one to include the next line in the string literal by<br>
inserting a continuation quote.<br>
<br>
Rules 1 and 2 should treat comments as though they are whitespace; this<br>
allows you to comment out individual lines in a multiline string literal.<br>
(However, commenting out the last line of the string literal will still<br>
make it unterminated, so you don't have a completely free hand in commenting.)<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code</a>>Impact<span><br>
on existing code<br>
<br>
Failing to close a string literal before the end of the line is currently a<br>
syntax error, so no valid Swift code should be affected by this change.<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered</a>>Alternatives<br>
considered<br>
<br>
<br>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character</a>>Requiring<span><br>
no continuation character<br>
<br>
The main alternative is to not require a continuation quote, and simply<br>
extend the string literal from the starting quote to the ending quote,<br>
including all newlines between them. For example:<br>
<br>
let xml = "<?xml version=\"1.0\"?><br>
<catalog><br>
<book id=\"bk101\" empty=\"\"><br>
<author>\(author)</author><br>
</book><br>
</catalog>"<br>
<br>
This has several advantages:<br>
<br></span>
1.<br>
<br>
It is simpler.<br>
<br>
2.<span><br>
<br>
It is less offensive to programmers' sensibilities (since there are no<br>
unmatched |"| characters).<br>
<br></span>
3.<span><br>
<br>
It does not require that you edit the string literal to insert a<br>
continuation quote in each line.<br>
<br>
Balanced against the advantages, however, is the loss of the improved<br>
diagnostics, code formatting, and visual affordances mentioned in the<br>
"Benefits of continuation quotes" section above.<br>
<br>
In practice, we believe that editor support (such as "Paste as String<br>
Literal" or "Convert to String Literal" commands) can make adding<br>
continuation quotes less burdensome, while also providing other<br>
conveniences like automatic escaping. We believe the other two factors are<br>
outweighed by the benefits of continuation quotes.<br>
<br>
<br></span>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings</a>>Use<div><div><br>
a different delimiter for multiline strings<br>
<br>
The initial suggestion was that multiline strings should use a different<br>
delimiter, |"""|, at the beginning and end of the string, with no<br>
continuation characters between. This solution was rejected because it has<br>
the same issues as the "no continuation character" solution, and because it<br>
was mixing two orthogonal issues (multiline strings and alternate delimiters).<br>
<br>
Another suggestion was to support a heredoc syntax, which would allow you<br>
to specify a placeholder string literal on one line whose content begins on<br>
the next line, running until some arbitrary delimiter. For instance, if<br>
Swift adopted Perl 5's syntax, it might support code like:<br>
<br>
connection.sendString(<<"END")<br>
<?xml version="1.0"?><br>
<catalog><br>
<book id="bk101" empty=""><br>
<author>\(author)</author><br>
</book><br>
</catalog><br>
END<br>
<br>
In addition to the issues with the |"""| syntax, heredocs are complicated<br>
both to explain and to parse, and are not a natural extension of Swift's<br>
current string syntax.<br>
<br>
Both of these suggestions address interesting issues with string literals,<br>
solving compelling use cases. They're just not that good at fixing the<br>
specific issue at hand. We might consider them in the future to address<br>
those problems to which they are better suited.<br>
<br>
<br></div></div>
<<a href="https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues" rel="noreferrer" target="_blank">https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues</a>>Fixing<span><br>
other string literal readability issues<br>
<br>
This proposal is narrowly aimed at multiline strings. It intentionally<br>
doesn't tackle several other problems with string literals:<br>
<br></span>
*<span><br>
<br>
Reducing the amount of double-backslashing needed when working with<br>
regular expression libraries, Windows paths, source code generation,<br>
and other tasks where backslashes are part of the data.<br>
<br></span>
*<span><br>
<br>
Alternate delimiters or other strategies for writing strings<br>
with |"| characters in them.<br>
<br></span>
*<span><br>
<br>
String literals consisting of very long pieces of text which are best<br>
represented completely verbatim.<br>
<br>
These are likely to be subjects of future proposals, though not necessarily<br>
during Swift 3.<br>
<br>
This proposal also does not attempt to address regular expression literals.<br>
The members of the core team who are interested in regular expression<br>
support have ambitions for that feature which put it out of scope for Swift 3.<br>
<br>
--<br>
Brent Royal-Gordon<br>
Architechies<br>
<br>
<br>
<br></span><span>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br>
</span></blockquote><div><div>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div></div></div>
_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div></div></div>