124 comments

[ 1.2 ms ] story [ 170 ms ] thread
Clojure is badass the whole way through: great language, great designers, great support, great community.

I don't think it will ever get more than a 2% share in the software world, but I think it can get the right 2 percent. At least, that's what I hope will happen. I also think that it will live (possibly even surviving the JVM) for a long time.

I don't think it will ever get more than a 2% share in the software world, but I think it can get the right 2 percent.

There will always be detractors. But then again, you can't teach a dog math.

I spent a tiny amount of time getting to know Clojure. I liked what I saw, but some things confused me due to lack of looking into it/thinking about it. I'll need to spend more time with it to find out if I'm a dog. ;)

Clojure is the first purely functional language I've ever tried to teach myself. I'm still learning, but I already find it a liberating experience to stop worrying about state and learn to love the function.
Clojure is not 'pure'. At least in Haskell's sense of 'pure'.
He might be considering it from a functional-as-the-only-paradigm angle as opposed to the technical definition of pure functional.
If a Lisp-like was ever going to explode, it would have done so within the last 55 years.
Right, because nothing in the technological landscape changes, ever, in any way that could be relevant to the success of a Lisp-like language.

I'm not saying I'm convinced a Lisp-like will explode, much less that it'll be Clojure in particular, and I do think it important to keep the history in mind, but I think you overstated things.

I wonder if any Rubyists said something similar pre-Rails.
Lisp suffered from the AI Winter and the lack of acceptance of GC based languages on mainstream computers due to their limited capabilities.

Many of the capabilities of modern IDEs were already available in Lisp and Smaltalk environments in the early 80's, but you could buy a house with the price of those systems.

Reasons I believe Clojure will never be successful:

(1) it's a lisp. This is 2013, compilers can deal with +-*/, I don't need to.

(2) it lacks good documentation. Most functions are documented, but badly. In particular, they lack examples; sometimes they are really tricky to use

(3) it lacks tutorials (on the main page). There is a set of pages that explain the basic concepts of clojure, such as datatypes, variables and multimethods/protocols, but they are really terse. I think Clojure assumes you already know lisp, quote, unquote, syntax trees, defs, vars, etc...

(4) it's full of magic. You can feel it, but you can't really understand it without digging through the source code.

I know OCaml, can read Haskell, and wrote a small library in closure. I still find it very hard do get around and very hard to learn.

> it's full of magic. You can feel it, but you can't really understand it without digging through the source code.

Are you trolling? If not, care to provide concrete examples?

I've written a number of small applications in Clojure and I find that it /lacks/ magic, even in comparison to something like Python (which is generally highly un-magical). For instance, Clojure's namespaces prevent circular dependencies; while a simple example, this is idiomatic to the larger philosophy of Clojure and indicative of a general dislike of magic that permeates the language as a whole, in my experience.

Lisper trend to write one-liners with functions such as map, doseq etc. with big combination chains with many other functions. When doing this in a dynamic type language with no documentation, I guess that's why he calls it magic.
How in hell does 'map' qualify as a magical function? Though I suppose that for a programmer who couldn't understand a simple concept like map, damn near anything would look like sorcery to them. ( to clarify, I'm not accusing you of being unintelligent , just wondering-out-loud )
As a Clojure noob I can see 'map' and quite a few other functional things seeming seeming like magic to programmers who aren't used to the paradigm. Until you get used to thinking that way and using the tools, they seem a lot less intuitive.
I can't speak a speck of German. The words look so long and intimidating and I find that if I try to pronounce them I get lost from the beginning to the end. The worst part is that sometimes German words look like something in English and when I try to use them in sentences my German speaking friends giggle at me. German definitely seems less intuitive as a spoken human language.
There is very little that is 'magical' about a lisp-like language (in terms of the bastardized vision of 'magic' popularized by blessed hashes, operator overloading, and dynamically constructed objects in various scripting languages). There are few concepts required to understand it:

    (function arg arg) ; is the default form
And every form is passed to eval, which calls apply, which calls eval... until you get to a fully expanded form and the final call to eval.

    (map #'my-func '(1 2 3 4)) ; might eval to
    (lambda () (my-func 1) (my-func 2) ...) ; which when passed to apply might result in
    (list 1 4 9 16) ; which eval's to itself, a list object... 'list being a primitive
I just describe a theoretical evaluator (#'map is probably not implemented this way in most lisps). You can implement eval/apply in terms of a register machine if that makes you happy. Just read SICP for a good, basic description of one.

I appreciate what the Algol-derivative languages have done and what they're useful for; but there are a large class of programming problems where telling the compiler how to solve your problem for you is far more efficient than manipulating the machine with primitives. It all boils down to that eventually and lisp-like languages simply take you to higher levels of abstractions with consistent semantics.

I think magic is not the right word here (and I see that you do not endorse it yourself, merely attributing it to him, a distinction others are ignoring.) Instead of magic, I would call it bad or unfamiliar style caused by a habit of doing everything in a single expression with large unnamed sub-expressions. This is much easier to do in functional languages because of how well functional idioms compose with each other. Martin Odersky gave an example of this in Scala in his style talk at Scaladays. Sometimes it seems simplest to express things in one expression:

    jp.getRawClasspath.filter(
             _.getEntryKind == IClasspathEntry.CPE_SOURCE).
             iterator.flatMap(entry =>
               flatten(ResourcesPlugin.getWorkspace.
                 getRoot.findMember(entry.getPath)))
But giving informative names to the subexpressions can make things clearer for the next programmer to come along:

    val sources = jp.getRawClasspath.filter(
             _.getEntryKind == IClasspathEntry.CPE_SOURCE)
    def workspaceRoot = ResourcesPlugin.getWorkspace.getRoot
    def filesOfEntry(entry: Set[File]) =
             flatten(workspaceRoot.findMember(entry.getPath)
    sources.iterator flatMap filesOfEntry
When to use named vals instead of subexpressions is a matter of style and judgment. From my limited and dated experience, the "one big expression" style is more common and more culturally accepted in Common Lisp than in other languages I've used. You could even call it the norm. In less expressive imperative OO languages, programmers are used to using a plethora of named variables, simply because they usually can't avoid it. In languages like Scala and Clojure, there's bound to be some culture clash when people who are used to more or fewer explicit names have to read each others' code.
I understand map.

Here's the code I was trying to understand.

https://github.com/nakkaya/net-eval/blob/master/src/net_eval...

I'm not sure I do even now. I mean, I kinda know what different symbols and functions do, but I couldn't write it myself.

When you say full, of magic I think you mean the core langauge, witch is actually very simple. The example you provide is from a small test lib somewhere one github.

Lets look at the macro, once you understand the basic macro concepts, witch are actually quite simple but still hard to understand. Its like a normal function, exept that the function code will be added to the var as data.

It's a (fairly simple) macro that defines a function which while doing so associates a quoted function definition (the same as the function being defined) with the metadata of the defined function's var: it might require a double reading (based on my inferior description) because it's got some meta-ness going on.

But the salient point here is there's really nothing magical about what's happening there.

If you understand clojure that code sample isn't hard to understand. Of course, I don't really know what it does, because reading 4 lines in a library without knowing anything else is always confusing.
It puts the code of a function into its metadata so that it can send it for remote evaluation easily (see fire-request below that extracts the :task metadata and sends it to a remote nrepl server).
I'm confused. Is it magical because you don't understand it, or do you not understand it because it's magical? It seems like you're saying the first one.
Agreeing with everyone else here: there's no magic, but macros and metadata are fairly late topics in Clojure, and starting on a piece of code responsible for distributing code across a network... well, it wouldn't be my favourite place to start.

Of course, the power of Clojure is that you actually can express this concept in the language. RMI looks pretty ugly by comparison.

I've always wondered how a company can scale a development group using lispy languages. I can read Clojure fairly efficiently, but I don't assume that all developers, even good developers, can. I don't doubt that one can develop rapidly with them, but we all know that more time is spent in maintenance. How many developers out there 1) can read and visualize what is going on, 2) have the tolerance to work with lispy languages?
I work at Factual, which I'd estimate has about 20 Clojure engineers. We've found folks generally enjoy working with the language--both newly hired programmers who already use Clojure, and internal converts. Code structure for maintainability is always a concern, but because Clojure doesn't impose as much rigid OO hierarchy as other languages, refactoring is a little simpler, I think.

It decimates your hiring pool--but the programmers who are fluent in Clojure or other Lisps tend to be skilled. I also think Clojure is more concise and more productive than, say, Java--which reduces the volume of code, and lets you do more with fewer people. Keeping the team small reduces the number of meetings and managers, and keeping the codebase small makes it easier to understand and maintain.

YMMV, naturally--but I wouldn't consider these concerns as insurmountable obstacles to using the language in production.

Clojure is already successful. Not Java or C++ successful, but successful enough that there's a decent eco-system around it.

As for the reasons I use it, it has great development tools, a good amount of libraries, Java interop (a big one), and it's just a well designed language.

Don't agree with 1&4, but 2&3 are subsets of a feature of the Clojure landscape: the guys behind Clojure aren't laser focused on driving adoption like, for instance, Scala is. Indeed, some of them don't really like the idea of a "Clojure Community". http://stuartsierra.com/2013/01/16/the-reluctant-dictator

On the other hand, there's an amazing focus on doing the right thing rather than throwing features at a wall, which I like immensely. Sadly, long lists of new features seems to drive adoption. :(

> (1) it's a lisp. This is 2013, compilers can deal with +-*/, I don't need to.

I don't understand what you mean here, the lack of infix operators in Lisp? You make it sound like prefix notation is inferior. But given how Lispers usually sell it as the best thing since sliced bread, such reactions don't surprise me.

Anyway, you're right. It really seems like C-style syntax has won, and deviating from that is certainly a barrier of adoption. Clojure has been remarkably successful despite this, but I really don't see it becoming the next Java.

The thing with infix operators is not about being C-like, but rather about mathematical expressions looking like they do in actual mathematics (not to mention that each term potentially adds another level of nesting).

At least I've personally found that doing linear algebra, physics calculations or anything with more complex equations in Lisp-like languages is a huge pain.

Clojure is one of the best documented languages, bookwise, especially the ones from Pragmatic, 2 from OReilly and 2 from Manning(Joy of, especially).

(4) it's full of very reasoned data structures and designs, like, e.g. HAMT, transients. You can write dense/nested functions, and people do, and yes, other people have problems with it, see https://olabini.com/blog/2012/08/6-months-with-clojure/

(5) Being a haskeller/ocamler I thought you were going to make a type system argument, which is a valid argument, liek this blogger i saw yesterday http://failex.blogspot.com/

>(1) it's a lisp. This is 2013, compilers can deal with +-/, I don't need to.

The s-exp notation is actually more* programmer friendly because when you're using a decent editor you can work with code at structural level.

When I work in Clojure I'm not thinking in term of manipulating lines. I think in terms of expressions. I want to take this expression and parent it here or there, I do that. I want to factor out a piece of logic I can select the block and move it out, etc.

This also facilitates the powerful macro system where I can trivially write code that templates code for me or create DSLs to express the particular problem domain I'm working on. The whole aversion to prefix notation is incredibly superficial.

>it lacks good documentation. Most functions are documented, but badly. In particular, they lack examples; sometimes they are really tricky to use

This is simply false. There's excellent documentation available at

http://clojuredocs.org/quickref/Clojure%20Core

and

http://clojure-doc.org/articles/content.html#clojure_languag...

with lots of examples for each function, tutorials, and guides. Furthermore, there's tons of traditional documentation available in form of books.

>it's full of magic. You can feel it, but you can't really understand it without digging through the source code.

It's quite the opposite in my experience.

>I know OCaml, can read Haskell, and wrote a small library in closure. I still find it very hard do get around and very hard to learn.

I find Haskell is much more difficult to read than Clojure. Perhaps it has something to do with familiarity as opposed to any inherent difficulty?

When I work in Clojure I'm not thinking in term of manipulating lines. I think in terms of expressions. I want to take this expression and parent it here or there, I do that. I want to factor out a piece of logic I can select the block and move it out, etc.

Lips has just a really tiny (if any) advantage over other languages in this. I can move code around quite easily in Java. And I don't have to care about formatting (I use autoformatter). In Lisps, formatting code manually is needed and it's a bit of a PITA especially when changing the code.

This also facilitates the powerful macro system where I can trivially write code that templates code for me or create DSLs to express the particular problem domain I'm working on. The whole aversion to prefix notation is incredibly superficial.

Usefulness of macros is overrated. In my experience, the s-exp syntax is too high price for macros. I like Julia's approach to macros much more.

vim/emacs autoindent clojure just fine

I love that s-exps are totally unambiguous and find them easy to read personally.

+1 for Julia. No need for sexprs for useful macros.
Or Dylan, sadly Apple killed the project back in the day.
There is Open Dylan http://opendylan.org/ and it actually seems to be actively developed from the looks of it.
Dylan was a very interesting language for its time, but way too verbose for modern day developers.

I'd love to see a stream-lined Dylan-like language that targets the JVM or CLR.

You mean HTML designers? :)
I am fully aware of it, but its development seems to have stalled, if you look around.
>Lips has just a really tiny (if any) advantage over other languages in this. I can move code around quite easily in Java.

I don't find it to be the same at all in practice. Lisp has a huge advantage in this because the code is written by manipulating the AST. You see the tree and the branches of executions visually. So, I can say I want to move this node to that position, or extract this node into a separate function.

I find it's like playing with lego. You just stick individual pieces of logic together to produces complex functionality.

You simply can't do this in Java on any practical level in my experience. It also doesn't help that Java code is imperative so even if you selected a block of logic, it doesn't mean you can just move it elsewhere without any side effects.

>Usefulness of macros is overrated. In my experience, the s-exp syntax is too high price for macros. I like Julia's approach to macros much more.

I strongly disagree, I find macros are incredibly useful. Clearly most people agree as some sort of a macro system creeps up into pretty much every language.

However, most languages don't allow you to apply the language to itself when templating code. So you end up with special crufty syntax that eventually becomes a whole separate language that you have to learn.

I'm not sure what price you're talking about either. I actually prefer s-exps to ALGOL style syntax. With s-exps your code is very regular and it follows the principle of least astonishment much better than alternatives.

There are no inherent downsides to the syntax, if anything it makes the interaction between pieces of code more visually apparent. It provides extra visual information about the structure of the code. I personally like that very much.

I was quite enthusiastic about Clojure at first, I rally enjoyed experimenting with it but when the novelty fade off I lost interest because of:

1. The minimal syntax makes it harder to read than more traditional languages.

2. It's uncomfortable to do imperative or object-oriented programming in Clojure. (Yes, many problems are easier to express in other than the functional paradigm.)

3. Using state is not a priori wrong but it's difficult in Clojure.

4. The parentheses are sometimes annoying, especially when I want to quickly test something in the REPL.

Some lispers (like Paul Graham) believe in something like "macros make lisp the most productive language on Earth, at least for the top x % programmers". From my experince, this is just wishful thinking. It makes them feel special and better than others.

> It makes them feel special and better than others.

That's an incredibly cynical view. I'm sorry that Clojure was not for you -- it happens. People have different ways of thinking and the language that makes sense to you might not make sense to me. This is natural I would say and not likely reflective of general intelligence. There's no need to be bitter about it.

I loved playing with Clojure, especially with the overtone library. But I just couldn't see myself be more productive in Clojure than in Python.

> People have different ways of thinking and the language that makes sense to you might not make sense to me. This is natural I would say and not likely reflective of general intelligence. There's no need to be bitter about it.

I was mostly refering to the essay by Paul Graham that is sometimes referenced here on HN. I find some of PG's claims about lisp's productivity ridiculous and almost religious.

Macros are frowned-upon within the Clojure community, and for very good reasons.

EDIT: okay, I got downvoted for some reason. Care to explain why?

The mantra in Clojure is "don't write macros until you NEED macros" (or some alternative[1]). They make things horribly complicated and are awful to debug and make code that uses them hard to debug too... especially within a JVM environment (your code gets translated twice).

[1] http://clojurefun.wordpress.com/2013/01/09/when-do-you-need-...

I didn't downvote you but the only significant advantage of the lisp syntax is macros. I was always under the impression that the syntax is a price for macros. If macros aren't really used, I don't see reasons for the lisp syntax.
Macros are frowned-upon but used when necessary.

To put an analogy: people would've disgusted if you used a life jacket for no good reason, but they're handy when you really need them :)

I also like Lisp syntax regardless of macros, mainly because it's simple, consistent and prefix notation is really handy. The S-expr abstraction IS useful when dealing with code blocks (see https://news.ycombinator.com/item?id=5940620)

Brainfuck syntax is even simpler and more consistent ;)
If Brainfuck syntax was half as powerful as powerful as S-expressions that would be a valid comparison.
I would argue that s-expressions are powerful for reasons other than macros, but I agree that the prefix notation and boatloads of parentheses can initially require a lot of extra effort for no apparent payoff. When I began writing clojure code (in vim) this was a constant source of frustration for me. The paredit.vim plugin [https://github.com/vim-scripts/paredit.vim] made things much easier and led me to give emacs a serious try. Writing lisp in an editor with paredit is a magical feeling. It turns the onion of parentheses into a structure that you can navigate and modify without having to worry about keeping things balanced. For me, this has made the parens effectively disappear from my focus.
"Don't write a macro when you could write a function instead" has been standard advice since decades before Clojure. "Macros make things horribly complicated" is nonsense, or no skilled programmer would use them. And from the frustrations my Clojure friends recount to me, ease of debugging is an issue quite apart from anything to do with macros.
> ...has been standard advice since decades before Clojure.

Yes, but we're in a thread dedicated to Clojure ;)

> "Macros make things horribly complicated" is nonsense, or no skilled programmer would use them.

Which is what happens, really, and when used it's in a very limited fashion. For example, for quite popular projects inside the Clojure community: Leiningen used one macro[1] and Compojure two[2].

A properly done (and properly used) macro might not make things complicated, but this leads me to the next paragraph.

> ease of debugging is an issue quite apart from anything to do with macros.

It's usually hard, but macros make it HORRIBLE since you can easily lost track of the generated code. Like if translating from Clojure to Java Stack Traces wasn't hard enough...

Whenever you use a macro, the stack traces you receive from the code using it might not like like what you expect at all. Macros are bad because they mutate your code. You usually have to expand the macro and debug there instead of just looking at your damn code.

The big problem is not macros, but code which uses macros.

[1] https://github.com/technomancy/leiningen/search?q=defmacro&r... [2]https://github.com/weavejester/compojure/search?q=defmacro&r...

This does not match my experience. I write macros to make my code shorter when I notice a repeating pattern. To see what the macros do, I use macroexpand. Is debugging a problem? Well, I understand the macroexpansions so I can read them when I need to—so no, it's not that big a problem. You're not the first Clojure person I've heard talk this way about macros, and I don't understand why anyone would be so eager to deprecate such a powerful technique. Especially since it actually works (and works well) in Lisps, and not nearly as well elsewhere.

Also, these comments seem odd:

A properly done (and properly used) macro

The big problem is not macros, but code which uses macros.

The macros I know are effectively impossible to misuse. They tell you how they're supposed to be used and you just do it. There's not a lot of room to go wrong! Can you give an example of a macro which is hard to use properly?

> I write macros to make my code shorter when I notice a repeating pattern.

I do that using functions :)

