Exactly
Kernel.send/2 and Process.send/3 deliver messages into a process’ inbox, which are then picked up by receive statements that pattern match on the messages. That pattern matching is super useful as it makes it easy to respond to the messages that are relevant ..
GenServer’s call/cast/info functions are driven by these messages: the GenServer behaviour does the receiving and sends them on to the module’s handle_* callbacks. It makes the whole message passing a lot easier, both conceptually and to use.
This isn’t unique to GenServer, of course
All the modules that are driven by messaging have something similar. Task is an example: it coordinates with the original caller by sending messages.
There is so much that can be done with this deceptively simple pattern. It allows the BEAM to run your code across multiple threads safely, is part of the shared-nothing memory management approach, and makes working with processes running in different VMs (even on different machines) that are connected as a cluster trivial as the message passing remains identical.
Enjoy your explorations! Liked your blog entry, hope to read more in future ![]()






















