multi-line string literals.


(Paweł Wojtkowiak) #1

I think that there's nothing wrong with two "tools" for the same task in this case. Multiline strings look better in the code and are easier to read and can serve many purposes. By reading different texts from swift dev team I feel like this is something the language was designed with in mind. They're also easier to type and it needn't neccessarily be a string presented to the user.

Lets say I want a simple json literal for testing purposes - reading from a file takes much more effort comparing to inserting it directly in the code. Taking out every new line character makes it hard to read, and inserting quotes and pluses every line both needs extra effort and also decreases readability. Adding it as a multiline string would make a perfect solution for this to me.

There are so many other cases where this could be useful too. I like how python has the """ and I think this would be a good direction to go, although this is true that python uses indentation in a different way, so I think backslashes at the end of each line would be a nice idea - this is still better than concatenating each line with " and +, and would have the least readability impact. Also, it could be treated as a literal and be evaluated at compile time.

···

I just checked with -O and without and was surprised to find that `let x = "abc" + "def" + "ghi"` wasn't collapsed into a single string literal "abcdefghi" in the generated assembly code. Maybe it's more difficult than it is in some other languages because of operator overloads and different kinds of text literals (strings, extended grapheme clusters, Unicode scalars)?

Regardless of the reasons, a separate syntax isn't the right way to achieve this optimization―the compiler should just do it automatically. Like Ricardo, "multi-line string literals" should be reserved for string literals that include the newline characters that are used to break them up in source. The idea of supporting something like the Python example above just provides two ways to do the same thing, which I don't think we really need.

On Mon, Apr 3, 2017 at 8:18 AM Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

I would think that the concatenation would get resolved at runtime, unless the compiler gets smart about it. But either way I do not see it as a problem. The reason is that I don't remember ever worrying about the performance of concatenating a few lines of text. :slight_smile:

Thanks

On Apr 3, 2017, at 11:13 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

To me a literal a single entity which is solved at compile time. The concatenation is however resolved at runtime if I’m not mistaken here (it might be optimized at compile time but I still would expect a function executed a couple of times at runtime).

Please correct me if I’m wrong here.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 17:10:36, Ricardo Parada (rparada@mac.com) schrieb:

How is that better than this?

template = "This is the first line.\n" +
            "This is the second line.\n" +
            "This is the third line."

On Apr 3, 2017, at 10:42 AM, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

It look prettier without the \n

It's not laziness.

I want my code to look pretty.

On Apr 3, 2017, at 10:40 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

What I was trying to say is that by automatically adding a new line character does not provide any benefit except of being lazy to type \n.

// In your model this would be equivalent
let s1 = "\n\n\n"
let s2 = """
    " // However in my model this is an empty string and should be banned
    "
    """ // That's also an empty string, but it that case it indicates the end of the multi lined string
I dislike the tradeoff of precision for laziness.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 16:29:44, Ricardo Parada (rparada@mac.com) schrieb:

By the way, the multi-line string should allow \n\n, or as many as you may want to throw in there. I don't see a problem with that.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Ricardo Parada) #2

Why would backslashes at the end of each line be a nice idea?

···

Sent from my iPhone

On Apr 3, 2017, at 2:44 PM, Paweł Wojtkowiak via swift-evolution <swift-evolution@swift.org> wrote:

I think that there's nothing wrong with two "tools" for the same task in this case. Multiline strings look better in the code and are easier to read and can serve many purposes. By reading different texts from swift dev team I feel like this is something the language was designed with in mind. They're also easier to type and it needn't neccessarily be a string presented to the user.

Lets say I want a simple json literal for testing purposes - reading from a file takes much more effort comparing to inserting it directly in the code. Taking out every new line character makes it hard to read, and inserting quotes and pluses every line both needs extra effort and also decreases readability. Adding it as a multiline string would make a perfect solution for this to me.

There are so many other cases where this could be useful too. I like how python has the """ and I think this would be a good direction to go, although this is true that python uses indentation in a different way, so I think backslashes at the end of each line would be a nice idea - this is still better than concatenating each line with " and +, and would have the least readability impact. Also, it could be treated as a literal and be evaluated at compile time.

I just checked with -O and without and was surprised to find that `let x = "abc" + "def" + "ghi"` wasn't collapsed into a single string literal "abcdefghi" in the generated assembly code. Maybe it's more difficult than it is in some other languages because of operator overloads and different kinds of text literals (strings, extended grapheme clusters, Unicode scalars)?

Regardless of the reasons, a separate syntax isn't the right way to achieve this optimization—the compiler should just do it automatically. Like Ricardo, "multi-line string literals" should be reserved for string literals that include the newline characters that are used to break them up in source. The idea of supporting something like the Python example above just provides two ways to do the same thing, which I don't think we really need.

On Mon, Apr 3, 2017 at 8:18 AM Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

I would think that the concatenation would get resolved at runtime, unless the compiler gets smart about it. But either way I do not see it as a problem. The reason is that I don't remember ever worrying about the performance of concatenating a few lines of text. :slight_smile:

Thanks

On Apr 3, 2017, at 11:13 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

