What's the main reason that Elixir chooses to compile to abstract format rather than core Erlang?

Recently I found some other BEAM programming languages, and most of them choose to compile to core Erlang or standard Erlang. And this makes the Elixir’s choice – the Erlang abstract format become a little mysterious.

Because I’m planning to make a kind of toy language base on BEAM, I’m curious about the pros and cons of each choice.



It gives us access to more tools in OTP, such as erl_eval, cover, debugger, etc. In the past, even Dialyzer required abstract erlang, but I have fixed it a couple releases ago.


I would strongly recommend that you use the Erlang abstract format. It will always be better supported by the OTP team and will have fewer compatibility issues.

For example, in OTP 23 we improved the syntax for binary matching. To do that, we had to change how we generated Core Erlang. We stopped using the receive construct in Core Erlang and started using new low-level primops for handling the mailbox. The changes were not in violation of the Core Erlang specification, but it broke tools that depended on the old implementation.


Last time I checked there was no convenient way to compile a module from core data directly, I had to write out the .core file first to the filesystem. (edit: I stand corrected, see response below!)

I think the core is an interesting target for toy languages because it is very simple, even if you lose tooling support and stability.

You can use compile:forms/2 with the from_core option to compile from Core Erlang forms directly.


As @bjorng mentioned sometimes the translation from Erlang AST to Core erlang changes which can cause confusion. I had such problem before with LFE when I generated Core. I was generating guards very simply and naively, though correct, and in one version of Erlang one of the optimising passes decided my guards should just fail. Which is not quite what I had intended. :grinning:

So generating Erlang AT is safer and more future proof.


Is Abstract Erlang the same representation we have to handle when implementing a parse transform?


Yes, it is.


Can abstract Erlang be serialized out and be human readable to some extent? Will it be more forward compatible to future erlang versions than Beam bytecode?

Well, you can pretty print Erlang AST. That is how I am managing module generation in BEAM compiler (serialisation format, it is no language).