Hi all,
For much of my career I've written clients and servers for custom
network protocols. It's tedious and easy to make errors. For my
first project in Clojure I decided to automate that process as much as
possible. I want to be able to declare what I want and have the tools
generate the code. For example, declare this:
(http-server
(port 8081)
(hosts "localhost:8081"
(methods "GET"
(path "/" (respond-ok
(html-format '(:html
(:p "root"))))
"/bogus" (respond-ok
(html-format
'(:a {:href "
http://localhost:8080/index"}
"index page")))
"/data" (send-file
"data.txt")))))
and have the tools generate an HTTP server that is fast and secure.
The first step towards this was to implement state machines. Zed Shaw
riffs on how to use state machines to make bulletproof code in this
post:
http://www.zedshaw.com/tips/ragel_state_charts.html
So I've uploaded a file state-machine.clj to the files area. It has
the explanation of a data structure to specify state machines with and
the code to run those machines. The file is written to be loaded from
the REPL and also to be read as a tutorial. There's another file I
uploaded as well called utilities.clj that should be loaded before
state-machine.clj. It has some basic utilities that didn't fit
anywhere else.
The coolest insight I had doing that part is that I could generate a
list of states in a lazy fashion, consuming the input as I needed it.
That's a pretty powerful abstraction. And also that the input to a
state machine in Clojure can be anything that can be used as a key
value in a map.
Jim