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 ->
""""""
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?
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?
yes. This transformation is "correct" in that the value does not change
but I think we should special-case the multiline strings to preserve a trailing newline in the source
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
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?
straight-up PR is fine
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