I want to add AST dump functionality but not sure what's the most meaningful way to do it. On the one hand, the simplest as-is serialization from what we have is a reflection of the parser. On the other hand, it's complicated and not unified (e.g. Defs
is a SoA but it's not important for AST dump).
I'm leaning towards creating a separate crate but want to discuss the problem first.
like dump to disk?
a separate crate sounds smart, that way we don't spend any time building it or its unique dependencies when we don't need it
like dump to disk?
yeah, for different purposes. the nearest is ast visualization. the furthest is roc code generation from ast externally (e.g. for lang-to-roc transformers. roc preprocessors? :death: )
Hi @Kiryl Dziamura , I'm also interested in this for the purpose of refactoring tools. I have some local experiments but nothing I'm particularly happy with. If you have any demos or insights feel free to loop me in maybe I can help.
Hey @Ray Myers ! Unfortunately, have nothing to show yet, and I have a hectic schedule these days :disappointed:
Feel free to create a PR!
Oh cool! Are you thinking some kind of textual / human-readable format? Will it need to be parsable back into the exact same types - or just visualized in some separate process?
BTW I've been thinking broadly in the same area, but from the angle of serializing the AST for the purpose of sharing it with "plugins" written in Roc, that would take the AST, do some modification, and send it back for formatting / saving to the editor. (e.g. things like writing your own auto-upgrade scripts to migrate from one version of a library to another / etc)
Maybe these could be the same thing?
On second try I had some progress, I was able to convert this code to S-Expressions using the Expr data structure returned by can_expr_with
, which is a canonicalized AST. This is probably too lossy for a refactoring tool, we can talk about what the different needs are. I'll try to get this into a draft PR.
birds = 3
iguanas = 2
total = addAndStringify birds iguanas
addAndStringify = \num1, num2 ->
Num.toStr (num1 + num2)
"There are $(total) animals."
(manually indented)
(LetNonRec ("Test.birds" (Num 3))
(LetNonRec ("Test.iguanas" (Num 2))
(LetNonRec ("Test.addAndStringify"
(Closure ("Test.IdentId(4)" "Test.IdentId(5)") (Call (Var "Num.toStr") (Call (Var "Num.add") (Var "Test.IdentId(4)") (Var "Test.IdentId(5)")))))
(LetNonRec ("Test.total" (Call (Var "Test.addAndStringify") (Var "Test.birds") (Var "Test.iguanas")))
(Call (Var "Str.concat")
(Str "There are ")
(Call (Var "Str.concat") (Var "Test.total") (Str " animals.")))))))
https://gist.github.com/raymyers/72d82720d20848d99dd7350b4d29a6a1
Curious what your goals are for using the canonicalized ast? I agree that may be hard to get to work properly for a refactoring tool.
Joshua Warner said:
Curious what your goals are for using the canonicalized ast? I agree that may be hard to get to work properly for a refactoring tool.
It was for an interpreter. Not sure how necessary it is though, those steps might not be hard to re-implement.
Ahh that makes sense.
Last updated: Jul 26 2025 at 12:14 UTC