Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Elixir Quoting and AST

notebooks/tutorial/02_ast.livemd

Elixir Quoting and AST

The Elixir AST

It is straightforward to generate an AST from Elixir code:

quote do: x = 2 + 4

Also it is possible to generate AST from string:

{:ok, ast} = "x = 2 + 4" |> Code.string_to_quoted()
ast

A lot of Elixir coding is about reaching into large data structures, bringing a piece out to your function and then reassembling the structure. Later in this tutorial, we’ll examine libraries that streamline this process.

It is possible to generate a string from an AST:

{:ok, ast} = "x = 2 + 4" |> Code.string_to_quoted()
Macro.to_string(ast)

By changing the AST, it’s possible to refactor the code:

{:=, [line: 1], [{:x, [line: 1], nil}, {:*, [line: 1], [2, 4]}]}
|> Macro.to_string()

ASTs and Comments

For refactoring, a core problem with traditional AST generation is that comments are not preserved:

"""
# my important comment
x = 2 + 4
"""
|> Code.string_to_quoted()
|> elem(1)
|> Macro.to_string()

We cannot have a refactoring library that strips out comments!!

Introducing Sourceror

A new library Sourceror solves the comment-stripping problem. Let’s install it:

Mix.install([{:sourceror, "~> 0.5"}])

Now let’s use a Sourceror function to generate an AST that preserves comments:

require Sourceror

"""
# my important comment
x = 2 + 4
"""
|> Sourceror.parse_string!()

The AST generated by Sourceror has more detail than the one generated by Code.string_to_quoted()!

Using Sourceror, we can go full roundtrip, from code to AST and back again to code:

require Sourceror

"""
# my important comment
x = 2 + 4
"""
|> Sourceror.parse_string!()
|> Sourceror.to_string()

In the next tutorial, we’ll look at how to use Sourceror to refactor your Elixir code.