The "lisp is the most productive language on Earth" claim is mainly a selective bias. People who are good with their tools are very productive. Naturally they view their own tools as superior.

One of the biggest Lisp proponents (forgot his name) when joining Google found out that other good developers using other languages were just as productive.

Clojure is the language I find easiest to read because of it's minimal syntax.

I guess while I'm here, my feelings on the other points: 2) good, it's a functional language 3) Clojure's state management is excellent, discouraging mutable state is a good thing. 4) the reply highlights the matching parens when you close them, it hasn't been much of a problem for me

2) Fine, but functional paradigm is suitable only for a subset of real world problems, so it shrinks the usefulness of the language.

3) Sometimes mutable state is the best way to go. I'm not in the "mutable state is wrong" religion :)

I'd argue that the functional model more accurately represents the real world than mutable objects.

When you use mutable state, you're creating a model that essentially ignores time. Sometimes this is a useful omission when performance is required, but time is so integral to our Universe it's hard to remove it from a model without unforeseen consequences.

Functional programming is definitely not the best approach in every situation. Sometimes it's more useful to look at the problem from imperative, object-oriented views, logic, etc. perspective. There's no paradigm that rules them all. Paradigm's are just different ways to look and decompose the problem. You need different tools in different situations.

I'm not sure what you mean by saying that mutable state ignores time. Real world applications have state, you can't avoid it.

