losvedir

losvedir

Why do atoms need to be in the same module for String.to_existing_atom/1?

I’ve always used String.to_existing_atom/1 without issue after verifying that the atoms are in the codebase somewhere.

However, I noticed that starting with Elixir 1.14, the docs for the function carry this guideline:

Since Elixir is a compiled language, the atoms defined in a module will only exist after said module is loaded, which typically happens whenever a function in the module is executed. Therefore, it is generally recommended to call String.to_existing_atom/1 only to convert atoms defined within the module making the function call to to_existing_atom/1.

I’m trying to better understand how Elixir is compiled, loaded, and run. I don’t understand the limitation that the atoms need to be in the same module for this to be reliable. I found Issue with loading existing atoms from other modules · Issue #4832 · elixir-lang/elixir · GitHub which was about inconsistent behavior where the atoms weren’t always available, so it seems to be a real problem.

Suppose my app is deployed as a mix release. If the String.to_existing_atom/1 function is looking at runtime for existing atoms, why wouldn’t any atom in the code work? I would expect all the code to have been compiled prior to the release running, so wouldn’t the lookup always work?

Maybe the guideline is around partial compilation in the test environment or something like that?

Or maybe my mental model of an “internal atom database” that gets queried is wrong. Maybe the code compilation essentially inlines a mapping lookup in the code right at the time that it’s compiled?

Most Liked

al2o3cr

al2o3cr

In Erlang’s “interactive mode”, modules aren’t loaded until they are referenced.

So if a function in Foo does a String.to_existing_atom expecting to find an atom defined in Bar, it could fail if nothing else has yet referenced Bar.

IIRC releases run in the other mode (“embedded mode”) so that can’t happen.

gregvaughn

gregvaughn

Note “generally recommended”. Using atoms in the same module is always safe and doesn’t require any deeper knowledge of how the BEAM handles atoms. But it’s not necessary to do that.

If (building on @al2o3cr 's example) Foo requires Bar directly or indirectly, then Bars atoms will be available even in interactive mode. However, that brings in additional concerns about compile time dependencies that were out of scope for the simple recommendation in the docs.

Where Next?

Popular in Questions Top

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
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
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
tduccuong
Hi, is there any work on GUI with Elixir, that is similar to Electron/Javascript? My idea is to bundle Phoenix and BEAM into a single se...
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
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
chewm
Hi guys, nice to meet you to the whole forum, I’m new here, I’m trying to configure visual studio code for elixir, right now the intellis...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> 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

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
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
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement