2

Elixir source may be injected using Code.eval_string/3. I don't see mention of running raw Erlang code in the docs:

https://hexdocs.pm/elixir/Code.html#eval_string/3

I am coming from a Scala world in which Java objects are callable using Scala syntax, and Scala is compiled into Java and visible by intercepting the compiler output (directly generated with scalac).

I get the sense that Elixir does not provide such interoperating features, nor allow injection of custom Erlang into the runtime. Is this the case?

3 Answers 3

5

You can use the erlang standard library modules from Elixir, as described here or here.

For example:

def random_integer(upper) do
  :rand.uniform(upper) # rand is an erlang library
end

You can also add erlang packages to your mix.exs dependencies and use them in your project, as long as these packages are published on hex or on github.

You can also use erlang and elixir code together in a project as described here.

So yeah, it's perfectly possible to call erlang code from elixir.

Vice-versa is also possible, see here for more information:

Elixir compiles into BEAM byte code (via Erlang Abstract Format). This means that Elixir code can be called from Erlang and vice versa, without the need to write any bindings.

Sign up to request clarification or add additional context in comments.

3 Comments

Also, as asked in the original question, with Code.eval_string/3: Code.eval_string(":rand.uniform(100)") #⇒ {38, []}.
Excellent. Thank you for pointing me to the documentation for this.
Accepting because documentation is referenced, but also see @Hauleth's answer which has very good examples.
5

Expanding what @zwippie have written:

All remote function calls (by that I mean calling function with explicitly set module/alias) are in form of:

<atom with module name>.<function name>(<arguments>)

# Technically it is the same as:
# apply(module, function_name_as_atom, [arguments])

And all "upper case module names" in Elixir are just atoms:

is_atom(Foo) == true
Foo == :"Elixir.Foo" # => true

So from Elixir viewpoint there is no difference between calling Erlang functions and Elixir functions. It is just different atom passed as the receiving module.

So you can easily call Erlang modules from Elixir. That mean that without much of the hassle you should be able to compile Erlang AST from within Elixir as well:

"rand:uniform(100)"
|> :merl.quote()
|> :erl_eval.expr(#{})

No need for any mental translation.


Additionally you can without any problems mix Erlang and Elixir code in single Mix project. With tree structure like:

.
|`- mix.exs
|`- src
|  `- example.erl
 `- lib
   `- example.ex

Where example.erl is:

-module(example).

-export([hello/0]).

hello() -> <<"World">>.

And example.ex:

defmodule Example do
  def print_hello, do: IO.puts(:example.hello())
end

You can compile project and run it with

mix run -e "Example.print_hello()"

And see that Erlang module was successfully compiled and executed from within Elixir code in the same project without problems.

1 Comment

Excellent, very nice thank you for the examples.
3

One more thing to watch for when calling erlang code from elixir. erlang uses charlists for strings. When you call a erlang function that takes a string, convert the string to a charlist and convert returned string to a string.

Examples:

iex(17)> :string.to_upper "test"
** (FunctionClauseError) no function clause matching in :string.to_upper/1

    The following arguments were given to :string.to_upper/1:

        # 1
        "test"

    (stdlib 3.15.1) string.erl:2231: :string.to_upper/1
iex(17)> "test" |> String.to_charlist() |> :string.to_upper
'TEST'
iex(18)> "test" |> String.to_charlist() |> :string.to_upper |> to_string
"TEST"
iex(19)>

1 Comment

Thanks for the tip. For reference this documentation describes the difference between string and charlist: elixirschool.com/en/lessons/basics/strings

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.