In Swift 3 the string literal is a simple stream of characters that is enclosed by starting and ending "
delimiters without new lines after and before the delimiters.
// Example #1
"\"Title\"\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum commodo sem, a congue orci porta sit amet.\nDuis facilisis, est et vehicula congue, turpis dui ultricies nunc, ut elementum quam elit nec felis."
This issue makes it very hard to write code that has a fixed line width.
We can solve this issue by introducing an additional form of string literals with an easy way for hard wrapping very long strings. Leading whitespaces are trimmed by the whitespace-prefix calculated from the ending delimiter. Trailing whitespaces also need an explicit annotation, we'll choose the \
character (almost as a shorthand for \("")
, but not entirely - later we'll explain why):
// Example #1.1
"
\"Title\"\n
\n
Lorem ipsum dolor sit amet, consectetur adipiscing elit. \
Integer elementum commodo sem, a congue orci porta sit amet.\n
Duis facilisis, est et vehicula congue, turpis dui \
ultricies nunc, ut elementum quam elit nec felis.
"
Note that blank lines are not allowed and will be an error.
The syntax is simple to learn and the issue with the trailing whitespaces becomes clear to reason about. Now let's enhance that syntax by simplifying the inner content:
Let's come up with a syntax that is able to inject new lines automatically, but still allows us to hard wrap long lines. As a consequence we can also allow blank lines. For now, let's use $
for its delimiters.
// Example #2
$
abc
def
$ == "abc\n\ndef"
In fact we run into a corner here, because if we now inject new lines automatically when an actual new line occurs, how would we be able to hard wrap long lines? Keep in mind that we're still only simplifying the multi-line form for the single quoted syntax from above. This implies that we have to be explicit about the trailing whitespaces. Well that's an interesting hint, because we could reuse the trailing backslash for hard wrapping such a string literal, which also means that we can escape new line injection if desired (this syntax is very similar to other programming languages). This is also the reason why the trailing backslash is not a simple replacement for \("")
!
// Example #3
$
000 \
\"abc\"
000
$ == "000 \"abc\"\n000"
We can adopt the lorem
example from above like this:
// Example #1.2
$
\"Title\"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. \
Integer elementum commodo sem, a congue orci porta sit amet.
Duis facilisis, est et vehicula congue, turpis dui \
ultricies nunc, ut elementum quam elit nec felis.
$
Let's come up with a syntax that is able to have "
character without the need to escape them. For now, let's use #
for its delimiters.
// Example #4
#"abc"# == "\"abc\""
// Example #2.1
#
"abc" \
\n
"def"
# == "\"abc\" \n\"def\""
As for an experiment let's try a different delimiter, which would be similar to the double quoted one from above. We'll choose ""
here.
// Example #4.1
"""abc""" == "\"abc\""
// Example #2.2
""
"abc" \
\n
"def"
"" == "\"abc\" \n\"def\""
This works fine except for one common edge case where the actual string is ""
.
// Example #5
""\"""" == """\""" == "\"\""
// Example #6
""
\""
"" == "\"\""
// Example #6.1
""
"\"
"" == "\"\""
To solve that particular issue we could increase the amount of double quotes once again to """
.
// Example #5.1
"""""""" == "\"\""
// Example #6.2
"""
""
""" == "\"\""
Let's merge the syntaxes from step (2) and step (3) into a single syntax. As for this step we decide to go with the """
delimiter.
// Example #5.2
"""""""" == "\"\""
// Example #6.3
"""
""
""" == "\"\""
// Example #4.2
""""abc"""" == "\"abc\""
// Example #2.3
"""
"abc" \
"def"
""" == "\"abc\" \n\"def\""
// Example #3.1
"""
000 \
"abc"
000
""" == "000 \"abc\"\n000"
// Example #1.3
"""
"Title"
Lorem ipsum dolor sit amet, consectetur adipiscing elit. \
Integer elementum commodo sem, a congue orci porta sit amet.
Duis facilisis, est et vehicula congue, turpis dui \
ultricies nunc, ut elementum quam elit nec felis.
"""
The evolution process jumped directly to step (4). Futhermore, SE-0168 accepted a half baked version of step (4) and ripped apart hard wrapping, ignored trailing whitespaces and the single lined version of the syntax such as """abc"""
.