Not all paradigms are equally useful. Mutable state pretends that change happens instantaneously, which isn't how the real world works.

Let's say you observe the state of a lightbulb. You might say "The lightbulb is on," but the lightbulb could be turned off, rendering your statement technically invalid. So instead you might say, "The lightbulb is on, now", but even that's not necessarily true, as in the time it took the light to reach your eyes, the lightbulb could have been turned off. So the most accurate description you could give would be "The lightbulb was on, 10 nanoseconds ago."

Systems with mutable state have no explicit time element. So "x = 1" is analogous to saying "The lightbulb is on." Systems with immutable state have to be more specific about time, so they might say "x[when t=0] = 1". Can you see how this is a more accurate representation?

Mutability is really only useful under the following circumstances:

1. You need performance. 2. You have only one thread. 3. You are performing no I/O.

I'm not really sure how the lightbulb metphor translates into real world code, what kind of situation does it describe?

In Java, I can very easily choose between mutability and immutability. If I put "final" in the variable declaration, the variable is immutable. So what I usually do is default to immutability but opt out if needed. Which is very often, usually because 1) it would make the code more elegant and easier to understand 2) for performance reasons.

You are performing no I/O.

Why does I/O make mutability useless?

It describes a situation where read latency is a factor, which is any situation where you cannot guarantee a single observer. This is true if you have multiple threads, but also true if you're accessing a shared I/O resource, such as a filesystem.

