unfode
Consider the Erlang code below, case_a, case_b, and case_c are equivalent to three channels in a for-select loop in Go.
receive
{case_a, ...} -> ...
{case_b, ...} -> ...
{case_c, ...} -> ...
end
But there are two possible sources of incorrectness in this Erlang code:
- we don’t know the type of the data associated with
case_a, which means we may send wrong data to this process or process the data incorrectly. case_amay never happen, i.e., no code sends{case_a, ...}to this process.
I like Go channels because they have better correctness guarantee compared to mailboxes in Erlang:
- Go channels are protected by the type checker. So programmers get alerted instantly when they try to send an
intto achan bool. - Go channels have to be introduced before use, e.g., via function parameters. In Erlang, I can try to receive a message in
receivethat nobody ever sends, but I can only receive from channels that are in scope.
I don’t have much experience in both Go and Erlang, so I’d like to know your thoughts.
Trending in Discussions
As the title says, please share what you’ve been up to with Elixir. Whether that’s been learning it, looking into it, making stuff with i...
New
Hey there,
It’s been more than a year since we started using LiveView as our main UI library and building a whole library of UI componen...
New
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Quite interesting article Google brought me. Didn’t find any mentions about it here.
What do you think in general? Would you use togethe...
New
Hi everyone!
The first release candidate for the Expert language server project is now available!
We’ve published a press release detai...
New
Since we have deprecated our Erlang sections (as we have dedicated Erlang Forums now) let’s add this thread for those who’d like to post ...
New
What IDE or editor are you using for Elixir development?
Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
brightball
One of the biggest factors is the ability to send across nodes in a cluster.
In that same vein, you can’t guarantee correctness on the other node of the cluster if updates have been deployed, for example. Similar to making an API call to an outside service that can change. There’s only so much the type checker can actually do.
unfode
That’s true. API definition languages like Protobuf are a remedy for this case. I can’t think of a better approach.
For the single node scenario, I think typed channels improve code correctness and readability.
D4no0
This is the same argument oriented around static types and there are prices to pay in flexibility when introducing such a thing, moreover in elixir/erlang world we do not use low-level constructs on application layer, we use abstractions like GenServer.
Comparing erlang messages to golang channels is like comparing apples to oranges, both in terms of features and in terms on how concurrency is handled with these constructs.
This is very questionable, as things are nowadays, writing code with goroutines and channels is times more error-prone, can have deadlocks, and contains more boilerplate compared to elixir, but at the same time golang aims to be more performant by sacrificing a lot of abstraction.
sodapopcan
I don’t really know anything about Go but there is Ergo that was announcement relatively recently that brings Erlang-style abstractions to Go.
As I understand it from having very shallow discussions with Go devs and some people around here, goroutines are kinda like “fire and hope for the best” compared to OTP’s fine-grained control and observability over processes. I mainly wanted to share the ergo project so someone please correct or expand if I’m wrong
dimitarvp
This is a purely theoretical danger only. Unless your team is huge then nobody will attempt to use the code incorrectly or send the wrong shape of data.
Such adversarial conditions simply don’t happen in smaller teams (and I’ve never stumbled upon a big Elixir team and I know that even if it exists it is 99% likely it’s not a productive one).
That’s why you can and should put an
afterblock.Sure. You can also send a value to a closed channel and panic (read: abrupt abort) the program.
I love Golang but it has nasty foot-guns.
This can go both ways. It can be positive because there are many cases when you want to read from several channels – Golang offers you idioms for this (verbose but still readable enough). It can also be a negative because if you want something like an Erlang process (i.e. an actor) you would prefer the goroutine and its channel to be firmly bound to each other – but they aren’t so you end up emulating Erlang anyway (though don’t get me wrong, this is easy enough to do in most cases).
Basically, if you need more flexibility, machine speed and are ready to sacrifice correctness for speed of development – Golang is close to perfect.
If you prefer a more deliberate development with good speed and not a hard requirement to be uber-fast: just use
Phoenix.PubSubwith Elixir and you’ll be just fine.unfode
I noticed another difference between message passing in Go (via channels) and in Erlang. Sending to a Go channel is a blocking operation — the sender process/goroutine blocks until another goroutine receives from the channel. Whereas in Erlang, sending a message is non-blocking.
I feel non-blocking send is better, but don’t have good arguments. I’d love to know your thoughts on this.
lud
I don’t know Go but according to what you say it looks like this blocking mechanism prevents to flood the receiver with too much message, providing “natural” backpressure.
Process mailboxes are easily flooded and bottlenecks can arise. But it is generally not a problem because we can emulate the blocking mechanism, the most common way being “send and await response”, just as in
GenServer.call. But we do have a choice, so more flexibility and more power. The power/responsibility quote would fit well here.dimitarvp
It depends.
This will block.
This will not.
You can also use Golang’s select mechanism to make sure you will never block even if a buffered channel is full: Channel push non blocking in GoLang - DEV Community
unfode
Yeah, but buffered channels still block when the buffer is full.
As for
select, it postpones but doesn’t solve the problem — you need to send to the channel at the end of the day.dimitarvp
Sure, but
selectalso gives you a mechanism for retrying and timing out. Code gets little verbose but it works fine.