Hacker News new | comments | show | ask | jobs | submit login
First hundred days of Clojure (niclas-meier.de)
143 points by pron 1893 days ago | hide | past | web | 42 comments | favorite

Thanks for the long post and sharing your experiences.

I learned from you that Clojure is appealing for folks coming from Java. I read your conclusions and just got a vague feeling only. Coming from other worlds (like node/js, Haskell, ocaml, Go, Erlang and for the sake of completeness Ruby/Python, C++), I'd like to know good reasons why one should try Clojure from your point of view? What is the main USP to dive into Clojure (except the similarity to LISP)?

I just checked Wikipedia sayings things like 'treats code as data and has a sophisticated macro system' or 'concurrent programming through software transactional memory, an agent system, and a dynamic var system'—but I'd be happy to get more explanations/reasoning on this and why Clojure is so special compared to other languages.

Other people's attempts to answer your question seem to have not done what you're looking for, so I'm going to try to be more specific.

First and foremost, Clojure is a Lisp. Many other people more qualified to describe the benefits of Lisps have done so, so if you're looking to be convinced about why that aspect of the language is valuable, go and read what they've written. Looking at Clojure and ignoring the Lisp-related arguments is a bit silly.

It's dynamically typed, which sets it apart from the ML family of languages (SML, OCaml, Haskell, F#, etc). It has immutable data structures, which sets it apart from some of the elements of ML-like languages. It's eager, which sets it apart from Haskell (although Tyr42 rightly points out that many of its sequence operations are lazy). It has good support for multi-processor concurrency, unlike OCaml, because it has STM, and so doesn't have the problem of a global lock.

It's functional, and its primary programming style is functional, and it has immutable data structures, which sets it apart from Ruby, Python, Go, and to some extent JS. It's higher-level than Go/C++/C. It doesn't rely on callbacks for absolutely everything, like JS does. It's not object-oriented, which sets it apart from Ruby/Python/JS. It's a new language, which means it doesn't have the many accumulated years of cruft that Ruby/Python have, and it's well-designed, which means it doesn't have the many, many problems JS has as a language. It has multi-processor concurrency support that Ruby/Python/JS don't have.

Compared to other Lisps, it's a very practical language. It has native syntax support for vectors and hash tables. It's built on the JVM, which gives access to a lot of existing tools and libraries.

Well, most of it's sequences are lazy. map, take, ect are all lazy. Which is awesome because they are composable (at least, to me, coming from a Haskell background).

clojure has a nicer community as compared to other lisps (c.l.l was notorious). That is a major advantage.

clojure's package manager (lein/cake) is as good as bundler+gems which is a big advantage over similar languages.

However, the packaging itself is closely tied in to java/maven way of working - which I personally things needs to go away.

Great post, thanks!

First answer that gave me some motivation to look more into Clojure.

I started using Clojure roughly around the same time as the OP and have mostly abandoned Python as my general programming language in favor of Clojure. Here's why:

1. Simplicity. No more thinking about objects and their weird/complex interactions. Although even in Python I was used to writing functions instead of classes, every once in a while I was forced to think about classes. I think objects are the wrong kind of abstraction for 99% of what I do. In clojure you just define a map and write functions that operate on it.

2. Incremental development. Yes, you can somewhat do that in iPython, but it's limited. In Clojure, I can start development at the repl, move code to the file/namespace when it is good enough, run the program, go back to the repl and insert myself into that namespace and modify live code, on the fly.

3. Immutability. I was already sold on immutability from Erlang.

4. Functional programming. Same as above.

5. One language, multiple runtimes. Clojure was designed to be a hosted language. This means it is not endemic to the JVM as noted elsewhere in this thread. You can already use clojure to target the JVM, CLR, Javascript and Python. No more encode/decoce Json/Xml/Yaml whatever between runtimes.

Now, one of the reasons it took me so long to "discover" clojure is the JVM. Most books assume you are a Java programmer and are familiar with Java and the JVM, which was not my case at all. In fact, besides not knowing anything about the JVM, I also hated Java the language. But you eventually learn to like the JVM and everything that comes with it.

Thanks. Gave me a much better understanding. Now, I want to try it. How does Clojure compare to ClojureScript?

