4 ms·
Answer: Because you're not using Erlang/Elixir. This sounds flippant, but it's not. The erlang BEAM VM is the only system designed to do concurrency correctly.
by MCRed 12y ago
Answer: Because you're not using Erlang/Elixir.
This sounds flippant, but it's not. The erlang BEAM VM is the only system designed to do concurrency correctly. Unfortunately, I think that many people think that concurrency can be done in a library, or on non-concurrent systems like the JVM. I understand fully why Go would like to claim to be concurrent, and all the other languages would like to claim it, because the reality is we're in a multi-core multi-node distributed world. But don't fall for it.
Worse, there are some simple low hanging "concurrent" fruit like go-routines that make it seem like you've solved the problem.
I would have no problem if someone had made a language and VM or compiled-to-binary like go, that was truly concurrent, and that copied the erlang solution (no mutable state, supervision trees, let it fail, etc.)
Seriously, steal from the best if you're making a new language.
So far, nobody has. And since we live in a multi-node, multi-CPU world, you really should learn erlang (or elixir- which adds some features and has an easier syntax).
Seriously, I know it's much easier to go with flavor-of-the-month and pretend that there is no downside. But sooner or later-- hopefully sooner, because it will be much more painful later-- you have to pay the piper for not being concurrent. We've seen massive failures and re-architecting of systems as a result-- twitter survived years of fail whales because of their poor initial engineering. Can you count on enough VC money to do the same?
PS- not to pick on Go. Go has several features that are really bright choices. I am just using it as an example here, but I've heard of everything up to and including node.js being claimed as making erlang unnecessary.
- wyager 12y ago> The erlang BEAM VM is the only system designed to do concurrency correctly. That's a fairly bold claim. Erlang is good at the actor model. It's not an all-around winner in concurrency. Another shining example is the Glasgow Haskell Compiler runtime system. It has an exceptionally fast and efficient green thread system that (in the latest version of GHC) can scale almost-linearly up to 32 cores, even with some resource contention, and can easily handle millions of concurrent threads. I suspect you could emulate Erlang actors with very little loss of efficiency. (And, of course, you're also free to use a thread-based model.) And being a language with type-system-encapsulated mutability (and very nice resource contention management mechanisms like STM), concurrency is often "free" and very safe. An example of how concurrency is "free": main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") threadDelay 1000 Anything that is IO typed can get free concurrency like this. I need make no change to my putStrLn code: as long as it returns IO, I can use it concurrently. A few interesting things to look at: http://benchmarksgame.alioth.debian.org/u32/performance.php?test=threadring http://benchmarksgame.alioth.debian.org/u32/performance.php?... http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask035-voellmy.pdf http://haskell.cs.yale.edu/wp-content/uploads/2013/08/hask03... edit: Added thread delay so code example works out of the box.
- millstone 12y agoI tried this code with ghc 7.6.3: import Control.Concurrent main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") It only outputs "thing1", not "thing2". What gives?
- wyager 12y agoThe whole process dies before "thing2" gets a chance to do anything. The idea is that if the main thread is done and not waiting, we don't really care about what any of the child threads are doing, so we just axe them.
- millstone 12y agoHmm, ok. I tried adding an infinite loop after the forkIO calls: import Control.Concurrent loop :: Int -> Int loop x = loop x main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") putStrLn $ show (loop 0) Now the program runs forever, but to my surprise doesn't output anything. I think Haskell's concurrency must be very different from the types I'm familiar with.
- dragonwriter 12y agoThe parallelism (or not) of GHC concurrency depends on various options; if you don't link with the "-threaded" option, you are running green threads in a single native thread (N:1 instead of M:N). See: http://www.haskell.org/haskellwiki/Concurrency http://www.haskell.org/haskellwiki/Concurrency and http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/using-smp.html http://www.haskell.org/ghc/docs/7.0.1/html/users_guide/using... And Haskell threads aren't preempted except on memory allocation, so a tight loop without memory allocation never is preempted, so the main thread here never is forced out of control.
- wyager 12y ago>I think Haskell's concurrency must be very different from the types I'm familiar with. It's very different from most concurrency systems. It's a very, very lightweight cooperative green thread system. We're kind of dealing with pathological edge cases here. We're forking to do exceptionally simple, fast things (you shouldn't do that) and we're trying to sleep by wasting CPU cycles (you shouldn't do that). For example, this works fine: import Control.Concurrent main = do forkIO (putStrLn "thing1") forkIO (putStrLn "thing2") threadDelay 1000 threadDelay doesn't hog CPU cycles, so the other threads are able to run.