Question about spawn/1

No, the lambda does not go into the new process’ mailbox. It is, rather, executed right away. The purpose of the mailbox is communication between processes. The purpose of the lambda is to basically define what the process created by spawn/1 actually does. So that lambda is a pure function. The way you make it dynamic is by writing a function that dynamically defines the lambda when it runs and passes that lambda to spawn/1. In Elixir In Action, they define async_query/1 immediately after they introduce spawn/1 (pg. 137 of my copy). The async_query/1 takes an argument that winds up being part of the lambda definition, which is how you have a pure 0-arity function that can nonetheless be dynamic (because dynamically defined).

Think of it like this: you have to have shared mutable state in order to really do anything with a computer program. But, shared mutable state is a huge source of problems. OOP deals with this by locking state in objects. Functional languages (like Elixir) tend to have immutable data structures, which is nice and clean and mathematical. But when the time comes to do things in the real world, you need mutable state. The purpose of having things like genservers and message passing is to give you a way to deal with mutable state while still remaining functional; instead of holding state in an object, you hold it in a genserver process. It’s actually kind of similar to OOP in that respect.

Do you need it for a simple LiveView webapp? Not at the beginning, no. As time goes by, though, it will help to know the underlying OTP voodoo because that’s what LiveView is built on. It will pay off because you’ll be able to figure things out more quickly as a result of understanding the underlying theory.

If, on the other hand, you’re doing stuff that actually requires knowledge of concurrency, e.g. a IOT app processes a gazillion messages per second, then yeah, knowledge of concurrency fundamentals is important.