Optional dictionary subscripts

Instead of creating yet another set of string quotation rules, I would prefer copy & pasting the Perl 5 rules :)

I wouldn't.

I'm a big fan of Perl. It was my daily driver for many years. I participated in the Perl 6 design process, was pumpking for a Parrot (the early Perl 6 interpreter) subsystem, and have patches in the Perl 5 interpreter. I'm fluent in Perl 5's various literal syntaxes. (Actually, a piece of syntax I added had to be disambiguated from empty-regex.)

I've used and appreciated virtually all of Perl's literal syntaxes, but I don't think they'd be a good fit for Swift.

Every language has its own character. Perl's is that it's maximally expressive and deeply embraces precedent from other languages, even at the cost of making code ambiguous, obscure, or downright ugly. In that context, having two quoting mechanisms (q and qq) in three forms ('/", q/qq, heredoc) is a great solution, and the lack of indentation handling is not a big deal. It fits perfectly into Perl's concept of TMTOWTDI ("there's more than one way to do it").

Swift's character is quite different from Perl's, though. Swift aims to be simple and clear, permitting shorthands, omissions, and inferences, but usually not outright redundancy. If the language is making something difficult, you should enhance an existing construct, not create a new one:

* Too much junk in a closure declaration? Let people omit inferrable types or even parameter names.
* Immutable collections too slow, mutable ones too dangerous, and having both is an ugly compromise? Make them value types, giving you the best of both worlds.
* String and Array are kind of similar, but not really the same? Unite them with common protocols. (And if Int indexing is too dangerous for Strings, use an associated type to make sure Strings can use a safely opaque Index.)

The huge preponderance of quoting syntaxes in Perl isn't very Swifty, but neither is the decision to leave a major style issue (indentation) on the table. Swift generally does not tolerate designs that lead to ugly code.

If I had to create a slogan like TMTOWTDI for Swift, I would probably choose "one way, maximally elegant". That's quite a different approach to language design, and it calls for a different approach to string literals.

···

--
Brent Royal-Gordon
Architechies

+1 for Brent's comments

···

On Sunday, 24 April 2016, Brent Royal-Gordon via swift-evolution < swift-evolution@swift.org> wrote:

> Instead of creating yet another set of string quotation rules, I would
prefer copy & pasting the Perl 5 rules :)

I wouldn't.

I'm a big fan of Perl. It was my daily driver for many years. I
participated in the Perl 6 design process, was pumpking for a Parrot (the
early Perl 6 interpreter) subsystem, and have patches in the Perl 5
interpreter. I'm fluent in Perl 5's various literal syntaxes. (Actually, a
piece of syntax I added had to be disambiguated from empty-regex.)

I've used and appreciated virtually all of Perl's literal syntaxes, but I
don't think they'd be a good fit for Swift.

Every language has its own character. Perl's is that it's maximally
expressive and deeply embraces precedent from other languages, even at the
cost of making code ambiguous, obscure, or downright ugly. In that context,
having two quoting mechanisms (q and qq) in three forms ('/", q/qq,
heredoc) is a great solution, and the lack of indentation handling is not a
big deal. It fits perfectly into Perl's concept of TMTOWTDI ("there's more
than one way to do it").

Swift's character is quite different from Perl's, though. Swift aims to be
simple and clear, permitting shorthands, omissions, and inferences, but
usually not outright redundancy. If the language is making something
difficult, you should enhance an existing construct, not create a new one:

* Too much junk in a closure declaration? Let people omit inferrable types
or even parameter names.
* Immutable collections too slow, mutable ones too dangerous, and having
both is an ugly compromise? Make them value types, giving you the best of
both worlds.
* String and Array are kind of similar, but not really the same? Unite
them with common protocols. (And if Int indexing is too dangerous for
Strings, use an associated type to make sure Strings can use a safely
opaque Index.)

The huge preponderance of quoting syntaxes in Perl isn't very Swifty, but
neither is the decision to leave a major style issue (indentation) on the
table. Swift generally does not tolerate designs that lead to ugly code.

If I had to create a slogan like TMTOWTDI for Swift, I would probably
choose "one way, maximally elegant". That's quite a different approach to
language design, and it calls for a different approach to string literals.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-- Howard.

To audition Xcode using the following multi-line syntax:

        let xml = "<?xml version=\"1.0\"?>
            "<catalog>
            " <book id=\"bk101\" empty=\"\">
            " <author>\(author)</author>
            " <title>XML Developer's Guide</title>
            " <genre>Computer</genre>
            " <price>44.95</price>
            " <publish_date>2000-10-01</publish_date>
            " <description>An in-depth look at creating applications with XML.</description>
            " </book>
            "</catalog>
            ""
        print(xml)

You can install: http://johnholdsworth.com/swift-LOCAL-2016-04-25-a-osx.tar.gz

···

On 24 Apr 2016, at 23:35, Chris Lattner <clattner@apple.com> wrote:

On Apr 23, 2016, at 2:08 PM, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org> wrote:

I’m trying to avoid more advanced features such as the handling of indenting which
for me complicates something that if kept simple can be documented very easily.

I don't think you can tackle multiline strings without worrying about indenting. Indentation may fundamentally change the approach you choose.

I agree with this and almost every point you make in your email (and your other subsequent one about one approach maximally general). That said, I wonder if there is a different conclusion that can be reached. I’m going to rearrange your three features a bit:

The way I would prefer to tackle these is:

* Multiline literals: If the closing quote of a string is not present, look at the next line. If it consists of (optional) indentation followed by a matching opening quote, the string has a newline and then continues after the quote on the next line. (The handling of comments is an open question here.)

  let xml: String = "<?xml version=\"1.0\"?>
        "<catalog>
        "\t<book id=\"bk101\" empty=\"\">
        "\t\t<author>\(author)</author>
        "\t</book>
        "</catalog>"

The cool things about this are that (a) the compiler can tell you really do mean this to be part of the literal and you haven't just forgotten to close the string, and (b) there's no guesswork about how indentation should be handled. The uncool thing is that you need to insert the quote at the beginning of each line, so you can't just blindly paste into a multiline literal. Editors can help make that easier, though—a "paste as string literal" feature would be a nice addition to Xcode, and not just for multiline strings or just for Swift.

Yes, I completely agree. This is is awesome, and a nice & simple generalization of our existing syntax. It has obvious behavior even if you encounter it in code without knowing about the feature.

* Disabling escapes: If you use single quotes instead of double quotes, backslash escapes are disabled.

