jmitchell

jmitchell

Writing a library for use in both Elixir and Erlang

What is the best practice for implementing a library for use in both Elixir and Erlang? My goals include:

  1. minimize code duplication
  2. feels idiomatic to both Elixir and Erlang users
  3. no syntactic function call remapping like :lists.sort [3, 2, 1] or 'Elixir.String':downcase(Bin).
  4. integrates seamlessly with common package management and build solutions
  5. doesn’t break any features like maybe hot code reloading (or anything else, really)
  6. written primarily in Elixir because I like defmacro.

Without knowing better, the first strategy I’d probably try is implementing an Elixir library and making an Erlang wrapper. This seems good, except I’d have to manually keep the wrapper synced with the Elixir code. Are there recommended wrapper generators for this?

I’m not familiar enough with Elixir/Erlang/BEAM to know whether that approach might break any features. If so, would writing the library primarily in Erlang be any better?

I don’t have a specific project in mind yet. Just mulling over how I would approach this when the time comes. Thanks, everyone.

Marked As Solved

PragTob

PragTob

So, @josevalim came around and suggested another way to do this which I like better as it is simpler:

elixirdoc = """
...
"""

erlangdoc = """
...
"""

for {module, moduledoc} <- [{Benchee, elixir_doc}, {:benchee, erlang_doc}] do
  defmodule module do
    @moduledoc moduledoc
    # all defs here without using
  end
end

It is implemented in this benchee PR.

Also Liked

michalmuskala

michalmuskala

What I saw frequently in Erlang codebases using Elixir is the use of macros to alias elixir modules into something more consumable. You could provide an erlang header file that would provide some of those macros, eg:

-define(string, 'Elixir.String')
# later in code
?string:downcase(Bin).

On the other hand, I don’t see anything wrong with calling erlang-style modules from Elixir. You could use those:

defmodule :foo do
  # ...
end
# use in elixir
:foo.bar(1, 2, 3)
# use in erlang
foo:bar(1, 2, 3).

In general I would say that a wrapper is the worst approach - it doesn’t add any significant value and has considerable downsides and risks regarding it getting out of sync.

vic

vic

Asdf Core Team

So if @jmitchell would like to be able to call Foo.bar nicely from both Elixir and foo.bar from Erlang, would this be an acceptable approach to expose the api for both ?

defmodule Foo.Impl do
  defmacro __using__(_) do
    quote do
      def bar(), do: # ...
     # more of Foo public API
   end
  end
end

defmodule :foo do
   @moduledoc "For use from erlang"
   use Foo.Impl
end

defmodule Foo do
   @moduledoc "Alchemist way"
   use Foo.Impl
end
PragTob

PragTob

Not sure about the compiled artifact size but as it’s just one top level module that does a bunch of delegates to other things I don’t think the size impact (even if it duplicates all that code) is worth worrying about as I’d say it’s maybe ~1% of the overall code size.

I like the solution because it’s very simple and uses the simplest constructs to make it work - i.e. no macros.

Where Next?

Popular in Questions Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
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
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New

Other popular topics Top

jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
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
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
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
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
Qqwy
Update: How to use the Blogs &amp; Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 126479 1222
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement