Wednesday, 03 November 2010

Configuring a static 6in4 tunnel in Gentoo

I recently started experimenting with IPv6, using tunnels available from Hurricane Electric and SixXS. I want the tunnel to automatically be set up when my computer starts, but the directions available from the official IPv6 Router Guide only show how to manually configure the tunnel using the ip command from the iproute2 package.

Fortunately, it is possible to use Gentoo’s network configuration scripts to set up the tunnel, and I hope to document how to do this in this post.

Getting started

In order to configure your tunnel, you must ensure that you are running an IPv6-enabled kernel. Additionally, you should have set up a 6in4 tunnel with a broker such as Hurricane Electric or SixXS. If you need help with these steps, please refer to the Gentoo IPv6 Router Guide.

Tunnel endpoint addresses

Your tunnel broker should have provided the following information for you:

Name Example value Description
IPv4 server endpoint 172.17.15.24 The IPv4 address of the tunnel server
IPv4 client endpoint 172.21.187.195 Your public IPv4 address
IPv6 server endpoint 2001:db8:a7d0:d3fa::1/64 The IPv6 address of the tunnel server
IPv6 client endpoint 2001:db8:a7d0:d3fa::2/64 Your IPv6 address in the tunnel
Network interface names

The interface name for the tunnel generally has the form sitn where sit stands for Simple Internet Transition and n is a number. You will most likely already have a sit0 interface created by the kernel. This guide will use the generic name sit1, but you can give it any name you like.

You will also need to know the name of the interface that has your public IPv4 address, such as eth0.

Updating /etc/conf.d/net

You will need to add the following lines to /etc/conf.d/net, substituting your tunnel’s address and interface names:

  # Create tunnel interface ‘sit1’ with given IPv4 endpoints
  iptunnel_sit1="mode sit local 172.21.187.195 remote 172.17.15.24 ttl 255"
  # Assign local IPv6 address to tunnel interface
  config_sit1="2001:db8:a7d0:d3fa::2/64"
  # Make the tunnel the default route for IPv6 traffic
  routes_sit1="::/0"
  # Ensure that eth0 is up before setting up the tunnel
  RC_NEED_sit1="net.eth0"

Creating and starting the service

Finally, you will need to create the service for your tunnel just as you would for any other network interface:

  # cd /etc/init.d
  # ln -s net.lo net.sit1

You can now add the service to the default run level and start it:

  # rc-update add net.sit1 default
   * net.sit1 added to runlevel default
  # /etc/init.d/net.sit1 start
   * Caching service dependencies ...
   * Starting sit1
   *   Creating tunnel sixxs ...                                             [ ok ]
   *   Bringing up sixxs
   *     2001:db8:a7d0:d3fa::2/64                                            [ ok ]
   *   Adding routes
   *     ::/0 ...                                                            [ ok ]

Testing your tunnel

Now that your tunnel has been established, you should be able to ping the other end of your tunnel. This requires the ping6 utility which should be available if you installed iputils with the ipv6 USE flag.

  # ping6 -c 1 2001:db8:a7d0:d3fa::1
  PING 2001:db8:a7d0:d3fa::1(2001:db8:a7d0:d3fa::1) 56 data bytes
  64 bytes from 2001:db8:a7d0:d3fa::1: icmp_seq=1 ttl=64 time=16.4 ms

  --- 2001:db8:a7d0:d3fa::1 ping statistics ---
  1 packets transmitted, 1 received, 0% packet loss, time 0ms
  rtt min/avg/max/mdev = 16.410/16.410/16.410/0.000 ms

If the above test worked, you have successfully set up your tunnel. Welcome to the world of IPv6.

Learning more

Now that you have set up your IPv6 tunnel, there are any number of things you can do. Some good resources for further reading include:

  • Gentoo IPv6 Router Guide: From the Gentoo documentation team, this guide covers setting up DNS, routing, automatic configuration (e.g. DHCP), and client configuration.
  • Linux+IPv6-HOWTO: This HOWTO contains some good background information on IPv6 and contains some more detailed instructions on setting up IPv6 on Linux.