We need a way to disable escapes, but it seems to me that (since it is orthogonal to the other concerns) that it should not be tied to the “multiple single quotes” syntax. What is your thought on “modifier” prefix characters for string literals? e.g.:

  let x = e”no \escapes \(processed here”

If we supported these, they would be supported with multi-line string literals by putting the modifiers on the first line of the literal, and the multi-line approach above would “just work”. You could introduce several different modifiers, e.g. one that disabled general escapes, but still allowed \(x) for substitution.

* Yes, with a number of backslashes matching the number of quotes, which allows you to insert literal \( text: ''' <author>\\\(author)</author>

Egads!

Notes on alternatives:

1. If you wanted to not provide no-escaping strings, an alternative would be to say that *all* escapes require as many backslashes as there are quotes in the string delimiter. Thus, a newline escape in a `"""` string would be `\\\n`. This would in practice give you the same flexibility to write a literal without worrying (much) about escaping.

I’m really not a fan of requiring “stacking” of escapes to re-enable them. This (IMO) just makes it less likely that you’ll run into an edge case. I also don’t like the “fix" being to have to use 5 quotes around your strings :-)

3. It might be useful to make multiline `"` strings trim trailing whitespace and comments like Perl's `/x` regex modifier does.

If you have modifier characters already, it is easy to build a small zoo full of these useful beasts.

* Alternative delimiters: If a string literal starts with three, or five, or seven, or etc. quotes, that is the delimiter, and fewer quotes than that in a row are simply literal quote marks. Four, six, etc. quotes is a quote mark abutting the end of the literal.

  let xml: String = """<?xml version="1.0"?>
        """<catalog>
        """\t<book id="bk101" empty="">
        """\t\t<author>\(author)</author>
        """\t</book>
        """</catalog>"""

You can't use this syntax to express an empty string, or a string consisting entirely of quote marks, but `""` handles empty strings adequately, and escaping can help with quote marks. (An alternative would be to remove the abutting rule and permit `""""""` to mean "empty string", but abutting quotes seem more useful than long-delimiter empty strings.)

I agree that there is a need to support alternative delimiters, but subjectively, I find this to be pretty ugly. It is also a really unfortunate degenerate case for “I just want a large blob of XML” because you’d end up using “"” almost all the time, and you have to use it on every line.

For cases like this, I think it would be reasonable to have a “heredoc” like scheme, which does not allow leading indentation, and does work with all the same modifier characters above. I do not have a preference on a particular syntax, and haven’t given it any thought, but this would allow you to do things like:

  let str = <<EOF
<?xml version="1.0"?>
<catalog>
\t<book id="bk101" empty="">
\t\t<author>\(author)</author>
\t</book>
</catalog>
EOF

for example. You could then turn off escaping and other knobs using the modifier character (somehow, it would have to be incorporated into the syntax of course).

I generally agree with your down thread remarks about how Swift doesn’t like to have multiple different solutions for the same problem. OTOH, you could look at “” syntax as being analogous to closure exprs, and heredoc syntax as being analogous to nested functions :-)

-Chris

My thinking here was two-fold:
1) Address the need to accommodate the lack of regex literals today, and
2) Future-proof the proposal to accommodate the eventuality of regex literals.

-Patrick

···

On Apr 24, 2016, at 6:09 PM, Chris Lattner <clattner@apple.com> wrote:

On Apr 22, 2016, at 12:54 PM, Patrick Gili via swift-evolution <swift-evolution@swift.org> wrote:

If we use a quoting structure similar to Perl6, then we future proof the grammar to accommodate regular expression literals (and multi-line regular expression literals) later. It also gives us the possibility for support for fine-grain control over escaping and interpolation.

Wouldn’t the natural regex literal syntax be to enclose them in /’s, e.g. /foo*/ ?

I don’t see how this proposal conflicts with that.

-Chris

* Disabling escapes: If you use single quotes instead of double quotes, backslash escapes are disabled.

We need a way to disable escapes, but it seems to me that (since it is orthogonal to the other concerns) that it should not be tied to the “multiple single quotes” syntax. What is your thought on “modifier” prefix characters for string literals? e.g.:

  let x = e”no \escapes \(processed here”

If we supported these, they would be supported with multi-line string literals by putting the modifiers on the first line of the literal, and the multi-line approach above would “just work”. You could introduce several different modifiers, e.g. one that disabled general escapes, but still allowed \(x) for substitution.

3. It might be useful to make multiline `"` strings trim trailing whitespace and comments like Perl's `/x` regex modifier does.

If you have modifier characters already, it is easy to build a small zoo full of these useful beasts.

Modifiers are definitely a workable alternative, and can be quite flexible, particularly if a future macro system can let you create new modifiers.

(The Perl script I just posted about supports the e"" syntax you're proposing.)

* Yes, with a number of backslashes matching the number of quotes, which allows you to insert literal \( text: ''' <author>\\\(author)</author>

Egads!

Yeah, that's a little more clever than nice. :^)

* Alternative delimiters: If a string literal starts with three, or five, or seven, or etc. quotes, that is the delimiter, and fewer quotes than that in a row are simply literal quote marks. Four, six, etc. quotes is a quote mark abutting the end of the literal.

  let xml: String = """<?xml version="1.0"?>
        """<catalog>
        """\t<book id="bk101" empty="">
        """\t\t<author>\(author)</author>
        """\t</book>
        """</catalog>"""

You can't use this syntax to express an empty string, or a string consisting entirely of quote marks, but `""` handles empty strings adequately, and escaping can help with quote marks. (An alternative would be to remove the abutting rule and permit `""""""` to mean "empty string", but abutting quotes seem more useful than long-delimiter empty strings.)

I agree that there is a need to support alternative delimiters, but subjectively, I find this to be pretty ugly. It is also a really unfortunate degenerate case for “I just want a large blob of XML” because you’d end up using “"” almost all the time, and you have to use it on every line.

On the other hand, the `"""` does form a much larger, more obvious continuation indicator. It is *extremely* obvious that the above line is not Swift code, but something else embedded in it. It's also extremely obvious what its extent is: when you stop seeing `"""`, you're back to normal Swift code.

I *really* don't like the idea of our only alternatives being "one double-quote mark with backslashing" or "use an entire heredoc". Heredocs have their place, but they are a *very* heavyweight quoting mechanism, and relatively short strings with many double-quotes are pretty common. (Consider, for instance, strings containing unparsed JSON.) I think we need *some* alternative to double-quotes, either single-quotes (with the same semantics, just as an alternative) or this kind of quote-stacking.

For cases like this, I think it would be reasonable to have a “heredoc” like scheme, which does not allow leading indentation, and does work with all the same modifier characters above. I do not have a preference on a particular syntax, and haven’t given it any thought, but this would allow you to do things like:

  let str = <<EOF
<?xml version="1.0"?>
<catalog>
\t<book id="bk101" empty="">
\t\t<author>\(author)</author>
\t</book>
</catalog>
EOF

for example. You could then turn off escaping and other knobs using the modifier character (somehow, it would have to be incorporated into the syntax of course).

There are two questions and a suggestion I have whenever heredoc syntax comes up.

Q1: Does the heredoc begin immediately, at the next line, or at the next valid place for a statement to start? Heredocs traditionally take the second approach.

Q2: Do you permit heredocs to stack—that is, for a single line to specify multiple heredocs?

S: During the Perl 6 redesign, they decided to use the delimiter's indentation to determine the base indentation for the heredoc:

  func x() -> String {
    return <<EOF
    <?xml version="1.0"?>
    <catalog>
    \t<book id="bk101" empty="">
    \t\t<author>\(author)</author>
    \t</book>
    </catalog>
    EOF
  }

Does that seem like a good approach?

I generally agree with your down thread remarks about how Swift doesn’t like to have multiple different solutions for the same problem. OTOH, you could look at “” syntax as being analogous to closure exprs, and heredoc syntax as being analogous to nested functions :-)

Function declarations vs. closure variable assignments were actually the only example I could think of where Swift offers two hugely different ways to write the same thing. I ultimately decided that closure syntax is an inline shorthand for function syntax, and the fact that a declared function is kind of like a declared variable of function type is a red herring. :^)

···

--
Brent Royal-Gordon
Architechies

Doesn't strike me as a problem needing a solution, though. Strings are syntax-colored differently than actual code. So if it's really runaway, you're likely to notice the wrong color. And the likelihood of the code actually still compiling after grabbing the next random quote to terminate its string is rather small, too.

Personally, I've noticed in the last few days that I don't actually trust syntax highlighting very much to tell me where the end of a complicated string literal is, particularly when it uses complex features like multiline strings, escapes, and interpolations. Xcode and TextMate *are* both usually pretty reliable, but not always, and I have a lot of experience with older text editors with worse highlighting. As a result, I seem to automatically dismiss "obviously wrong" highlighting.

···

--
Brent Royal-Gordon
Architechies

It’s +1 from me also. Swift’s Lexer is less than 2000 lines in it’s entirety whereas Perl’s
tokeniser is more than 11,000 lines so I don’t think this is a direction we want to head in.

Besides, I don’t feel there is a need for more than one type of string as Swift's
\() interpolation syntax is sufficiently distinct that needing an un-interpolated
string is comparatively rare. With respect to the “picket fence” problem with
complex regular expressions one proposal is that unknown escape sequences
be passed into the string literal instead of giving an error. This would make the
following a legal string/regex: “\w[\w\d]+”. This involves a shift from thinking of
\ as an escape character. More specific supported escape sequences \r \n \( etc.

This leaves the question of indentation inside string. I’d prefer not to address this
as it prevents data being pasted directly into a program and on KISS grounds.
If someone suggests a simple consistent syntax however I could take a look at it.

If you want to give the proposal a test drive you can download a 3.0 toolchain
supporting multiline strings including the regex suggestion installing it as follows :

$ curl http://johnholdsworth.com/swift-LOCAL-2016-04-24-a-osx.tar.gz > multiline.tar.gz
$ sudo tar xfz multiline.tar.gz -C /

Select "Local Swift Development Snapshot 2016-04-24” in preferences and restart Xcode.

John

···

On 24 Apr 2016, at 04:31, Howard Lovatt <howard.lovatt@gmail.com> wrote:

+1 for Brent's comments

On Sunday, 24 April 2016, Brent Royal-Gordon via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> Instead of creating yet another set of string quotation rules, I would prefer copy & pasting the Perl 5 rules :)

I wouldn't.

I'm a big fan of Perl. It was my daily driver for many years. I participated in the Perl 6 design process, was pumpking for a Parrot (the early Perl 6 interpreter) subsystem, and have patches in the Perl 5 interpreter. I'm fluent in Perl 5's various literal syntaxes. (Actually, a piece of syntax I added had to be disambiguated from empty-regex.)

I've used and appreciated virtually all of Perl's literal syntaxes, but I don't think they'd be a good fit for Swift.

Every language has its own character. Perl's is that it's maximally expressive and deeply embraces precedent from other languages, even at the cost of making code ambiguous, obscure, or downright ugly. In that context, having two quoting mechanisms (q and qq) in three forms ('/", q/qq, heredoc) is a great solution, and the lack of indentation handling is not a big deal. It fits perfectly into Perl's concept of TMTOWTDI ("there's more than one way to do it").

Swift's character is quite different from Perl's, though. Swift aims to be simple and clear, permitting shorthands, omissions, and inferences, but usually not outright redundancy. If the language is making something difficult, you should enhance an existing construct, not create a new one:

* Too much junk in a closure declaration? Let people omit inferrable types or even parameter names.
* Immutable collections too slow, mutable ones too dangerous, and having both is an ugly compromise? Make them value types, giving you the best of both worlds.
* String and Array are kind of similar, but not really the same? Unite them with common protocols. (And if Int indexing is too dangerous for Strings, use an associated type to make sure Strings can use a safely opaque Index.)

The huge preponderance of quoting syntaxes in Perl isn't very Swifty, but neither is the decision to leave a major style issue (indentation) on the table. Swift generally does not tolerate designs that lead to ugly code.

If I had to create a slogan like TMTOWTDI for Swift, I would probably choose "one way, maximally elegant". That's quite a different approach to language design, and it calls for a different approach to string literals.

--
Brent Royal-Gordon
Architechies

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <javascript:;>
https://lists.swift.org/mailman/listinfo/swift-evolution

--
-- Howard.

My thinking here was two-fold:
1) Address the need to accommodate the lack of regex literals today, and
2) Future-proof the proposal to accommodate the eventuality of regex literals.

MHO is that regex literals are an essential feature for Swift to eventually have, but that they are a huge design project and completely separate from multi-line string literals.

-Chris

···

On Apr 25, 2016, at 4:55 AM, Patrick Gili <gili.patrick.r@gili-labs.com> wrote:

-Patrick

On Apr 24, 2016, at 6:09 PM, Chris Lattner <clattner@apple.com> wrote:

On Apr 22, 2016, at 12:54 PM, Patrick Gili via swift-evolution <swift-evolution@swift.org> wrote:

If we use a quoting structure similar to Perl6, then we future proof the grammar to accommodate regular expression literals (and multi-line regular expression literals) later. It also gives us the possibility for support for fine-grain control over escaping and interpolation.

Wouldn’t the natural regex literal syntax be to enclose them in /’s, e.g. /foo*/ ?

I don’t see how this proposal conflicts with that.

-Chris

To audition Xcode using the following multi-line syntax:

        let xml = "<?xml version=\"1.0\"?>
            "<catalog>
            " <book id=\"bk101\" empty=\"\">
            " <author>\(author)</author>
            " <title>XML Developer's Guide</title>
            " <genre>Computer</genre>
            " <price>44.95</price>
            " <publish_date>2000-10-01</publish_date>
            " <description>An in-depth look at creating applications with XML.</description>
            " </book>
            "</catalog>
            ""
        print(xml)

You can install: http://johnholdsworth.com/swift-LOCAL-2016-04-25-a-osx.tar.gz

This is super-cool, and in a little bit of testing, I really like what this does to multiline strings. The quotation marks on the left end up forming a column that marks the lines as special, much like using `///` on multiline doc comments instead of `/**`.

In the spirit of building prototypes, I wrote a Perl script which generates literals in various formats: <https://dl.dropboxusercontent.com/u/64017186/make-swift-literal.pl&gt; It allows you to feed in different strings and evaluate how they might look with various language features we might add.

The command takes a file on the command line ("-" for stdin, nothing to use the contents of the pasteboard) and prints it as a Swift literal. It supports the following options:

* --multiline|nomultiline: Controls the hanging-quote format we've been discussing for multiline quotes.
* --unescaped|nounescaped: Controls the `e"string"` format we've been discussing for quotes that ignore escaping.
* --quotes=n: Sets the number of quotation marks to be used.
* --auto|noauto: If enabled, the exact settings are chosen heuristically, with the command-line options being used as maximums. If disabled, the options directly control the settings used.

The default is to use heuristics, enable all options with a very high maximum number of quotes, and read the string from the pasteboard. (These defaults are controlled from lines 9 and 13-16.) I chose these defaults so that this can be used to prototype a "Paste as String Literal" command in TextMate 2. Just open the Swift bundle in the bundle editor, paste the script into a new "Paste as String Literal" command, and choose "Key Equivalent: Ctrl-Cmd-V", "Input: Nothing", and "Output: Replace Selection".

···

--
Brent Royal-Gordon
Architechies

3. It might be useful to make multiline `"` strings trim trailing whitespace and comments like Perl's `/x` regex modifier does.

If you have modifier characters already, it is easy to build a small zoo full of these useful beasts.

Modifiers are definitely a workable alternative, and can be quite flexible, particularly if a future macro system can let you create new modifiers.

Right. I consider modifiers to be highly precedented in other languages, and therefore proven to work. If we go this way, I greatly prefer prefix to postfix modifiers.

* Alternative delimiters: If a string literal starts with three, or five, or seven, or etc. quotes, that is the delimiter, and fewer quotes than that in a row are simply literal quote marks. Four, six, etc. quotes is a quote mark abutting the end of the literal.

  let xml: String = """<?xml version="1.0"?>
        """<catalog>
        """\t<book id="bk101" empty="">
        """\t\t<author>\(author)</author>
        """\t</book>
        """</catalog>"""

You can't use this syntax to express an empty string, or a string consisting entirely of quote marks, but `""` handles empty strings adequately, and escaping can help with quote marks. (An alternative would be to remove the abutting rule and permit `""""""` to mean "empty string", but abutting quotes seem more useful than long-delimiter empty strings.)

I agree that there is a need to support alternative delimiters, but subjectively, I find this to be pretty ugly. It is also a really unfortunate degenerate case for “I just want a large blob of XML” because you’d end up using “"” almost all the time, and you have to use it on every line.

On the other hand, the `"""` does form a much larger, more obvious continuation indicator. It is *extremely* obvious that the above line is not Swift code, but something else embedded in it. It's also extremely obvious what its extent is: when you stop seeing `"""`, you're back to normal Swift code.

Right, but it is also heavy weight and ugly. In your previous email you said about the single quote approach: "The quotation marks on the left end up forming a column that marks the lines as special”, so I don’t see a need for a triple quote syntax to solve this specific problem.

I *really* don't like the idea of our only alternatives being "one double-quote mark with backslashing" or "use an entire heredoc". Heredocs have their place, but they are a *very* heavyweight quoting mechanism, and relatively short strings with many double-quotes are pretty common. (Consider, for instance, strings containing unparsed JSON.) I think we need *some* alternative to double-quotes, either single-quotes (with the same semantics, just as an alternative) or this kind of quote-stacking.

I agree that this is a real problem that would be great to solve.

If I step back and look at the string literal space we’re discussing, I feel like there are three options:

1) single and simple multiline strings, using “
2) your triple quote sort of string, specifically tuned to avoid having to escape “ when it occurs once or twice in sequence.
3) heredoc, which is a very general (but also very heavy weight) solution to quoting problems.