Mutable OOP presents the fiction that you can retrieve the current value of a property or object, but we know this isn't true. In reality, all we can do is to find a past value of a property, because there's always some latency involved in reading. If it's a single value, maybe the latency is only a few nanoseconds. If it's a lookup against a hashtable, perhaps we're talking microseconds. If we need to access I/O, our latency increases to milliseconds or higher.

The more concurrency and latency in a system, the harder it is to maintain the fiction that latency does not exist. It's worth asking whether a model that falls apart so quickly (which it does whenever you need a synchronized method or data structure) is actually useful to have in the first place.

Java does allow variables to be marked as being immutable using the final keyword, but it doesn't have very good tools for dealing with immutable data. It doesn't have efficient immutable data structures in its core language and it has no tail call optimisation, or even a pseudo-TCO structure like Clojure's loop/recur. In short, it's much more difficult to use immutable data in Java than it is in a functional language like Clojure.

Oh, I understand now, you were talking about shared mutable state. I think that Java has a solid support for parallelism and there's more in libraries (e.g. implementations of the actor model). When I share data between threads, I almost always use immutable objects (one can even mark immutable classes with an annotation to make it explicit). Clojure's software transactional memory is a very interesting feature but I haven't really played with it.

Java does allow variables to be marked as being immutable using the final keyword, but it doesn't have very good tools for dealing with immutable data. It doesn't have efficient immutable data structures in its core language and it has no tail call optimisation, or even a pseudo-TCO structure like Clojure's loop/recur. In short, it's much more difficult to use immutable data in Java than it is in a functional language like Clojure.

Mostly agree, functional languages like Clojure are definitely more immutable-friendly.

Well, sure, but why would you want local mutable state? In some cases it's more efficient to alter transient data in place, but mutability makes it much harder (and usually less efficient) to effectively compose functionality.

I guess Java does make it seem like the opposite is the case; that it's easier to work with mutable data, and that immutability is just a needless restriction. However, in languages with lambdas and higher-level functions, local mutability is rarely required, and becomes a hindrance rather than a help. Just look at how many times "options.dup" turns up in Ruby code: https://github.com/search?q=options.dup&ref=cmdform&type=Cod... . It's an annoying pattern in Ruby to work around the lack of immutable maps in the core language.

2 I think is an agree to disagree moment, I just don't really care for OO.

I agree on three though, and I think the way Clojure handles mutable state is excellent, but it's a good thing that it's not trivial to just say x = 5, x++.

I've been solving real-world problems with Clojure for some time now, and haven't had any problems with immutable state or functional programming. Perhaps you haven't used the language enough to really get a handle on how things are done?
Clojure does not remotely hold that "mutable state is wrong." That precisely why it provides several different ways to access mutable state from concurrency primitives down to mutable arrays.

Rich's philosophy on this is "mutable code isn't needed most of the time." It's a very different argument.

As for (2), if by "real world problems" you mean "commonly occurring, trivial, day to day problems", then yes, I also solve "real world problems" every day with clojure.

A lot of the objections your raise are very subjective.

>1. The minimal syntax makes it harder to read than more traditional languages.

I personally find that the minimal syntax makes it much easier to read the code.

The more syntax the language has the more of it you have to keep in your head when reading code. Different language features might interact in unexpected ways, and so on. This is mental overhead that I don't need to worry about when the syntax is regular.

>2. It's uncomfortable to do imperative or object-oriented programming in Clojure. (Yes, many problems are easier to express in other than the functional paradigm.)

Could this stem from the fact that you're likely much more familiar with OO and you've spent years internalizing OO patterns for solving problems.

I find that for majority of problems I deal with functional solutions tend to be simpler, cleaner, and more reusable.

OO on the other hand is directly at odds with reuse because you marry logic and data together into classes. If you write a method and you need to use it for a different problem, you often have to jump through hoops to do it.

On top of it OO encourages premature classification. If you create a class and you need to use that data in a different way later you have to translate it in some way. This is why you have things like wrapper and adapter patterns.

This problem simply doesn't exist in functional code. You simply group functions into a namespace that has same organizational benefits as a class. A namespace can represent a specific domain, but you can easily pass the output of a function from one namespace to a function in a different namespace.

>4. The parentheses are sometimes annoying, especially when I want to quickly test something in the REPL.

There's a lot less control characters in Clojure than say in Java. If you count all your parens, curly brackets, semicolons, commas, and so a language like Java has far more noise in it. There are very few languages that have cleaner significantly syntax in my opinion.

Also, if you're using a proper editor you rarely have to deal with something like balancing parens by hand.

>From my experince, this is just wishful thinking.

From my experience, actually having worked with Clojure production systems for a few years, now macros can be incredibly helpful in expressing problems cleanly and removing boilerplate.

I find that for majority of problems I deal with functional solutions tend to be simpler, cleaner, and more reusable. OO on the other hand is directly at odds with reuse because you marry logic and data together into classes. If you write a method and you need to use it for a different problem, you often have to jump through hoops to do it. On top of it OO encourages premature classification. If you create a class and you need to use that data in a different way later you have to translate it in some way. This is why you have things like wrapper and adapter patterns.

This can't be emphasized enough. I never understood why so many people thought that putting methods and data together was a good idea.

I think Rich Hickey in an interview with Stuart Halloway possibly once said that when you jam your methods in with your data you're essentially creating a mini-dsl that makes reuse impossible. I can't agree more.

So we're agreed that we can throw (4) out right? You're wrong about Clojure being "full of magic." As to your example, you don't understand Clojure macros so you don't understand that simple Clojure macro. That's not magic.