If you're starting out, I would recommend Clojure first. ClojureScript is basically the same language, although there are large pieces missing (since JS is single-threaded the only managed reference supported is atom, there is less support for runtime reflection like docstrings and exploring namespaces dynamically) but right now things are a bit rough around the edges, although they are getting better rapidly (see: ClojureScript One). It's just that when you get stuck with some issue with ClojureScript (like a browser connected REPL barfing on you or debugging the JS that comes out of the ClojureScript/Google Closure compiler, or understanding how macros work) I think it really helps to have a solid grasp of Clojure. See this for more details, although it might not mean much to someone new to Clojure: https://github.com/clojure/clojurescript/wiki/Differences-fr...

That being said, if you have some desire to experiment with alternatives to JS in the environments that is has traditionally been the only choice, ClojureScript is a compelling alternative, and ClojureScript One is an absolutely fantastic place to start. I have really enjoyed working with it and with ClojureScript in general, and huge props are deserved to those making it a better experience, because it's come a long way very fast.

> What is the main USP to dive into Clojure (except the similarity to LISP)?

1. Runs on JVM. JVM is good for long running and/or compute intensive processes, has extensive ecosystem and enterprises dig it.

2. STM and immutability makes reasoning about concurrent programs simpler. Concurrent programs are needed for a lot of problems, and are difficult to get right.

3. The seq abstractions are good. If you program idiomatic clojure, your program is as concise as your ruby code.

4. It doesn't support conventional OOP, but allows inter-operability with Java and class generation. When you are programming clojure, you use records and types which are Clojure's way of doing OOP.

All that said, look at a couple of programs written in Clojure, and try translating it to the language you are familiar with. That will be the best estimate of what Clojure is good for.

So, 1 and 4 are beneficial for people coming from Java. Could you give more info on 2 and 3 in comparison to node for example?

> try translating it to the language you are familiar with. That will be the best estimate of what Clojure is good for.

That's the point, even if I follow your advice: I don't have any clue why I should try Closure, me not coming from Java it doesn't appeal at all. I am aware that Clojure seems to be the new kid on the block many are talking about and therefore I am asking (to just get it).

My feeling is that Clojure's USP is the mentioned features combined with the closeness to Java and the JVM—so is it right to assume that it's basically the new kid on the block primarily for Java devs who like to get some fresh air without moving to far away from their ecosystem?

What I like best about Clojure is that it's so opinionated. It says: "this is how you should program". It has opinions on state and concurrency, on data structures and polymorphism, and on meta-programming. I think this is what sets it apart from all current programming languages except, possibly, Erlang.

Also, the JVM should appeal mostly to people not "coming from Java". Java devs already have the JVM. They're only getting a great programming language. I think that the biggest selling point of all modern JVM languages is the JVM - the absolutely best software platform in existence. I know of no other platform that comes close to the JVM in performance, monitoring, tooling and a wide ecosystem. Programmers that shied away from Java's verbosity and boilerplate can finally take advantage of the awesome JVM.

I had never programmed a line of Java before starting to use Clojure, so I'll try telling you my perspective.

