Björn, since there are so many people writing (or wanting to write) languages that run on the BEAM you could probably start a consultancy advising them - given you wrote so much of it ![]()
(caveat: I’m not a language design expert, and only got about half way through Crafting Interpreters)
iirc, it’s that values on the BEAM are truly immutable (they have to be, otherwise the GC doesn’t work). For straight-up imperative code, that’s not actually a huge problem – you can fake a lot of stuff with Elixir-style rebinding. But when you introduce anonymous functions that in other languages (such as Dart or Rust) would allow mutating the outer context, you simply can’t do that on the BEAM.
There are other places this’ll bite you, which escape me right now.
There are workarounds – you could keep all of your mutable variables in ETS, or in gen_server state, or whatever – I think Luerl does some of this – but it feels like cheating to me.
I am working on an Elixir compiler which uses Elixir’s (Elixir → Abstract Forms) then Erlang’s (Abstract Forms → v3_core) and then my own SoN (v3_core → IR → beam) backend.
I am mostly using it to explore the possible optimizations on IR level. I use Sea of Nodes IR graph cause it works well when combining different levels of abstractions.
Very fun project, but a lot of work
For example, that’s the IR for
def f(a, b, pid) do
case a do
1 ->
send(pid, :first_clause)
b
2 ->
send(pid, :second_clause)
3
end
end
End node is the result of the function and dotted lines represent ordering of side effects.
Making languages is great fun, you’ve picked a fantastic challenge @ValorZard ! Lots of fun hacking to be had ![]()
I would say there’s not really much special or unusual about making a language on the BEAM, so perhaps expand your search for information to learning materials about compilation in general.
My #1 tip for making languages is to not get bogged down in the making of compilers. If you have an idea for some language feature, start writing programs using that feature in your language, even though you don’t have a compiler for it yet! You can compile it with your brain and work out how it would feel to use, and what the compiler would need to do. This is slow work, but it is much faster than implementing the feature. If you invest all the time into making the compiler you will likely be more attached to the feature due to sunk-cost-fallacy, but if you spend more time iterating on the design you would likely come up with something better.