Now, of (1)-(3), the only one which has the hope of backing up your point is (1). Why should Clojure not having good documentation right now be a reason Clojure will never be successful? Why should Clojure not having tutorials right now be a reason Clojure will never be successful? It doesn't make sense. What if those "facts" change?

You're right; "never" was a bit too long-term.
it's a lisp. This is 2013, compilers can deal with +-/, I don't need to.*

Modern Lisps use homoiconicity not because it is easier for the compiler, but because it is easier for the human. In languages with syntactic macros, (as opposed to string-interpolating macros), one manipulates the program's AST directly as a data structure. Making the code's AST regular, predictable, and explicit facilitates code transformation, which is an integral part of programming in a Lisp dialect.

1) It seems hard because you didn't learn this way in school. I agree that writing 1 + 2 * 5 is easier than (+ 1 (* 2 5)). It's true for very simple expressions. But as your expression grown you end up (if you haven't forgot) adding parentheses to ensure your operators executed in the right order. Multi-line expressions are just unreadable in traditional notation. But lisp notation with indentation is just fine.

2, 3) There is tons of material on Clojure. Read a book or two, google for christ's sake to get live examples on stackoverflow and hackers' blogs. Also great features are (doc fname) and (source fname) to get source right away without even leaving your REPL.

4) It's very subjective what you wrote, so it can't be falsified.

Clojure is already successful for many people. What you probably meant to say is that Clojure will never be mainstream. That's probably true, but I have been subscribed to the clojure mailing list for quite a while now and actually quite surprised how much Clojure code is in production.

That said, the two big "strikes" against clojure for "mainstream" adoption are as you pointed out, it's a Lisp, and it's dynamically typed.

I like the core concepts of Clojure. That there are a small set of primitives that have a uniform interface and how Clojure is anti-OO. Clojure actually does OO better than OO languages do, but that's another story.

If I could just get a Clojure with some optional typing, a python-like syntax, and awesome tools, I'd be a happy camper.

Does Clojure still have a non-trivial impact on performance? And if it doesn't, does it still look as pretty?

I only ask because the whole idea of using it for "Big Data" flies right out the window if it's significantly slower than plain old Java. Especially if it's slower using naive or expected Clojure methodology. And if there's not a speed advantage, than companies can find a lot more people who know and can work Java code than Clojure.

Performance and scalability are two different things. My favorite example is to think of performance as being like the speed limit, and scalability as the ability to easily add more lanes to the road. Once there are enough vehicles on the road, it doesn't matter how high you set the speed limit, they'll still slow to a crawl. Now imagine if there was a trivial way to add more lanes to the road.

Clojure has very nice concurrency mechanisms baked right into the language.

This doesn't answer the author's question. We know the difference between performance and scalability. How does it perform compared to Java?
It is slower than java. It can approach Java with type annotations which aren't that hard to do. It is faster than any other dynamic language I have used, including python, ruby, javascript(v8), and lua(jit).
Faster than LuaJIT? At what? Did you run benchmarks to back that up?

That's a very strong claim, and I've never heard anyone make it before. LuaJIT is unbelievably fast. I'd be extremely curious to see the proof.

(As a side note, on some level it's hard for me to accept that Clojure is fast because using it feels gratingly slow — since all the tools take several seconds to do anything thanks to the JVM's startup time. `lein repl`: 4 seconds wait. `luajit`, or `python` for that matter: utterly instant.)

No benchmarks, just a few small algorithm implementations (kmeans, random forest, ff neural net). Clojure was faster, although the difference was pretty trivial.

I have been frustrated with Clojure lately because of startup time (I do a lot of CLI tools), and would love to use Luajit, but my coworkers hate when I write in languages other than Ruby or Clojure. For my own pet projects it is great.

Well that's pretty darn cool to hear that Clojure can achieve LuaJIT's level of speed. But I agree, I feel Clojure just isn't suited for CLI tools at all, unfortunately. I know there are solutions that keep a background JVM ready and reuse it but I've never managed to get that to work smoothly.
How does Java compare to C or Fortran? And how much does it matter?

Ruby and Python are incredibly popular despite being incredibly slow. Clojure has decent enough performance, plus easy parallelism/concurrency...

Performance and language prettiness are also two different things. Again, when we're talking about "Big Data", the implication is that there is a very large number of rows being processed. That's nice that "adding lanes" looks pretty in Clojure, but it's not like it's impossible to do in Java. And if I can double or quadruple my throughput by switching to uglier Java code? And on top of that I drastically widen up the pool of potential employees? Well, this is starting to look like a pretty shut case from a business perspective.

And that's also why I asked about whether naive Clojure script is performant, or whether you have to take so many non-obvious routes to eek out the performance that it loses "conciseness" as a point in its favor.

(Disclaimer: I don't have recent performance numbers on Java vs Clojure; that's why I was asking for them. The double/quadruple numbers above were pulled from thin air.)

In my experience it's always possible to get java level performance out of clojure when you need it, even if that ends up meaning that you essentially write java with sexpressions and macros. However, even for "medium data", when I find clojure too slow I fall back to C/C++. I've never found myself thinking "maybe I should write this in java."

Unfortunately, I can't find good examples of modern performant clojure with benchmarks at the moment. As far as I understand, the alioth benchmarks are still out of date.

Funny you mention big data, because it's something of Clojure's sweet spot in my opinion. Take a look at Cascalog and Storm. Both are in use at Twitter. Then add pallet for dynamic provisioning.
It's a good question, and it really depends.

