Stream: beginners

Topic: Multiline strings formater bug


view this post on Zulip Arya Elfren (Aug 18 2022 at 10:03):

I don't know if this is known? What should I do about is and how should I do this properly?

$ roc format . panicked because it changed the ast after formatting.

renderTree = \node ->
    when node is
        Data load ->
            """
            \(load.text)
            """
        Link load ->
            """
            """
        Tag load ->
            """
            """

Became

renderTree = \node ->
    when node is
        Data load ->
            """\(load.text)"""

        Link load ->
            """"""

        Tag load ->
            """"""

view this post on Zulip Arya Elfren (Aug 18 2022 at 10:06):

Also, should this be a panic? If I do roc format . I want to format a bunch of files, does failing on one mean I can't bulk format the others? so I have to remove the failing files and then run it before putting them back?

view this post on Zulip Qqwy / Marten (Aug 18 2022 at 13:12):

Seems like it made a multiline string into a one-line string while still using the multiline string syntax. Is that even correct Roc syntax?

view this post on Zulip Folkert de Vries (Aug 18 2022 at 13:15):

yes. This transformation is "correct" in that the value does not change

view this post on Zulip Folkert de Vries (Aug 18 2022 at 13:16):

but I think we should special-case the multiline strings to preserve a trailing newline in the source

view this post on Zulip Arya Elfren (Aug 18 2022 at 14:14):

Another one:

renderTree = \node ->
    when node is
        Data load ->
            """
            \(load.text)
            text!
            """
        Link load ->
            """
            Link!
            Link!
            """
        Tag load ->
            """
            Tag!
            Tag!
            """

Became

renderTree = \node ->
    when node is
        Data load ->
            """\(load.text)
text!"""

        Link load ->
            """Link!
Link!"""

        Tag load ->
            """Tag!
Tag!"""

Which is then Formatted code is invalid

view this post on Zulip Ralf Engbers (Aug 23 2022 at 11:02):

Folkert de Vries said:

but I think we should special-case the multiline strings to preserve a trailing newline in the source

I was working at #3793 and this relates to basically the same part of the code. So I played around a bit with the code and I think I have a fix for this, assuming we really want to always format multi-line strings on multiple lines. Should I first create an issue for this bug and then make a PR, or is it fine to go straight to the PR and mentioning this topic?

view this post on Zulip Folkert de Vries (Aug 23 2022 at 11:16):

straight-up PR is fine

view this post on Zulip Ralf Engbers (Aug 23 2022 at 11:40):

PR is ready.

view this post on Zulip Ralf Engbers (Aug 23 2022 at 15:25):

In the PR, @Ayaz Hafiz and I had a short discussion about how multi-line strings are parsed into a Block literal. A Block contains a list of lists of StrSegments, so I would expect each sublist to represent a line, with each line consisting of segments. But no matter what multi-line string I pass, I only get flat list inside another list.

For example

"""
Line 1
Line 2
Line 3
"""

is parsed as

Block([[Plaintext("Line 1\n"), Plaintext("Line 2\n"), Plaintext("Line 3")]])

instead of

Block([[ Plaintext("Line 1") ], [ Plaintext("Line 2") ], [ Plaintext("Line 3") ]])

This is consistent no matter if the string contains only Plaintext or Unicode or Interpolated string segments.

Can anyone (@Richard Feldman?) shed some light on whether there is a reason for this, and why the Block contains a nested list, but only ever has one outer list?


Last updated: Jul 05 2025 at 12:14 UTC