In the next couple of weeks I plan to write about both Hurricane Electric and SixXS and their IPv6 services.

Saturday, 24 April 2010

Building EJBs with Clojure

Rich Hickey, the inventor of Clojure, recently announced support for Java annotations in Clojure. This is great news, and in this entry I will show an example of how to create a simple stateless EJB in Clojure.

A simple stateless session bean

I base my example on the simple stateless example from OpenEJB, an embeddable and lightweight EJB 3.0 implementation. I have based my code as closely as possible to the original, for the sake of comparison.

The local interface

The local interface is fairly simple. There are no annotations needed, and is easily written with a simple definterface.

(definterface CalculatorLocal
  (#^int sum [#^int add1, #^int add2])
  (#^int multiply [#^int mult1, #^int mult2]))
The remote interface

The remote interface is remarkably similar to the local interface, but includes our first annotation:

(definterface #^{Remote {}} CalculatorRemote
  (#^int sum [#^int add1, #^int add2])
  (#^int multiply [#^int mult1, #^int mult2]))

The #^{Remote {}} is equivalent to Java’s @Remote annotation on the interface. Note that in order for this code to work, you must import javax.ejb.Remote, as in Java.

The bean

Now that the business interfaces have been implemented, we can now implement the bean itself.

(deftype #^{Stateless {}} CalculatorImpl []
  CalculatorLocal
  CalculatorRemote
  (sum [this add1 add2]
    (+ add1 add2))
  (multiply [this mult1 mult2]
    (* mult1 mult2)))

Similar to the remote interface, the bean is annotated, this time with #^{Stateless {}} for javax.ejb.Stateless. Otherwise, this type is implemented just like any other using deftype.

And that is all there is to it. You can AOT compile the above forms, and you will have a working stateless session bean you can drop into any EJB container.

Get the bean from GitHub

I have created ejb-annot, a simple Clojure project that implements the above bean, along with some unit tests to show that the bean will work. It uses an embedded OpenEJB instance as the bean container.

To see the bean in action, simply:

git clone http://github.com/sattvik/ejb-annot.git
cd ejb-annot
lein deps
lein compile
lein ejb-test

Note that it is ejb-test and not test. This is because OpenEJB seems to have some issues when running from within the same JVM as Leiningen, due to some class loading issues. Also, for OpenEJB to automatically discover the bean, it needs to find an ejb-jar.xml in the same path as the class files.

Final thoughts

Annotations in Clojure are dead simple and will help make Clojure more Java EE friendly. In fact it was an order of magnitude more difficult to get the tests to run within Leiningen than it was to implement the bean and the tests.

I would like to thank Rich for implementing annotations in Clojure. I attempted to add some EJB annotation support in a library last fall, but never completed the project. Now, none of it will be necessary.

Monday, 19 April 2010

Programming Clojure with Vim

Update 2013-11-20: Please check out the 2013 edition of this article.

I have been using Vim for a decade and a half. It has become ingrained in how I do things. I use vi bindings in my browser (via Vimperator), my command line, my e-mail client, my newsreader, etc. Whenever I am editing a document in some strange environment, like Word, I inevitably end up inserting a load of aitches, jays, kays, and ells—much to my infuriation.

Unsuprisingly, when I started working with Clojure, I immediately sought a plug-in to provide the sorts of niceties we all expect in a development tool, such as syntax highlighting, completion, etc. Of course, with Clojure, I also wanted a REPL. However, getting a satisfactory REPL from Vim is easier said than done.

A word about SLIME

SLIME, the Superior Lisp Interaction Mode for Emacs, is an Emacs mode for working with Common Lisp. Even if you are not familiar with Emacs, it does not take long to realise how nice and convenient it is. Unsurprisingly, Clojure programmers have written the necessary plug-ins for a Clojure mode in Emacs with SLIME support. Often, Emacs is considered the preferred choice for working with Clojure.

Unfortunately for those of us who are hard-wired for vi, it is currently very difficult to implement a “Superior Lisp Interaction Mode for Vim”. This is because Vim lacks support for asynchronous subprocesses. Nevertheless, there are a number of Clojure options for Vim users. Most prominent among these is VimClojure.

VimClojure

VimClojure is a Vim plug-in developed by Meikel Brandmeyer. It provides support for Clojure syntax highlighting (including rainbow parentheses), indentation, and completion.

In addition, it supports a number of SLIME-type features, such as:

  • Evaluate and see the results of the current:
    • top-level s-expression
    • file
    • line
    • visual block
    • paragraph
  • Tell Clojure to require the current namespace with either a :reload or :reload-all
  • See the macro expansion of the current innermost s-expression with either macroexpand or macroexpand-1
  • Interactively execute (find-doc …)
  • For the current word or an interactively given word:
    • Lookup documentation using (doc …)
    • Lookup JavaDoc using (clojure.contrib.repl-utils/javadoc …)
    • See the source using (clojure.contrib.repl-utils/source …)
    • Open the source in Vim
    • Show the word’s metadaka, like (meta #'…)
  • Start a REPL within Vim

This is a pretty nice set of features that can make developing Clojure within Vim a much more delightful experience. For example, say one of your functions is failing a test. From Vim, you can fix the function and type ,et to send the entire (defn …) form to Clojure (assuming , is your LocalLeader). Now you can re-run your tests and see whether or not your fix worked.

Unfortunately, VimClojure is not without its idiosyncrasies.

Caveat lector

No tool is perfect, and think VimClojure does a very good job. Nonetheless, there a few things about which you should be aware:

  1. For most of the above functionality to work, The gorilla (nailgun) server for VimClojure must include your Clojure source directories in its class path.
  2. You can't mix VimClojure 2.1.2 with Clojure 1.2. The current mercurial version of VimClojure is no longer tied to a particular Clojure version.
  3. The REPL stinks. Admittedly, because of the above-mentioned Vim shortcoming, it's hard to get a REPL that is quite as nice as the one for SLIME. However, things that I normally expect to have, such as the ability to arrow keys to navigate the REPL history, are not supported.

Alternative Clojure plug-ins for Vim

VimClojure is not the only way to go with Clojure and Vim. Some of the alternatives include using VimClojure in off-line mode, using VimClojure in off-line mode with an alternative REPL, and Slimv, another Vim plug-in.

VimClojure (off-line)

It may be a stretch to call this a ‘VimClojure alternative’, but it is possible to use Vim without any of the SLIME-like features. In this mode, you keep the indentation, syntax highlighting, and completion. It may not be as powerful as the full VimClojure plug-in, but it saves you the trouble having to start a nailgun server and worry about class paths.

VimClojure (off-line) and slime.vim

This method is described by Lee Hinman in his article ‘How I develop Clojure with Vim’. This method uses a supplemental Vim script called slime.vim that works around Vim’s asynchronous shortcomings through the use of GNU Screen.

In this arrangement, you can run your REPL in a separate Screen and have Vim send commands to it using screen’s command line interface. I first encountered this plug-in when I tried some Lisp development in Vim. I do not use it because I think that VimClojure’s capabilities are much better.

Slimv

Slimv is a relatively unknown plug-in in the Clojure community. It is written by Tamas Kovacs, and originated as plug-in for Lisp programmers. However, in the past few versions, it has begun to support Clojure.

Slimv uses a Python script to launch a REPL, to which it sends commands in a way, in principle, not terribly unlike slime.vim. Instead of running a REPL using Screen, it launches the REPL in a new terminal.

Unlike slime.vim, it seems like it supports a much greater amount of functionality, much like VimClojure. In fact, it supports having a REPL inside of Vim that has the potential to be vastly superior to the one provided by VimClojure. In particular, it allows using the arrow keys in insert mode to navigate the REPL history.

Unfortunately, the current version is a bit buggy. For example, the REPL works, but after every command I get series of Vim errors that, although apparently harmless, make the experience intolerable.

The latest version also includes a paredit plug-in, that promises some of the features of Emacs’ paredit minor mode. Unfortunately, I found it fairly buggy. For example, in one case where I wanted to delete to the end of a line using D, it deleted my entire line. In another case when I wanted to move a one-line def using dd and p, I found that the p pasted nothing at all. Yanking and putting still worked, though.

I think Slimv has some great features, but until some of these bugs are worked out, it is not going to be my plug-in of choice. Unfortunately, there does not seem to be a project page or repository available anywhere for Slimv.

How I develop Clojure with Vim

My ideal Vim plug-in would combine all of the best features of both VimClojure and Slimv, eliminate all of the bugs, and make it simple to install and use. Unfortunately, no such plug-in exists, nor will I be taking the time to write it any time soon. So, I do the best I can with the tools that are available.

For a given Clojure project, my development environment consists of three things:

  1. A Clojure script that I use to launch nailgun, set up utility functions, and run my REPL.
  2. A shell script to set up my class path and run my script.
  3. Vim with VimClojure
The development script

This development script does a few things that make development easier. I will load clojure.contrib.repl-utils, start nailgun, and often times write a function that runs all of my unit tests. Here is an example of such a script:

(ns #^{:doc "A sample development.environment Clojure script"
       :author "Daniel Solano Gómez"}
  example-repl
  (:import com.martiansoftware.nailgun.NGServer
           java.net.InetAddress)
  (:use clojure.contrib.repl-utils
        clojure.test))

(defn- dotests []
  (require :reload-all :verbose 'example.test)
  (run-tests 'example.test))

(def ng-host "127.0.0.1")
(def ng-port 2113)
(def ng-server (NGServer. (InetAddress/getByName ng-host) ng-port))
(.start (Thread. ng-server))

(println "Welcome to your development REPL")
(clojure.main/repl)
(.shutdown ng-server false)

Without going into a lot of detail, this script accomplishes the following:

  1. Set up a namespace, making the necessary imports to get nailgun to run and including repl-utils so can (source …) from the REPL.
  2. Set up a convenience function that will reload all my namespaces and execute my tests. From the REPL, I only have to (dotests).
  3. Instantiate and start a nailgun server.
  4. Start the REPL with a friendly welcome message.
  5. When the REPL ends, shut down the nailgun server gracefully.

You can do other things in this script, such as set up a server for Compojure development or set values for vars like *warn-on-reflection*.

The shell script

The job of the shell script is to set up my class path and run the development script. I also use rlwrap to give me readline support with vi key bindings within the REPL.

A minimal example of such a script:

#!/bin/sh

CLOJURE_CP=/usr/share/clojure-1.1/lib/clojure.jar
CLOJURE_CONTRIB_CP=/usr/share/clojure-contrib-1.1/lib/clojure-contrib.jar
VIMCLOJURE_CP=/tmp/vimclojure-2.1.2/build/vimclojure.jar
PROJECT_CP=src

CLASSPATH="${CLOJURE_CP}:${CLOJURE_CONTRIB_CP}:${VIMCLOJURE_CP}:${PROJECT_CP}"

BREAK_CHARS="(){}[],^%$#@\"\";:''|\\"
rlwrap --remember -c -b "${BREAKCHARS}" -f "${HOME}/.clj_completions" java -cp ${CLASSPATH} clojure.main devrepl.clj
VimClojure

I usually develop within GNU Screen. In one screen, I launch my REPL, via ./devrepl, and in another I launch Vim. With this configuration, I have all of the goodies from VimClojure along with a REPL with readline support and Vim bindings.

On occassion when I have just launched my REPL, VimClojure will complain that it can not connect to the nailgun server. If I do a netstat -lt, I will in fact see that the REPL is not listening on the nailgun port. I have usually found that running (.isRunning ng-server) within the REPL remedies this situation. I suppose this is a bug in nailgun.

Concluding remarks

Is this a perfect set-up? No, not entirely. Am I missing out on some SLIMEy goodness? Probably. However, it gives me most of what I need to be able to develop Clojure productively.

If you have any good Vim and Clojure hints or tips, feel free to share them by posting a comment.

Monday, 12 April 2010

Generate your class and proxy it too

Sometimes, you need to create a Java class from Clojure so that it can be called from a Java-based framework. At the same time, you want to use the class in your Clojure environment without needing to add a compile step to your workflow. To accomplish this, you can combine both gen-class and proxy.

In this article, I will show how to implement a servlet that can be both compiled into a Java class for inclusion in a WAR file and used via proxy within a development environment.

What about reify and deftype?

In Clojure 1.2, which is still in development, reify is preferred over proxy in most cases, and deftype can create classes both dynamically and AOT—all with better performance. Unfortunately, neither of these can extend other Java classes; they can only implement Java interfaces. As a result, neither of these can be used to subclass HttpServlet.

Implementing HelloServlet

Implementing a servlet is fairly simple. Using gen-class subclass javax.servlet.http.HttpServlet and implement any of the doXXX methods you would like your servlet to support. The following example shows the obligatory Hello servlet:

(ns #^{:doc "The servlet that says hello."
       :author "Daniel Solano Gómez"}
  example.HelloServlet
  (:gen-class :extends javax.servlet.http.HttpServlet
              :main false)
  (:import javax.servlet.http.HttpServletResponse))

(defn -doGet [_ _ response]
  (let [out (.getWriter response)]
    (.println out "Hello, world!"))
  (doto response
    (.setContentType "text/plain")
    (.setStatus HttpServletResponse/SC_OK)))

Assuming you have the proper class path set up, you can (compile 'example.HelloServlet). Now you have a servlet that you can include in a standard web application. However, unlike normal Java servlets, you can modify your Clojure servlet at run-time using an attached REPL. For example, since the -doGet function is called by the AOT-generated class, you should be able to redefine it without regenerating the class file. However, you will not be able to add or remove class methods, such as -doPut or -init, without recompiling. This may be an acceptable, but let’s take this a step further and add proxy…

Adding proxy to HelloServlet

At first, it may seem relatively simple to create a proxy for HelloServlet. For example, you could simply add a function that returns a proxy instance as follows:

(defn servlet []
  (proxy [javax.servlet.http.HttpServlet] []
    (doGet [request response] (-doGet this request response)))))

This works; you are able to get the proxy by calling servlet. However, whenever you compile your namespace, you will find example/HelloServlet/proxy$javax/servlet/http/HttpServlet$0.class among your generated class files. Even trying to use (when-not *compile-files* …) does not avoid this. If you want to keep your generated classes free from the proxy class, you will need to move this function to a new namespace. For example:

(ns #^{:doc "Dynamic proxy generator for example.HelloServlet"
       :author "Daniel Solano Gómez"}
  example.HelloServlet.proxy
  (:use example.HelloServlet))

(defn servlet []
  (proxy [javax.servlet.http.HttpServlet] []
    (doGet [request response] (-doGet this request response))))

Now, from Clojure, you can use the servlet function from the new namespace to add an instance of the servlet to your container. Furthermore, when you AOT compile, the proxy class will not be generated.

Using the proxy with Jetty 7

The following is a somewhat minimal example of how to do this with Jetty 7:

(ns #^{:doc "An example program that uses Jetty 7 to serve HelloServlet"
       :author "Daniel Solano Gómez"}
  jetty-hello-demo
  (:import org.eclipse.jetty.server.Server
           org.eclipse.jetty.servlet.ServletHolder
           org.eclipse.jetty.webapp.WebAppContext)
  (:require [example.HelloServlet.proxy :as hello-servlet]))

(defn- hello-servlet-holder []            
  (doto (ServletHolder.)                  
    (.setServlet (hello-servlet/servlet))))

(defn- create-webapp []
  (doto (WebAppContext.)
    (.setResourceBase "./web")
    (.setContextPath "/")
    (.setParentLoaderPriority true)              
    (.addServlet (hello-servlet-holder)
                 "/hello")))                                                          

(defn- create-server []
  (doto (Server. 8081)
    (.setStopAtShutdown true)
    (.setHandler (create-webapp))))

(def jetty-server (create-server))
(.start jetty-server)

Finally, a note about init

What if your servlet needs to use the init and destory life cycle methods? You may be tempted to do the following to generate your class:

(ns #^{:doc "The servlet that says hello." 
       :author "Daniel Solano Gómez"}
  example.HelloServlet 
  (:gen-class :extends javax.servlet.http.HttpServlet
              :main false)
  (:import javax.servlet.http.HttpServletResponse))

(defn -init [this]
  (.log this "Initialising…"))

(defn -doGet [this request response]
  (let [out (.getWriter response)]
    (.println out "Hello, world!"))
  (doto response
    (.setContentType "text/plain")
    (.setStatus HttpServletResponse/SC_OK)))

(defn -destroy [this]
  (.log this "Destructing…"))

And for your proxy, you would do:

(ns #^{:doc "Dynamic proxy generator for example.HelloServlet"
       :author "Daniel Solano Gómez"}
  example.HelloServlet.proxy
  (:use example.HelloServlet))

(defn servlet []
  (proxy [javax.servlet.http.HttpServlet] []
    (init [] (-init this)) 
    (doGet [request response] (-doGet this request response))
    (destroy [] (-destroy this))))

However, this does not work. The problem is that the nullary form of init is merely a convenience method that is called by the unary GenericServlet.init(ServletConfig). As explained by Mark Triggs in Tricky uses of Clojure gen-class and AOT compilation and Meikel Brandmeyer in proxy – gen-class little brother, using gen-class and proxy with methods that have multiple arities can be tricky.

As a result, you need to implement both the nullary and unary forms of init in order for your servlet to work. As explained in the documentation for GenericServlet, when you override init(ServletConfig), you must call super.init(config).

For gen-class you need to expose the superclass’s init function so that it can be called from your init function, as follows:

(ns #^{:doc "The servlet that says hello."
       :author "Daniel Solano Gómez"}
  example.HelloServlet
  (:gen-class :extends javax.servlet.http.HttpServlet
              :main false
              :exposes-methods {init initSuper})
  (:import javax.servlet.http.HttpServletResponse))

(defn -init [this]
  ([this config]            
   (. this initSuper config))
  ([this]                      
   (.log this "Initialising…")))

For proxy, you will need to use proxy-super as follows:

(ns #^{:doc "Dynamic proxy generator for example.HelloServlet"
       :author "Daniel Solano Gómez"}
  example.HelloServlet.proxy
  (:use example.HelloServlet))

(defn servlet []
  (proxy [javax.servlet.http.HttpServlet] []
    (init [config]
          (proxy-super init config)
          (-init this))
    (doGet [request response] (-doGet this request response))
    (destroy [] (-destroy this))))

Note that the proxy only implements the unary form of init. I am not entirely sure why, but it seems that if proxy provides both the nullary and unary forms of init, the nullary form is never called.

Conclusion

I hope that I have shown how you can successfully use both gen-class and proxy together to provide both a dynamic Clojure-driven development environment and a means of creating code that will be used within existing Java frameworks. The example I provided used a servlet, but the same techniques can be applied to other frameworks such as Spring or EJB.

Sunday, 11 April 2010

Released: sh-clojure version 0.9.1

Yesterday, I released version 0.9.1 of sh-clojure. It includes the following updates:

  • sh-clojure now supports the ‘@’ reader macro
  • sh-clojure is now dual-licensed under the LGPL and EPL. This allows the script to be used in programs that are not compatible with the LGPL.
  • The brush script is now minified in the distribution, reducing size by about 20%.
  • I have applied some JSLint-inspired cleanup.

It is available on the sh-clojure GitHub download page as a tarball and as a zip file.

As always, I appreciate any user feedback. Also, if you use sh-clojure on your web page or software and let me know, I may place a link to your project on a page or in the README.

Wednesday, 07 April 2010

New Clojure Brush for SyntaxHighlighter

I was looking over Stuart Halloway’s labrepl recently, and I was irritated by the poor quality of the syntax highlighting. As I looked into it, it turns out that it uses SyntaxHighlighter, a popular JavaScript-based code syntax highlighter.

The old Clojure brush

SyntaxHighlighter depends on plug-ins called brushes to provide language-specific highlighting based on regular expressions. The brush used by labrepl has a few deficiencies, namely:

  • Keyword highlighting would break at hyphens
  • Form highlighting included only a subset of the basic Clojure functions and macros
  • A name such as my-println would be incorrectly highlighted.

Annoyed by these short-comings, I decided to try my hand at developing a better brush for Clojure.

Developing the new Clojure brush

I encountered a number of hurdles to develop the new brush. Clojure’s extremely flexible naming makes it difficult to create regular expressions to match names. Names such as *out* contain characters that must be escaped, and names such as every? have characters that keep you from being able to use the word boundary zero-width assertions.

Moreover, JavaScript’s regular expression engine is limited. In particular, it lacks support for lookbehind zero-width assertions. Luckily, JavaScript is a dynamically-typed language, and I was able to simulate the RegExp.exec method as if it supported lookbehinds.

The new Clojure brush

So, I am now announcing version 0.9 of sh-clojure, my new SyntaxHighlighter brush for Clojure. It is licensed under the LGPL, like SyntaxHighlighter, and the source is available on GitHub.

Some of the features of this new brush include highlighting of:

  • Special forms
  • All forms from clojure.core of Clojure 1.1
  • Number, character, boolean, and nil values
  • Strings and regular expressions
  • Parentheses and other syntax elements such as reader macros for collections and type hinting
  • Special highlighting for quoted and unquoted symbols

You can download it now from GitHub either as a tarball or as a zip file.

Demo

If you have JavaScript enabled, the following code should be highlighted using sh-clojure. If not, it should fall back to my default code block formatting.

(ns #^{:doc "This is a demo of my new Clojure brush for SyntaxHighlighter"
       :author "Daniel Solano Gómez"}
  sh-clojure.demo)

; Including the obligatory ‘Hello, world!’
(defn say-hello
  "A simple function that says hello."
  ([]
   (say-hello "world"))
  ([#^String who]
   (if (re-matches #"^Mr. [A-Z]$" who)
     (println (str "Good afternoon, " who "."))
     (println (str "Hello, " who "!")))))

(defn average
  [& nums]
  (/ (reduce + nums) (count nums)))

Feedback welcome

I released sh-clojure as version 0.9 as I imagine there may be a bug or two that have escape me. Feel free to file an issue on GitHub or leave a comment here if you run into any problems or would like to suggest a new feature.

Thursday, 25 March 2010

Clojure now in java-overlay

I recently received commit access to Gentoo’s Java overlay, and so I took the chance to commit my ebuilds for Clojure and Clojure-contrib. This means that Clojure is now a step closer to becoming a standard part of Gentoo.

The following step-by-step guide should help you get started. Note that the following instructions assume you are using the standard Gentoo package management tools. If you use some other system, such as Paludis, you will need to refer to the documentation for your preferred manager about how to add overlays and keyword packages.

In order to get started, you will have to first make sure that the Java overlay is installed on your system.

Installing the Java overlay on Gentoo

In order to install Clojure, you will need to install layman according to the instructions in the User’s Guide. Be sure to enable the subversion USE flag. Once you have layman installed, you should be to execute layman -L and see a line similar to the following:

* java-overlay              [Subversion] (svn://overlays.gentoo.org/proj/java/java-overlay/

Once layman is installed, add the Java overlay using layman -a java-overlay. After a lengthy checkout, you should see the line:

* Successfully added overlay "java-overlay".

Congratulations, you now have the Java overlay installed. Now you can move onto installing Clojure.

Emerging Clojure

With the Java overlay installed, the Clojure and Clojure-contrib ebuilds are now available through portage.

Note that Clojure is currently keyworded ~amd64 and ~x86. This means that if you are running on the stable branch of Gentoo (the default), or if you are not using an amd64- or x86-based computer, you will need to take a few extra steps. The good news is that if you can run Java on your system, you should be able to run Clojure as well1.

With the proper keywording done, installing Clojure is as simple as emerge clojure. Note that both 1.0.0 and 1.1.0 versions of Clojure are available, and you can install them concurrently using Gentoo’s slot mechanism. By default, portage will install the latest version (1.1.0 slotted as 1.1), but you can force installing version 1.0 by using slot ‘0’, i.e. emerge clojure:0.

The above instructions also apply for installing Clojure-contrib—simply emerge clojure-contrib or emerge clojure-contrib:0.

Running Clojure

With Clojure emerged, running the REPL is as simple as typing clojure or clojure-1.1, depending on which version you are using.

Including Clojure-contrib manually

Note that, by default, the Clojure commands will not include Clojure-contrib in your class path. You can do this manually on the command line by invoking Clojure using one of the following commands:

For clojure-contrib 1.1.0:

CLASSPATH=$(java-config -p clojure-contrib-1.1) clojure-1.1

For clojure-contrib 1.0.0:

CLASSPATH=$(java-config -p clojure-contrib) clojure
Including Clojure-contrib automatically

The way I prefer to run Clojure is to have the launcher script automatically include Clojure-contrib. This can be done by customizing the launcher’s class path by adding files to the .gentoo/java-config-2/launcher.d directory under your home directory2.

For version 1.1.0:

% echo 'gjl_package="clojure-contrib-1.1"' > .gentoo/java-config-2/launcher.d/clojure-1.1

For version 1.0.0:

% echo 'gjl_package="clojure-contrib"' > .gentoo/java-config-2/launcher.d/clojure

Having accomplished the above, Clojure-contrib should now be available from the launcher. For example, you could try:

% clojure-1.1
Clojure 1.1.0
user=> (use 'clojure.contrib.str-utils)
nil
user=>

Final Thoughts

This is merely the first step towards getting better Clojure support in Gentoo. Some of the next few things I am considering doing include:

  • Add ebuilds for editor integration with Clojure. There is a VimClojure ebuild in java-experimental that I will soon be moving to java-overlay. Although I don’t use other editors, I think that Emacs integration would be good, too.
  • Add some sort of eselect-based method to automate much of the above. I envision a script that will manage it so that typing clj will launch the appropriate version of Clojure and include Clojure-contrib if desired.
  • Package more Clojure applications and libraries.

I am working towards become a full-fledged Gentoo Developer. Once I get there, I will have a better opportunity to help get Clojure-related packages into the main tree and help make Gentoo a very Clojure-friendly Linux distribution.

In the meantime, I appreciate any user feedback. You can find me as ‘sattvik’ on Freenode on #gentoo-java and #clojure. Of course, you can also leave comments on this site.

Footnotes
  1. If you do get Clojure working on non x86 or amd64 system, please make a note of it in the bugs for Clojure and Clojure-contrib.
  2. Alternatively, you can add these files to /etc/java-config-2/launcher.d/ to have the effect system-wide.

Now with comments

I am happy to announce that Deep Blue Lambda now supports comments and TrackBacks. For the moment, they are moderated, so it may take a bit of time before you see your comment or TrackBack. My intention is to get rid of moderation once I have implemented some other anti-spam measure.

I will continue to add new features to the site as time permits. Unfortunately, it seems that the original Perl-based version of Blosxom has fallen into disuse, so it has become harder to find plug-ins that implement the types of features people expect in web log software these days.

So, please feel free to leave a comment to let me know what else you’d like to see on this site.

Thursday, 18 March 2010

Teaching Clojure at RubyLearning

RubyLearning is a web site that offers on-line courses for people wanting to learn Ruby. They recently announced Clojure 101, an introductory course on Clojure. I will be assisting Michael Kohl in teaching the course by helping write course materials and answering questions on the course forums.

If you are interested in learning Clojure, this is an excellent opportunity. You will have the chance to interact with the other assistant teachers and hundreds of other participants. Best of all, it is free of charge.

Please, check it out and join if you are interested.

Wednesday, 17 March 2010

Welcome to Deep Blue Lambda

Allow me to welcome you to Deep Blue Lambda. My name is Daniel Solano Gómez, an independent software developer in Houston, Texas. The purpose of this web site is to help me communicate and network with fellow professionals around the world.

On this web site I will be posting:

  • Technical documentation I believe may be of use to others,
  • Information about my open source projects,
  • Announcements about talks or appearances that I make, and
  • Any other thoughts or musings regarding the state of the art.

Unfortunately, I am launching this site a bit sooner than I had anticipated, so for the moment it is a bit lacking on both features and content. However, I will remedy this in the coming days.