Clojure is carefully designed to be a certain kind of simple. It does this by making good use of the bounded parametricity ideas Rich Hickey got from Haskell. For instance, many, many objects implement the Seq protocol and thus there are many, many functions which can operate on them. This is a different kind of orthogonal and division of concerns than Java seems to use (in fact, writing Java/Clojure interfaces is hard, not because there's any sort of data conversion or calling convention trouble, just because the Java ideas feel terribly clunky in a Clojure program).

You also get the usual functional/lisp benefits from Clojure. Declarative style (accentuated by some lazy semantics), higher order looping constructs, homoiconicity and macros.

Clojure isn't my favorite language, but it sits at a pretty neat spot in the design tradeoff. It also has a very vibrant community of smart people, which may or may not be a direct consequence of it being a JVM Lisp.

For me Clojure is the best Lisp available, JVM platform or not. It's more functional than the other Lisp, use immutable data-structures, have a lot of data types (vector, set, map, list) with literal syntax and unified abstraction on top of them and the macros are easier to write than in the other Lisp thanks to autogensym and name capturing.

Main selling point: it's Lisp and it's the best available.

A lot of other people have already made the case for Clojure, and you may not be swayed by me either, but I want to add one point that hasn't been explicitly made yet.

I think irahul's point number 4 is one of the more interesting parts of Clojure, and would be beneficial for any programmer who is interested in alternatives to classical OOP, as found in Java, Ruby, Python, C++, C# and many other languages.

Clojure's approach to OOP has been described by many people as "OOP a la carte", meaning that you get to pick and choose which parts of OOP you want to leverage. Protocols, multimethods, hierarchies,... they all give you a lot of flexibility and choice to determine the kind of OOP you want to use.

I think in general, Clojure is just a fantastically well designed language, and that the underlying goals of reducing complexity in programming are things that almost any curious programmer should investigate. I think if you just went to clojure.org and read through the list of links on the left, which wouldn't take more than an hour or two, you would get a great idea if there's anything you find interesting. Alternatively, the "Clojure for Java Programmers" talk is a great intro to the language for non-Lispers, whether you're coming from Java or not. The "Clojure for Lisp programmers" is even better, if you have some experience with Lisp.

Clojure also targets JavaScript via ClojureScript. So you could write Node.js apps with ClojureScript as well.

Let's say you have some data, perhaps some of it is from an SQL database, some from files, some from NoSQL. In Clojure there is a small set of data structures, and a unified lazy sequence abstraction that can bring all of these together. You've got a huge standard library of functions for manipulating sequences and maps, rather than having to write your own one-off functions for working with custom OO classes.

Perhaps you want to do some processing on the data and convert it to JSON. Immutability and lazy sequences let you work from the problem towards the solution by layering small reusable functions over your data to get it to where you want it. And you can do this without it being hopelessly inefficient.

Another advantage that is easy to overlook is the environment. The ideal Clojure environment is an editor or IDE that is backed with a REPL. You can write a bit of code in your editor, perhaps assign some test data to a variable, and then with a couple of keystrokes, send the code to the REPL and see it working in a live environment. Perhaps your function isn't quite right, no problem, fix it, a couple more key-strokes and try it again. Writing code incrementally in this way has a similar effect to test-driven development. You are writing small pieces of code and the code is being tested as you develop it (albeit only informally).

Clojure's approach to state is often cited as being great for concurrency, but it really simplifies things across the board. Old hat for those coming from an ML background, but for most this is a huge benefit vs traditional OO: http://clojure.org/state

Agreed; this was the most revolutionary idea for me when learning Clojure (coming from a classic C/C++/Java background).

Clojure's approach to state is so good/different that it has completely changed the way I write code. It was a huge paradigm shift for me.

It really depends which "world" you're coming from. Someone coming from Ruby might benefit from the immutable data structures, but someone coming from Haskell would take such things for granted.

Thanks, then I'd opt for a comparison to nodejs if you don't mind.

EDIT: Sorry that I was unclear, I meant obviously JavaScript, in particular server-side JavaScript, e.g. Node.JS

In my opinion, I'd say the main difference is that Clojure tends to be a box of many tools that have very specific functionality, while Javascript tends to have fewer tools with very generic functionality.

For instance, in Javascript an object is a way of storing values, defining an identity (i.e. a mutable pointer to a value), namespacing, polymorphism and inheritance.

In Clojure, each piece of functionality is handled by a different tool. If you just want a value you can use an immutable map. If you want a changeable identity you might use an atom. Polymorphism is provided by protocols or multimethods, namespacing by namespaces and so forth.

The advantage of using discrete tools is that you can afford to specialise. Clojure has atoms, refs and agents for maintaining identity, and each has unique properties. Libraries (such as Avout) can extend this with their own systems for maintaining identity.

Javascript, along with many OOP languages, has the problem that objects are a jack of all trades, but a master of none. An object cannot handle atomic state change as well as an atom, nor handle polymorphism as well as a protocol, nor is it a good at namespacing as a Clojure namespace. By being so general-use, it can't be as good as tools that focus on doing one job.

Node.js is not a language.

Just as an FYI there is some work to implement a Lisp with the Clojure dialect for Python and the standard library: https://github.com/halgari/clojure-py

Why would you need an IoC framework in clojure? It's already built in, pass a function.

I think the author wants something like parametrized modules, but the idiomatic way to do it is to use vars created by (def) or (defn) with (binding) which gives you thread-local global variables.

What scare me the most about Clojure is collaborate with other devs. I.e. In 2 years, who will maintain the project.

We're switching to Clojure specifically because of maintainability. In Clojure your functions tend to be concise, operate on immutable data structures (no side effects) and can be tested/mocked easily. The lack of boilerplate alone makes for a much better signal-to-noise ratio during review or refactoring.

I've been a Perl hacker for 15+ years and still spend too much time reviewing code from CPAN to understand what's going on. I've been using Clojure for about 6 months and find that I can read and understand many of the major Clojure projects on GitHub quickly. Some may claim that says more about Perl than Clojure, but I'm chalking it up to Clojure :)