I have one system where clojure performs better than java. It's not an apples-to-apples comparison as the java source is very rigid and stateful. There's a ton of recalculations being done and there's almost no way to thread it out because the current implementation relies heavily on mutation. The clojure equivalent is much smaller and just overpowers the java implementation due to the ease of threading (pmap, memoize). In that specific example I was looking at maybe 20x performance increase?

I have another test where I cannot even get close to java performance. Even after adding in type specific checks. In that example java wins because it's a native/primitive java implementation. Even without threading the java side wins because it's been reduced to such a simplistic operation (500 lines of java code using only primitive types) that the overhead of clojure can't beat it. In this test java is about 5x fastar than the clojure equivalent.

It really depends on what you are doing I tend to think of it like raw java > clojure > over engineered java... In some instances it can be very, very powerful.

Just a note for anyone interested in what was mentioned in the article but more comfortable with JavaScript.

There is mori http://swannodette.github.io/mori/#mori for persistent data structures.

Callbacks are handled by Promises or say async https://github.com/caolan/async

For heavy compute tasks you can launch child processes under Node.js and communicate with one management process, the Cluster http://nodejs.org/docs/latest/api/cluster.html lib is experimental as of now.

For those who were around in the early '80s, was the Prolog/Transputer/FGCS hype similar back then?

Plus ça change, plus c'est la même chose...

Most of us only had BBS, if we were lucky, so hype levels were kept very low.
We had Byte magazine which had Dick Pountain's articles of sexy hardware with which fantasize too...
And Computer Shopper, Micromania, Micro-Hobby, Crash, ....

Oh and books with code listings to type in hexadecimal rows of opcodes. :)

It would certainly seem to me (in London at least) that scala has most of the "enterprise functional programming on the JVM" pie. I hardly see any clojure jobs pop up. From what I've seen I'd say demand for FP skills looks like:

Scala > F# > clojure > Haskell (really bummed about the last one!)

In London finance circles. Does that sound about right?

Sounds about right, but there's certainly people working in Clojure: there's startups like MastodonC (who employ Vishal), there's ForwardTek who love it, there's a number of hedge funds based around it, there's the credit derivatives desk at Citi. There's some stuff at DB as well.

But tbh, if you want a Clojure job, it wouldn't hurt to go to the clojure meetings at SkillsMatter. With all of that said, the market depth does worry me, especially for finance.

Got about 30 guys here using Haskell. More in other centers.
I didn't know the team at SCB was that big! You guys should come to some of the London Haskell meetups! In fact I think one of your guys is doing a talk soon right?
Tomorrow night (Wednesday).
(comment deleted)
My excitement about Clojure led me to core.logic, which led me to kanren, which led me to Prolog. Am I doing it wrong?
If you want to write productive code, yes you are wrong.
Constraint Logic Programming is extremely productive in logistics planning problems which are NP-Complete/Hard. Even SWI-Prolog, which is hardly the fastest implementation out there, is faster than the fastest IP solvers I have found (Gurobi and CPLEX).

Of course, if you want to coerce the word "productivity" to mean "making boring CRUD webapps quickly", you have a point.

When you say Prolog, I think of the standard without CLP. Also if you want to do anything other then solving logical problem you will be better served with clojure/core.logic or anouther 'mainstream' language with a good logic implmentation.
Not if those tools are helping you solve the problems you want to solve. Also, not if they're expanding how you think about computation. I'm willing to guess at least one, if not both, are true for you.
Yeah, it is both. It does seem a little counter-intuitive to some people, and I get made fun of a bit for it.
I don't think it's going to explode. And I don't think it needs to.

Even after decades there are still people who use Lisp-like languages and who find them fascinating and just right tools for their job. I, for example, am a huge fan of Common Lisp and I'm really glad to see new stuff happening around it and new people discovering it because there were times I was a bit afraid about its future.

But will it ever dominate or explode? No, it won't. Same with any other Lisp. And it's okay.

Interesting take: "Over the past 20 years or so OO has dominated the landscape and rightly so. It provides structure and a simplified way of organising your code. OO design patterns such as MVC are going nowhere. But today with live in a world with events, mobile phones trigger events, more intricate interaction with UIs and apps all trigger a vast amount of events and traditional OO doesn’t embrace this style of interaction as well. Instead functional programming copes better."

We still need to organize our code tho, even with a functional language... and I have missed the abstraction of OO (Using node.js)

I remember reading someone say that much of the class-based OO written in the wild amounts to little more than a function namespacing convention plus a way to jam in a bunch of hidden arguments. That hit home to what I was doing.
I keep hearing this over and over. I like the idea of just changing 'map' to 'pmap' everything just working over multiple cores.

While cool,but really, Is there such a great clamoring for scaling programs over multiple cores ? I never hear anyone asking about it job postings. May be I am working in the wrong part of the industry than those mentioned in the blog post. But I rarely hear game programmers talking about clojure/ functional programming. Most popular clojure projects on github are web frameworks. I am puzzled why clojure is so popular among web developers if concurrency over multiple cores is its 'killer' application.

From what I remember this paper never mentions 'concurrency' as to 'why functional programming matters'

http://www.cs.utexas.edu/~shmat/courses/cs345/whyfp.pdf

Neither does this( the only one?? ) poster child for lisp's success in wild talk about concurrency http://www.paulgraham.com/icad.html

I think the whole multiple core thing is over blown in association with functional programming. I think it would be pretty misguided for someone to adopt a functional programming with multiple cores in mind.

> I keep hearing this over and over.

Hearing what? That pmap is a drop-in for map giving instant speed gains? That's odd. I've never heard that. Like anything pmap has its tradeoffs.

> poster child for lisp's success

You're conflating "functional programming" with Lisp.

> I think the whole multiple core thing is over blown

