> Personally, I see limited benefits to making things fully distributed at the runtime level. I'm sure it's nice sometimes.
I think it's nice because when you write code as processes that receive requests and send responses, they can handle requests from the same node or different nodes with no change in code, you only change where you start that process (and make sure you register the process somewhere either as a named registered process or pg2/pg or whatever). Certainly there can be some scaling difficulties (see Rick Reed's talk linked elsewhere), but it generally works. And, you can move the processes while the system is running to address changing needs. Building on top of asynchronous messaging makes it easy to do things like normally wait for a reply after sending for a synchronous feel, but occassionally doing multiple sends and then waiting for parallelism, or just sending without waiting for a reply when that's appropriate.
> BEAM also support shared memory concurrency? A little thing called ETS? I would guess that there are other escape hatches as well, but I'm not familiar enough with Erlang or the BEAM to say for sure.
Ets is built with shared memory, yes, but interaction with your code is as if you were messaging a table process; the data you get back from an ets read won't change while you have it, but it might not be what you wrote, because another process may have written something else; same as if another process messaged a storage process in between your write and read. ETS is less of an escape hatch and more of a performance optimisation -- acknowledging shared memory concurency is helpful for data storage and retrieval, but it's tricky to get right and should be written once, so BEAM doesn't give the tools to do it and it needs to be done in C.
You can also do fun things with erlang:process_info or tracing to snoop on some data from other processes (but I don't think modify?). And, BEAM allows native code (NIFs) which is the ultimate escape hatch --- you can do lots of fun things there, of course.
> Ets is built with shared memory, yes, but interaction with your code is as if you were messaging a table process
To me, this is a distinction without difference.
Shared, mutable memory access without some form of synchronization is a bug and is always invalid.
You either hold a lock the entire time you're using a shared value, or you use a lock to take a copy of the value and then go about your business. With the singular exception of atomic values, the value should never change while you have it without you taking an explicit action to update it, and atomics are rarely used outside of either metric tracking or very specialized code. Besides atomics, everything you described about ETS is the same as any shared memory system.
> Shared, mutable memory access without some form of synchronization is a bug and is always invalid.
That doesn't prevent it from being really easy to write, and sometimes very hard to notice in a lot of languages. In BEAM languages, you can, of course, set up similar bugs through the use of other processes (or ETS), but you have to work harder to do it wrong than to do it right.
I think it's nice because when you write code as processes that receive requests and send responses, they can handle requests from the same node or different nodes with no change in code, you only change where you start that process (and make sure you register the process somewhere either as a named registered process or pg2/pg or whatever). Certainly there can be some scaling difficulties (see Rick Reed's talk linked elsewhere), but it generally works. And, you can move the processes while the system is running to address changing needs. Building on top of asynchronous messaging makes it easy to do things like normally wait for a reply after sending for a synchronous feel, but occassionally doing multiple sends and then waiting for parallelism, or just sending without waiting for a reply when that's appropriate.
> BEAM also support shared memory concurrency? A little thing called ETS? I would guess that there are other escape hatches as well, but I'm not familiar enough with Erlang or the BEAM to say for sure.
Ets is built with shared memory, yes, but interaction with your code is as if you were messaging a table process; the data you get back from an ets read won't change while you have it, but it might not be what you wrote, because another process may have written something else; same as if another process messaged a storage process in between your write and read. ETS is less of an escape hatch and more of a performance optimisation -- acknowledging shared memory concurency is helpful for data storage and retrieval, but it's tricky to get right and should be written once, so BEAM doesn't give the tools to do it and it needs to be done in C.
You can also do fun things with erlang:process_info or tracing to snoop on some data from other processes (but I don't think modify?). And, BEAM allows native code (NIFs) which is the ultimate escape hatch --- you can do lots of fun things there, of course.