Thursday, April 9, 2009

VimClojure on Ubuntu

I have just installed vimclojure-2.0.0 on Ubuntu. Here is my log, in case someone wants to do something similar

Download vimclojure: http://kotka.de/projects/clojure/vimclojure.html

cd
mkdir clojure
cd clojure/
svn co http://clojure.googlecode.com/svn/trunk clojure
cd clojure/
ant
cd ..
mkdir jars
cp clojure/clojure.jar jars
git clone git://github.com/kevinoneill/clojure-contrib.git
cd clojure-contrib/
ant -Dclojure.jar=../clojure/clojure.jar
cp *jar ../jars
tar xvfz vimclojure-2.0.0.tar.gz
cd vimclojure-2.0.0/
vi local.properties
clojure.jar=/home/johan/clojure/jars/clojure.jar
clojure-contrib.jar=/home/johan/clojure/jars/clojure-contrib.jar
nailgun-client=ng
vimdir=/home/johan/.vim
ant
mkdir ~/.vim/autoload
mkdir ~/.vim/doc
mkdir ~/.vim/indent
mkdir ~/.vim/syntax
mkdir ~/.vim/ftdetect
mkdir ~/.vim/ftplugin
mkdir ~/.vim/ftplugin/clojure
cp autoload/vimclojure.vim /home/johan/.vim/autoload/
cp doc/clojure.txt /home/johan/.vim/doc/
cp indent/clojure.vim /home/johan/.vim/indent/
cp syntax/clojure.vim /home/johan/.vim/syntax/
cp ftdetect/clojure.vim /home/johan/.vim/ftdetect/
cp ftplugin/clojure.vim /home/johan/.vim/ftplugin/
cp ftplugin/clojure/completions-clojure.* /home/johan/.vim/ftplugin/clojure
vi ~/.vimrc
filetype plugin indent on
syntax on
let clj_highlight_builtins = 1
let clj_highlight_contrib = 1
let clj_paren_rainbow = 1
let clj_want_gorilla = 1
let vimclojure#NailgunClient = "/home/johan/clojure/vimclojure-2.0.0/ng"
autocmd BufRead,BufNewFile *.clj nmap ClojureEvalFile
autocmd BufRead,BufNewFile *.clj nmap ClojureEvalLine
autocmd BufRead,BufNewFile *.clj nmap ClojureEvalToplevel
autocmd BufRead,BufNewFile *.clj nmap ClojureStartRepl
autocmd BufRead,BufNewFile *.clj nmap ClojureDocLookupWord
autocmd BufRead,BufNewFile *.clj nmap ClojureDocLookupInteractive
vi ~/.bashrc
# Clojure
export CLOJURE_EXT=/home/johan/clojure/jars
export LD_LIBRARY_PATH=/home/johan/clojure/bin-linux
alias clojure='/home/johan/clojure/clojure-contrib/launchers/bash/clj-env-dir'
if ! (ps -ef | grep com.martiansoftware.nailgun.NGServer > /dev/null)
then
sh /home/johan/clojure/vimclojure-2.0.0/bin/ng-server &
fi


And for the final step, start vim and type ":helptags ~/.vim/doc" to make the documentation available with ":help clojure"

You can also add this Nailgun startup script in /etc/init.d/nailgun

#! /bin/sh
# Install: ln -s /etc/init.d/nailgun /etc/rc3.d/S99nailgun

do_start () {
export CLOJURE_EXT=/home/johan/clojure/jars
export LD_LIBRARY_PATH=/home/johan/clojure/bin-linux
sh /home/johan/clojure/vimclojure-2.0.0/bin/ng-server &
}

do_stop () {
`ps -ef | grep java | grep NGServer | awk '{print "kill -9 "$2}'`
}

case "$1" in
start)
do_start
;;
stop)
do_stop
exit 0
;;
restart)
do_stop
do_start
exit 0
;;
*)
echo "Usage: $0 start|stop|restart" >&2
exit 3
;;
esac

Monday, February 2, 2009

Xith3D with Clojure

I've been working a bit with 3D graphics with Clojure, and I have now tested various libraries. jME was a bit awkward to set up in Clojure, and Java3D is dying, so my current efforts are concentrated on Xith3D. I had some problems installing Xith3D in Ubuntu 8.10, so here is how to get started:

