One of the key features of LISP is that it is homoiconic which, one could say, enables creative use of the source.
The most prominent example are macros. Second, the generation of documentation from the the source is common practice
even in heteroiconic languages but homoiconicity certainly makes it a lot easier. In this post I like to present a
more exotic application: automatic generation of flow charts.
The liberator HTTP library provides a declarative way to implement HTTP
resources conforming to the HTTP RFC. This is not as simple as it sounds, actually,
RFC2616 is a large and complected piece of network engineering.
To tame the beast liberator implements a decision graph containing a lot decision function callbacks which a developer
can fill in or rely on a default implementation.
Based on this information the program flow takes a certain route and finally arrives at a handler
which is responsible to build the actual HTTP response. The response will be based on the dervied status code,
negotiated representation parameters as language and media type and so on.
For a more advanced use case consider a PUT a resource with a If-Not-Modified-Since-Header which returns a 302
see other. And there is more: content negotiation, conditional requests, checking for existance…
The exact reason why a certain outcome was produced can be tricky to understand.
This was the motivation to build a flow chart of the decision process, a feature that Erlang’s webmachine provides
too. Webmachine actually was my inspiration to start what used to be called “compojure-rest” and now is liberator.
You can find the flow chart for webmachine here.
And this is how it correlates with clojure’s homoiconicity. In the liberator code every decision is defined using
a macro (defdecision name test then else) where “then” and “else” are names of other decisions. This actually looks
We can then use a reader to read the source file that contains all the decisions (and actions, and handlers) into
a list of lists and convert it into a Graphviz file:
Central idea is to “(read pr)” until no more expressions are available. Then map every expression to a string
snippet which encodes one edge of the graph. To make this happen, to-graph looks for the two well known expressions
(defdecision name then else) and (defaction name then) and convert them to an edge definition and some formatting.
The current implementation is more complete and formats “decisions”, “actions” and “handlers” differently. You can find it
in the liberator source repository in
test/doc.clj. For the current revision
It produces this dot file (cut down to a reasonable size):
A rendered version of the graph looks like this:
You can access it in full size as png,
svg and dot.
In clojure there is always more then one to do it.
Here are some variations on conditionals. All five implementations
use different ways to conditionally execute code and all satisfy
the tests given in test-conditional.
Do you know more variation on this theme? Let me know in the comments!
The other day I was toying around with RedHat’s PaaS
openshift. Openshift has a free
developer preview but here is currently no support for running
leiningen or clojure apps. However, you can use the Do-It-Yourself
application type and add the following as hooks to run leiningen
yourself. The repository directory and home dir must be set
because the home dir and working dir are read only. Leiningen or
the maven libs seem to ignore $HOME, so I used -Duser.home to force
the repository to another location.
I tested it with a dummy ring web application that runs with
ring-jetty-adapter and binds to to $OPENSHIFT_INTERNAL_IP:$OPENSHIFT_INTERNAL_PORT
Another option is to use the available JBossAS-7 cartridge and
deploy a .war-file. I failed to build an uberwar with the lein ring plugin,
but this should be a perfectly valid option, too.