How do you approach Erlang?

erlang
#1

I’m curious about the use cases of Erlang when you’re already using elixir, what use cases have you found or would you consider to be better to use Erlang instead?

Note: I’m not saying you should use one or the other, I’m just curious about the community’s take on the subject

#2

The two languages are similar enough for it to mostly be a matter of personal taste I think.

I’m a big fan of both and like to use Erlang for libraries (Erlang/LFE/Gleam users don’t need to include the Elixir compiler + stdlib) and use Elixir for applications.

7 Likes
#3

Thanks for answering!

That makes sense as they both compile to the Beam VM, I’m also interested in Gleam btw :slight_smile:

1 Like
#4

If you are already using Elixir in a project I don’t see a good case for Erlang. You will pretty much end up switching one syntax for another.

#5

Aside from the case that there is an Erlang library you want to use and want to contribute to, I think the only real reason to consider Erlang instead of Elixir, in the case of an existing Elixir user, is when you have a library that you want shared across the beam languages.

A couple good examples of this are https://github.com/beam-telemetry/telemetry and https://github.com/hexpm/hex_core

5 Likes
#6

I only use it to patch erlang libraries. My buddy wrote a really useful http server in erlang that I use in “unit” tests all over the place (makes a server a lambda), and there was a bug in the post handler that I fixed.

I find the erlang syntax hard on the eyes and not having the elixir syntactic sugar (like keyword lists) makes parsing data structures by eye exhausting.

I should probably link to the http server, if someone wanted to take on getting it up.on hex.pm that might be cool :slight_smile: https://github.com/stonecypher/htstub

1 Like
#7

I’ve been writing in Elixir for some time now and sincerely if given the choice I won’t write in anything else than Elixir (or Erlang), mostly because of the Erlang programming model. I do write quite a bit of JS as well (mostly w/ Vue) but sincerely, I do it because I can’t write Elixir for it, otherwise I would. I also wrote Ruby for some time, and used Salesforce’s Apex (which is basically Java), and again, I much prefer to write in Elixir.

I think Elixir does a great job in cutting down the initial complexity of understanding the process model by giving you a syntax that is more “current” (hence familiar if you don’t have decades of experience) and allowing you to slowly shift from a normal sequential like programming model to a more process oriented one. It also has the benefit of hindsight, so it packs a much more, lets say, normalised stdlib/base lib, where things are grouped in a more logical way. You can mostly write an Elixir app with Phoenix and Ecto as, say, if you were using Ruby on Rails. You’ll be using the process model underneath it even if you never write those parts yourself and don’t see them in your code. But then you start seeing/reading/using other bits, that are really unique to the BEAM. Even in those, Elixir does a good job of making their initial usage more “accessible”, by only requiring you the minimum to try them (say GenServers for instance not requiring all the callbacks, etc), or providing some useful abstractions, like Tasks and Agents, that do not require you to be totally familiar with the process-receive-loop and monitoring and linking semantics.

This on the other hand has the drawback that you might not fully grasp what these constructs are doing, but I think it works well as a step from “totally linear sequential code” to “process oriented code”, which is probably the most difficult transition (even more than OOP to FP), in terms of concepts. Once you start using processes you might be interested in understanding how it actually works underneath in terms of BEAM.

I bought Programming Erlang 2/3 weeks ago and I’m enjoying going through it (about 45% in), because Joe focus on using basically raw processes (spawn & direct messaging & receive blocks), which in turn makes you understand why the concept of links, monitors, supervisors, gen_*, calls/casts, timeouts, OTP etc exist and are needed/useful in the language. You can understand those without going through Erlang, but going through it in this fashion certainly drives the point home very easily.

In terms of syntax they’re actually very close (I mean the way you write it while making it looking good), but Erlang forces you much more into it due to a more strict syntax, but I find them to look quite equivalent (like say Spanish & Portuguese, if you understand one, and you’re given a text on the other you’ll be able to understand what is being said).

Now for bike shedding, I prefer elixir’s atom conventions (:), even though it’s a bit more ambiguous (nil/false/true don’t have the preceding :) while in erlang those are atoms and none have : indicating they’re atoms - on the other hand, in Erlang false & true have special meanings but they aren’t signaled in any way - so it’s also ambiguous. I also prefer writing var bindings with lower case, although I prefer that erlang enforces “no-rebinding” in written code. I’m not sure about the do blocks versus -> comma, semi-colon, period. I like pipe’s in elixir, and I think the String/Binary/Chr List handling is more intuitive in Elixir as well, although I can understand the benefits of “forcing” you to treat everything as <<binaries>> to allow easy message passing inside the program and to the outside (sockets, etc).

