gleam: Elixir external functions don't work when no Elixir modules are present
When generating a new Gleam project:
gleam new exffi
And adding an FFI function to Elixir:
import gleam/io
pub fn main() {
  io.println("Hello from " <> cwd())
}
external fn cwd() -> String = 
  "Elixir.File" "cwd!"
Calling the function results in:
exffi:main().
% ** exception error: undefined function 'Elixir.File':'cwd!'/0
%      in function  exffi:main/0 (build/dev/erlang/exffi/_gleam_artefacts/exffi.erl, line 8)
Elixir files are not being generated in the build directory until there’s an elixir dependency:

Adding a .ex file to the project generates the files and solves this issue.
About this issue
- Original URL
- State: open
- Created a year ago
- Comments: 16 (14 by maintainers)
As all Elixir (stdlib) modules are prefixed with
Elixir(I think I remember that there is a way to define a module without having an Elixir prefix in Elixir, but it is an uncommon hack), thus when we see this:… the
"Elixir.part could be the trigger to run the elixir compiler? Unless I missunderstood.The error is thrown by the BEAM, we have no control over how the virtual machine builds exceptions I’m afraid.
Matching on
Elixir.matches on most cases, but not all. In the unlikely scenario where someone wants to use something from the Elixir compiler and bootstrap modules:This function call fails at runtime without a an empty
.exfile, since it’s a module that only exists in Elixir.Not even a rule with
Elixir.andelixir_would work, since-module(iex).is in Elixir’s source. (To my knowledgeiexis the only exception to the more general rule, but it doesn’t preclude the addition of others).Alternatively, we can consider that the
elixir_andiexmodules are internal, undocumented modules of Elixir’s source code, and therefore not worth supporting explicitly.For situations where the Elixir standard lib is interested in being used, I’m in favor of an empty dependency or TOML flag to enable it.
That would be good, but I’m not sure when we could emit that. We only know for sure that a native module is not defined at runtime, and we have no control over errors at runtime.
Emitting it during compilation could be incorrect as the module may exist. I would only want to emit warnings etc when we know there certainly is a problem
We can’t modify the language for this as the language doesn’t know anything about the environment in which it is compiled in, that is the responsibility of whatever build tool is being used.
We could possible look for
Elixir.prefixes. That would normally work but I’m unsure if it’s the best approach.