[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