> The other mystery here are the 2 different syntaxes in use for charlists – single quotes ('charlist') vs. the ~c"charlist" sigil. That’s a rather recent development, it was changed in Elixir 1.15, after some discussion …
>
> So, it’s now less confusing but still confusing – which is why it made this list.
Charlists with single quotes are deprecated since Elixir 1.17 - the ~c[…] sigil should always be preferred.
This would be more helpful if it dove into the Erlang side, as many of these "gotchas" are due to how Erlang and the BEAM work, and Elixir, being built on top of it and binary-compatible with the entire ecosystem, necessarily exhibits these behaviours.
Keyword lists, charlists vs strings (actually called binaries) [1], empty map matching all maps are obvious if you look at how they work in Erlang.
I haven't written a single line of Erlang though I can grok it pretty well by now. Knowing the entire platform is how you become a productive Elixir programmer, though it seems some devs refuse to look behind the curtains to understand the Erlang side of it, thus never truly understand the power of the BEAM platform.
---
1: I admit I still unsure about the separation of charlists and binaries. As far as I understand it, binaries are stored in their own heap to avoid copying when sending across processes, so are ideal for sharing large payloads, and charlists are not great for UTF-8 content, as they simply are a naive list of integers (hence one of the gotchas). Erlang uses charlists a lot for "string" content.
Elixir made the right choice to use binaries for strings, as they can ensure they are correctly encoded, provide high-level API to deal with the intricacies of Unicode, and still retain compatibility with Erlang by providing charlists and raw binaries for non-UTF-8 data.
Also, elixir team decided to deprecate single-quotes for charlists. No more single quotes (charlist, only for erlang interop) vs double quotes (binary string, used everywhere in elixir) surprises
> Knowing the entire platform is how you become a productive Elixir programmer, though it seems some devs refuse to look behind the curtains to understand the Erlang side of it, thus never truly understand the power of the BEAM platform.
This should be a lesson learned by all that boost about Scala, Kotlin, Clojure, F#, C and C++ replacements, JavaScript replacement, without bothering to learn the underlying infrastructure they are build upon.
Many times the X is going to replace Y advocacy, is a bit hard to achieve when the platform was designed for Y and will never go away from Y, for its whole lifetime.
Agreed, even with f# a first class citizen in the .net world, written, maintained and distributed by Microsoft, I still have needed to gain a working knowledge of c# to properly interact with the .net libs and third party libs (which I absolutely need to do as the f# ecosystem is tiny compared to c#). So at the end of the day I needed to learn two languages to atain my goal of learning one enough to be useful.
Disclaimer - I am still learning both - I am no expert on either - and I am still strugling!
Are these even gotchas if they are all very well documented in the official documentation already? I was expecting to see some unusual or undocumented behaviours...
many functional languages (if not all) do not have arrays (intended as a contiguous areas of memory containing indexable elements of fixed size) they are usually left as an implementation as libraries (i.e. Haskell's Data.Array)
There are also easy workarounds to that (including NIFs), I personally never needed arrays in Elixir
Not disagreeing with you, but it's worth noting that tuples support random O(n) access by index. They can therefore be used in place of arrays for some simple applications.
There is also some hope that future versions
of the Erlang compiler will allow mutable O(1)
update of tuple elements through setelement
(code inside a process is - almost - guaranteed
not to have shared references).
Safe destructive update of tuples has been implemented
in the compiler and runtime system. This allows the VM to
update tuples in-place when it is safe to do so, thus
improving performance by doing less copying but also by
producing less garbage.
That is the curse of guest languages, either they have to deal with leaky abstractions, or have to create their own, slower, implementation on top of platform primitives.
Also why with time, I learned to stay with platform languages, even if they aren't as shinny, or have warts that in hindsight could have been done better.
Also, if it's read heavy, you can use use tuples for O(1) access.
Besides all that, the community is extremely helpful, if you have questions check out the forum, for example on this very topic there's quite a bit of helpful discussion
Unless you are fine letting old homebrew work its "magic" - the installation is too lengthy and involved for a new language. It should just be click, download:
That is the biggest gotcha for me. There doesn't seem to be a simple installer or binary you just get up and running unlike other major languages. Is it a distribution issue with erlang or something? I'd have thought it'd be easy to package it up.
Not requiring a package manager is the point. Python, node, Zig etc supply binaries or a binary installer for each major OS, so why not Elixir? I can't see how it'd be a bad thing for anyone.
I imagine that part is slightly complicated by the fact that it requires host language runtime (Erlang). Elixir compiled with one version of OTP is not necessarily compatible with another version so supporting binaries for N versions of Elixir becomes NxM problem when you factor in OTP versions, plus supporting distribution of OTP binaries is probably complicated in itself. If there is a problem with OTP, users would swarm first party distributor, but their ability to help would be very limited.
37 comments
[ 4.3 ms ] story [ 69.1 ms ] thread> The other mystery here are the 2 different syntaxes in use for charlists – single quotes ('charlist') vs. the ~c"charlist" sigil. That’s a rather recent development, it was changed in Elixir 1.15, after some discussion … > > So, it’s now less confusing but still confusing – which is why it made this list.
Charlists with single quotes are deprecated since Elixir 1.17 - the ~c[…] sigil should always be preferred.
So hopefully that will reduce the confusion!
Keyword lists, charlists vs strings (actually called binaries) [1], empty map matching all maps are obvious if you look at how they work in Erlang.
I haven't written a single line of Erlang though I can grok it pretty well by now. Knowing the entire platform is how you become a productive Elixir programmer, though it seems some devs refuse to look behind the curtains to understand the Erlang side of it, thus never truly understand the power of the BEAM platform.
---
1: I admit I still unsure about the separation of charlists and binaries. As far as I understand it, binaries are stored in their own heap to avoid copying when sending across processes, so are ideal for sharing large payloads, and charlists are not great for UTF-8 content, as they simply are a naive list of integers (hence one of the gotchas). Erlang uses charlists a lot for "string" content.
Elixir made the right choice to use binaries for strings, as they can ensure they are correctly encoded, provide high-level API to deal with the intricacies of Unicode, and still retain compatibility with Erlang by providing charlists and raw binaries for non-UTF-8 data.
This should be a lesson learned by all that boost about Scala, Kotlin, Clojure, F#, C and C++ replacements, JavaScript replacement, without bothering to learn the underlying infrastructure they are build upon.
Many times the X is going to replace Y advocacy, is a bit hard to achieve when the platform was designed for Y and will never go away from Y, for its whole lifetime.
Disclaimer - I am still learning both - I am no expert on either - and I am still strugling!
(Calling erlang from elixir much eaiser!)
I really wish that someone would magically transpile all of ERTS so the documentation syntax was uniform.
Elixir is almost more of a guest syntax than it is a diff language.
I'm sure everyone who has used Elixir has been bitten by the list of numbers to string conversion.
There are also easy workarounds to that (including NIFs), I personally never needed arrays in Elixir
Of course if your goal is to re-implement sorting algorithms that were designed for mutable memory, you will be disappointed.
This isn't a deal-breaker. If you want a platform language, use that. But for web, you'd be hard-pressed to find something better suited than Elixir.
O(1) for reading I believe. The slightly awkward array module is built on top of tuples, a 10-tree of tuples? or something like it.
But good point, once in a while I see list_to_tuple to provide faster indexed reads on lists.
https://www.erlang.org/doc/system/system_limits
There is also some hope that future versions of the Erlang compiler will allow mutable O(1) update of tuple elements through setelement (code inside a process is - almost - guaranteed not to have shared references).
https://github.com/erlang/otp/releases?q=27&expanded=trueIt should be possible to add Elixir syntactic sugar to make this more concise and natural.
Just not used across the language
Tuples and binaries give O(1) read access, so depending on your use case, they may be better.
Also look at zippers, finger trees and ropes for more dynamic use, especially local operations (cursors).
Also why with time, I learned to stay with platform languages, even if they aren't as shinny, or have warts that in hindsight could have been done better.
https://www.erlang.org/doc/apps/stdlib/array.html
https://hexdocs.pm/arrays/Arrays.html
Also, if it's read heavy, you can use use tuples for O(1) access.
Besides all that, the community is extremely helpful, if you have questions check out the forum, for example on this very topic there's quite a bit of helpful discussion
https://elixirforum.com/t/elixir-array-like-data-structure/2...
That's exactly what JavaScript does (as I understand it), but it hides it from you. And the implementation authors have optimized it over the years.
https://stackoverflow.com/questions/5048371/are-javascript-a...
https://elixir-lang.org/install.html
That is the biggest gotcha for me. There doesn't seem to be a simple installer or binary you just get up and running unlike other major languages. Is it a distribution issue with erlang or something? I'd have thought it'd be easy to package it up.
I imagine that part is slightly complicated by the fact that it requires host language runtime (Erlang). Elixir compiled with one version of OTP is not necessarily compatible with another version so supporting binaries for N versions of Elixir becomes NxM problem when you factor in OTP versions, plus supporting distribution of OTP binaries is probably complicated in itself. If there is a problem with OTP, users would swarm first party distributor, but their ability to help would be very limited.