[swift-evolution] [Accepted] SE-0168: Multi-Line String Literals

Pyry Jahkola pyry.jahkola at iki.fi
Sun Apr 23 06:14:19 CDT 2017


Hmm, I can see that Wux already replied to this question but let me give another more or less obvious answer which I believe has come up in a shape or another already:

Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:

>> No, I am suggesting that whatever design is used for escaped newlines, if at all possible it should be equally apt for "strings" and """strings""" such that it will not require indentation stripping.
> 
> Could you share an example of such a design?

One way to achieve the criteria below for both singly and triply quoted strings would be to borrow the repeated opening quote syntax (from earlier discussions) for singly quoted strings:

    let s1 = "abc\
              "def\n\
              "ghi \
              "xyz"
    assert(s1 == "abcdef\nghi xyz")
    
    let s2 = "abc\
             "def\n\
    /* Leading white space, */ "ghi \
    // as well as comments
    
    // and empty lines in between are
    // insignificant when it comes to singly
    // quoted literals.
        "xyz"
    assert(s2 == s1)
    
    let s3 = """
        abc\
        def
        ghi \
        xyz
        """
    assert(s3 == s1)

The criteria:

> * Permits non-significant hard-wrapping in a string literal.

✅ The string continues from the position of the backslash, with no extra space or line break inserted.

> * Works equally well with single and triple string literals.

✅ In both cases, a trailing `\` has the same meaning. In singly quoted strings, the only way to insert a newline is by quoting (`\n`), as it always was.

> * Preserves code indentation, but does not require single string literals to do indentation stripping.

✅ The indentation is just more explicit with singly quoted string literals.

> * Is not horribly inconvenient.

🤷‍♂️ Depends who you ask, I guess, but I think not horrible. And, after all, the programmer is free to choose between two quoting styles with different trade offs.

* * *

One thing that remains to be defined is whether trailing space is allowed (and ignored) after the backslash or not (and thus an error). I initially thought it's best to make into a compiler error, just like the indenting white space of the triple quoted string literals.

OTOH, we could also allow inline comments after the backslash:

    let whyNot = "this, \
        "that, \ // <- Oxford comma
        "and stuff"
    assert(whyNot == "this, that, and stuff")
    
    let list = """
        - this,
        - that,\n\// comment using "Adrian's \n\"
        - and stuff
        """
    assert(list == "- this,\n- that,\n- and stuff")

[Nit: If comments after the backslash were allowed, we'd need to either require a space after the backslash (e.g. `\ //`), or else accept as string continuation / comment start markers both `\//` (until newline) and `\/*` (until `*/`), as seen in the latter example above.]

I find this design — with or without comments — would naturally allow the programmer to choose between precision (singly quoted) and convenience/legibility (triply quoted). And of course it would allow breaking long string literals to multiple lines in a consistent way, which, for triply quoted strings, is also lighter than just concatenating with `+`.

— Pyry

PS. I also slightly regret that SE-0168 ended up stripping the trailing newline, because multiline strings seem to compose (concatenate) better with a trailing newline there by default. But I understand if the inconvenience of `print(str, terminator: "")` weighed more than the other option.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170423/2215bc4d/attachment.html>


More information about the swift-evolution mailing list