I’m trying to eliminate the middle one, so we only have to have "two things”. Here are some alternative ways to solve the problem, which might have less of an impact on the language:

A) Introduce single quoted string literals to avoid double quote problems specifically, e.g.: ‘look “here” I say!’. This is another form of #2 which is less ugly. It also doesn’t help you if you have both “ and ‘ in your string.

B) Introduce a modifier character that requires a more complex closing sequence to close off the string, see C++ raw string literals for prior art on this approach. Perhaps something like:

   Rxxx”look “ here “ I can use quotes “xxx

That said, I still prefer C) "ignore this issue for now”. In other words, I wouldn’t want to block progress on improving the string literal situation overall on this issue, because anything we do here is an further extension to a proposal that doesn’t solve this problem.

For cases like this, I think it would be reasonable to have a “heredoc” like scheme, which does not allow leading indentation, and does work with all the same modifier characters above. I do not have a preference on a particular syntax, and haven’t given it any thought, but this would allow you to do things like:

  let str = <<EOF
<?xml version="1.0"?>
<catalog>
\t<book id="bk101" empty="">
\t\t<author>\(author)</author>
\t</book>
</catalog>
EOF

for example. You could then turn off escaping and other knobs using the modifier character (somehow, it would have to be incorporated into the syntax of course).

