Installing Leiningen behind a proxy

Leiningen is the defacto build tool for clojure projects. Installing in any corporate environment probably means you will need to install behind a proxy, which I found wasn’t that well documented even though it’s very simple with just a few steps:

  1. Set the environment variables http_proxy and https_proxy, leiningen will honor these settings.
  2. Download the lein installer script from http://leiningen.org/#install
  3. Make sure the script is executable & on your path
  4. Run it with the argument self-install, for example on windows run lein.bat self-install

After that you will have it installed, from anywhere on your machine run lein new my-project and get to work!

Read More

Clojure by example: Basic Application

This weekend I decided to knock up an example of some of the great features of Clojure such as java inter-op, multi-threading, it’s data structures and its functional style of coding.

Clojure is a fantastic language that runs on the JVM, it’s a true modern language that takes into account the impact that Moore’s Law is becoming more prevalent in programming and that object orientation comes with a number of downsides that slow the progress of creating reliable, quality software quickly. If you’re new to Clojure its well worth checking out this video

I created this project to demonstrate how a simple use case can be answered using the various features in Clojure, the source code is up on github. The features demonstrated are:

Functional Code

The key to creating concise, reliable and quality code in Clojure is that its a LISP. Taking the step from Java to Clojure means getting used to working in a lisp, if this is your first step into programming Clojure I would suggest you checkout Try Clojure and the Clojure Koans before looking into this code, it will make a huge difference to your understanding.

To understand how this works in use, look the following line. It takes a list of tweets, filters out any tweets that have less that 5 retweets, sorts the list in order of tweets (which by default is ascending) and then reverse that list.

(reverse (sort-by :retweets (filter (fn [x] (< 5 (x :retweets ))) @tweets)))

For anyone coming from a Java world being able to do that in a concise, clear way is a revelation.

Java Inter-Op

As Clojure is built on the JVM it provides access to any libraries and code that would be available to an application written in java. This is a killer feature of Clojure, it means that it already has a huge base of libraries that it can access and use. There are a number of special forms for accessing the underlying functions which make use of the dot operator, for example you can call a function on a java object as such:

(.getText x)

Multi-Threading

Clojure has first class support for working in multiple threads, it’s software transactional memory model ensures safe and consistent access to data. In this example the data is accessed using refs, it is read by dereferencing (using the @ symbol for shorthand):

@tweets

Writes occur in a dosync block, very much like transactional writing to a database.

(dosync
    (ref-set tweets
    (map (fn [x] {:content (.getText x) :retweets (.getRetweetCount x)}) (get-timeline))))

Data Structures

Clojure provides 4 basic data structures, lists, vectors, hash-maps and sets. Their mapping to java objects can be seen as such:

  • List – Linked List
  • Vector – Array List
  • Hash-map – hash-map
  • Sets – Sets

The difference between the java collections and Clojure ones are that the Clojure ones are immutable and persistent. These qualities mean that accessing them in the multithreaded manor above ensures it is safe, fast and reliable. Again, if these ideas are new to you, it’s worth watching the video above.

Summary

I wrote this code to demonstrate some of the key features of Clojure and as a stepping stone from learning the basics into seeing how these tools could be used to create a useful program in very few lines of code. Clone the repo, play around and if you think it could be improved please chuck me a pull request.

Read More