
(Though do your actual programming in a more powerful language such as MzScheme if you have any choice).
Having done concurrent programming in Java, and even implemented some concurrency primitives like semaphores, Clojure was incredible to use. For those that don't know, Clojure uses immutable data structures that mitigate concurrency issues. If you are curious how that's even practical, I highly recommend the paper and also reading about Persistent Data Structures. They reuse shared data, similar to how Git only tracks the delta's between commits, rather than multiple, full copies of the file.
On top of that, you up reducing lines of code by 60-70% of traditional Java or C#.
I don't even try to think about concurrent designs too much at work and sometimes feel guilty about it. Occasionally I'll use or suggest someone use a CompleteableFuture, but there is so much code and irrelevant detail compared to Clojure's "wrap body in (future), done". On the other hand some more junior devs have expressed lack of interest in studying concurrency at all since "we don't really work on concurrent or distributed systems", at which point I have to point out that as a company we serve a giant web application with API entry points from multiple bits of hardware with clients all over making concurrent requests... The road is long.
Then we have four conclusions:
1. the notion of declarative programming is a the 'core' of programming languages
2. it will also stay there
3. it is concluded that message passing "seems to be the correct default for general purpose concurrent programming" (my emphasis)
@1: what's the 'core'? Without any useful definition, this is a meaningless statement.
@2: aha! The core seems to change over time. OK, I rephrase my last question: what's the 'core' today?
@3: First, it's a weak conclusion that something 'seems' to be the case. But, ignoring the odd usage of the word 'correct', how does the author support this conclusion? It seems like the author thinks that presenting a couple examples for your proposed solution (message passing) allows to conclude that a competing solution (shared memory programming) is worse. I fail to see evidence for that. Yeah, programming with locks is harder than programming with actors. But it's also more expressive, so the comparison is unfair. If you want to compare erlang to, say, java, you need to compare it to programming with higher level data structures (queues, actors, ...).
btw, this one's a gem: "Declarative concurrency is a deterministic form of concurrency that is much simpler to program with than the shared-state concurrency used in mainstream languages such as Java [18]" -- if you look at [18], it doesn't support the simplicity claim; it's a reference to Doug Lea's "Concurrent Programming in Java". The simplicity claim remains a claim. That may be sloppy writing. Or not.