There are two questions and a suggestion I have whenever heredoc syntax comes up.

Q1: Does the heredoc begin immediately, at the next line, or at the next valid place for a statement to start? Heredocs traditionally take the second approach.

Q2: Do you permit heredocs to stack—that is, for a single line to specify multiple heredocs?

S: During the Perl 6 redesign, they decided to use the delimiter's indentation to determine the base indentation for the heredoc:

  func x() -> String {
    return <<EOF
    <?xml version="1.0"?>
    <catalog>
    \t<book id="bk101" empty="">
    \t\t<author>\(author)</author>
    \t</book>
    </catalog>
    EOF
  }

Does that seem like a good approach?

I think that either approach could work, that you have a lot more experience on these topics than I do, and I would expect a vigorous community debate about these topics. :-)

That said, if you look at what we’re discussing:

1. “Continuation" string literals, to allow a multi-line string literal. You and I appear to completely agree about this.
2. Heredoc: You and I seem to agree that they are a good “fully general” solution to have, but there are the details you outline above to iron out.
3. Modifier characters: I’m in favor, but I don’t know where you stand. There is also still much to iron out here (such as the specific characters).
4. A way to avoid having to escape “ in a non-heredoc literal. I’m still unconvinced, and think that any solution to this problem will be orthogonal to the problems solved by 1-3 (and therefore can be added after getting experience with the other parts).

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. After that, we can discuss heredoc and modifiers (if you think they’re a good solution) on their own threads. If those turn out to be uncontroversial, then perhaps they can get in too.

On the heredoc aspects specifically, unless others chime in with strong opinions about the topics you brought up, I’d suggest that you craft a proposal for adding them with your preferred solution to these. You can mention the other answers (along with their tradeoffs and rationale for why you picked whatever you think is right) in the proposal, and we can help the community hash it out.

What do you think?

-Chris

···

On Apr 25, 2016, at 5:22 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

To audition Xcode using the following multi-line syntax:

let xml = "<?xml version=\"1.0\"?>
"<catalog>
" <book id=\"bk101\" empty=\"\">
" <author>\(author)</author>
" <title>XML Developer's Guide</title>
" <genre>Computer</genre>
" <price>44.95</price>
" <publish_date>2000-10-01</publish_date>
" <description>An in-depth look at creating applications with XML.</description>
" </book>
"</catalog>
""
print(xml)

You can install:
http://johnholdsworth.com/swift-LOCAL-2016-04-25-a-osx.tar.gz

Personally, I don't like that this syntax requires the moral equivalent
of a continuation character. It means I need to run a regex
search/replace over my text after I paste it between quotation marks.

···

