I'm a strong static-typing advocate, and for years this has put me off learning Clojure. (In fact, my very first HN submission, back in 2010, was about Clojure: https://hackernews.hn/item?id=1453259). I've been coding exclusively in Clojure for the last month however, and I found it extremely enjoyable to use. Much easier to learn than Haskell, for example, because Clojure isn't purely functional.
The key of Clojure is that it's pragmatic, as opposed to dogmatic. It's a language designed to solve real-world problems in production environments (hence the focus on concurrency, for example).
Also, being a lisp, it's a "programmable programming language", and once you realize the power that that gives you, it's hard not to fall in love with it.
I learned Clojure from the book Clojure Programming (http://smile.amazon.com/Clojure-Programming-Chas-Emerick/dp/...). Once the book gets past the basics, it starts giving lots of concrete examples for how to solve real problems idiomatically in Clojure.
Well, p in pmap does stand for parallel. :) The two are obviously linked, Storm does both parallel and concurrent processing on the data. Another example is PigPen (http://techblog.netflix.com/2014/01/introducing-pigpen-map-r...) from Netflix. As far as pure concurrency goes, I'm not sure any companies have articles discussing that.
Ok thank you. Implementing map reduce style parallzation doesn't need any language level support. I don't see how clojure is any better at this than say java ( hadoop is java after all).
I am looking for 'pure concurrency' in a app like videos games exctracting last ounce of processing power from a multicore machine. This what the original comment stated was the core competence of Clojure.
>I am looking for 'pure concurrency' in a app like videos games exctracting last ounce of processing power from a multicore machine. This what the original comment stated was the core competence of Clojure.
That's not actually what the parent comment stated though. It says that Clojure is designed to solve real-world problems in production environments.
In many cases this doesn't mean squeezing out the last ounce of processing power, but being able to reason about concurrent code safely. You pay an overhead of using immutability in order to facilitate higher correctness.
When your system grows it becomes important to be able to reason about parts of it in isolation. This is particularly important when you're running in a multithreaded environment.
That's what people generally mean when they say that Clojure has focus on concurrency. Since the data is immutable you can make assumptions about what the code is doing that you wouldn't be able to make otherwise.
I have a friend who is deeply into modern static-typed languages (Haskell and OCaml), but has worked professionally for a couple of years in Clojure. His big gripe with Clojure is that it's still dynamically typed, and thus vulnerable to type-based uncertainties. In languages like OCaml, lots of bugs are actually syntax errors and will be caught at compile time.
On the other hand, Clojure is at least a functional language. You get the benefits of immutability, no side effects, higher order functions, etc, in a neat and understandable package. And it runs in the JVM and thus has access to the bazillion or so libraries written in Java, thus getting around the interop problems that other modern languages (and some older ones) have.
Has your friend used core.typed[0]? I haven't really, but I've wondered if it might be the perfect balance for people who really miss their type system.
On the contrary, I came from Haskell-land and was impressed by Typed Clojure, at least in that it is capable of representing some things that are not easily represented in Haskell types. For example, union and intersection types can be pretty powerful. They can have easy variadic functions, and the occurrence typing is sweet -- after a runtime null check, it will remove the `Nil` type from a type union within the if-branch, or a runtime collection-empty check will modify the type in the subsequent branch to no longer include a case for a possibly-empty sequence.
On the other hand, Typed Clojure does not offer nearly the cohesive experience one gets from Haskell, nor do the types guide optimizations etc. Type checking is really a lint step rather than a build step. And almost all existing Clojure code is still dynamically typed, so you can't usually infer how to use a lib based on its type signatures (since it doesn't have them), which I love being able to do in hs.
I'm a huge static typing fan though outside of Java I'm really only currently into Scala. The issue comes up once in a while, mostly when I miss my tooling, but for a lot of cases, a library like Schema by Prismatic meets what you would want a type system for.
Back to tooling, usually you're into a mess of apis because you are forced to use or choose a type, which then enters a whole world of semantics architects love arguing about. For Clojure, a lot of functionality can be clear and concisely done in maps and lists and the handful of functions which operate on them.