Close
Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

LABS
Everything I know about Clojure after one week

This week I decided to clear out the cobwebs of my Ruby-trained brain and try a completely different language. Ruby and Rails have been my staples for over seven years, and I’m starting to tire of my patterns of thinking, and of the common problems found in large Rails applications. Specifically, I’m pretty bored of running into slow test suites and difficult-to-maintain apps. I suspect the primary cause of these problems is the entanglement of business logic with database and other stateful resource code. I get the feeling that it can’t be just coincidence that so many teams of competent developers fall into the same old traps.

I’d heard a bit about Clojure, so decided to explore the ecosystem and community. I’m attracted to the idea of learning a functional language, avoiding mutable state and re-evaluating the object oriented programming paradigm. Functional programmers are often accused of being “idealistic”, “academic” or a variety of other thinly-veiled primitive insults. If nothing else, I could learn to sympathise with these crackpot underdogs who claim to have the cure for most of the technical pain I suffer in my chosen occupation.

Hopefully this assortment of links and lessons learned will encourage you to try out the language, or inspire you to try something else that’s refreshingly new.

Clojure is easy to get started with

There are various tutorials online. However, they can be a little out of date. The quickest route to Clojure hacking is via leiningen, a sort of rake-meets-bundler utility. Assuming you’re on a Mac, have homebrew installed, a recent JDK and the usual code compilation dependencies:

brew install leiningen
lein repl

That’ll pull in Clojure for you. Once you’ve had a play in the REPL, use leiningen to generate an app:

lein new my-test-project

The project.clj that the above command generates is the equivalent of a gemspec, and declares the dependencies of your app. Leiningen helpfully fetches dependencies lazily when you start a repl, server or run tests. No bundle install step!

Homebrew can also install Clojure for you, but this version will be independent of leiningen apps. When you install it, you’ll be recommended to use a REPL wrapper for rlwrap. I’ve found that the one from the wikibooks site works better (i.e. at all).

Rich Hickey is an entertaining figurehead

Rich Hickey, creator of Clojure and designer of Datomic, the FP-friendly database system everyone’s talking about, has some inspiring talks from the end of last year about Clojure and Datomic, and notably why everybody is doing programming wrong. There are some pretty strong views in the talks, but they’re a refreshing take on the sociological patterns in our industry, and how project pathologies can be treated.

There’s an active community

Many clojure developers are ex- or current-Rubyists. For example, Jay Fields maintains the expectations testing library (more on this below).

Clojure has artsy cred, too: there are several videos on the web showing Clojure being used for live music.

Syntax change requires healthy brain re-wiring and thought simplification

After spending so much time wrapping my head around object-oriented constructs and trying to work out how best to structure OO programs, it’s a refreshing change to work with a functional language. Not having a CS degree, I’d previously tinkered with Scheme following a workbook. I wasn’t put off by parentheses, but did have some fears that I’d be transported back to the bad old days of the top-level PHP namespace. I soon realised, however, that my beef with PHP was mainly the aforementioned comingling of state and logic, as well as the inconsistencies of method signatures and names.

Clojure philosophy is all about consistency and reuse. I’ve trained myself to believe that reuse is all about identifying concepts, naming them and adding an abstraction, often a named value object. I’m pretty attached to my explicitly named classes of values, like SubscriptionEvent or PersonName. This is largely in reaction to the recognisable OO smells like Primitive Obsession. The problems inherent in such smells generally melt away in the FP world, since you’re encouraged to use the built-in types to provide equality and the like, and to use the common functions like map, reduce and so forth to achieve what you would do in OO with a value object’s methods.

Web development is potentially full-stack

This is worth knowing if you don’t already: Clojure already compiles to JavaScript in the browser, as well as to Java on the server. So we potentially could be doing single-language full-stack development like node.js but without the oft-cited pitfalls of JavaScript. An excellent resource for newcomers to Clojure is this translation between JS and Clojure.

I’ve begun a project for playing around with the Compojure web routing library. Compojure forms the basis of many Clojure web apps, and I’m using that repository as a place to stick my learnings. I’m test-driving each new feature, so that it might serve as a reference for other newcomers on how to do TDD for Clojure web apps.

TDD is easy, fast and totally not banned.

Watching the Hickey talks, you might come away with the impression that the Clojure community is anti-TDD. However, there are some excellent developments going on in this area, such as the aforementioned Jay Fields’ expectations library, which provides an achingly simple way to express intent in tests. See my first attempts at testing a web app for an example of this. Structural whitespace optional.

Monads still a mystery

One week just wasn’t enough. See if you can figure it out and send me a postcard with a succinct summary.

Until next time!

Comments
  1. Dmitri says:

    I’m trying to make life easier for web dev with Luminus (http://www.luminusweb.net/) as well. It’s a template for Ring/Compojure apps along lots of documentation.

  2. Andrew Bruce says:

    Thanks for your comments, Eric. We’ve been reading the Nathan Marz book in a group here at Pivotal. Like Hickey says in his Value of Values talk, it’s pretty embarrassing the amount of resistance that we currently put up when asked to implement analytics or time-based queries of any sort. Not to mention the fragility of systems that mutate state – “oops, we lost your data again, you don’t mind if we restore from yesterday do you?” I think this happens largely because of the tools we use, and the mindset we’re in as a result of using them for so long. Both the Lambda Architecture and Datomic approach seem to give us room to grow in terms of what we offer to the businesses we serve.

    Absolutely agree with you on the wins in terms of immutability and how important it can be in any language. As for TDD, it’s a huge area. I made a gross oversimplification of something I briefly caught onto in one of the Hickey talks. Effective TDD takes a lot of practice, and I’m constantly learning new ways to approach it. I’m hoping some of the pain associated with test driving is alleviated in a functional language due to the enforced separation of state, but I don’t doubt there will be new challenges too.

  3. Masashi Fujita says:

    A good monads tutorial is here: Functors, Applicatives, And Monads In Pictures http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

  4. Stewart says:

    This may help with Monads:

    http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

    It helped me get a handle on them for all of 2 seconds :)

  5. Vinicius Fuentes says:

    I’ve found monadic, a Ruby gem to add monadic patterns to Ruby, the best way to understand monads. for my ruby-wired brain. Check it out, maybe it helps: https://github.com/pzol/monadic

  6. Sam Backus says:

    If you’re in the Boston area and interested in Clojure, come checkout the Boston Clojure meetup group.
    http://www.meetup.com/Boston-Clojure-Group/

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *