A Blog. » Fixing paredit in the clojure REPL
I haven’t fully tested this yet, but it would be great if it worked!
I haven’t fully tested this yet, but it would be great if it worked!
Want!
A great post on why Clojure is practical.
2 is a smell : Pure Danger Tech
Solid advice. I’m happy to report that I don’t have any occurrences of second in my own code base, but it wasn’t because I knew or thought of it as a smell. I have structure specific code all over, though, because I deal with a particular map data structure that’s core to my system.
I wonder if I can get rid of that…
Lately, I’ve been getting into a new(ish) language for the JVM called Clojure. It’s wicked cool, fulfills my rabid desire to learn a Lisp, and is backed by some people I’ve come to respect a lot.
The bullet points of Clojure are fairly simple:
Lisp is this ultra-cool language designed by a guy named John McCarthy over 50 years ago which itself was based on the Lambda Calculus. Amazingly, he proved that you can create a language where every computable problem can be expressed in terms of just 7 primitives (quote, atom, eq, car, cdr, cons, and cond). As such, Lisp has been described as beautiful, elegant, concise, syntaxless, etc. and all of the negative corollaries you can imagine: obtuse, obscure, opaque. Doubtless, though, no one interested in Computer Science can not get goose bumps reading about all of computation being described in just 7 terms.
Lisp has this funny habit of continually coughing politely and reminding people that it was doing every cool new innovation in computer science since it’s invention. XML has been described as Lisp redone. Metaprogramming is just Lisp multimethods and ad-hoc hierarchies. Functional programming like Haskell? It’s just Lisp. Of course whenever that comes up there’s a large bevy of extremely smart people who calmly attempt to remind everyone that it’s not exactly true. Lisp didn’t invent every good idea known in computer science. What is true is that as programming languages become more powerful, they do begin to adopt features of Lisp and many other functional languages that Lisp has had for decades. They do so with different syntaxes and larger libraries, but many of the greatest ideas of computer science were expressed quite elegantly in functional languages like Lisp.
As such, Rich Hickey, who was a Lisp fan to begin with while not being able to afford to be a Lisp professional, thought it wise to attempt to reintroduce the language, especially since it has such potential power for use in todays concurrency-oriented world.
Where many Lisps have failed in the past has been in the area of libraries and platforms. I’ve never coded in Common Lisp, and the old saying is that “Every C program includes a poorly written and buggy implementation of half of Common Lisp”, but at the same time, since Lisp never really caught the imagination of the professional development community, new libraries are hard to come by. Compared to the explosion of Libraries for a poor language like Java, Lisp has always been somewhat left in the dust.
So M. Hickey decided that he’d solve the library problem, and the GC problem, and the System Call problem, and the etc. problem, by using the stunning piece of technology called the JVM as his platform. This means that at the expense of adding a couple of new primitives to McCarthy’s 7, he was able to provide amazingly good interoperability with Java, and thus open up the entire ecosystem of Java libraries to Clojure developers.
Many Clojure programmers like to say that Clojure does Java better than Java. And I’m inclined to agree.
A canonical example:
(doto (JFrame.) (add (JLabel. "Hello World")) pack show)
It’s important to note that the only special, Clojure, part of that
line is doto. Everything is purely Java Swing. (JFrame.)
constructs a new JFrame, doto is a macro that is a little like the
with operator of languages like Ruby that allow you to avoid typing
the thing you’re operating on over and over and over again, the rest,
if you’ve done any Swing programming, should be familiar to you
because it’s just native Java calls.
The interesting thing here, for people who think that Lisp stands for Lots of Irritating Superfluous Parentheses, is that that code snippet beats Java, handily, for paren count.
Beyond being able to call Java from Clojure, all of Clojure’s core abstractions are defined in terms of Java Interfaces which mostly implement things like Collection. All data is the Object version of that data (i.e. ints are Integers), but can be coerced into primitive types for performance. That means that Java code written against the core Java abstractions (like all good code should be) can seamlessly interoperate with the Clojure data structures.
Java interop in Clojure rocks. Really.
I’ve never had the joy it sounds like programming concurrently in lock based languages personally, but reading through JCIP and listening to people who’ve done it extensively scares me enough that I never want to.
Clojure provides amazing support for concurrency directly in the language through reference types, persistent, immutable data structures, and a remarkable STM implementation based on the MVCC.
While Haskell may be the only possible truly functional language, Clojure strikes a better balance between the real world that does actually change and the functionally pure world that’s easy to reason about and model. Rich Hickey is not an academic by profession and he knows that when you’re programming most systems, you need side effects and you need state. Suffice it to say that where purity conflicted with practicality, M. Hickey sided with practicality most of the time. The persistent data structures and how they interoperate with change and transaction semantics is truly remarkable and easy to grok. At the end of this post I’ll link to some videos that are worth your time which do a much better job describing why Clojure’s concurrency primitives are the best concurrency story on the market today.
Because of pragmatic Dave’s efforts, software kata seem to be all the rage these days. I was actually introduced to them via Uncle Bob’s excellent Bowling Game Kata, which indeed is the subject of this post. Uncle Bob, in this case though, is the one who hit the nail on the head as far as the point of kata and how they should be thought about, over against Pragmatic Dave.
A kata is meant to be memorized. Students of a kata study it as a form, not as a conclusion. It is not the conclusion of the kata that matters, it’s the steps that lead to the conclusion. If you want to lean to think the way I think, to design the way I design, then you must learn to react to minutia the way I react. Following this form will help you to do that. As you learn the form, and repeat it, and repeat it, you will condition your mind and body to respond the way I respond to the minute factors that lead to design decisions.
So, what’s his basis?
From Wikipedia:
Kata is a Japanese word describing detailed choreographed patterns of movements practiced either solo or in pairs.
One explanation of the use of kata is as a reference guide for a set of moves. Not to be used following that “set” pattern but to keep the movements “filed”.
A nice moving example (for however long it stays up) can be found in this clip from Fist of Legend round about 9 minutes 11 seconds.
A software kata takes the traditional notion of a short but thorough series of movements designed to tune your body to react in certain ways to a preconceived set of situations as well as to become used to moving in certain ways and translates it into a series of actions leading to the solution of a software problem.
It’s very important to realize that the ‘point’ is not the solution. If that were the point then ‘practicing’ a kata would make no sense. Once the problem’s been solved, why solve it again? Even more important is that no problem can be truly interesting and solvable in a short enough amount of time that you can practice it every day. Katas are short enough that you can spend 15 minutes in the morning ‘loosening up’ with one and actually get some benefit from it.
A kata a day keeps the debugger away
Uncle Bob is an all around great dude who cares intensely about software, developers, and customers. His video from OREDEV about clean functions changed the way I thought about writing code. I read pretty much anything I can get my hands on from him. The reason I bother mentioning him at all is because he’s the one who designed this particular kata in Java.
Stuart Halloway is another of these luminaries who I’ve begun to come in contact with mainly because of my interest in Clojure. He’s one of the big name Clojure users and is a regular contributor not only on the Google Group but on the actual code base as well. His solution is what I ultimately based this kata on, with some minor tweaks..
The bowling game Kata is quite simple.
The problem is that we want to score a game of American 10 pin bowling.
The steps to memorize are these.
Test 5 should actually require no extra coding. The way it was originally published was as a Java kata.
Now, Uncle Bob is getting into Clojure and he wants to translate his kata into it. This leads to some difficulties and some not too pretty code as it’s really his first foray into Clojure any way. He publishes it nonetheless and asks for feedback.
Stuart Halloway comes along and does a nice implementation of the kata solution and even publishes a wonderful little post about his thoughts while refactoring.
So why am I bothering writing this? Well, because I can’t find anywhere where this kata was published as a kata on the web and I figured I’d rectify that. Remember, the kata isn’t the solution, the kata is the process leading to the solution. For a kata to be a kata, you should be working in the same IDE and use the same file names, and literally do every single thing exactly the same as the kata you’re following. Do it a hundred times before you start looking for ways to improve it!
Here’s the kata, then.
I’ll give the high level steps. The easiest way to learn the kata the way I do it is to watch the video I’ll embed at the end.
A Design Session
(repeat 0) or (repeat 10)(reduce + (map score-frame (to-frames game-rolls)))(strike? game-rolls)game-rolls => (10 5 3 0 0 0 0 ...)
(to-frames game-rolls) => ((10 5 3) (5 3) (0 0) (0 0) ...)Set Up
main and test directories under their.bowling-game.clj in both of those directories.bowling-game namespace in test/bowling-game.clj and
use deftest, is, and run-tests from clojure.test.Test 1
You’re first test!
Score a gutter game. At the end you have
test/bowling-game.clj:
(is (= 0 (score-game (repeat 0))))
main/bowling-game.clj:
(defn score-game [game-rolls]
0)
Test 2
Score a game of 2 pin frames. At the end you’ve added
test/bowling-game.clj:
(is (= 20 (score-game (repeat 1))))
main/bowling-game.clj:
(defn score-game [game-rolls]
(reduce + (take 20 game-rolls))
Test 3
Score a game of 1 spare and a 3 pin frame. At the end you’ve added
test/bowling-game.clj:
(is (= 16 (score-game (concat [5 5 3] (repeat 0)))))
main/bowling-game.clj:
(defn score-game [game-rolls]
(reduce + (map score-frame (take 10 (to-frames game-rolls)))))
Test 4
Score a game of 1 strike, an 8 pin frame, and gutters. At the end you’ve added
test/bowling-game.clj:
(is (= 26 (score-game (concat [10 5 3] (repeat 0)))))
`main/bowling-game.clj:
nothing
Test 5
Score a perfect game. This simply runs.
Test 6
Score a game of spares specifically of the configuration 0 10 repeating. My favorite.
test/bowling-game.clj:
(is (= 100 (score-game (cycle [0 10]))))
main/bowling-game.clj:
nothing
Formatting
Format to your tastes. I find that because of how compressed Clojure code tends to be it benefits more than most languages that I’ve seen from good formatting practices.
Done
Have a beer.
For the nitty gritty details of myself performing this kata, I present the following:
Bowling Game Kata in Clojure from Tim Visher on Vimeo.
So there you have it. The Bowling Game Kata published as a Clojure Kata (not just a solution!).
If the common wisdom that I hear from almost every software luminary is true, I would absolutely recommend you learn new languages and for the best bang for your buck, make it a language as different from what you’re used to as Clojure almost certainly is.
Here’s some great clojure resources: