kerryb

kerryb

How do unquote sigils?

I have some AST rewriting code (using Sourceror) that has started failing in Elixir 1.18 – I believe because unquote has become stricter about valid AST, whereas in earlier versions it was only an issue within macros.

The issue is that it’s trying to generate code containing a ~D[...] sigil. It works in Elixir 1.17:

iex(1)> quote do: unquote(~D[2025-01-07])
~D[2025-01-07]

But not in 1.18:

iex(1)> quote do: unquote(~D[2025-01-07])
** (ArgumentError) tried to unquote invalid AST: ~D[2025-01-07]
Did you forget to escape term using Macro.escape/1?
    (elixir 1.18.1) src/elixir_quote.erl:542: :elixir_quote.argument_error/1
    iex:1: (file)

I can use Macro.escape as suggested, but this inserts the date as a raw map instead of a sigil. This works, but doesn’t look great in the generated code:

iex(2)> quote do: unquote(Macro.escape(~D[2025-01-07]))
{:%{}, [],
 [__struct__: Date, calendar: Calendar.ISO, day: 7, month: 1, year: 2025]}

Is there some way to end up with a call to the ~D macro in the generated code, rather than the resulting struct/map?

Marked As Solved

LostKobrakai

LostKobrakai

The quote/unquote has nothing to do with how the final generated code looks like. They’re just means of generating AST/injecting given AST in the resulting AST. You’d need to figure out the correct AST you want to return for sourceror:

iex(1)> quote do: ~D[2024-12-12]
{:sigil_D, [delimiter: "[", context: Elixir, imports: [{2, Kernel}]],
 [{:<<>>, [], ["2024-12-12"]}, []]}

Depending on what input you actually have you can build that AST for the return value.

iex(1)> quote do: unquote(~D[2025-01-07])
~D[2025-01-07]

This here is basically a noop. It does/did nothing.

Where Next?

Popular in Questions Top

yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Other popular topics Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New

We're in Beta

About us Mission Statement