5 ms·
While I agree wholeheartedly that Erlang's design is better: To be fair, you can't get Erlang's semantics without also inventing processes and supervisor trees
by atombender 10y ago
While I agree wholeheartedly that Erlang's design is better:
To be fair, you can't get Erlang's semantics without also inventing processes and supervisor trees. And those things would be largely meaningless without immutability.
Erlang's magic comes from how all the puzzle pieces fit together into a whole: For example, with immutability comes the ability to always be able to restart from a known state, and probably greatly simplifies the internal implementation of the per-process heap.
Those things fundamentally change the language; Go couldn't adopt Erlang's semantics without eschewing almost everything that makes it "Go".
Error handling is really the least of it. Attempting to replicate some of Erlang's high-level design principles at a quickly lead to roadblocks. For example, goroutines cannot be killed; this means it's impossible to fully implement supervisor trees in Go. It's possible that the runtime could support this at some point, but it's a big can of worms.
- pmarreck 10y agoAgree, and thank you for pointing those additional considerations out!
- solidsnack9000 10y agoImmutability probably does simplify a lot of things; but it isn't actually required to get Erlang's model, since Erlang isolates the state of processes from each other. Each process could have its own isolated mutable state as opposed to an immutable one and it wouldn't change the "let it crash" philosophy.
- lobster_johnson 10y agoYou can't guarantee that isolation without immutabilty, or at least forced copying. In Go, it's extremely easy to accidentally send a pointer (or a data structure that contains a deeply nested pointer somewhere; this includes embedded maps, slices and channels, which are all reference types) on a channel, which is bound to break mutability guarantees at some point.
- deleted 10y ago[deleted]
- solidsnack9000 10y agoMutable locals do not necessarily imply pointers...
- lobster_johnson 10y agoNo, but how do you pass "mutable locals" to other processes? That's the whole question. If you pass a "local" on a channel to a different goroutine, Go can't guarantee to the receiver (which now has it as a "local" variable) that the sender (which still has it as a "local") won't change it: d := map[string]int{} ch <- d d["foo"] = 42 // Oops! The only way to do this safely is to to write a channel abstraction which uses gob or similar to marshal and unmarshal all data, thus copying it and preventing concurrent mutation, and then always use the channel abstraction. But always copying tends to be terrible for performance. Erlang is able to do zero-copy sends to process mailboxes because the data is guaranteed to be immutable. Sure, you could instead mandate that senders never hold on to data sent on channels, but can you ensure this 100% across a codebase contributed to by an entire team?
- klibertp 10y ago> Sure, you could instead mandate that senders never hold on to data sent on channels, but can you ensure this 100% across a codebase contributed to by an entire team? Isn't that precisely what Rust is all about?
- lobster_johnson 10y agoPretty much, yes.
- deleted 10y ago[deleted]
- dragonwriter 10y ago>Each process could have its own isolated mutable state Erlang processes do have their own isolated mutable state. But it's walled off and accessed through calls rather than variable references; in the non-SMP implementationthis enabled copy-free local (same node) message sends (and it still does, but only for large binaries -- the more general use turned out to be less efficient than copying in SMP because of locking issues related to garbage collection and some other implementation details.)