To me a literal a single entity which is solved at compile time. The concatenation is however resolved at runtime if I’m not mistaken here (it might be optimized at compile time but I still would expect a function executed a couple of times at runtime).

Please correct me if I’m wrong here.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 17:10:36, Ricardo Parada (rparada@mac.com) schrieb:

How is that better than this?

template = "This is the first line.\n" +
            "This is the second line.\n" +
            "This is the third line."

On Apr 3, 2017, at 10:42 AM, Ricardo Parada via swift-evolution <swift-evolution@swift.org> wrote:

It look prettier without the \n

It's not laziness.

I want my code to look pretty.

On Apr 3, 2017, at 10:40 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

What I was trying to say is that by automatically adding a new line character does not provide any benefit except of being lazy to type \n.

// In your model this would be equivalent
let s1 = "\n\n\n"
let s2 = """
    " // However in my model this is an empty string and should be banned
    "
    """ // That's also an empty string, but it that case it indicates the end of the multi lined string
I dislike the tradeoff of precision for laziness.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 16:29:44, Ricardo Parada (rparada@mac.com) schrieb:

By the way, the multi-line string should allow \n\n, or as many as you may want to throw in there. I don't see a problem with that.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Tony Allevato) #3

Hi Pavel, you've misunderstood what I was saying. :slight_smile:

I was focused specifically on the example Adrian posted a few messages up,
where he cited wanting something like Python's implicit concatenation when
a string is broken across multiple lines but each segment is still quoted;
as Ricardo pointed out, that's not a significant improvement over adding +
to the end of each line, and it's what I meant when I said doing the same
things two ways.

I'd be much more supportive of *true* multi-line strings or heredocs where
the newlines that are part of the string in the source code are also part
of the string—not just implicit concatenation around line breaks, but
retaining the structure of the string as well. That's not two ways to do
the same thing, since the latter isn't supported yet by Swift. So we're
probably in agreement.

That being said, while I can see the necessity, I'm actually not a fan of
large strings in the middle of source code for many of the reasons cited
already—I think it's a bit of a code smell to embed that much data in the
source, and editors can have difficulty handling it when the syntax
highlighting context changes to drastically. In my ideal world, I'd like a
way for me to import the contents of an external file as a String or a
binary blob so that it still gets brought into the data segment but it's
not a huge chunk of unrelated content in the middle of my logic.

That's a harder sell when you think of the Apple OS use cases because you
can just load data from bundled resources, but it might be more valuable in
server contexts, and if they could support interpolation as well, that
would be a powerful templating mechanism as well.

···

On Mon, Apr 3, 2017 at 11:44 AM Paweł Wojtkowiak <neframair@gmail.com> wrote:

I think that there's nothing wrong with two "tools" for the same task in
this case. Multiline strings look better in the code and are easier to read
and can serve many purposes. By reading different texts from swift dev team
I feel like this is something the language was designed with in mind.
They're also easier to type and it needn't neccessarily be a string
presented to the user.

Lets say I want a simple json literal for testing purposes - reading from
a file takes much more effort comparing to inserting it directly in the
code. Taking out every new line character makes it hard to read, and
inserting quotes and pluses every line both needs extra effort and also
decreases readability. Adding it as a multiline string would make a perfect
solution for this to me.

