Posted on 16 November 2011
I was wanting to play around with counterclockwise, the eclipse plugin for clojure, recently, when I got stuck trying to open an existing leiningen project in eclipse. If I were coding Java, I’d have no trouble with the analagous problem of importing a maven project into IntelliJ, but I struggled a bit with this one enough that I thought I’d miniblog it so I’d remember in future.
This post assumes you have Leiningen, eclipse and counterclockwise installed.
Install the lein-eclipse
plugin. (You may want to check the
latest version on
clojars. As of writing, there seems to be a rival 1.1.0 from
robertrolandorg; I’m not sure of the difference.
$ lein plugin install lein-eclipse 1.0.0 Including lein-eclipse-1.0.0.jar Created lein-eclipse-1.0.0.jar
Run lein eclipse
to create the files eclipse needs:
$ lein eclipse Copying 15 files to /Users/philippotter/src/mobile/jquery-mobile-experiment/lib Created .classpath Created .project
Then, in eclipse, do “File->Import->Existing Project into Workspace”. You should now have your project imported.
Posted on 12 November 2011
I’m currently attending the second annual Clojure Conj, the premiere Clojure-specific conference. One of the themes that has been emerging is evangelizing Clojure: getting more people to use it, and convincing people to use Clojure who otherwise wouldn’t choose to use it.
This was in fact the central theme of Neal Ford’s talk “Neal’s Master Plan for Clojure Enterprise Mindshare Domination”, in which he put forward his ideas for how to get large organizations full of institutional inertia to adopt Clojure. Phil Bagwell also made reference to this in the introduction to his talk, in which he asked everyone using Clojure in their day job to put their hand up, then asked everyone who’s never deployed Clojure to production to put their hand up, then asked group 2 to talk to the nearest person in group 1 and ask them how they got to work in Clojure.
Clojure evangelism has also been a common theme of Q&A sessions after talks: a talk on ClojureScript will often be followed with a question such as “How do you fit this into an existing JavaScript project?”
There are a few key themes emerging:
There’s a lot of competition amongst the new language communities, particularly between Scala, Clojure, and Groovy. This is absolutely fine and as it should be. Furthermore, if Scala is successful, this is in no way directly detrimental to Clojure.
Scala, Clojure and Groovy are in competition, but they are not enemies of each other. The real enemy is the status quo. It is the nasty feeling that people have when they say things like:
Ultimately, these statements reflect a sentiment that staying with the same old technology is safer than trying to improve productivity by choosing a newer, but less well-known, technology.
If a client has switched from Java to Groovy, Scala, or JRuby, they have already rejected the status quo. Encouraging an environment in which people feel able to explore new technologies will make more people who are interested in Clojure overcome their fears and try it out. In other words, a rising tide raises all ships.
By and large the feeling of the conference has been upbeat and positive, rather than tribal. That is why, when a couple of off-hand jokes about Ruby were made, people immediately called it out as nonconstructive.
Clojure and Scala in particular are languages which make many things possible which simply aren’t possible in other languages. This can lead to a feeling of superiority. Fight that feeling! Clojure is not going to gain mindshare by denigrating Ruby and Java; it is going to gain mindshare by promoting itself and solving problems effectively.
Furthermore, there are many problem domains where the existing tools are entirely appropriate — Rails is a fine framework, and although it has limitations, those limitations don’t manifest in most use cases. Even some of the clojure.core team use Rails for most of their work, and Clojure only for the difficult problems. Denigrating Rails builds walls, when we want to be building bridges.
Many recent successes in language proliferation have been achieved simply by providing great tools in those languages. Even if someone doesn’t particularly want Ruby, they might well want Cucumber. If they don’t want Groovy, they might still want Gradle.
On my current project, we’re using node.js for a test stub, even though none of us is a particular JavaScript advocate. Node was just the best tool for the job, so we used it. But that’s caused a lot of us to look at JavaScript in a new way, and I’d say we’re all more likely to use JavaScript again in future as a result.
This is a great way to build up mindshare. I think one tool I’ve learned about at the conj which could fill this role is pulse from Heroku, described in Mark McGranaghan’s “Logs as Data” talk. Pulse is a tool for processing logs not as a stream of bytes but as a stream of events and rich data objects. Another is Cascalog, from Nathan Marz at Twitter, which is a high-level abstraction over Hadoop MapReduce, which creates a very nice internal DSL for modelling MapReduce computations as queries and predicates.
It’s been a really exciting conference for me, because Clojure is both a great language, and at a key point in its history. It has reached maturity, it is being used by a few people in production to solve interesting and difficult problems; but the next step is to evangelize Clojure, to get it used in earnest by more and more people.
Happy hacking!
Posted on 28 October 2011
Sadly I wasn’t able to attend this month’s dojo; but Robert Chatley has done a great writeup.
Thanks also to Mark Needham for stepping in at the last minute as a replacement ThoughtWorks representative at the dojo!
Posted on 25 October 2011
I was inspired to learn about monads by Chris Ford recently; his description of encapsulating impurity safely within a pure language had me intrigued immediately. I decided that I wanted to learn about monads in Clojure, a language I am currently diving into.
However, I found learning about monads in Clojure full of fake difficulty (or accidental complexity, if you will). Here I document the issues I found. And the key issue I came across was this:
You probably know where I’m going with this. Clojure is dynamically typed. Haskell, the spiritual home of monads, is statically typed. For me, the key to understanding monads was reasoning about types — in particular, drawing a clear distinction between the ordinary type and the type of a monadic expression.
In drawing this distinction, it helped me reason about the behaviour
of the monadic functions. By learning that m-bind
must return a
monadic expression and not a simple value, I learned a key fact about
monads; but the number of times I tried to write m-bind
expressions
beforehand which did not return monadic expressions beforehand was too
many.
It’s quite possible to reason about types in a dynamically typed language, but it’s made much harder. If your reasoning is faulty, the program will try to carry on regardless, and in Clojure’s case, give an incredibly cryptic error message. This is not an environment that makes learning easy. If I had been learning in Haskell, my failure to understand the distinction between monadic expression and ordinary value would have immediately been set right by the type checker.
But it’s worse than just making learning hard: Clojure’s dynamic typing has led to a pervasive failure of type reasoning.
A key example of this is that Clojure’s implementation of the maybe
monad, maybe-m
, breaks the monad laws! It does this because it does
not properly distinguish between the monadic expression and the
underlying type. The law in question is the first monad law, expressed
here as a Midje test:
;;; given a monad which defines m-bind and m-result, ;;; f, an arbitrary function, and ;;; val, an arbitrary value (fact "The first monad law" (m-bind (m-result val) f) => (f val))
The failure of maybe-m
to adhere to this law is demonstrated thus:
;;; failing midje test (fact "maybe-m should adhere to the first monad law" (with-monad maybe-m (m-bind (m-result nil) not)) => (not nil))
The reason that this law is violated is that the maybe-m
monadic
expression type is no different from the underlying value type. It is
therefore possible to find a value such that (m-result val)
is
nil
, the maybe monad’s value for failure.
The Haskell Maybe monad is not so sloppy:
> let myNot x = Just (x == Nothing) > (return Nothing :: Maybe (Maybe Char)) >>= myNot Just True > myNot (Nothing :: Maybe (Maybe Char)) Just True
This is because in Haskell, there is no value foo
such that Nothing
== return foo
; in Clojure, there is such a value: (= nil (m-result
nil))
.
The repercussions of maybe-m
’s violation of the first monad law are
relatively minor: it means that when using maybe-m
, the value nil
has been appropriated and given a new meaning; which means that if you
had any other meaning for it, you’re stuffed.
For example, suppose you wanted to implement a distributed hash table
retrieval, where failure could be caused by a network outage. You want
a function behaviour similar to (get {:a 1} :b)
, where if the value
is not in the table you return nil. If you use maybe-m
to perform
this calculation, you cannot tell the difference between failing to
communicate with the DHT, and successfully determining that the DHT
does not contain anything under the key :b
; both will result in the
value nil
. Worse, if you want to use this value later in the
computation, the maybe-m
will assume a value missing in the DHT to
be a failure, and cut your computation short — even if that’s not
what you wanted.
If you want to learn monads, do it in Haskell.
If you must do it in Clojure, the key is to understand and distinguish
the various types in play. The monadic type is distinct from the
underlying type. m-result
takes an underlying value and gives you an
equivalent value in the monadic type. m-bind
takes a monadic value,
and a function from an underlying value to a monadic value.
Posted on 19 October 2011
I recently found out that a vegetarian friend of mine had never heard of chestnut roast! Although I am a massive carnivore now, I was in fact a vegetarian for five years, and during this time I discovered that chestnut roast is possibly the best vegetarian dish there is. I mentioned it in passing to my fiancée, who immediately suggested that I could cook it for her. I should learn to keep my damn mouth shut.
Heat the butter in a frying pan, then chop and fry the onions. After a while, chop and add the mushrooms.
Meanwhile, chop/bash/whizz the cashews. Add the chestnuts and whizz or mash.
When the onions and mushrooms are done, add to the nut mix and stir well. Add the goat’s cheese, veg stock, chopped parsley, sage and tarragon, and breadcrumbs.
Roast in a pre-heated oven at 200 °C for an hour.
Serve with potatoes and veg. We had mash and peas.
Delicious.
I think next time I’d ditch the tarragon, as it tends to overpower the rest of the flavours. Also, I think I have too many things competing with the chestnuts — the mushrooms and breadcrumbs are probably diluting the flavour too much. This is a delicious meal, and one I had for christmas dinner when I was a vegetarian. It takes a fair amount of prep work and a long cooking time, so it’s not going to become a normal after-work evening meal for me, but I’ll keep it in my repertoire for special occasions.