3 ms·
> can I run Erlang code on it efficiently? (This question also disqualifies LLVM Are you saying LLVM can't be used to efficiently implement Erlang-style proces
by sixbrx 13y ago
> can I run Erlang code on it efficiently? (This question also disqualifies LLVM
Are you saying LLVM can't be used to efficiently implement Erlang-style processes/tasks? I thought Rust was aiming to be able to handle a large number of lightweight tasks, and its based on LLVM?
- derefr 13y agoErlang actually uses LLVM as a JIT, but it does so by doing the same layering-on of semantics that I talk about here (https://news.ycombinator.com/item?id=6359716 https://news.ycombinator.com/item?id=6359716). By itself, LLVM IR has neither a "send" instruction, nor a "call" instruction with yield-semantics, and LLVM offers no tail-call elimination support. The JIT has to do a lot of pre-munging (dynamic recompilation) to produce code that LLVM can treat "blindly" as sequential machine-code. (LLVM also has a specific calling-convention implemented just for Erlang code, similar to the one it uses for Haskell code, since both generally avoid mutable state, which confuses LLVM's regular register-allocator.) Rust is a lot more like Go, with its multitasking primitives being based on channels (shared-memory atomic data structures) rather than message-passing-by-copying, and each actor/thread of execution allowing mutable state within itself, as long as its mutations don't leak across actor boundaries. In other words, it doesn't really change the semantics overmuch from that of the non-NUMA multicore Von Neumann machine (e.g. x86) it's running on; it just does "green threads" the traditional way, with some elegant builtins for getting data from one to another. Rust's and Go's semantics are both isomorphic to x86/LLVM/JVM/CLR semantics, as far as I can tell; you can translate directly from one to the other without any overhead from maintaining an implicit VM state machine (in est, a monad) across the compiled code chunks.
- kibwen 13y agoOne clarification: Rust's concurrency primitives aren't based on shared-memory data structures, because that leaves you vulnerable to data races and can require either a stop-the-world or concurrent GC. Instead it makes use of linear types to keep track of ownership between tasks, which is more restrictive but also means that sending data between any two tasks is memory-safe and never more expensive than the cost of copying a pointer.