[swift-evolution] [Review] SE-0168: Multi-Line String Literals
Tony Allevato
tony.allevato at gmail.com
Wed Apr 12 07:59:09 CDT 2017
I also would oppose comments inside multi-line strings because one place I
imagine using it is in Swift code generation and I also want to generate
comments, and it seems pointless to have to escape those.
Let's not over-engineer this and end up with feature creep. A simple
multi-line string that takes its contents more or less verbatim (with the
exception of necessary escapes, interpolation, and dedenting) is fine.
On Wed, Apr 12, 2017 at 5:50 AM Xiaodi Wu via swift-evolution <
swift-evolution at swift.org> wrote:
> Right, I think it might be too much.
>
> Consider that the multi-line literal could be code with comments in it,
> but that you could also escape and embed an actual multi-line comment with
> \ /* */ that isn't part of the multi-line literal code with multi-line
> comments! How confusing!
> On Wed, Apr 12, 2017 at 07:36 Ricardo Parada via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> I don't think I would use that. I don't find the aesthetics pleasant.
> I would rather comment above the string literal.
>
> Would the escape character cause the newline for the line to be ignored
> thereby continuing the string on the next line?
>
>
>
> On Apr 12, 2017, at 6:59 AM, Adrian Zubarev via swift-evolution <
> swift-evolution at swift.org> wrote:
>
> One last pitch, can we allow comments in multi-line strings if the string
> is broken up by a backslash?
>
>
> let myString = """
> text text
> text text text \ // Comment allowed in the current line here, but not in the line above it
> text text text \ /* this type of comment is fine too */
> text text\// notice whitespace can be ignored
> """
>
> You might have some interpolation and want to comment around it.
>
> let foo = """
> bar bar bar
> bar \(x) bar\ // `x` does some magic
> """
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 12. April 2017 um 12:48:57, Adrian Zubarev (
> adrian.zubarev at devandartist.com) schrieb:
>
> Actually I’m fine with such a compromise. Such a model has everything
> we’ve asked for, it’s easy, it has both leading and trailing precision and
> implicit new lines where needed.
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 12. April 2017 um 12:42:17, Vladimir.S via swift-evolution (
> swift-evolution at swift.org) schrieb:
>
> On 12.04.2017 13:16, Thorsten Seitz via swift-evolution wrote:
> >> Am 12.04.2017 um 10:11 schrieb Adrian Zubarev via swift-evolution
> >> <swift-evolution at swift.org <mailto:swift-evolution at swift.org
> <swift-evolution at swift.org>>>:
> >>
> >> Great explanation thank you Brent. I’m convinced about the closing
> delimiter now. =)
> >>
> >>
> -------------------------------------------------------------------------------------
> >>
> >> If I understood correctly what Xiaodi Wu meant in his reply, then we
> could simplify
> >> the whole multi-line string literal and also remove the need of
> disabling the
> >> stripping algorithm.
> >>
> >> We should ban these examples completely:
> >>
> >> |"""Hello·world!"""|
> >>
> >
> > Being able to use ""“ for single line strings containing lots of " is
> useful in
> > itself and explained in the motivational section of the proposal:
> > "Tripled string literals can also do double duty as a syntax for
> handling short
> > string literals with many internal quotation marks“
> >
> > -Thorsten
>
> Yes, I also think the single line string can be very useful and we should
> not
> disallow it.
>
> But I agree that we should disallow multi-line cases when we have text on
> the same
> line with leading or trailing """ because this complicates the mental
> modal and adds
> confusion points.
>
> I.e. I suggest to allow only two forms:
> 1. Single line: """this is "just" text""" (no line end will be inserted)
> 2. Multiline, where leading and trailing """ has no text after/before them
> and *all*
> the text is in lines *between* triple quotes:
> """
> first line
> second line
> """
>
> One can use backslash at the line end to emulate all other needed cases.
> Like:
>
> """
> first line \
> second line\
> """
>
> will produce "first line second line"
>
> >
> >> |"""Hello↵ world!""" |
> >> |"""Hello↵ world!↵ """ |
> >> |"""↵ Hello↵ world!""" |
> >>
> >> Instead an empty multi-line string literal would look like this:
> >>
> >> |"""↵ """ |
> >>
> >> To fix the above example you’d need to write it like this:
> >>
> >> |"""↵ Hello·world!\↵ """ |
> >> |"""↵ Hello↵ world!\↵ """ |
> >>
> >> * Each line in between the delimiters would add implicit new lines if
> not
> >> disabled by a backslash.
> >> * The trailing precision is also handled by the backslash.
> >> * The indent is handled by the closing delimiter.
> >> * It’s easier to learn/teach.
> >> * It’s easier to read, because most of the time the line where the
> starting
> >> delimiter is, is filled with some other code.
> >>
> >> |let myString = """↵ ⇥ ⇥ Hello↵ ⇥ ⇥ world!\↵ ⇥ ⇥ """ |
> >>
> >> Now that would be a true multi-line string literal which needs at least
> two lines
> >> of code. If you’d need a single line literal,|""|is the obvious pick.
> >>
> >>
> >>
> >>
> >> --
> >> Adrian Zubarev
> >> Sent with Airmail
> >>
> >> Am 12. April 2017 um 02:32:33, Brent Royal-Gordon (
> brent at architechies.com
> >> <mailto:brent at architechies.com <brent at architechies.com>>) schrieb:
> >>
> >>>
> >>>> On Apr 11, 2017, at 8:08 AM, Adrian Zubarev via swift-evolution
> >>>> <swift-evolution at swift.org <mailto:swift-evolution at swift.org
> <swift-evolution at swift.org>>> wrote:
> >>>>
> >>>> That’s also the example that kept me thinking for a while.
> >>>>
> >>>>
> -------------------------------------------------------------------------------------
> >>>>
> >>>> Overall the proposal is a great compromise to some issues I had with
> the first
> >>>> version. However I have a few more questions:
> >>>>
> >>>> * Why can’t we make it consistent and let the compiler add a new line
> after the
> >>>> starting delimiter.
> >>>>
> >>>> | let string = """↵ Swift↵ """ // result ↵Swift↵ |
> >>>>
> >>>> If one would would the behavior from the proposal it’s really easy to
> add a
> >>>> backslash after the starting delimiter.
> >>>>
> >>>> | let string = """\↵ Swift\↵ """ // result Swift |
> >>>>
> >>>> This would be consistent and less confusing to learn.
> >>>>
> >>> That would mean that code like this:
> >>>
> >>> print("""
> >>> A whole bunch of
> >>> multiline text
> >>> """)
> >>> print("""
> >>> A whole bunch more
> >>> multiline text
> >>> """)
> >>>
> >>> Will print (with - to indicate blank lines):
> >>>
> >>> -
> >>> A whole bunch of
> >>> multiline text
> >>> -
> >>> -
> >>> A whole bunch more
> >>> multiline text
> >>> -
> >>>
> >>> This is, to a first approximation, never what you actually want the
> computer to do.
> >>>>
> >>>> * Can’t we make the indent algorithm work like this instead?
> >>>>
> >>>> |let string = """\↵ ····<tag>↵ ······content text↵ ····</tag>""" //
> Indent starts
> >>>> with the first non space character // result <tag>↵ ··content text↵
> </tag> |
> >>>>
> >>>> The line where the closing delimiter is trims all space chapters and
> the indent
> >>>> for the whole multi-line string is starting at the point where the
> first
> >>>> non-space chapters is in that line.
> >>>>
> >>> We could; I discuss that briefly in the very last section, on
> alternatives to the
> >>> indentation stripping we specify:
> >>>
> >>> • Stripping indentation to match the depth of the least indented line:
> Instead of
> >>> removing indentation to match the end delimiter, you remove
> indentation to match
> >>> the least indented line of the string itself. The issue here is that,
> if all lines
> >>> in a string should be indented, you can't use indentation stripping.
> Ruby 2.3 does
> >>> this with its heredocs, and Python's dedent function also implements
> this behavior.
> >>>
> >>> That doesn't quite capture the entire breadth of the problem with this
> algorithm,
> >>> though. What you'd like to do is say, "all of these lines are indented
> four
> >>> columns, so we should remove four columns of indentation from each
> line". But you
> >>> don't have columns; you have tabs and spaces, and they're incomparable
> because the
> >>> compiler can't know what tab stops you set. So we'd end up calculating
> a common
> >>> prefix of whitespace for all lines and removing that. But that means,
> when someone
> >>> mixes tabs and spaces accidentally, you end up stripping an amount of
> indentation
> >>> that is unrelated to anything visible in your code. We could perhaps
> emit a
> >>> warning in some suspicious circumstances (like "every line has
> whitespace just
> >>> past the end of indentation, but some use tabs and others use
> spaces"), but if we
> >>> do, we can't know which one is supposed to be correct. With the
> proposed design,
> >>> we know what's correct—the last line—and any deviation from it can be
> flagged *at
> >>> the particular line which doesn't match our expectation*.
> >>>
> >>> Even without the tabs and spaces issue, consider the case where you
> accidentally
> >>> don't indent a line far enough. With your algorithm, that's
> indistinguishable from
> >>> wanting the other lines to be indented more than that one, so we
> generate a result
> >>> you don't want and we don't (can't!) emit a warning to point out the
> mistake. With
> >>> the proposed algorithm, we can notice there's an error and point to
> the line at fault.
> >>>
> >>> Having the closing delimiter always be on its own line and using it to
> decide how
> >>> much whitespace to strip is better because it gives the compiler a
> firm baseline
> >>> to work from. That means it can tell you what's wrong and where,
> instead of doing
> >>> the dumb computer thing and computing a result that's technically
> correct but useless.
> >>>>
> >>>> PS: If we’d get this feature in Swift, it would be nice if Xcode and
> other IDEs
> >>>> which supports Swift could show space characters that are inside a
> string literal
> >>>> (not other space character <- which is already supported), so it
> would be easier
> >>>> to tell what’s part of the string and what is not.
> >>>>
> >>> That would be very nice indeed. The prototype's tokenizer simply
> concatenates
> >>> together and computes the string literal's contents after whitespace
> stripping,
> >>> but in principle, I think it could probably preserve enough
> information to tell
> >>> SourceKit where the indentation ends and the literal content begins.
> (The
> >>> prototype is John's department, though, not mine.) Xcode would then
> have to do
> >>> something with that information, though, and swift-evolution can't
> make the Xcode
> >>> team do so. But I'd love to see a faint reddish background behind
> tripled string
> >>> literal content or a vertical line at the indentation boundary.
> >>>
> >>> In the meantime, this design *does* provide an unambiguous indicator
> of how much
> >>> whitespace will be trimmed: however much is to the left of the closing
> delimiter.
> >>> You just have to imagine the line extending upwards from there. I
> think that's an
> >>> important thing to have.
> >>>
> >>> --
> >>> Brent Royal-Gordon
> >>> Architechies
> >>>
> >>
> >> _______________________________________________
> >> swift-evolution mailing list
> >> swift-evolution at swift.org <mailto:swift-evolution at swift.org
> <swift-evolution at swift.org>>
> >> https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> >
> >
> > _______________________________________________
> > swift-evolution mailing list
> > swift-evolution at swift.org
> > https://lists.swift.org/mailman/listinfo/swift-evolution
> >
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> 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/20170412/675cecad/attachment.html>
More information about the swift-evolution
mailing list