I'd be very much interested to know more about your experience and insights comparing Perl and Clojure. Would you mind writing them up?

I'd love to do a detailed blog post on it, but unfortunately I'm too swamped right now.

The summary:

- Any serious codebase is going to exceed the complexity you can hold in your mind at one time

- Once that happens, it's crucial that you can reason about the part you are focusing on

- Interactions between components are MUCH harder to reason about if they share mutable data

- It's possible to design cleanly isolated components in any language

- But we found that Clojure makes it natural to write concise, testable and isolated code

- So much so that writing sloppy/badly designed systems _feels awkward_ in Clojure

- For us, that was more beneficial than a book full of patterns or best practices

- YMMV, but I'd try it out and be sure to get over any aversion to Lisp before passing judgement

edited for formatting

Every single time I visited on a github repo of a Clojure based project, almost all of them are structured nicely (src and test) and have unit-tests.

This alone makes me think that Clojure developers are just regular people who care of the maintainability aspect of their code (and quite possibly the readability). Not just a "hacker" that writes code and jump into the next shiny stuff.

As a non-participating viewer from afar, Clojure community seems to have less hipster, less emotional, less roller-coaster, but more mature feeling when it comes to software development.

It also helps that they have a unified build+dependency tools, not a bunch of "upcoming great projects that will solve your build+dependency problem for the umpteenth time".

As a non-participating viewer from afar, Clojure community seems to have less hipster, less emotional, less roller-coaster, but more mature feeling when it comes to software development.

I wonder if the average age of clojure hackers is higher? I'm not in the Clojure community but it appeals to me (in my forties) coz... well... Lisp! Brings back fond memories of when I shared an office with the dude who did the Common Lisp implementation for Poplog.

The folk I know who are into Clojure are all in their 30s-40s.... but it's probably just sampling bias.

If the Clojure folks are in the 30s and 40s that'll be awesome: a community for older software programmers (with a few dads or even grandpas in between).

We are not going to get any younger so I very much welcomed the existence of such community.

The Clojure/core team helped tremendously by many brilliant people volunteering fixes, features, and docs -- just like now.

Indeed, the developer base around Clojure and core libraries seems to have reached a critical mass so the continuity in that front is no longer a real concern.

However, I think the question was about projects built with Clojure, i.e. how to ensure that future developers in the company I work for will be able to continue where I left off? The global Clojure talent pool, while growing, is still on the small side (e.g. compared to even Ruby).

I think this is a moot point, as we've seen time and time again using technologies such as Clojure/OCaml/Haskell/Etc is a boon for hiring great talent, not the other way around.

http://janestreet.com/minsky_weeks-jfp_18.pdf See part 4 "Personnel" for Jane Street's experience hiring OCaml devs.

An excellent point. Definitely something we should all keep in mind when promoting cutting edge tech choices.

That said, I don't think the matter is quite that straightforward where I come from; I would imagine Clojure dev head count in the whole of Finland is in the low double digits. If I were making business decisions involving future staffing, I would not feel confident I could replace the (hypothetical) only in-house Clojure dev in this job market.

But what's the number of good developers? I think the point is that good developers can learn whatever language they need. You don't need to hire Clojure developers.

Yes, thats something that some people don't seen to get. Good developers not only can learn new languages as needed, but they will learn new languages and idioms with time, else they will quickly become obsolete.

We have a team of Clojure devs and I think all but one of us has learned Clojure "on the job". Clojure is not hard to learn, imho.

I'm also a pretty big proponent of distributed teams :)

That said, as others have noted, if you're hiring quality people, there's no reason they can't learn Clojure on the job. Plus if you make an investment in your people they're more likely to be invested in you ;)

What's a good place to start learning Clojure?

I came across a HN comment recently that has a bunch of resources: http://news.ycombinator.com/item?id=1033503

It's old, but still is useful.

Also, see http://dev.clojure.org/display/doc/Getting+Started

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact