Learn You Some Erlang for Great Good (2013)
learnyousomeerlang.com
learnyousomeerlang.com
It's very well done and if you're at all interested in Erlang, is worth purchasing.
If you're learning Elixir right now, I can't recommend enough to also learn a bit about Erlang. The OTP and BEAM VM sit underneath both systems, and learning about what's going on under the hood helps a ton when troubleshooting production issues!
If you mean that you end up calling certain library functions and such which are written in Erlang from Elixir.... well, yes, and you need to by design.
But I'd argue calling a function written in Erlang or from Erlang's standard libraries isn't the same as having to write Erlang code. I use Erlang's ETS, its in-memory key-value store, quite a lot from Elixir. I'm calling the Erlang ETS functions, but I'm not writing Erlang code I'm writing Elixir code which simply calls the Erlang functions. To me that isn't the same.... which for me is probably good: I know enough about Erlang to read the docs and to read Erlang code well enough by now... but not to write it; I've been writing Elixir code for years now and never had to write actual Erlang to accomplish anything. The closest would be a matchspec (kind of a matching DSL used by certain built-in Erlang databases), but I don't consider that writing Erlang, but more DSL like. I've also used Mnesia from Elixir in the same fashion: I call the Erlang libraries which are Mnesia, but I'm not writing Erlang code to do it: I'm writing Elixir code which calls Erlang libraries.
I'd disagree with the larger statement where you say, "Elixir only has lists not arrays, so if you need a good indexed data structure you end up using some Erlang." You are correct that Elixir doesn't have arrays and only lists... but that's also true of Erlang. Elixir and Erlang basically share the same primitive data types. I have to assume by "a good indexed data structure" you are referring to the previously discussed ETS which is more a K/V store than something like a data or data structure. Otherwise, you'd have to be more specific to what you are referring.
I think it's true that if you are going to write any serious amount of Elixir, you will benefit greatly from having some familiarity of Erlang. Not because you're necessarily going to write Erlang, but because Elixir was designed to be very compatible with Erlang's approaches, philosophies, and, most importantly, Erlang's runtime the BEAM. Because we do use Erlang library calls we will read Erlang documentation, frequently. We will see examples of those libraries written in Erlang, errors coming from the Erlang side, etc. None of this is to say I have to "write Erlang" to do any of this, but familiarity with Erlang doesn't hurt at all.
In the end, Elixir is simply a more expressive way to address certain kinds of problems while still reaping the benefits of Erlang and its VM, the BEAM. If you don't leave the kinds of problems to which Elixir is well suited, you will certainly encounter Erlang's standard libraries and benefit from being able to read Erlang and its documentation... but you won't really have to write it, just call its libraries.
Erlang has the array module, which IIRC uses lists of tuples internally to simulate arrays. I assume that's what they are referring to.
$ iex
Erlang/OTP 27 [erts-15.2] [source] [64-bit] [smp:20:20] [ds:20:20:10] [async-threads:1] [jit:ns]
Interactive Elixir (1.18.1) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> my_array = :array.new()
{:array, 0, 10, :undefined, 10}
iex(2)> my_array = :array.set(0, "test 1", my_array)
{:array, 1, 10, :undefined,
{"test 1", :undefined, :undefined, :undefined, :undefined, :undefined,
:undefined, :undefined, :undefined, :undefined}}
iex(3)> my_array = :array.set(1, "test 2", my_array)
{:array, 2, 10, :undefined,
{"test 1", "test 2", :undefined, :undefined, :undefined, :undefined,
:undefined, :undefined, :undefined, :undefined}}
iex(4)> my_array = :array.set(2, {:a_test, :test_tuple}, my_array)
{:array, 3, 10, :undefined,
{"test 1", "test 2", {:a_test, :test_tuple}, :undefined, :undefined,
:undefined, :undefined, :undefined, :undefined, :undefined}}
iex(5)> my_array = :array.set(3, %{test_field: "test map"}, my_array)
{:array, 4, 10, :undefined,
{"test 1", "test 2", {:a_test, :test_tuple}, %{test_field: "test map"},
:undefined, :undefined, :undefined, :undefined, :undefined, :undefined}}
iex(6)>
That is using the Erlang array module directly from the Elixir REPL, including such fancy features as rebinding on the single variable name `my_array`.The Erlang docs say this about the underlying data type: "A functional, extendible array. The representation is not documented and is subject to change without notice. Notice that arrays cannot be directly compared for equality."
Based on my REPL test, at least when the element count is small, it looks like they're using tuples; specifically a tuple nested inside another tuple where the outer tuple is defining the array metadata.
I think the reason I've not used the Erlang module is that the Elixir Enum module (https://hexdocs.pm/elixir/Enum.html) is sufficient for the cases where I'd want some sort of indexed data structure. Typically though if I'm indexed I'm really after some sort of associative array and maps are sufficient for that case.
I think by now there's also more open source Elixir code out there, which means LLMs will be somewhat more proficient in Elixir (they're not great at it though, but enough to help).
It's harder to work in Erlang and incorporate Elixir libraries than the reverse, although it's certainly possible (you would use the mix build tool from Elixir to do so).
My main pros for Erlang are that it's a simpler language than Elixir with less "magic" and fewer footguns. I still use both, in the same system even, but most new code in the system is written in Elixir.
I've been playing with Claude 3.7 thinking and, perhaps unsurprisingly, I find it overthinks the problem or tries to do far more than I really want it to for any prompt. I expect that I'm just using the wrong tool, and probably should just use Claude 3.7.
Of course in all of this, I'm using the LLM in a "junior" capacity and I'm not giving it giant multi-faceted problems to solve: I'm giving it relatively narrow problems to solve at any one time and am guiding it through that process.
https://github.com/jxzhangjhu/Awesome-LLM-Prompt-Optimizatio...
Really a lot of stuff you'd find in any university/college English course for academic writing style for getting your point across clearly applies as well:
https://alum.mit.edu/succinct-writing-guide
https://owl.purdue.edu/owl/general_writing/academic_writing/...
https://writingcenter.unc.edu/tips-and-tools/conciseness-han...
Personally though I've been avoiding its use in code and keeping it to where it shines. I've said this over and over. It's so good for writing drivel like copy and product descriptions and instagram posts and SEO-able text content. Stuff that people have been used to sounding kinda fake for decades if not over a century by now, that I have no heart to write myself but I can now literally just tell a robot to "increase engagement" and it shows in $$$.
Where I've found limits in what it can generate with code is with complex concurrency stuff that you really need to have knowledge about yourself to be able to prove isn't going to crash. The kind of stuff that you might pick up Elixr or Go for, specifically, I have always found it hits serious problems generating that kind of stuff. You need serious engineers who know stuff like TLA+, coq, spin etc to get that right if you're making systems that peoples lives or finances might depend on. I worry there's a lot of generated code being put out there in production which is not taking these things into consideration and people are just like 'wow it compiles, ship it'
I would start with Elixir, if only because of its newbie friendly community. The Erlang community is reflected in the 'erlang in anger' book.
But if you need to deploy on a small platform, say 32 bit 100MBytes, Erlang is the way to go.
You can decompile bytecode to erlang .