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

Adrian Zubarev adrian.zubarev at devandartist.com
Sun Apr 23 09:39:07 CDT 2017


Yep I really did pitched this instead of a triple quoted multi-line literal string.

let string =   
    "Hello   \ // Three trailing space characters
    "Swift\
    "   4.0"   // Three leading space characters
      
print(string) // prints: "Hello___Swift___4.0" where _ is a space character
Ignore the comments above so we can focus on an easy design for both single and triple quoted literals.

The idea here was to fix the problem *continuation quotes* had and allow trailing precision. Now that we established a much simpler design for multi-line string literals, this can be reused in a much consistent way as a hard wrapping feature for both literals, where the backslash disables the new line injection in triple quoted literals.



-- 
Adrian Zubarev
Sent with Airmail

Am 23. April 2017 um 16:30:35, Adrian Zubarev (adrian.zubarev at devandartist.com) schrieb:

I’ve never thought about allowing hard wrapping from single quoted string literals until it come up during the latest discussion.

At first glance I don’t have anything against it. I wouldn’t put comments into the mix for now, to keep things simple. (I’ve already asked about comments, but the community rejected the idea _for now_.)

What was the exact use case for hard wrapping for the single quoted literals again? (Again I’m not against it.) Actually I believe I pitched a very similar design in the discussion thread (not during the review).



-- 
Adrian Zubarev
Sent with Airmail

Am 23. April 2017 um 13:14:35, Pyry Jahkola via swift-evolution (swift-evolution at swift.org) schrieb:

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.
_______________________________________________
swift-evolution mailing list
swift-evolution at swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170423/37fef0bf/attachment.html>


More information about the swift-evolution mailing list