Download

mkdir xith
cd xith
svn co https://xith3d.svn.sourceforge.net/svnroot/xith3d/trunk xith3d
svn co https://xith-tk.svn.sourceforge.net/svnroot/xith-tk xith-tk


Compiling problems and how to solve them

xith3d only compiles with java-6-sun, not openjdk-6, so
remove all other java implementations (see /usr/lib/jvm) first.

cd xith
ant

Another problem is that ant is too old, and svnrevget fails. To fix
this, go to xith and do "svn log". Note the latest revision number,
and go to xith-tk. Edit build.xml, and find the svnrevget line.
Comment it out and hard-code the version number:

[!-- svnrevget property="version.build" path="${project.xith3d}"/--]
[property name="version.build" value="1668"]

Now you can do "ant" in the xith-tk folder.

Testing

Here is a basic test file (put it in the xith folder, call it test.clj)

(import '(org.xith3d.loop RenderLoop)
'(org.xith3d.render Canvas3D Canvas3DFactory)
'(org.xith3d.base Xith3DEnvironment))

(let [env (Xith3DEnvironment.)
canvas (.createWindowed Canvas3DFactory 800 600 "My empty scene")
rl (RenderLoop.)]
(.addCanvas env canvas)
(.setMaxFPS rl 120.0)
(.setXith3DEnvironment rl env)
(.begin rl))

And a script to start it with

#!/bin/sh
export LD_LIBRARY_PATH=xith3d/third-party/gluegen/linux-i586:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=xith3d/third-party/jogl/linux-i586:$LD_LIBRARY_PATH
java -cp ~/.clojure/clojure.jar:xith3d/dist/xith3d.jar:xith3d/third-party/jagatoo.jar:xith3d/third-party/math/openmali.jar:xith3d/third-party/jogl/jogl.jar:xith3d/third-party/gluegen/gluegen-rt.jar clojure.lang.Script test.clj


and an empty window appears on the screen.

Saturday, January 17, 2009

XmlRpc with Clojure

I know, I know... I really should update this blog more often. Brief recap: last year I've made a fairly big Common Lisp project (funmv), and played quite a bit with both Haskell and Clojure. Today I want to share some experiences using XmlRpc with Clojure.

Clojure has the advantage of running on JVM, which means that it can use Java libraries. The problem is that, being a Lisp with a functional flavour, it sometimes doesn't mix well with the object-oriented programming style mandatory in Java development. I needed to implement a Xml-Rpc server in clojure, but my first attempts with apache xmlrpc and others ended in failure since their addHandler methods required an object, and would match the XmlRpc message methods with the name of the member functions. It is possible to instantiate Java-objects with the proxy special form in Clojure, but this only allows you to implement or subclass already declared methods, and creating an object completely from scratch seemed too complicated.

Finally I found an XmlRpc library from redstone (download redstone-simple-xmlrpc-1.0.zip), which allows you to define your own dispatch routine. This allows me to inspect the method name and call normal Clojure functions, rather than relying on Java reflection magic. The server code is short and sweet:

(def server (new redstone.xmlrpc.simple.Server 8080))
(def h (proxy [redstone.xmlrpc.XmlRpcInvocationHandler] []
(invoke [method-name arguments]
(cond
(= method-name "add") (+ (nth arguments 0) (nth arguments 1))
true (throw (new Exception "No such method"))))))
(doto (.getXmlRpcServer server) (.addInvocationHandler "test" h))
(.start server)


Here is a Java test client

import redstone.xmlrpc.XmlRpcClient;
public class SampleClient
{
public static void main( String[] args ) throws Exception
{
XmlRpcClient client = new XmlRpcClient( "http://localhost:8080", false );
Object reply = client.invoke( "test.add", new Object[] {1, 2} );
System.out.println (reply); // should be 3
}
}


You will need to add the jar files to the classpath:

javac -cp xmlrpc-1.1.1.jar SampleClient.java
jar cf SampleClient.jar *class
java -cp SampleClient.jar:xmlrpc-1.1.1.jar SampleClient