I haven’t gotten to releases yet - and Elixir is gaining direct support for them in the close future - so not sure about that part. I think elixir is more “tailored” to allow easy development of working web-apps, easy on-boarding and access to the BEAM (&Erlang) goodies, more aligned to current dev expectations. It also has meta-programming, which is also, sincerely, neat, you can do a lot without even touching macros. On the other hand Erlang is the underlying language so learning it can only help in using Elixir (if for nothing else, just because you can call “any” Erlang code directly, it basically will extend what you can do with Elixir).

It’s also worth noting that things such as Ecto do go a long way if you are used to using Postgres with an ORM, the documentation is also more “accessible” and really shines (Erlang’s documentation is quite complete too, it’s just more “technical”, and let’s say, scattered). To finish - I haven’t gone through the whole book yet, perhaps in the end I will prefer to start writing everything in Erlang, who knows, I’m enjoying it nonetheless - but I think that, really, the process model & BEAM is what’s more important.

2 Likes
#8

Not really no, true/false in erlang are just atoms, nothing special about them.

1 Like
#9

I probably phrased it wrong (and should have written bike shedding (& extreme pedantry)). What I meant was that:

-module(hello).
-export([test/1]).

test(X) when X ->
    io:format("x:~p is~n", [X]);

test(X) when not(X) ->
    io:format("x:~p isn't~n", [X]);

test(X) ->
    io:format("x:~p is something else~n", [X]).
1> c(hello).
{ok,hello}
2> hello:test(true).
x:true is
ok
3> hello:test(false).
x:false isn't
ok
4> hello:test(ok).
x:ok is something else
ok

They are boolean representations too, besides being “just atoms”, so when they appear in expressions that evaluate booleans (like guards, etc) they ofc have a “meaning”. While on elixir, although they’re atoms, since they don’t have the : you kinda recognize immediately that they must be not only atoms but atoms with a specific meaning.

None of this really matters ofc x)

1 Like
#10

I don’t think most people who learn Elixir realize they’re atoms on their own and I think it seems more hacky to special-case them on the syntax level to obscure it.

#11

That’s probably true, I think I didn’t noticed it “immediately”, but once I did it kinda made sense?

#12

Only by convention though. Technically booleans don’t exist in the runtime last I remembered looking through it, the atoms are just as expected, like not in erlang is basically just:

not(true) -> false;
not(false) -> true.

And similar with expressions like > that return an atom true/false and so forth, it is just convention, not necessarily hardlined enforced (excepting the conventions that the BIF’s use them too, but even internally they are still stored at atoms). :slight_smile:

That’s also why I really don’t like nil in Elixir. If anything it should have compiled down to :undefined, but even then nil in every language I’ve ever seen corresponds to the end-of-list marker, I.E. [], and even the erlang sources itself call [] as nil internally last I recall, so Elixir having a nil that doesn’t correspond to [] as I’m used to in any language I’ve ever learned that has had a nil was very disconcerting to begin with ([1 | nil] is not a proper list as one would expect based on the name!!!). Ever having nil compile down to [] would have been fine too, but having it as the atom nil is just… very odd… o.O

#13

I agree that it makes sense once you know it, but I think there’s an alternate reality where it wasn’t special-cased where the idea is simply that things concerned with booleans working on the atoms :true & :false work in certain ways. That alternate reality seems a perfectly fine place to end up to me and maybe makes more sense than the special-case we have now.

As you said, though, it hardly matters.

I’m just making guesses here, but I’d assume it’s because Ruby has nil but lacks any concept of cons cells, so consing with nil has no particular meaning in Ruby, and so the thought of having nil represent [] never occurred to anyone, seeing as it only served as null for Ruby.

Personally, I’m not much for nil usage in terms of it standing in for the empty list, though Racket has null which mirrors the predicate (null? lst) very nicely. '() is as many characters, though, so in terms of the value it just doesn’t make as much sense to me.

1 Like
#14

I don’t think there’s any greenfield project I’d make in Erlang, to be honest. In some idealistic fantasy maybe I’d make libraries in it, but then I’d just rather not. Working with Erlang is fine when there’s a historic reason and I like it to some extent, but in terms of starting new stuff I don’t know that there’s much of a point.

I do think that anyone who’s trying to be a professional Elixir developer needs to be able to read and modify Erlang code, however. There’s not much excuse to not be able to; it’s an even simpler language than Elixir and the system-wide idioms are 100% mirrored in Elixir, so it’s not as if there’s some large-scale difference. It’s not a big time investment to sit down and learn how you express yourself in Erlang and how to read other peoples’ code (especially in comparison to Elixir).

1 Like