Live data from Hacker News

Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

sites.google.com

111–120 of 145 posts

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#111

Earlier quoted context omitted.

The term deadlock has been used for message passing issues since the dawn of time. It is literally the same issue. Using timeouts to paper over issues is just wrong. I accept that timeouts are necessary to deal with network issues (and a timeout should cause the connection to be dropped, so won't solve the deadlock issue), but certainly they are not required for in-application message passing. Finally if an actor won…

> Finally if an actor won't send a message untill it has received another one, I fail to see how statically declared handlers will help. Think of it as reacting to messages, not waiting. In that model actors of course can react by sending messages, but can't have a special waiting state for specific messages, making it impossible to block other handlers. I'm not sure why this is hard to understand. We do have this pr…

Forget about waiting. Think about state machines. Let's say that that there is a rule that, if the machine is on state S1, on reception of message M, send message M and move to state S2. This the only rule for state S1. Now if two actors implementating this state machine and exchanging messages find themselves in state S1 at the same time, they are stuck. This is a bug in the state machine specification of course and I would call it a deadlock. How would you call it? How would the actor model statically prevent you from implementing such a state transition rule?

Edit: BTW, not sure why you got downvoted.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#112

Earlier quoted context omitted.

> Finally if an actor won't send a message untill it has received another one, I fail to see how statically declared handlers will help. Think of it as reacting to messages, not waiting. In that model actors of course can react by sending messages, but can't have a special waiting state for specific messages, making it impossible to block other handlers. I'm not sure why this is hard to understand. We do have this pr…

Forget about waiting. Think about state machines. Let's say that that there is a rule that, if the machine is on state S1, on reception of message M, send message M and move to state S2. This the only rule for state S1. Now if two actors implementating this state machine and exchanging messages find themselves in state S1 at the same time, they are stuck. This is a bug in the state machine specification of course and…

This is why I'm talking about specific model with static handlers per actor, where you can't choose handlers dynamically depending on the state you are in. Whether you are on state S1 or S2, all handlers are still able to receive messages, what they can't do is run at the same time.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#114

Earlier quoted context omitted.

Forget about waiting. Think about state machines. Let's say that that there is a rule that, if the machine is on state S1, on reception of message M, send message M and move to state S2. This the only rule for state S1. Now if two actors implementating this state machine and exchanging messages find themselves in state S1 at the same time, they are stuck. This is a bug in the state machine specification of course and…

This is why I'm talking about specific model with static handlers per actor, where you can't choose handlers dynamically depending on the state you are in. Whether you are on state S1 or S2, all handlers are still able to receive messages, what they can't do is run at the same time.

It can receive all messages you want, but if the only message that it that would cause a state transition, and send out a message, is M, then it is still stuck.

I mean, I'm no expert, but I guess you could statically analize the state machine and figure out, given a set of communicating actors, which sequence of messages would lead to a global state from which there is no progress. I assume that, because message ordering is not deterministic the analysis is probably non easy to do.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#115
I'd also like to mention cooperative concurrency. I know the author kind of skipped over this from the first sentence of the article where he defined a concurrent program as having more than one thread of execution. But with coroutines, we can have a single threaded-application that handles multiple tasks concurrently too. In fact I believe this is much easier to reason about for the programmer: the kernel won't randomly decide this thread's time slice is up in the middle of an important data operation; the programmer knows exactly when an operation may cause the current task to be "descheduled" because those are usually explicitly tagged with the "await" keyword. In my experience, this model eliminates the vast majority (but not all) of the use cases for locks and other synchronization primitives. It is also very performant.

Take a look at Python's asyncio, which has been in the standard library for years, and you'll see how easy it is to write concurrent networking code without threads and with very very few uses of locks.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#116
post #89

Earlier quoted context omitted.

Don't the core.async go-blocks have issues if you need to block on IO heavy stuff, as in the thread-pool will be blocked until the side-effects are done? Agents don't have that problem, at least I don't think they do.

I believe all I/O is blocking unless you use something that wraps NIO. This is definitely true for core.async threads, but I'm not sure why it would any different for agents. This is also a bit of a departure for people coming from Go or Erlang/Elixir.

Agents are run in a separate pool, and no one agent is processing at a time, so I suppose they're not "parallel", but concurrent still. I think the agents are preemptive, but I'm not 100% sure on that.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#117

Earlier quoted context omitted.

This is why I'm talking about specific model with static handlers per actor, where you can't choose handlers dynamically depending on the state you are in. Whether you are on state S1 or S2, all handlers are still able to receive messages, what they can't do is run at the same time.

It can receive all messages you want, but if the only message that it that would cause a state transition, and send out a message, is M, then it is still stuck. I mean, I'm no expert, but I guess you could statically analize the state machine and figure out, given a set of communicating actors, which sequence of messages would lead to a global state from which there is no progress. I assume that, because message orde…

Well, this is the limit all models have. You can abuse memory safety the same way and use indices of bounds checkable arrays as raw pointers for example.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#118
post #89
post #86

Earlier quoted context omitted.

I did use agents in the past, but stopped since core.async became available: it addresses the use cases for agents in a much more flexible way. Also, I found that handling errors in agents is difficult. As for the general use case, atoms and core.async are great tools, and I haven't needed to use refs (aka the STM) for years.

Don't the core.async go-blocks have issues if you need to block on IO heavy stuff, as in the thread-pool will be blocked until the side-effects are done? Agents don't have that problem, at least I don't think they do.

Well, they don't have "issues", they are simply not intended for I/O — but you can simply do your I/O processing in a (thread) block instead of a (go) block and use Agents also have a fixed thread pool, and you should use send-off if you intend to do I/O.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#119
post #89

Earlier quoted context omitted.

Don't the core.async go-blocks have issues if you need to block on IO heavy stuff, as in the thread-pool will be blocked until the side-effects are done? Agents don't have that problem, at least I don't think they do.

Yeah this is true, typically you want to keep blocking functions outside this. By default, core.async allocates as many threads as cores in your CPU. In addition to this, I personally find core.async to deal poorly with flow control (e.g. slow subscribers slowing down the entire flow for every subscriber), and seems to not have a lot of telemetry / it’s difficult to find out what’s going on in the thread pool behind…

Hmm, interesting — but manifold is clj-only, and I use core.async both on server side and client-side in ClojureScript.

Re: Fearless Concurrency: Clojure, Rust, Pony, Erlang and Dart

#120
post #55

I'm a bit surprised that there didn't appear to be any mention of Clojure's built-in concurrency support outside of basic immutability. core.async gives a nice channel-based system, agents give an actor-ish system, and STM/atoms let you mutate the variable safely, without having to manually work with locks. This is definitely a good high-level article, just something I was surprised by, since core.async is what drove…

52 major open issues, 2 critical issues, and 38 others major issues list memory leaks. https://dev.clojure.org/jira/secure/IssueNavigator.jspa?rese... first-party?

Every commonly used project has a ton of open issues. Look at React, VS Code, Docker, etc

It doesn’t mean it’s not production ready.

Post reply on HN