Some Clojure Projects
Table of Contents
- Intro
- A Starter ClojureScript Project
- Lisp In Small Pieces (In Clojure)
- Maze Logic - Part II
- Maze Logic
- A Thorny Issue
- Yahtzee in Clojure
- Org Babel Clojurescript Talk - Postscript
- Org Babel Talk
- Maze Game Dojo
- ClojureScript Automata
Intro
In which I document various projects and diversions executed using Clojure.
A Starter ClojureScript Project
In the spirit of shaving as many yaks as possible, I created a ClojureScript project to be the base of any actual ClojureScript programming I might (or might not) do.
It's the simplest project I could create that provides a browser connected ClojureScript repl using Boot and Cider.
Here it is on Github.
Lisp In Small Pieces (In Clojure)
This gist is chapter 3 of Lisp In Small Pieces - ported to Clojure. It was a fairly natural port, since the object system used in chapter 3 (not implemented until chapter 11) is easily simulated using Clojure's multimethods, and keyword heirarchies.
Here are some fun forms you can try to evaluate. Bonus points for being able to mentally follow what is going on with all the continuations flying around!
;; returns 3, since the throw to the first catch is interrupted ;; by another throw. (catch 1 (catch 2 (* 7 (throw 1 (throw 2 3))))) ;; proves that the cleanup form in the unwind protect ;; is being run during a throw. ((lambda (a) (cons (catch 1 (unwind-protect (throw 1 89) (set! a 45))) a)) 34) ;; proves that the return-from works, and that the cleanup form ;; in the unwind-protect is being run. ((lambda (a) (cons (block 1 (unwind-protect (return-from 1 2) (set! a 89)) 3) a)) 34)
Maze Logic - Part II
Here's another version of a maze solver in core logic. It uses the same algorithm as my second previous attempt, but I'm now using defne and matche to deconstruct the incoming logic variables, rather than all the work I was doing previously with firsto and resto. It doesn't seem to be any faster, but the code is certainly cleaner.
As before there are more details in the project's README, and the source code, both at github.
Maze Logic
There were two good talks at Clojure eXchange about Clojure's logic programming library core.logic. I decided to have a go myself and see if I could use core.logic to solve mazes. I have already written some code to generate mazes so the challenge is simply to see if core.logic can print out a path between the start and end points of the maze.
The answer is that of course it can, but I need to learn to write efficient logic code as my first two attempts can not solve mazes of any significant size.
There are more details in the project's README, and of course the source code, all at github.
There will be more attempts posted here, and hopefully I can address my performance issues.
A Thorny Issue
I gave a short talk today about an issue I was having with Clojure and Java interop.
The issue in question was how to determine which particular overloaded Java method is called when a single Clojure entity satisfies the requirements of both methods. The example I used is the submit method on the Java ExecutorService. There are three versions of the submit method, and two of them take one argument. One version takes a Runnable, and the other takes a Callable. A Clojure function implements both of these interfaces, so when you try and submit a function for an ExecutorService to run, how does Clojure choose which submit method to call?
It turns out that it will call the version that takes a Runnable, unless you take steps to force it to use the Callable version. The various permutations of using type hints, casts, and reify to cause this to happen are detailed in the talk, but the best solution, as suggested by @philandstuff during the talk is to type hint the function as a Callable, and the ExecutorService as an ExecutorService.
(defn submit-callable-hints [^Callable c ^ExecutorService ex] (.submit ex c))
Thanks to everyone who came to see the talk. There are a couple of artifacts from the presentation.
- The file I wrote during the presentation.
- The video (posted by the people at Skillsmatter.)
Yahtzee in Clojure
I've written a small implementation of the game of Yahtzee in Clojure.
The code is on github.
The aim was to be as purely functional as possible, and I think I achieved this. The only parts of the code that are not purely functional are the dice rolling function, for obvious reasons, and the UI, which is made a bit more convenient to use by keeping the game state for you.
There is also a good separation of the game code from the UI, so I could go on to implement other UIs, or plug the game into a game server without any changes. I would like to see how easy it is to convert my maze game dojo code so that participants can play Yahtzee instead of solving mazes. The maze game allows players to upload Clojure code to solve mazes - it would be good to try and extract a generic AI competition server, so that implementers can plugin any game of their choice. I'm sure there are lots of games for which it would be fun to write a robot player in a dojo environment.
Org Babel Clojurescript Talk - Postscript
Thanks to everyone who came along to the London Clojurians meetup yesterday. I really enjoyed giving my talk and seeing the other presenters (@sw1nn and @philandstuff) do their respective thing.
The talk was mostly about the Org mode emacs extension and how it can be used for literate programming. I demoed some nice Org features for working with source code, using a mixture of Clojurescript and Elisp.
I've posted some artifacts from my presentation.
- The file I wrote during the presentation, and the exported version.
- The links and bibliography file I didn't have time to go through.
- The video (posted by the people at Skillsmatter.)
Org Babel Talk
I am giving a short talk at Skills Matter in London about Org, Babel and Clojure on the 4th of September 2012.
Maze Game Dojo
The London Clojurians group organise a regular Dojo where people get together one or two evenings a month and practice some Clojure coding.
Its always a fun event and recently one of the participants wrote a server which would allow people to upload code that could play battleships. Inspired by this I wrote a similar server which would let people write code to solve simple mazes.
There are a few parts to the game. There is code to generate new mazes randomly. The maze is contained in a square grid, and the algorithm to create a new maze picks a random cell in the grid and grows a new maze from that point, putting in new passage ways and junctions at random. It is called a growing tree alogrithm, and as the name suggests it essentially generates a tree within the grid, and there are no loops in the generated mazes.
Players must write a function to solve the mazes. The function takes arguments describing the view of the maze from its current position, and it must return the move it wants to make. Given two functions, the code pits them against each other as they try and solve the same maze. The winner is the function that gets to the end in the fewest number of moves.
The controller portion of the code is responsible for picking the functions that will play against each other in each round and keeping score.
Finally there is a module for the UI, which is a website that displays the current scores and allows players to upload new maze solving functions.
The code is available, and the README contains a full description of how to write a function to play the game, and how to run the server.
The dojo is a constrained environment in that it is short, only 90 minutes or so of coding time, and people come with many different levels of Clojure experience. Any activity has to be tractable within that time - people love to make progress and have something for the show and tell session at then end. I think that (more by luck than judgement) I came up with a problem that fitted pretty well. Every group managed to produce a function that could solve a maze, and the scoreboard showed a pretty wide spread of success when the functions were raced against each other. The other good thing about this problem is that it is easy to think up a very simple strategy that has a good chance of solving mazes, i.e. pick a random move each turn. Lots of people started with this technique and it proved to be a good base to build from.
One thing I did consciously do was to make sure the documentation was good enough that people could get the code running quickly - it is a real pain in a short dojo to be spending lots of time before you can even start thinking about the problem. To this end the README contains simple instructions for running the code, generating mazes, and testing solver functions.
The results of the evening's coding are archived for posterity. Thanks to everyone who took part!
ClojureScript Automata
I last wrote a web application a long time ago, so I decided it was time to dip my toes in the waters again and learn a little bit about the modern way to do things.
In the olden days we wrote JSPs for the front end, and EJBs for the backend. For this experiment I didn't worry about any backend and decided to write a front end application purely in ClojureScript. So I learnt a bit about ClojureScript, CSS and a modern JavaScript API - in this case Google Closure.
I also wanted to try my hand at Literate Programming, the technique where a program is made more readable by mixing explanation and exposition in with the source code. You can then generate a pure source code file, or a nicely formatted document from the same source file. For this I used Org and its Babel extension.
The program I wrote draws diagrams of one-dimensional cellular automata.
I exported the main source file to HTML and posted it here.