And my point was that since you can invoke functions, you can in fact use many things from the Elixir ecosystem in Erlang. A couple of examples which come to mind and could be useful for erlangers:
Enum
module from stdlib for rich iteration and manipulation of enumerables (e.g. lists, maps, streams)
Stream
module from stdlib for lazy consumation of enumerables
Task
module for starting OTP compliant one-off jobs
- GenStage behaviour for producer-consumer pipelines with backpressure
- Connection behaviour for managing remote connections
The interfaces for these things are not based on macros, so they can be easily invoked from Erlang. Thus, I don’t agree that anything created in the Elixir space is useless for Erlangers.
Phoenix is indeed more difficult to use from Erlang, since its interface is heavily based on Elixir metaprogramming features which are obviously not available in Erlang. That said, where there’s a will, there’s always a way Let’s try to serve some requests from Phoenix using an Erlang module.
First, we need to create a Phoenix project:
$ mix phx.new --no-ecto --no-html --no-brunch my_site
Then, we need a small generic Elixir-Erlang plug bridge:
defmodule ErlangPlug do
def init(opts), do:
Keyword.fetch!(opts, :mod).init(opts)
def call(conn, opts), do:
Keyword.fetch!(opts, :mod).call(conn, opts)
end
Now, we can create a plug module in Erlang:
-module(my_controller).
-export([init/1, call/2]).
init(Opts) -> Opts.
call(Conn, _Opts) ->
'Elixir.Phoenix.Controller':text(Conn, <<"Hello from Erlang!">>).
And finally, in the endpoint module we can replace the call to Elixir router with the call to our plug:
defmodule MySiteWeb.Endpoint do
# ...
plug ErlangPlug, mod: :my_controller
end
Granted, the experience could be better. There is some room for improvements in some libraries, most notably in plug
, which currently makes it impossible to use Erlang modules as plugs. But with a little bit of trickery we can still work around that problem, and get to the point where we can write most of our Phoenix code in Erlang.
I absolutely agree with this. I also agree that some Elixir libraries are harder to use from Erlang. If a library provides its interface via macros, you obviously can’t use it directly from an Erlang module, so you need to have some adapter.
However, if a library is based on plain modules and functions, then the usage is straightforward. I don’t have any data, but my impression is that many libraries don’t provide a macro interface, which means that there should be quite enough of interesting Elixir things that could be easily used by Erlangers.
Of course, as has been repeatedly mentioned in this thread, in order to simplify the integration, Erlang build tools such as rebar3
and relx
should support Elixir dependencies.
So tl;dr:
- It is possible to invoke Elixir from Erlang.
- Many libraries have plain functional interface, and can therefore be easily invoked from Erlang.
- If a library provides a macro-based interface, then you need some bridge/proxy Elixir code.
- The support for using Elixir deps in Erlang projects is AFAIK currently missing, which is IMO the biggest obstacle to using Elixir from Erlang.