|
| 1 | +# Feature name |
| 2 | + |
| 3 | +* Proposal: [SE-XXXX](https://github.com/apple/swift-evolution/blob/master/proposals/XXXX-name.md) |
| 4 | +* Author(s): [John Holdsworth](https://github.com/johnno1962), [Brent Royal-Gordon](https://github.com/brentdax), [Tyler Cloutier](https://github.com/TheArtOfEngineering) |
| 5 | +* Status: **[Awaiting review](#rationale)** |
| 6 | +* Review manager: TBD |
| 7 | + |
| 8 | +## Introduction |
| 9 | + |
| 10 | +This proposal introduces multi-line string literals to Swift source code. |
| 11 | +This has been discussed a few times on swift-evolution most recently |
| 12 | +putting forward a number of different syntaxes that could achieve this goal |
| 13 | +each of which has their own use case and constituency for discussion. |
| 14 | + |
| 15 | +[Swift-evolution thread](http://thread.gmane.org/gmane.comp.lang.swift.evolution/904/focus=15133) |
| 16 | + |
| 17 | +## Motivation |
| 18 | + |
| 19 | +Multi-line String literals are a common programming-language feature that is, to date, still missing in |
| 20 | +Swift. Whether generating XML/JSON messages or building usage messages in Swift scripts, providing string |
| 21 | +literals that extend over multiple lines offers a simple way to represent text without having to manually |
| 22 | +break lines using string concatenation. Concatenation is ungainly and may result in slow compilation. |
| 23 | + |
| 24 | +## Proposed solution |
| 25 | + |
| 26 | +After consideration this proposal puts forward a single simple syntax for inclusion: `"""long strings"""`. |
| 27 | +This has the advantage that it is well supported by the syntax highlighters on github and existing editors |
| 28 | +and is a relatively minor change to the Swift Lexer. Interpolation would work as before. |
| 29 | + |
| 30 | +### Long strings |
| 31 | + |
| 32 | +Long strings are strings delimited by `"""triple quotes"""` that can contain newlines and individual `"` |
| 33 | +characters without the need to escape them. |
| 34 | + |
| 35 | + assert( xml == """ |
| 36 | + <?xml version="1.0"?> |
| 37 | + <catalog> |
| 38 | + <book id="bk101" empty=""> |
| 39 | + <author>\(author)</author> |
| 40 | + <title>XML Developer's Guide</title> |
| 41 | + <genre>Computer</genre> |
| 42 | + <price>44.95</price> |
| 43 | + <publish_date>2000-10-01</publish_date> |
| 44 | + <description>An in-depth look at creating applications with XML.</description> |
| 45 | + </book> |
| 46 | + </catalog> |
| 47 | + """ ) |
| 48 | + |
| 49 | +To allow free formatting of the literal an indentation stripping operation is applied whereby |
| 50 | +any whitespace characters in front of the closing delimiter are removed from each of the lines |
| 51 | +in the literal. As part of this process any initial linefeed is also removed. This allows the |
| 52 | +developer to paste literal content directly into the string without modification. Some concern |
| 53 | +has been expressed about could introduce confusion if the prefixing indentation of each line does |
| 54 | +not contain the same whitespace characters, though this can be checked for by a compiler warning. |
| 55 | + |
| 56 | +## Detailed design |
| 57 | + |
| 58 | +These changes are envisaged to be mostly confined to the Swift tokeniser: lib/Parse/Lexer.cpp. |
| 59 | +The new string literals would be presented to the grammar as simply being string literals. |
| 60 | +This has been explored in a PR for a [prototype toolchain](https://github.com/apple/swift/pull/2275) |
| 61 | +and seems to be a robust approach. Other details are explored in the prototype such as |
| 62 | +escaping the newline in literals resulting in it not being included in the final literal. |
| 63 | + |
| 64 | +## Impact on existing code |
| 65 | + |
| 66 | +As this proposal is additive it does not affect existing code. |
| 67 | + |
| 68 | +## Alternatives considered |
| 69 | + |
| 70 | +Two other alternative syntaxes were discussed in the swift-evolution thread. |
| 71 | +It became apparent that each syntax had its own, at times, non-overlapping |
| 72 | +constituency of supporters. |
| 73 | + |
| 74 | +### Continuation quotes |
| 75 | + |
| 76 | +The basic idea of continuation quotes is straightforward. If a quoted string literal is not closed by " |
| 77 | +before the end of the line and the first non-whitespace character on the next line is " it is taken to |
| 78 | +be a continuation of the previous literal. |
| 79 | + |
| 80 | + let xml = "<?xml version=\"1.0\"?> |
| 81 | + "<catalog> |
| 82 | + " <book id=\"bk101\" empty=\"\"> |
| 83 | + " <author>\(author)</author> |
| 84 | + " <title>XML Developer's Guide</title> |
| 85 | + " <genre>Computer</genre> |
| 86 | + " <price>44.95</price> |
| 87 | + " <publish_date>2000-10-01</publish_date> |
| 88 | + " <description>An in-depth look at creating applications with XML.</description> |
| 89 | + " </book> |
| 90 | + "</catalog> |
| 91 | + "" |
| 92 | + |
| 93 | +The advantage of this format is it gives precise control of exactly what is included in the literal. It also |
| 94 | +allows code to be formatted in an aesthetically pleasing manner. Its main disadvantage is that some external |
| 95 | +editors will not be familiar with the format and will be unable to correctly syntax highlight literals. |
| 96 | + |
| 97 | +### Heredoc |
| 98 | + |
| 99 | +Taking a precedent from other languages, a syntax such as the following could be used to introduce |
| 100 | +literals into a codebase. |
| 101 | + |
| 102 | + assert( xml == <<"XML" ) |
| 103 | + <?xml version="1.0"?> |
| 104 | + <catalog> |
| 105 | + <book id="bk101" empty=""> |
| 106 | + <author>\(author)</author> |
| 107 | + <title>XML Developer's Guide</title> |
| 108 | + <genre>Computer</genre> |
| 109 | + <price>44.95</price> |
| 110 | + <publish_date>2000-10-01</publish_date> |
| 111 | + <description>An in-depth look at creating applications with XML.</description> |
| 112 | + </book> |
| 113 | + </catalog> |
| 114 | + XML |
| 115 | + |
| 116 | +The same indentation stripping rules would be applied as for long strings. This syntax has the |
| 117 | +advantage of being able to paste content in directly and the additional advantage that the |
| 118 | +literal is separated from the line of code using it, increasing clarity. Its main disadvantage |
| 119 | +is a more practical one: it is a more major departure for the compiler in that tokens |
| 120 | +in the AST are no longer in source file order. Testing has, however, shown the toolchain |
| 121 | +to be surprisingly robust in dealing with this change once a few assertions were removed. |
| 122 | + |
| 123 | +------------------------------------------------------------------------------- |
| 124 | + |
| 125 | +# Rationale |
| 126 | + |
| 127 | +On [Date], the core team decided to **(TBD)** this proposal. |
| 128 | +When the core team makes a decision regarding this proposal, |
| 129 | +their rationale for the decision will be written here. |
0 commit comments