That's something that I would probably agree with. However, people tend to focus on that regarding Clojure because it provides more than one model for describing concurrent state changes. People get excited about that I suppose.

> That pmap is a drop-in for map giving instant speed gains? That's odd. I've never heard that.

That was just an example of how programming without state makes it easy to scale it over multiple cores.

> Like anything pmap has its tradeoffs.

No one said anything about pmap being a drop in replacement for map. If pmap didnt have tradeoffs there wouldnt be a 'map' and just pmap.Common Sense. I am not sure why you are even mentioning that. As I said that was just an example of ease of writing multithreaded programs in clojure. Which was one of the main points in the blog post. Did you get a chance to read the blog linked to this post?

Game programmers are especially unlikely to use Clojure for several reasons:

* New programming practices are adapted after the mainstream programming industry has adopted them.

* Java is not widely used, partially because when the great Java enterprise switch happened, game studios were still debating if switching to C++ was worth it.

* Because games deal with rapid state changes, switching from relatively intuitive object-oriented designs to functional designs requires a rethink of how most game engines operate.

* If it doesn't work on the consoles, the mainstream industry is much less likely to use it. Java isn't natively supported, and Microsoft is unlikely to add anything to the XBox to make it easier.

* Most games are still single-threaded 32-bit Windows applications interfacing with DirectX.

Not really, no.

Porting a 20 year old game for fun in Haskell doesn't mean that Haskell is ready for the cutting edge of modern games.

They don't need to develop the next Crysis on Haskell to make it accepted.

The plain fact that important personalities in the AAA games industry are willing to spend their valuable time coding something in Haskell instead of doing something else, means a lot.

For example, are you aware that quite a few studios are now using Erlang for their MMO servers?

While cool,but really, Is there such a great clamoring for scaling programs over multiple cores

Absolutely. Queues, databases, caches, machine learning, graph algorithms, CRDTs, image, audio, and video processing, stream algorithms, analytics, geospatial work, even HTTP APIs: all demand compute performance. Since CPU flops have been essentially stagnant for ten years, the only way to improve performance on commodity hardware is with parallelism. Almost every program I've worked on in the last five years has demanded multicore programming, or at least in-process concurrency.

Clojure is not the fastest language out there, but it does make reasoning about concurrent code dramatically simpler than other languages. My Clojure programs tend to parallelize trivially over 16 or 32 cores, and only rarely contain race conditions, deadlocks, or other threading bugs. In contrast, I routinely struggle to write correct multithreaded code in Java, and when I do, I usually adopt a slower locking mechanism because I'm just not smart enough to reason about concurrent mutable state.

Why is Clojure better for writing concurrent programs? For one, it's multi-paradigm. You can serialize transformations over state using normal JVM locks, agents, atoms, refs, or promises. Immutable shared-structure objects make concurrency safety trivial--but Clojure's identity types make reasoning about state easy, instead of having to express everything through monadic composition. For mutable state, you've got java.util.concurrent and Cliff Click's high_scale_lib available, plus great libraries like Netty. It's a deeply pragmatic language where the defaults are safe, but controlled speed is available where you need it.

Or you could run 64 Unicorn/V8 workers per node, and push all the hard problems into the database. That's a totally valid strategy--but I think there's a little more to life than that. ;-)

>I think the whole multiple core thing is over blown in association with functional programming. I think it would be pretty misguided for someone to adopt a functional programming with multiple cores in mind.

The multiple core thing, it not overblown. Clock speed scaling ended a few years ago. Single thread performance scaling is dead, and we need a paradigm shift to deal with the multi-core future. Intel MIC has 80 cores and it is only the beginning. We need new tools to handle this new level of parallelism. It’s likely that some form of functional, flow-Based, or reactive programming will emerge as the tool of choice in this coming era.

Keyword is 'in association with', I am not talking about multi-core in general.
I really like Clojure. My only gripe with it is that you absolutely need to know the Java standard library/ecosystem if you intend to do anything non-trivial with it. (And my Java experience ended in 2003.)

Though they are more and more 'native' clojure libraries being released.

Though I haven't and most likely won't do anything substantial in the language, I've got a lot out of Rich Hickey's talks that have steadily appeared on the web. He seems an extremely thoughtful designer and steward.
"...I knocked up a lot of stuff which I wanted to write about."

...you did... what?

Boy, another blog echos the empty chant on functional being superior than OO without substantiating the claim.

"OO design patterns such as MVC are going nowhere." Really? MVC is going nowhere? And how is functional organizing UI and model data better?

You can promote a technology without trashing another one. People know what functional is and it has its niche as with any other things.

I think he meant OO and MVC aren't going to disappear. They're useful concepts, and functional isn't going to make them obsolete.
Clojure actually embraces many of the great lessons of OO, you'll find them in the form of first class namespaces, a standard library built on abstractions not concrete types, a multimethod facility which supports derivation, and protocols which support local and future extensions in much safer nicer fashion than what the current popular OO languages provide.

To your other points - Clojure does data great - much nicer than OO languages I've used. As far organizing UIs better Clojure programmers adopt many of the same patterns that are currently en vogue. However I think there are some more interesting new techniques just around the corner and we will be hearing about them soon enough.

I don't think it's useful to criticise other programming paradigms without substantiation, and it's hard to claim one paradigm is better than another without making some pretty large assumptions.

That said, if you subscribe to the assumption that good software design is about separating a system into discrete elements of functionality, then the functional model is generally preferable over the OO model. In OO languages, unrelated concepts such as polymorphism, encapsulation, namespacing, inheritance and (often) mutable state are combined together to produce classes and objects. In functional languages, these concepts are generally kept separate.