on Sun Apr 24 2016, John Holdsworth <swift-evolution@swift.org> wrote:

    On 24 Apr 2016, at 23:35, Chris Lattner <clattner@apple.com> wrote:

        On Apr 23, 2016, at 2:08 PM, Brent Royal-Gordon via swift-evolution > <swift-evolution@swift.org> wrote:

        I’m trying to avoid more advanced features such as the handling of
            indenting which
            for me complicates something that if kept simple can be documented
            very easily.

        I don't think you can tackle multiline strings without worrying about
        indenting. Indentation may fundamentally change the approach you choose.

    I agree with this and almost every point you make in your email (and your
    other subsequent one about one approach maximally general). That said, I
    wonder if there is a different conclusion that can be reached. I’m going to
    rearrange your three features a bit:

        The way I would prefer to tackle these is:

        * Multiline literals: If the closing quote of a string is not present,
        look at the next line. If it consists of (optional) indentation followed
        by a matching opening quote, the string has a newline and then continues
        after the quote on the next line. (The handling of comments is an open
        question here.)

        let xml: String = "<?xml version=\"1.0\"?>
        "<catalog>
        "\t<book id=\"bk101\" empty=\"\">
        "\t\t<author>\(author)</author>
        "\t</book>
        "</catalog>"

        The cool things about this are that (a) the compiler can tell you really
        do mean this to be part of the literal and you haven't just forgotten to
        close the string, and (b) there's no guesswork about how indentation
        should be handled. The uncool thing is that you need to insert the quote
        at the beginning of each line, so you can't just blindly paste into a
        multiline literal. Editors can help make that easier, though—a "paste as
        string literal" feature would be a nice addition to Xcode, and not just
        for multiline strings or just for Swift.

    Yes, I completely agree. This is is awesome, and a nice & simple
    generalization of our existing syntax. It has obvious behavior even if you
    encounter it in code without knowing about the feature.

        * Disabling escapes: If you use single quotes instead of double quotes,
        backslash escapes are disabled.

    We need a way to disable escapes, but it seems to me that (since it is
    orthogonal to the other concerns) that it should not be tied to the
    “multiple single quotes” syntax. What is your thought on “modifier” prefix
    characters for string literals? e.g.:

    let x = e”no \escapes \(processed here”

    If we supported these, they would be supported with multi-line string
    literals by putting the modifiers on the first line of the literal, and the
    multi-line approach above would “just work”. You could introduce several
    different modifiers, e.g. one that disabled general escapes, but still
    allowed \(x) for substitution.

        * Yes, with a number of backslashes matching the number of quotes, which
        allows you to insert literal \( text: ''' <author>\\\(author)</author>

    Egads!

        Notes on alternatives:

        1. If you wanted to not provide no-escaping strings, an alternative
        would be to say that *all* escapes require as many backslashes as there
        are quotes in the string delimiter. Thus, a newline escape in a `"""`
        string would be `\\\n`. This would in practice give you the same
        flexibility to write a literal without worrying (much) about escaping.

    I’m really not a fan of requiring “stacking” of escapes to re-enable them.
    This (IMO) just makes it less likely that you’ll run into an edge case. I
    also don’t like the “fix" being to have to use 5 quotes around your strings :
    -)

        3. It might be useful to make multiline `"` strings trim trailing
        whitespace and comments like Perl's `/x` regex modifier does.

    If you have modifier characters already, it is easy to build a small zoo
    full of these useful beasts.

        * Alternative delimiters: If a string literal starts with three, or
        five, or seven, or etc. quotes, that is the delimiter, and fewer quotes
        than that in a row are simply literal quote marks. Four, six, etc.
        quotes is a quote mark abutting the end of the literal.

        let xml: String = """<?xml version="1.0"?>
        """<catalog>
        """\t<book id="bk101" empty="">
        """\t\t<author>\(author)</author>
        """\t</book>
        """</catalog>"""

        You can't use this syntax to express an empty string, or a string
        consisting entirely of quote marks, but `""` handles empty strings
        adequately, and escaping can help with quote marks. (An alternative
        would be to remove the abutting rule and permit `""""""` to mean "empty
        string", but abutting quotes seem more useful than long-delimiter empty
        strings.)

    I agree that there is a need to support alternative delimiters, but
    subjectively, I find this to be pretty ugly. It is also a really unfortunate
    degenerate case for “I just want a large blob of XML” because you’d end up
    using “"” almost all the time, and you have to use it on every line.

    For cases like this, I think it would be reasonable to have a “heredoc” like
    scheme, which does not allow leading indentation, and does work with all the
    same modifier characters above. I do not have a preference on a particular
    syntax, and haven’t given it any thought, but this would allow you to do
    things like:

    let str = <<EOF
    <?xml version="1.0"?>
    <catalog>
    \t<book id="bk101" empty="">
    \t\t<author>\(author)</author>
    \t</book>
    </catalog>
    EOF

    for example. You could then turn off escaping and other knobs using the
    modifier character (somehow, it would have to be incorporated into the
    syntax of course).

    I generally agree with your down thread remarks about how Swift doesn’t like
    to have multiple different solutions for the same problem. OTOH, you could
    look at “” syntax as being analogous to closure exprs, and heredoc syntax as
    being analogous to nested functions :-)

    -Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dave

Tracking the discussion, I’ve updated the prototype toolchain to support the following types of string:

        let multipart1 = "one" "two"
        let multipart2 = “one\n"
            “two\n"
        let multipart3 = "one
            “two\n"
        let regex = e"\w[\w\d]*\n"

It can be downloaded here: http://johnholdsworth.com/swift-LOCAL-2016-04-26-a-osx.tar.gz

Due to an implementation detail the e”” escaped strings still process escapes and interpolation
which is how I would argue it should be anyway. The “e” modifier just mutes the invalid escape error.

I’d only like to add I hope we can avoid HEREDOC strings are compared to Brent’s continuation
approach as the aesthetics are not at all good.

···

On 26 Apr 2016, at 07:04, Chris Lattner <clattner@apple.com> wrote:

On Apr 25, 2016, at 5:22 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

3. It might be useful to make multiline `"` strings trim trailing whitespace and comments like Perl's `/x` regex modifier does.

If you have modifier characters already, it is easy to build a small zoo full of these useful beasts.

Modifiers are definitely a workable alternative, and can be quite flexible, particularly if a future macro system can let you create new modifiers.

Right. I consider modifiers to be highly precedented in other languages, and therefore proven to work. If we go this way, I greatly prefer prefix to postfix modifiers.

* Alternative delimiters: If a string literal starts with three, or five, or seven, or etc. quotes, that is the delimiter, and fewer quotes than that in a row are simply literal quote marks. Four, six, etc. quotes is a quote mark abutting the end of the literal.

  let xml: String = """<?xml version="1.0"?>
        """<catalog>
        """\t<book id="bk101" empty="">
        """\t\t<author>\(author)</author>
        """\t</book>
        """</catalog>"""

You can't use this syntax to express an empty string, or a string consisting entirely of quote marks, but `""` handles empty strings adequately, and escaping can help with quote marks. (An alternative would be to remove the abutting rule and permit `""""""` to mean "empty string", but abutting quotes seem more useful than long-delimiter empty strings.)

I agree that there is a need to support alternative delimiters, but subjectively, I find this to be pretty ugly. It is also a really unfortunate degenerate case for “I just want a large blob of XML” because you’d end up using “"” almost all the time, and you have to use it on every line.

On the other hand, the `"""` does form a much larger, more obvious continuation indicator. It is *extremely* obvious that the above line is not Swift code, but something else embedded in it. It's also extremely obvious what its extent is: when you stop seeing `"""`, you're back to normal Swift code.

Right, but it is also heavy weight and ugly. In your previous email you said about the single quote approach: "The quotation marks on the left end up forming a column that marks the lines as special”, so I don’t see a need for a triple quote syntax to solve this specific problem.

I *really* don't like the idea of our only alternatives being "one double-quote mark with backslashing" or "use an entire heredoc". Heredocs have their place, but they are a *very* heavyweight quoting mechanism, and relatively short strings with many double-quotes are pretty common. (Consider, for instance, strings containing unparsed JSON.) I think we need *some* alternative to double-quotes, either single-quotes (with the same semantics, just as an alternative) or this kind of quote-stacking.

I agree that this is a real problem that would be great to solve.

If I step back and look at the string literal space we’re discussing, I feel like there are three options:

1) single and simple multiline strings, using “
2) your triple quote sort of string, specifically tuned to avoid having to escape “ when it occurs once or twice in sequence.
3) heredoc, which is a very general (but also very heavy weight) solution to quoting problems.

I’m trying to eliminate the middle one, so we only have to have "two things”. Here are some alternative ways to solve the problem, which might have less of an impact on the language:

A) Introduce single quoted string literals to avoid double quote problems specifically, e.g.: ‘look “here” I say!’. This is another form of #2 which is less ugly. It also doesn’t help you if you have both “ and ‘ in your string.

B) Introduce a modifier character that requires a more complex closing sequence to close off the string, see C++ raw string literals for prior art on this approach. Perhaps something like:

   Rxxx”look “ here “ I can use quotes “xxx

That said, I still prefer C) "ignore this issue for now”. In other words, I wouldn’t want to block progress on improving the string literal situation overall on this issue, because anything we do here is an further extension to a proposal that doesn’t solve this problem.

For cases like this, I think it would be reasonable to have a “heredoc” like scheme, which does not allow leading indentation, and does work with all the same modifier characters above. I do not have a preference on a particular syntax, and haven’t given it any thought, but this would allow you to do things like:

  let str = <<EOF
<?xml version="1.0"?>
<catalog>
\t<book id="bk101" empty="">
\t\t<author>\(author)</author>
\t</book>
</catalog>
EOF

for example. You could then turn off escaping and other knobs using the modifier character (somehow, it would have to be incorporated into the syntax of course).

There are two questions and a suggestion I have whenever heredoc syntax comes up.

Q1: Does the heredoc begin immediately, at the next line, or at the next valid place for a statement to start? Heredocs traditionally take the second approach.

Q2: Do you permit heredocs to stack—that is, for a single line to specify multiple heredocs?

S: During the Perl 6 redesign, they decided to use the delimiter's indentation to determine the base indentation for the heredoc:

  func x() -> String {
    return <<EOF
    <?xml version="1.0"?>
    <catalog>
    \t<book id="bk101" empty="">
    \t\t<author>\(author)</author>
    \t</book>
    </catalog>
    EOF
  }

Does that seem like a good approach?

I think that either approach could work, that you have a lot more experience on these topics than I do, and I would expect a vigorous community debate about these topics. :-)

That said, if you look at what we’re discussing:

1. “Continuation" string literals, to allow a multi-line string literal. You and I appear to completely agree about this.
2. Heredoc: You and I seem to agree that they are a good “fully general” solution to have, but there are the details you outline above to iron out.
3. Modifier characters: I’m in favor, but I don’t know where you stand. There is also still much to iron out here (such as the specific characters).
4. A way to avoid having to escape “ in a non-heredoc literal. I’m still unconvinced, and think that any solution to this problem will be orthogonal to the problems solved by 1-3 (and therefore can be added after getting experience with the other parts).

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. After that, we can discuss heredoc and modifiers (if you think they’re a good solution) on their own threads. If those turn out to be uncontroversial, then perhaps they can get in too.

On the heredoc aspects specifically, unless others chime in with strong opinions about the topics you brought up, I’d suggest that you craft a proposal for adding them with your preferred solution to these. You can mention the other answers (along with their tradeoffs and rationale for why you picked whatever you think is right) in the proposal, and we can help the community hash it out.

What do you think?

-Chris

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&gt;

Multiline string literals

Proposal: SE-NNNN <https://github.com/apple/swift-evolution/blob/master/proposals/NNNN-name.md&gt;
Author(s): Brent Royal-Gordon <https://github.com/brentdax&gt;
Status: First Draft
Review manager: TBD
<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction&gt;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. <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html&gt;
<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes&gt;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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#motivation&gt;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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution&gt;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>"
(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 <punctuation - Why does the multi-paragraph quotation rule exist? - English Language & Usage Stack Exchange

“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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#benefits-of-continuation-quotes&gt;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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#detailed-design&gt;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.)

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#impact-on-existing-code&gt;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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#alternatives-considered&gt;Alternatives considered

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#requiring-no-continuation-character&gt;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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings&gt;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.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#fixing-other-string-literal-readability-issues&gt;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

Can you clarify how this is different from heredoc? Because really, whether I write <<DELIMITER
stuff
DELIMITER

or RDELIMITER" stuff "DELIMITER

doesn't seem to make much of a difference.

FWIW, what I did in Hammer (my HyperCard clone's programming language) was to simply support several different international quotes. So you had standard inch signs:

"foo"

which were extended to support line breaks. I also offered:

“foo”
«foo»

All these do is behave essentially like the inch signs, but require you to quote a different character. So if you're Swiss or French, you'd stick with inch signs. If you're English and not that good at typography, you'd use guillemets. If you're writing French HTML, you'd go with the typographic quotes. It solves pasting in longer text as long as it doesn't contain too many different characters, you can use several different ones on one line, the optimizer doesn't car which you use and will merge the actual text data of consecutive strings.

Since most larger documents are better included as separate resource files instead of pasted into the code, this covers common uses of multiline or regexes. Since such text won't be very long it's also not as bad to ignore indentation (and if you don't like the look, that's something that can be fixed by the editor applying an indent).

Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."

···

On 26 Apr 2016, at 08:04, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

B) Introduce a modifier character that requires a more complex closing sequence to close off the string, see C++ raw string literals for prior art on this approach. Perhaps something like:

   Rxxx”look “ here “ I can use quotes “xxx

Sorry for any extra noise here. I've read the 58 emails in this thread and I just wanted to chime in my support for Dave here.

I think a multiline string literal implementation along the lines of Python is a no brainer.

In particular when I've needed and wanted multiline string literals it has almost always been when I've wanted to embed text from somewhere external (a text file for example, or string contents of a JSON file as part of unit testing).

Needing to append a token at the beginning of each line of my text would make multiline string literals considerably less productive for myself.

Just thought I'd chime in with that. Sorry again for the extra noise.

Regards,
Daniel

···

On 26 Apr 2016, at 10:55 pm, Dave Abrahams via swift-evolution <swift-evolution@swift.org> wrote:

on Sun Apr 24 2016, John Holdsworth <swift-evolution@swift.org> wrote:

To audition Xcode using the following multi-line syntax:

let xml = "<?xml version=\"1.0\"?>
"<catalog>
" <book id=\"bk101\" empty=\"\">
" <author>\(author)</author>
" <title>XML Developer's Guide</title>
" <genre>Computer</genre>
" <price>44.95</price>
" <publish_date>2000-10-01</publish_date>
" <description>An in-depth look at creating applications with XML.</description>
" </book>
"</catalog>
""
print(xml)

You can install:
http://johnholdsworth.com/swift-LOCAL-2016-04-25-a-osx.tar.gz

Personally, I don't like that this syntax requires the moral equivalent
of a continuation character. It means I need to run a regex
search/replace over my text after I paste it between quotation marks.

   On 24 Apr 2016, at 23:35, Chris Lattner <clattner@apple.com> wrote:

       On Apr 23, 2016, at 2:08 PM, Brent Royal-Gordon via swift-evolution >> <swift-evolution@swift.org> wrote:

       I’m trying to avoid more advanced features such as the handling of
           indenting which
           for me complicates something that if kept simple can be documented
           very easily.

       I don't think you can tackle multiline strings without worrying about
       indenting. Indentation may fundamentally change the approach you choose.

   I agree with this and almost every point you make in your email (and your
   other subsequent one about one approach maximally general). That said, I
   wonder if there is a different conclusion that can be reached. I’m going to
   rearrange your three features a bit:

       The way I would prefer to tackle these is:

       * Multiline literals: If the closing quote of a string is not present,
       look at the next line. If it consists of (optional) indentation followed
       by a matching opening quote, the string has a newline and then continues
       after the quote on the next line. (The handling of comments is an open
       question here.)

       let xml: String = "<?xml version=\"1.0\"?>
       "<catalog>
       "\t<book id=\"bk101\" empty=\"\">
       "\t\t<author>\(author)</author>
       "\t</book>
       "</catalog>"

       The cool things about this are that (a) the compiler can tell you really
       do mean this to be part of the literal and you haven't just forgotten to
       close the string, and (b) there's no guesswork about how indentation
       should be handled. The uncool thing is that you need to insert the quote
       at the beginning of each line, so you can't just blindly paste into a
       multiline literal. Editors can help make that easier, though—a "paste as
       string literal" feature would be a nice addition to Xcode, and not just
       for multiline strings or just for Swift.

   Yes, I completely agree. This is is awesome, and a nice & simple
   generalization of our existing syntax. It has obvious behavior even if you
   encounter it in code without knowing about the feature.

       * Disabling escapes: If you use single quotes instead of double quotes,
       backslash escapes are disabled.

   We need a way to disable escapes, but it seems to me that (since it is
   orthogonal to the other concerns) that it should not be tied to the
   “multiple single quotes” syntax. What is your thought on “modifier” prefix
   characters for string literals? e.g.:

   let x = e”no \escapes \(processed here”

   If we supported these, they would be supported with multi-line string
   literals by putting the modifiers on the first line of the literal, and the
   multi-line approach above would “just work”. You could introduce several
   different modifiers, e.g. one that disabled general escapes, but still
   allowed \(x) for substitution.

       * Yes, with a number of backslashes matching the number of quotes, which
       allows you to insert literal \( text: ''' <author>\\\(author)</author>

   Egads!

       Notes on alternatives:

       1. If you wanted to not provide no-escaping strings, an alternative
       would be to say that *all* escapes require as many backslashes as there
       are quotes in the string delimiter. Thus, a newline escape in a `"""`
       string would be `\\\n`. This would in practice give you the same
       flexibility to write a literal without worrying (much) about escaping.

   I’m really not a fan of requiring “stacking” of escapes to re-enable them.
   This (IMO) just makes it less likely that you’ll run into an edge case. I
   also don’t like the “fix" being to have to use 5 quotes around your strings :
   -)

       3. It might be useful to make multiline `"` strings trim trailing
       whitespace and comments like Perl's `/x` regex modifier does.

   If you have modifier characters already, it is easy to build a small zoo
   full of these useful beasts.

       * Alternative delimiters: If a string literal starts with three, or
       five, or seven, or etc. quotes, that is the delimiter, and fewer quotes
       than that in a row are simply literal quote marks. Four, six, etc.
       quotes is a quote mark abutting the end of the literal.

       let xml: String = """<?xml version="1.0"?>
       """<catalog>
       """\t<book id="bk101" empty="">
       """\t\t<author>\(author)</author>
       """\t</book>
       """</catalog>"""

       You can't use this syntax to express an empty string, or a string
       consisting entirely of quote marks, but `""` handles empty strings
       adequately, and escaping can help with quote marks. (An alternative
       would be to remove the abutting rule and permit `""""""` to mean "empty
       string", but abutting quotes seem more useful than long-delimiter empty
       strings.)

   I agree that there is a need to support alternative delimiters, but
   subjectively, I find this to be pretty ugly. It is also a really unfortunate
   degenerate case for “I just want a large blob of XML” because you’d end up
   using “"” almost all the time, and you have to use it on every line.

   For cases like this, I think it would be reasonable to have a “heredoc” like
   scheme, which does not allow leading indentation, and does work with all the
   same modifier characters above. I do not have a preference on a particular
   syntax, and haven’t given it any thought, but this would allow you to do
   things like:

   let str = <<EOF
   <?xml version="1.0"?>
   <catalog>
   \t<book id="bk101" empty="">
   \t\t<author>\(author)</author>
   \t</book>
   </catalog>
   EOF

   for example. You could then turn off escaping and other knobs using the
   modifier character (somehow, it would have to be incorporated into the
   syntax of course).

   I generally agree with your down thread remarks about how Swift doesn’t like
   to have multiple different solutions for the same problem. OTOH, you could
   look at “” syntax as being analogous to closure exprs, and heredoc syntax as
   being analogous to nested functions :-)

   -Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

--
Dave

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

In my opinion, one problem is that we don’t have a reference to a laundry or wish list of what features we would like around string literals in the language. Without evaluating a proposal against all of those features (moves forward, doesn’t impact, creates later issues for) it is hard to evaluate.

My guess here at an exhaustive list:

Main goals:
- reduce the impact on readability when dealing with certain kinds of string literals
- reduce the amount of editing needed when inserting/referencing text from an external source to be used as a string literal

Specific tasks/asks:
- for large string literals, reduce the amount of editing needed to span multiple lines
- for strings literals meant to represent multi-line text, allow the visual newline to be used rather than an encoding
  (note: this may mean in the first case newlines are considered formatting of the literal, while in the second they are considered part of the represented text)
- with string literals spanning multiple lines, allow for the author to indent the literal to match flow with surrounding code without impacting the represented text
- allow for text with double quotes to be represented in a string literal without requiring those quotes to be escaped
- have the ability to disable all/most escape interpretation to reduce impact on readability of certain text
- take into account that regular expressions, when added, will likely require different escaping rules than text string literals

Approach-specific
- if allowing for inline blocks of strings delimited by start/end points e.g. here docs, data segments
  - if the block end is on its own line, control whether that newline is part of the represented text

-DW

[couple minutes read]

I read with great attention this thread, trying to see it from the implementation viewpoint (I know that the compiler structure should not drive the language features). I also revisited the how-to-contribute notes as well as the dev-process description. One of the ideas that stood out in my mind was that when looking at an implementation, enablement changes should be separated from the bulk of the feature, such that reviews can be easier.

So I tried to elevate this to the rank of a hidden-mandatory-requirement for anything related to this feature. It lead me to a staged approach to this feature that would allow a lot of things to be done, OVER TIME.

When distilling this feature to the smallest part enabler that would have to be added to the compiler I came to the following short list

add a string_multiline_token to the lexer
I realize that the current lexer can be tweaked to work (as per John’s PR), but IMO adding a dedicated "hole" in the parsing code is what will give something working today (no difference with current compiler behavior) while allowing all future changes to be cleanly isolated from anything around
if one accepts the idea of a hole created by the token, then it stands to reason to have delimiters around it. I looking at the structure of the grammar, I came to the conclusion that _” and “_ where an easy, unambiguous choice (I believe “”” and “”” looked like an equally easy an unambiguous choice)
the next choice should be the creation of a lexStringMultilineLiteral() and lexMultilineCharacter() method in the Lexer. Again… bare with me, I do believe it is relevant to what everyone wants this feature to be… The latter method should contain only extensions specific to multiline literals delegating common use cases to lexCharacter()

The main point of following this route (or any equivalent) is that
it represents a very clear commitment to multiline string literals
it ensures that there is no strong commitment to feature details, while allowing many future scenarios
it will remain backward compatible with enhancements to the current string literal syntax (translation?)
external contributors will be able to prototype while making sure we stay within strict boundaries for integration with the compiler

The next equally small step would be to describe the required minimal changes to Parser, a step I do not want to take now if the compiler experts view no merit at all to the proposed staged approach.

A thought experiment pushing further down this path, shows how the following would be equally possible language features (with roughly equivalent implementation cost):

let whyOwhy = “”"\
    !! Can't understand what improvements it truly delivers
    !! It basically removes a handful of characters
    !! It works today
    !! But I don't see it as a likable foundations for adding in future enhancements
    !!\
    !! I don't envy the people who will have to support it outside of xcode
    !! Or even in xcode (considering how it currently struggles with indents/formatting
    !! As for elegance, beauty is in the eye of the beholder, they say.
“”"

var json1 = _"[json]\
    !!{
    !! "file" : "\(wishIhadPlaceholders)_000.md"
    !! "desc" : "and why are all examples in xml, i thought it died a while ago ;-)"
    !! "rational" : [
    !! "Here we go again"
    !! "How will xcode help make these workable"
    !! ]
    !!}
“_
var json2 = _"[json]\
{
  "file" : "\(wishIhadPlaceholders)_000.md"
  "desc" : "and why are all examples in xml, i thought it died a while ago ;-)"
  "rational" : [
          "Here we go again"
          "How will xcode help make these workable"
       ]
}
“_

[_"] --> start string
[_"\] --> start line + ignore spaces until eol (basically swallow \r\n)
[!!\] --> ignore everything until eol... basically the gap does not exits
["_] --> terminate string
[_"[TYPEID]\] --> start string knowing that it a verifyer or a formatter (or a chain of) understanding TYPEID can syntax check or format or or or

IMO splitting these expression from the current lexing/parsing has another long term benefits when coupled with the aforementioned idea of contents tagging:
allow external dedicated formatter to be created in any editor supporting swift
allow external validators (including in the form of compiler plugins)
open a door for an equivalent to the scala's macros for contents marked as [swift]

Once again I fully appreciate that implementation should not drive language design, but considering the flurry of great ideas, I thought it might in this instance be useful to identify a minimal, noncommittal, direction common to many scenarios, such that a step can be taken that will neither favor nor prohibit any of the proposals, but simply enable them all.

Thank you for your patience
Regards

PS: I am working on a rudimentary implementation that I hope could help people test all the ideas floating in this list.

···

On Apr 26, 2016, at 8:04 AM, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

On Apr 25, 2016, at 5:22 PM, Brent Royal-Gordon <brent@architechies.com> wrote:

3. It might be useful to make multiline `"` strings trim trailing whitespace and comments like Perl's `/x` regex modifier does.

If you have modifier characters already, it is easy to build a small zoo full of these useful beasts.

Modifiers are definitely a workable alternative, and can be quite flexible, particularly if a future macro system can let you create new modifiers.

Right. I consider modifiers to be highly precedented in other languages, and therefore proven to work. If we go this way, I greatly prefer prefix to postfix modifiers.

* Alternative delimiters: If a string literal starts with three, or five, or seven, or etc. quotes, that is the delimiter, and fewer quotes than that in a row are simply literal quote marks. Four, six, etc. quotes is a quote mark abutting the end of the literal.

  let xml: String = """<?xml version="1.0"?>
        """<catalog>
        """\t<book id="bk101" empty="">
        """\t\t<author>\(author)</author>
        """\t</book>
        """</catalog>"""

You can't use this syntax to express an empty string, or a string consisting entirely of quote marks, but `""` handles empty strings adequately, and escaping can help with quote marks. (An alternative would be to remove the abutting rule and permit `""""""` to mean "empty string", but abutting quotes seem more useful than long-delimiter empty strings.)

I agree that there is a need to support alternative delimiters, but subjectively, I find this to be pretty ugly. It is also a really unfortunate degenerate case for “I just want a large blob of XML” because you’d end up using “"” almost all the time, and you have to use it on every line.

On the other hand, the `"""` does form a much larger, more obvious continuation indicator. It is *extremely* obvious that the above line is not Swift code, but something else embedded in it. It's also extremely obvious what its extent is: when you stop seeing `"""`, you're back to normal Swift code.

Right, but it is also heavy weight and ugly. In your previous email you said about the single quote approach: "The quotation marks on the left end up forming a column that marks the lines as special”, so I don’t see a need for a triple quote syntax to solve this specific problem.

I *really* don't like the idea of our only alternatives being "one double-quote mark with backslashing" or "use an entire heredoc". Heredocs have their place, but they are a *very* heavyweight quoting mechanism, and relatively short strings with many double-quotes are pretty common. (Consider, for instance, strings containing unparsed JSON.) I think we need *some* alternative to double-quotes, either single-quotes (with the same semantics, just as an alternative) or this kind of quote-stacking.

I agree that this is a real problem that would be great to solve.

If I step back and look at the string literal space we’re discussing, I feel like there are three options:

1) single and simple multiline strings, using “
2) your triple quote sort of string, specifically tuned to avoid having to escape “ when it occurs once or twice in sequence.
3) heredoc, which is a very general (but also very heavy weight) solution to quoting problems.