There are so many other cases where this could be useful too. I like how
python has the """ and I think this would be a good direction to go,
although this is true that python uses indentation in a different way, so I
think backslashes at the end of each line would be a nice idea - this is
still better than concatenating each line with " and +, and would have the
least readability impact. Also, it could be treated as a literal and be
evaluated at compile time.

I just checked with -O and without and was surprised to find that `let x =
"abc" + "def" + "ghi"` wasn't collapsed into a single string literal
"abcdefghi" in the generated assembly code. Maybe it's more difficult than
it is in some other languages because of operator overloads and different
kinds of text literals (strings, extended grapheme clusters, Unicode
scalars)?

Regardless of the reasons, a separate syntax isn't the right way to
achieve this optimization—the compiler should just do it automatically.
Like Ricardo, "multi-line string literals" should be reserved for string
literals that include the newline characters that are used to break them up
in source. The idea of supporting something like the Python example above
just provides two ways to do the same thing, which I don't think we really
need.

On Mon, Apr 3, 2017 at 8:18 AM Ricardo Parada via swift-evolution < > swift-evolution@swift.org> wrote:

I would think that the concatenation would get resolved at runtime, unless
the compiler gets smart about it. But either way I do not see it as a
problem. The reason is that I don't remember ever worrying about the
performance of concatenating a few lines of text. :slight_smile:

Thanks

On Apr 3, 2017, at 11:13 AM, Adrian Zubarev < > adrian.zubarev@devandartist.com> wrote:

To me a literal a single entity which is solved at compile time. The
concatenation is however resolved at runtime if I’m not mistaken here (it
might be optimized at compile time but I still would expect a function
executed a couple of times at runtime).

Please correct me if I’m wrong here.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 17:10:36, Ricardo Parada (rparada@mac.com) schrieb:

How is that better than this?

template = "This is the first line.\n" +
            "This is the second line.\n" +
            "This is the third line."

On Apr 3, 2017, at 10:42 AM, Ricardo Parada via swift-evolution < > swift-evolution@swift.org> wrote:

It look prettier without the \n

It's not laziness.

I want my code to look pretty.

On Apr 3, 2017, at 10:40 AM, Adrian Zubarev < > adrian.zubarev@devandartist.com> wrote:

What I was trying to say is that by automatically adding a new line
character does not provide any benefit except of being lazy to type \n.

// In your model this would be equivalent
let s1 = "\n\n\n"
let s2 = """
    " // However in my model this is an empty string and should be banned
    "
    """ // That's also an empty string, but it that case it indicates the end of the multi lined string

I dislike the tradeoff of precision for laziness.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 16:29:44, Ricardo Parada (rparada@mac.com) schrieb:

By the way, the multi-line string should allow \n\n, or as many as you may
want to throw in there. I don't see a problem with that.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Nick Keets) #4

To me the discussion about precision of multiline strings is missing the
point. The biggest use case of this would be when using swift in a more
script-like fashion. You just paste something, add a
.components(separatedBy: “\n”).map { something() } and you print the result.

If you need precision, localizations, etc, multiline strings don’t have too
much to offer. You could just use plain + with marginal overhead. Or use
resource files.

···

On Mon, Apr 3, 2017 at 11:18 PM, Ricardo Parada via swift-evolution < swift-evolution@swift.org> wrote:

Why would backslashes at the end of each line be a nice idea?

Sent from my iPhone

On Apr 3, 2017, at 2:44 PM, Paweł Wojtkowiak via swift-evolution < > swift-evolution@swift.org> wrote:

I think that there's nothing wrong with two "tools" for the same task in
this case. Multiline strings look better in the code and are easier to read
and can serve many purposes. By reading different texts from swift dev team
I feel like this is something the language was designed with in mind.
They're also easier to type and it needn't neccessarily be a string
presented to the user.

Lets say I want a simple json literal for testing purposes - reading from
a file takes much more effort comparing to inserting it directly in the
code. Taking out every new line character makes it hard to read, and
inserting quotes and pluses every line both needs extra effort and also
decreases readability. Adding it as a multiline string would make a perfect
solution for this to me.

There are so many other cases where this could be useful too. I like how
python has the """ and I think this would be a good direction to go,
although this is true that python uses indentation in a different way, so I
think backslashes at the end of each line would be a nice idea - this is
still better than concatenating each line with " and +, and would have the
least readability impact. Also, it could be treated as a literal and be
evaluated at compile time.

I just checked with -O and without and was surprised to find that `let x =
"abc" + "def" + "ghi"` wasn't collapsed into a single string literal
"abcdefghi" in the generated assembly code. Maybe it's more difficult than
it is in some other languages because of operator overloads and different
kinds of text literals (strings, extended grapheme clusters, Unicode
scalars)?

Regardless of the reasons, a separate syntax isn't the right way to
achieve this optimization—the compiler should just do it automatically.
Like Ricardo, "multi-line string literals" should be reserved for string
literals that include the newline characters that are used to break them up
in source. The idea of supporting something like the Python example above
just provides two ways to do the same thing, which I don't think we really
need.

On Mon, Apr 3, 2017 at 8:18 AM Ricardo Parada via swift-evolution < > swift-evolution@swift.org> wrote:

I would think that the concatenation would get resolved at runtime,
unless the compiler gets smart about it. But either way I do not see it as
a problem. The reason is that I don't remember ever worrying about the
performance of concatenating a few lines of text. :slight_smile:

Thanks

On Apr 3, 2017, at 11:13 AM, Adrian Zubarev <adrian.zubarev@devandartist. >> > wrote:

To me a literal a single entity which is solved at compile time. The
concatenation is however resolved at runtime if I’m not mistaken here (it
might be optimized at compile time but I still would expect a function
executed a couple of times at runtime).

Please correct me if I’m wrong here.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 17:10:36, Ricardo Parada (rparada@mac.com) schrieb:

How is that better than this?

template = "This is the first line.\n" +
            "This is the second line.\n" +
            "This is the third line."

On Apr 3, 2017, at 10:42 AM, Ricardo Parada via swift-evolution < >> swift-evolution@swift.org> wrote:

It look prettier without the \n

It's not laziness.

I want my code to look pretty.

On Apr 3, 2017, at 10:40 AM, Adrian Zubarev <adrian.zubarev@devandartist. >> > wrote:

What I was trying to say is that by automatically adding a new line
character does not provide any benefit except of being lazy to type \n.

// In your model this would be equivalent
let s1 = "\n\n\n"
let s2 = """
    " // However in my model this is an empty string and should be banned
    "
    """ // That's also an empty string, but it that case it indicates the end of the multi lined string

I dislike the tradeoff of precision for laziness.

--
Adrian Zubarev
Sent with Airmail

Am 3. April 2017 um 16:29:44, Ricardo Parada (rparada@mac.com) schrieb:

By the way, the multi-line string should allow \n\n, or as many as you
may want to throw in there. I don't see a problem with that.

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution