[swift-evolution] multi-line string literals.

Dave Abrahams dabrahams at apple.com
Tue Apr 26 16:55:33 CDT 2016


on Sun Apr 24 2016, John Holdsworth <swift-evolution at 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 at apple.com> wrote:
>
>         On Apr 23, 2016, at 2:08 PM, Brent Royal-Gordon via swift-evolution
>         <swift-evolution at 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 at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 
Dave



More information about the swift-evolution mailing list