I’m trying to eliminate the middle one, so we only have to have "two things”. Here are some alternative ways to solve the problem, which might have less of an impact on the language:

A) Introduce single quoted string literals to avoid double quote problems specifically, e.g.: ‘look “here” I say!’. This is another form of #2 which is less ugly. It also doesn’t help you if you have both “ and ‘ in your string.

B) Introduce a modifier character that requires a more complex closing sequence to close off the string, see C++ raw string literals for prior art on this approach. Perhaps something like:

   Rxxx”look “ here “ I can use quotes “xxx

That said, I still prefer C) "ignore this issue for now”. In other words, I wouldn’t want to block progress on improving the string literal situation overall on this issue, because anything we do here is an further extension to a proposal that doesn’t solve this problem.

For cases like this, I think it would be reasonable to have a “heredoc” like scheme, which does not allow leading indentation, and does work with all the same modifier characters above. I do not have a preference on a particular syntax, and haven’t given it any thought, but this would allow you to do things like:

  let str = <<EOF
<?xml version="1.0"?>
<catalog>
\t<book id="bk101" empty="">
\t\t<author>\(author)</author>
\t</book>
</catalog>
EOF

for example. You could then turn off escaping and other knobs using the modifier character (somehow, it would have to be incorporated into the syntax of course).

