First hundred days of Clojure
niclas-meier.de
niclas-meier.de
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.
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.
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.
First answer that gave me some motivation to look more into Clojure.
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.
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.
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.
> 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?
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.
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.
Main selling point: it's Lisp and it's the best available.
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'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.
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).
EDIT: Sorry that I was unclear, I meant obviously JavaScript, in particular server-side JavaScript, e.g. Node.JS
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.
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 :)
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
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".
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.
We are not going to get any younger so I very much welcomed the existence of such community.
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).
http://janestreet.com/minsky_weeks-jfp_18.pdf See part 4 "Personnel" for Jane Street's experience hiring OCaml devs.
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.
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 ;)
It's old, but still is useful.
Also, see http://dev.clojure.org/display/doc/Getting+Started