There are two questions and a suggestion I have whenever heredoc syntax comes up.

Q1: Does the heredoc begin immediately, at the next line, or at the next valid place for a statement to start? Heredocs traditionally take the second approach.

Q2: Do you permit heredocs to stack—that is, for a single line to specify multiple heredocs?

S: During the Perl 6 redesign, they decided to use the delimiter's indentation to determine the base indentation for the heredoc:

  func x() -> String {
    return <<EOF
    <?xml version="1.0"?>
    <catalog>
    \t<book id="bk101" empty="">
    \t\t<author>\(author)</author>
    \t</book>
    </catalog>
    EOF
  }

Does that seem like a good approach?

I think that either approach could work, that you have a lot more experience on these topics than I do, and I would expect a vigorous community debate about these topics. :-)

That said, if you look at what we’re discussing:

1. “Continuation" string literals, to allow a multi-line string literal. You and I appear to completely agree about this.
2. Heredoc: You and I seem to agree that they are a good “fully general” solution to have, but there are the details you outline above to iron out.
3. Modifier characters: I’m in favor, but I don’t know where you stand. There is also still much to iron out here (such as the specific characters).
4. A way to avoid having to escape “ in a non-heredoc literal. I’m still unconvinced, and think that any solution to this problem will be orthogonal to the problems solved by 1-3 (and therefore can be added after getting experience with the other parts).

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. After that, we can discuss heredoc and modifiers (if you think they’re a good solution) on their own threads. If those turn out to be uncontroversial, then perhaps they can get in too.

On the heredoc aspects specifically, unless others chime in with strong opinions about the topics you brought up, I’d suggest that you craft a proposal for adding them with your preferred solution to these. You can mention the other answers (along with their tradeoffs and rationale for why you picked whatever you think is right) in the proposal, and we can help the community hash it out.

What do you think?

-Chris

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

+1 from me. This looks like a good compromise and the analogy to English
is good (though maybe less intuitive for non-native speakers).

I've seen objections that it would require significant work to "just"
paste in, say, a large XML file as a literal, and go back adding quotes
on every line. My reaction was that this is comparatively rare and
perhaps even should not be made overly easy :-).

On the other hand, Xcode (for one) already has a "paste and preserve
formatting" command. This could be extended to work as "paste as
multi-line string literal" under appropriate conditions, inserting
quotes after newlines, etc.

···

On 4/27/16 05:52, Brent Royal-Gordon via swift-evolution wrote:

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#proposed-solution&gt;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>"
(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 <punctuation - Why does the multi-paragraph quotation rule exist? - English Language & Usage Stack Exchange

--
Rainer Brockerhoff <rainer@brockerhoff.net>
Belo Horizonte, Brazil
"In the affairs of others even fools are wise
In their own business even sages err."

It is effectively an “inline heredoc style” syntax. The point of having it (which I’m not strongly arguing for) is only so that you can use it inline in an expression without breaking the line.

-Chris

···

On Apr 26, 2016, at 6:53 PM, Uli Kusterer via swift-evolution <swift-evolution@swift.org> wrote:

On 26 Apr 2016, at 08:04, Chris Lattner via swift-evolution <swift-evolution@swift.org> wrote:

B) Introduce a modifier character that requires a more complex closing sequence to close off the string, see C++ raw string literals for prior art on this approach. Perhaps something like:

   Rxxx”look “ here “ I can use quotes “xxx

Can you clarify how this is different from heredoc? Because really, whether I write <<DELIMITER
stuff
DELIMITER

or RDELIMITER" stuff "DELIMITER

doesn't seem to make much of a difference.

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.

Awesome. Some specific suggestions below, but feel free to iterate in a pull request if you prefer that.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#introduction&gt;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. <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160418/015500.html&gt;I would suggest - right up front - pointing out that “heredoc” style syntaxes are another potential solution to this problem, but that they are heavier weight (and other tradeoffs). This proposal doesn’t attempt to address there heredoc usecase, but it also doesn’t preclude adding it. It is also mentioning up front that this is part of multi-part proposal to make string literals nicer, and point to the “possible future directions” section at the end.
<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#draft-notes&gt;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.

White space seems “implementable”, but I’m not sure that it is good. Visually, it would break up the string literal and make it less obviously a unit.

Comments on the same line as a string chunk should *not* be split out IMO, in:

   let s = “fooo // hello world
              “ nice to know you”

the “hello world” text should be included in the literal. I suppose it would be possible to allow comments on whitespace lines, but I don’t see a reason to do that. I’d suggest starting simple, since that could always be added down the road if there was great demand.

This draft also specifies diagnostics which should be included. Feedback on whether these are good choices would be welcome.

I’d just say that these are suggested diagnostics that can be word smithed later.

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 don’t see a reason to do that. Why would this be helpful?

Benefits of continuation quotes

It would be simpler to not require continuation quotes,

I’d suggest being explicit here:

"It would be simpler to not require continuation quotes at the start of subsequent lines, "

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.)

As I mentioned above, I’d suggest keeping the proposal minimal - that makes it more likely to be accepted since you’re removing something that the discussion could rathole on.

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.

I would add a “Potential Future Directions” section here, mention modifier characters, here doc, etc. That will help explain how this proposal fits into your broader plan, and address the question of “ok, your XML example looks a little better, but what’s with all the escaping?!??” :-)

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.

Just a writing observation, but by bulleting the advantages (and not bulleting the disadvantages) you’re making it look visually like the advantages are stronger or more important than the disadvantages.

<https://gist.github.com/brentdax/c580bae68990b160645c030b2d0d1a8f#use-a-different-delimiter-for-multiline-strings&gt;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.

Personally, I think that “”” could be the compelling heredoc designator we will also need. :-) It would certainly fit elegantly with modifier characters, the same way that “” does.

-Chris

···

On Apr 27, 2016, at 1:52 AM, Brent Royal-Gordon <brent@architechies.com> wrote: