Sunday, 30 November 2008

AOT problem solved

Thanks to the swift responses of the Clojure google group I have got past my little problem. It was, of course, deceptively simple, but not clear to someone who doesn't do Java programming much.

The problem was basically that whatever I did I could not get Clojure to recognise that the source files existed in the classpath.

When you invoke java with the
command line option it completely ignores the classpath (both the environment variable, or the

So, when compiling my code I simply switch this:

java -cp ./classes:./src -jar ${HOME}/src/clojure/clojure.jar ./compile.clj

.. to this ...

java -cp ./classes:./src:${HOME}/src/clojure/clojure/jar clojure.lang.Script ./compile.clj

For the record the contents of
are as follows:

(binding [*compile-path* "/home/gteale/src/aot_test/classes"]
(compile 'de.teale.test))

I plan to replace that with either ant or lancet shortly.

Caught on a Clojure roller coaster

I was hoping to make some decent progress this weekend with my Clojure code. The plan was to port it to the new AOT model of compilation.

However, my efforts have been frustrated by me not being able to get AOT working. I have posted my problem to the group, so hopefully there will be some solution soon.

Clojure is developing so rapidly it's hard to keep up, I think that's how I got into this mess with AOT. However, for every new problem people are finding solutions that blow me away. This blog post details a really elegant solution to the lack of tail call optimisation for mutually recursive functions:

Thursday, 27 November 2008

AOT is cool, but it breaks some of the below content.

Clojure is a young language, and as such it's developing fast. It's an exhilarating ride to be on, but sometime it means things I've written change.

So, when reading the below posts, please note that the latest revisions to Clojure include the provision of Ahead-Of-Time (AOT) compilation. This will break the compilation mechanisms I used in some of the content below. When I get round to fixing up my programs I'll try an post revised instructions for Jar creation, till then I suggest you check out the docs here for compilation notes.

Sunday, 9 November 2008

On Clojure - part 3 - Qt Designer files and custom slots.

So, as promised, here's a few notes on how I am using Qt Designer with Clojure.
Some important things to remember:

  • You must use Qt Designer with the QtJambi plugins installed. The easiest way to do this is to run (Linux / UNIX / Mac OS X) or designer.bat (Windows) from the distribution folder that QtJambi came in. If you've got QtJambi installed as a package under Linux then you may need to check that the QtJambi plugins are correctly installed , they weren't in my case.

  • If you have the QtJambi plugins installed designer should be able to save .jui files instead of .ui files.

I don't intend to tell you how to use Qt Designer, there's a good user manual available.
Once you've put together a UI in Designer plugging it into a clojure application is relatively simple, though there are some subtleties that took me a while to work out (along with a large chunk of time trawling #clojure logs, the wiki and various blog post - thanks to all who share their work!)
What follows is the full source code for an incredibly simple app that uses a single QMainWindow with a Designer derived layout, I'll explain some more after the code:

(gen-and-load-class "foo.gen.Slot"
:methods [["slot" [] Void]])

(ns foo
(:import (foo Ui_MainWindow))
(:import (com.trolltech.qt.gui QApplication QMainWindow))
(:import (com.trolltech.qt.core QCoreApplication))
(:import (foo.gen Slot)))

(def slots
(proxy [Slot] []
(slot [] (prn "Slot Called"))))

(defn init []
(QApplication/initialize (make-array String 0)))

(defn exec []

(defmacro qt4 [& rest]
(try (init) (catch RuntimeException e# (println e#)))

(def Foo-main
(fn [& args]
(let [ui_main (new Ui_MainWindow)
mainWindow (new QMainWindow)]
(. ui_main (setupUi mainWindow))
(let [pushButton (. ui_main pushButton)]
(.. pushButton clicked (connect slots "slot()")))
(. mainWindow (show))))))

This code lives in the package "foo", in the file "Foo.clj". If you're familiar R.P. Dillon's guide to with making Jar's from clojure you'll know that Foo-main is the Main function of the resulting JAR. Notice that we also import Ui_MainWindow from the same package. This is the generated Java code from the Designer file Ui_MainWindow.jui. In order to generate the java code you simply run:

juic Ui_MainWindow.jui

As I want the resulting code to live in a package, "foo", I need to manually add the following line to the top of the resulting file,

package foo;

We also need to arrange for this .java file to be compiled before we can use it. How you use this depends on your build system, but you can choose to just compile it by hand when it changes (as this should be comparitevly rare). I guess you know how, but just for completeness:

javac foo/

Now, the qt4 macro I've defined there is directly lifted from Brian Carper's blog posting on using Qt4 in Clojure, and again I won't go into that here. Instead lets look at Foo-main. Note that we create instances of both the Ui_MainWindow class from the generated java code and the QMainWindow class. We call the setupUI method of the Ui_MainWindow class with the QMainWindow class as it's arguement (this essentially fills out the QMainWindow with the layout you put together in designer). Note also that I reference the pushButton widget inside the Ui_MainWindow class.

The remaining interesting thing about this file is that it defines a custom slot. Signals and Slots are fundemental to the way that Qt hangs together. Wiring together the prexisting signals and slots is very easy and can be done either in Designer or in code (as R.P. Dillon's example shows). Making a custom slot turns out to be rather more difficult. I naively assumed that I could just use a proxy around the QMainWindow class and add a slot function there, but this simply doesn't work. Instead I need to use (gen-class) to make a real class and bind a clojure function to it. For convenience I use (gen-and-load-class) - this call generates the bytecode and loads it. You have to pass it a fully qualifed class name - I've found it better to make it a subpackage, so I place it in foo.gen, and therefore the classname is foo.gen.Slot. I also have to give a place holder for the slot method. Confusingly enough I've chosen to call it "slot" here. We pass a vector containing a vector for each method, which in turn contains a method name, a vector of arguements and a return type. The method name will get bound to a function in the current namespace (not foo.gen, but foo) with the name -. In my example code this is contained in the proxy "slots" as the "slot" method. It's possible to just use a normal (defn) for this mapped method, in which case the function name would be "Slot-slot", I just find the proxy cleaner. Lastly you'll see that, back in Foo-main, I connect the pushButton's clicked signal to the custom slot, "slot" in the proxy, "slots". I hope that's clear!

Now all things being equal you should be able to make your JAR and execute the code. I hope that helps someone avoid spending a lot of time trying to work this out.

When I need to implement a custom signal I'll try and write that up too. Till then, ta ta!

Saturday, 8 November 2008

On Clojure - part 2 - Distributing QtJambi with Clojure.

One of the questions I've seen coming up a few times is how to distribute clojure programs. The obvious answer is to build executable JAR files.

I while ago I produced a simple database application for my girlfriends recruitment business, NRecruit. I developed this using Clojure on my Arch Linux based laptop, and deployed to her MacBook running OS X Leopard. The underlying database is sqlite3, but it could just as well be MySQL or anything else that is supported by JDBC. For simplicity I unzip the required JAR files in the root directory of the project and then rebundle them into a single distributable JAR following this guide.

That application is in production use right now, but there have been a number of problems with the Swing based GUI. I have been trying to address them, but I find Swing an unnecessarily painful toolkit to use.

Several years back (circa KDE 2, and early KDE 3) I used to do some development with Qt in C++ and Ruby. I have looked at Qt4 a couple of time before and I still feel that Qt is one of the nicest GUI toolkits out there. So I read this blog entry on using Qt4 with clojure with great excitement I started porting the NRecruit database UI over to Qt.

So far I've hit two issues. The first one (using Qt Designer files from within Clojure) I'll address in a later post; the second one is more fundemental. Distributing QtJambi in your jar has a few gotchas. The most succesful approach I've found is this:

  • unzip the qtjambi-4.4.3_01.jar and qtjambi-linux32-gcc-4.4.3_01.jar files in your projects root directory (where the version number and platform name vary based on the version of QtJambi you're using and the platform you're targetting).

  • When you make your jar file make sure you include the "com" and "lib" directories and the file "qtjambi-deployment.xml"

That leaves me with what I'd describe as a "statically linked" executable (it isn't in any sense statically linked, but the effect is the same).

More later...

On Clojure - part 1.

After many a dalliance with R6RS compliant(ish) Scheme implementations I have found myself inevitably drawn towards as new Lisp dialect instead. While I'm pleased to see Ikarus maturing to the state where it really is a very usable it's not what I've been using to get stuff done. No, instead, I (like everyone else it seems) have fallen for Clojure.

I won't harp on about Clojure - you can read about it everywhere, instead I'll just make some practical notes in the following posts.

Thursday, 9 October 2008

There is no way to peace; peace is the way. --A.J. Muste

Day24 Year2, originally uploaded by Tanzbar.

Nic is not usually one for politics, but she's doing some interesting things in her second year of dayshots. I like this a lot.

Thursday, 25 September 2008

Cool Clock

Day10 Year2, originally uploaded by Tanzbar.

Long time no post.

I don't have much to say right now, but Nic made this wonderful clock picture, and I think we should make it :)

Tuesday, 26 August 2008

What's next? Ypsilon


For a good long while I have been tracking the Ikarus Scheme implementation. I like it because it tries to comply with R6RS, compiles to some pretty quick code and recently added 64bit support. I like it so much that I even package it and a number of related libraries for Arch Linux.

However, Ikarus has a single annoyance for me - it is not easy to extend it with C libraries. You can of course do this by running a C program that allows calls to the library in question via socket or pipe communication - but I don't really like that model. For this reason I am quite excited to come across Ypsilon, an R6RS compliant Scheme implementation with a Multi-Core optomised garbage collection routine, simple FFI and support for Linux, Mac OS X and Windows.

As soon as I have found time to have a play I will write more!

Thursday, 14 August 2008

The danger of superfluity

There is an application that I have been working as an employee and a consultant for five years now. In the course of development I routinely run into a dialog in this application that handles errors at a global (or at least global to the GUI) level.

This dialog is very useful, it stops the GUI bombing out totally and presents the user with the sad news that something has gone wrong and allows them to report such an error. If you are a developer it even lets you enter debugging land. Today however I came across a subtle issue with this dialog that I believe has been there for several years. The dialog is headlined with the phrase "Unknown Error".

"Unknown Error?" "What's wrong with that?" I hear you cry. Well, we're all accustomed to seeing such messages, indeed I believe this text appears in this dialog because someone (possibly even me) saw it in other examples, and I wouldn't bother to post here if this problem wasn't one that extended beyond the domain of a commercial app in a very limited market. My issue is this, what is the value of the word "Unknown"?

Does it reassure the user? No, quite the opposite.

Does it distinguish the error case? No, if it were a known error then we should either have handled it of at least linked the user back to some information about the bug (for various reasons this isn't possible in the real world scenario for this application). In practice if a user reports this bug however they will often find out that this really is a "known error" from the support staff.

So what does the word "Unknown" get us? At best it adds nothing, at worst it scares the users and can even be plain wrong. Perhaps we would all do well to think a little more about what we say to the users

Friday, 4 July 2008

On the subject of Bill Gates retirement

I've waited a long time to talk about this. I was all ready to rant and rave about the torrent of lies that the media would put out. As it turned out, however, one of the nice things over the last couple of weeks is that there have been pockets of journalists who've have taken the time to actually accurately portray Bill Gates career in the computer industry. In the past journalists and news outlets have seen fit to repeat the myths that Bill and Microsoft have propagated. On his retirement though they seem happy to point out that Microsoft is not responsible for most of the innovations it gives it self credit for, and even fewer that the general public give it credit for, and contrary to popular belief Bill Gates is not one of the greatest technical minds of his generation. What he is a great business man, and his company has succeeded by putting business first, often at the direct expense of innovation and technical improvement.

However you feel about the man however he is one of the defining figures of his generation and as an economic entity he has the power to change the world, and I'm glad to say in his retirement he intends to spend more time using his fortune to rid the world of some of it's real problems through the Gates Foundation.

As for the computer industry, well the era of Microsoft's domination is slowly ebbing away, but I'll leave it to Richard Stallman as ever to present the ethical compass for the industry in this rather nice piece at the BBC:

Thursday, 3 July 2008

In this new fangled age of TrueType support in Emacs it's really useful to know the names of the Monospace fonts installed on your system in the format that Emacs understands. If you are on a Linux/UNIX system running Xorg with fontconfig installed then add this function to your .emacs file

(defun list-monospace-truetype-fonts ()
"Provide a list of available monospaced truetype fonts on this
(set-buffer (get-buffer-create "Monospaced Fonts"))
(call-process-shell-command "fc-list :spacing=mono:scalable=true family | sort" nil t)
(setq buffer-read-only t)
(switch-to-buffer-other-window (current-buffer)))

You can set these fonts in a number of ways, currently I am getting the most joy using this form:

(defun safe-set-initial-font (fontstring)
"Set the default frame font"
(interactive "s")
(setq initial-frame-alist
`((font . ,fontstring)
(background-color . ,(face-background 'default))
(foreground-color . ,(face-foreground 'default))
(horizontal-scroll-bars . nil)
(vertical-scroll-bars . nil)
(menu-bar-lines . 0)
(height . 40)
(width . 80)
(cursor-color . "red")
(mouse-color . "green")))
(setq default-frame-alist (copy-alist initial-frame-alist)))

That's pretty nasty, but it gets round a bug where opening a new frame results in a different font being used.

Wednesday, 2 July 2008

Things that happened yesterday

Hmmm   I am aware that I should put more technical content here, trouble is I don't have much to say at the moment.   Work is dragging on with the same old problems with different hardware.   Outside work I am actively working on something  (smallish) using Erlang to get my skills in that area up to scratch before starting something else (still smallish, but bigger).

In the mean time here are a couple of things that happened yesterday.   Firstly, Nicole and I both had pictures shortlisted by for their new Munich city guide.

Nic's photo is a day-shot she took in Karstadt, a department store in the center of Munich, it's a really cool shot.   Mine is a more typical, boring tourist shot of the Olympic centre.    We have no idea if they'll make it into the guide, but it is nice to be picked.    

Having been shortlisted I downloaded the current guide to have a look.   It's sort of a an offline google maps with tourist guide data for the points of interest.   It's OK, and handy to have on your laptop/PDA/Smart Phone when you travel I guess.    I imagine that this sort of thing will get a lot smarter with widespread adoption of always connected, location aware devices like the iPhone 3G.

In the evening we went t Tollwood, which sounds like a sleepy village in Surrey, but is in fact a culture festival in Munich.   To me it looked a little bit like the medieval festival a few months earlier, but with fewer silly costumes and more cultural diversity.   Still, it was fun and their was a good selection of food to choose from.

Monday, 30 June 2008

The defiant one.

This weekend was Silke's birthday.

I took time out from writing webstore code in Erlang using YAWS to take some photos.

Tuesday, 24 June 2008

A bug's life

A bug's life, originally uploaded by tealeg.

It starts with the Aphids. When we put our plants on the balcony this year those dastardly greenfly hit them with a vengance.

We tried a natural remedy, based on soaked nettles.. but without success we were left with no other option but to pray for ladybird or hover fly lavae. Just when we thought we would never get any luck we spotted the first ladybird lavae. They're ugly little critters but with plenty of aphids to munch on they soon grew big and strong.

One day they were looking very sleepy and hanging out on the leaves of a lavendar bush. The next morning they had turned into little pupae stuck to the undersides of the leaves. Just over a day later the world had some brand new ladybirds, ready to build a new generation of aphid munching predators. Hooray ladybirds!

Monday, 23 June 2008

Geoff embraces his new life

Geoff embrasses his new life, originally uploaded by Tanzbar.

Nic seems to specialise in taking shots of me in compromising positions.

Here I am at the local Biergarten (Lochham) , drinking König Lüdwig dunkels bier (my favourite German beer) and supporting Germany in the match against Portugal.

For some reason it looks like my ear was bleeding, it wasn't.

Role on Turkey.. probably not one to be in the center of München for given the reaction of the Turkish population here following their victory the following night.

Friday, 16 May 2008

OpenVPN and solaris

A little more solaris joy. Mainly as a note for myself here is how to setup an OpenVPN client on OpenSolaris 2008.05:

  1. Add Blastwave and SunFreeWare IPS repositories to the Image Packaging System:

    -bash-2.05b# pkg set-authority -O Companion
    -bash-2.05b# pkg set-authority -O Blastwave
    -bash-2.05b# pkg refresh

  2. Install and setup the TUN device:

    -bash-2.05b# pkg install IPStun
    -bash-2.05b# add_drv tun

  3. Install openvpn:

    -bash-2.05b# pkg install IPSopenvpn

... and now you're ready to put your openvpn.conf file in /etc/csw/openvpn/.

You start and stop the daemon using:

-bash-2.05b# /etc/init.d/openvpn start
-bash-2.05b# /etc/init.d/openvpn stop

... which is nice and familiar, but I'd rather have it set up for use with svcadm. Ah well, can't have everything.

Brandz Spanking New

So, long time no Solaris talk.

I've not been sleeping well this last couple of weeks (ironically this seems to have a lot to do with exhausting myself during my recent trip to England), but that inevitably leads to lots of mucking around with computers in the wee hours of the morning.

So OpenSolaris 2008.05 is on my laptop right now, and it's a bit of surprise to find it there as I am trying to hack on some code that is destined to run on Linux. The crux of the biscuit is this: I need a contained environment to much around with different Python implementations, it needs to be Linux and it needs to have network access from my laptop. Previously I'd been trying to achieve this on Linux using:

  • Plain old chroots
  • VMWare
  • VirtualBox

All of the above turned out to be failures. Chroots just don't cut it (the interaction between the chroot and the host is too strong - debootstrapping tends to lead to all sorts of issues with network services (sorry dbus didn't install correctly because it was already running..?!?!).

VM's seem like an obvious solution. The problem? My network access is predominantly wireless. Wireless and network bridging don't play well in Linux - you can do it, but it tends to screw up in all sorts of odd ways when the wireless card renegotiates with the AP. This isn't helped by the fact that my laptops wireless card (an Intel 4965ABG) is fairly new and the linux drivers are only just stabilising (Kudos to Ubuntu Hardy Heron for being the only Linux distro I've tried that made this card "just work" out of the box). Another factor is that same wireless card is also the only physical interface available to bind a tun to for my OpenVPN connection to my clients network. The reality of working with this setup for bridged interfaces is a series of hacks and, unfortunately, rebooting every 40 minutes or so. So I have made do with NAT'd and local networking in VMWare and switched between them based on my networking needs. Frustrating doesn't even begin to capture it!

Of course, I could plug in some cat 5 to the router, but the router is hidden in a cabinet in the front room, no where near a sensible location for doing work, so I've been living with NAT'd VM's for a couple of months now.

So where does OpenSolaris come into all of this? Well, I've been tracking OpenSolaris for a long time now - I've used Solaris several times over the past decade, but it's always been a fringe thing for me, Linux has always given me more bang for less effort. OpenSolaris 2008.05 is a pretty polished distribution and it's starting to address some of the issues. I don't want to write about that here, but one key thing is that the re-emergance of the iwk wireless driver and the immature, but suprisingly reliable Network Auto Magic Daemon (nwam - a sort of NetworkManager, sans braindamage, for OpenSolaris) combine to make my goddamn tricky wireless card work out of the box.

OK, that's nice, but what does that give me that Hardy Heron doesn't? Well, whilst OpenSolaris may only just be maturing into an operating system that a sane human being would want to use in the day to day, it does have some seriously powerful and reliable toolsets built in for large scale (if I ever say "Enterprise" just shoot me..) computing: ZFS, Containers/Zones and by extension Branz - a special kind of zone that can masquerade as something else, i.e. Linux.

So I have set up a lx branded solaris zone on my laptop. What does this give me, well, it gives me something that's more isolated than a chroot, but more lightweight than a VM. It looks like Linux (like CentOS specifically). It has it's own IP Address on the wireless network, bound to the same card as the global zone (the host) and both the global zone and the lx zone can see each other as first class peers on the same network as well as talking to the outside world. It has it's own ZFS filesystem (linux with ZFS? w00t!). I can choose to access that filesystem from the global zone (just like a chroot), which saves some tedious mucking around with network file transfer protocols to relatively simple things (security is not my prime concern in this case). I believe I can also dtrace this environment.. a unexpected benefit.

So what hoops did I have to jump through to set up such a marvel? Here's the transcript:

-bash-2.05b# zonecfg -z timaeuszone1
zonecfg:timaeuszone1> create -t SUNWlx
zonecfg:timaeuszone1> set zonepath=/export/timaeuszone1
zonecfg:timaeuszone1> add net
zonecfg:timaeuszone1:net> set address=
zonecfg:timaeuszone1:net> set physical=iwk0
zonecfg:timaeuszone1:net> end
zonecfg:timaeuszone1> commit
zonecfg:timaeuszone1> exit
-bash-2.05b# zoneadm -z timaeuszone1 install -d /export/home/gteale/Desktop/Centos_fs_image.tar.bz2
-bash-2.05b# zoneadm -z timaeuszone1 boot
-bash-2.05b# zlogin timaeuszone1

Not too shabby! Now let the hacking commence.

Friday, 18 April 2008

the bavarian builder

the bavarian builder, originally uploaded by Tanzbar.

I love this photo and I just had to share it.

BTW, Paul Graham's Arc rocks, but the anarki modifications rock even more...

Wednesday, 16 April 2008

Story of stuff

tardigrade, originally uploaded by fluffierworld.

So firstly, please, please take the time to go and watch:

.. some of it everyone knows, but it's still worth understanding *all* of it.

Once that's given you the picture you need to get an idea of how it's going to get fixed. Here's a good source:

.. there you'll learn how the little fella pictured (A tardigrade, or "little water bear") is helping prevent killer diseases in Africa without using up the earths resources (amongst other things).

Sunday, 13 April 2008


dude, originally uploaded by Tanzbar.

So, this weekend we found ourselves in the Thereisen fair ground looking for a new lens (long story - we ended up buying a dining table instead of a lens, such is life!). Whilst in this area of Munich, where Oktoberfest takes place, we got to see the young and trendy types and I realised that I was not as "down" with the young people as I imagined (I mean, can you even imagine me not being cool?).

So here is my attempt to reproduce the predominant style of dress amongst the young folk on that portion of Munich.

Clearly all men are jealous and all women will find this irresistable.

I thank you for you interest, but I am Nicole's sorry, better luck next time.

Saturday, 5 April 2008

Guest appearance

Day234, originally uploaded by Tanzbar.

I made a guest appearance in Nic's day-shot the other day. We were sitting having drinks on our balcony for the first time.

Very nice. I was actually pulling this expression on purpose but I do look like I've got something way too hot in that mug :-)

Tuesday, 1 April 2008

They can only break my heart

They can only break my heart, originally uploaded by tealeg.

Probably my favorite shot so far at 800mm focal length. It takes a really sunny day to get the best out of my £30 combination of Tokina 80-200mm f4 zoom, clubman 2x converter (costing me another 2 stops), OM->4/3 adapter and an E410...but when it comes off it's nice to have all that zoom.. :-)

Friday, 28 March 2008

Most intersting photo of mine on flickr.

Attention, originally uploaded by tealeg.

OK, I love this photo. It's from my old E1 with a Sigma 55-200mm lens. Still if I had a badger shot I'd have expected that to win.. this is a good substitute though :-)

2nd most intersting.

Blue water, originally uploaded by tealeg.

I guess.. though I wouldn't pick it.

3rd most interesting

Lens Time, originally uploaded by tealeg.

Rubbish - it's awful. Posting anything to the Canon G9 groups get's it a large number of hits, this happens to be interesing to Oly 410 users and users of legacy lenses as well, so it gets a lot of attention, but really this is not and interesting photo. Boooo.

4th most interesting

seagull_lampost, originally uploaded by tealeg.

A travesty - this isn't even a very good shot. It's here purely on the basis that is met the criteria required of several fairly active flickr groups.

5th most intersting

Somewhere to call home, originally uploaded by tealeg.

Suddenly became intersting when it was invited to be part of the a spinoff group from "the Blues" called "Best of the blues". I'm surpirsed but pleased that they like it so much.

6th most intersting

serious 4, originally uploaded by tealeg.

Actually I think this is one of the best shots I've taken recently, although there is one better one taken a second or too later that doesn't even register on Flickr's "interesting" scale - of course that seems to be down to it not matching the criteria required to post it to various groups - interestingness seems to have something to do with the broadness of attention a photo gets, not just the number of hits.

7th most intersting

You saw me standing alone, originally uploaded by tealeg.

Hmmm, maybe...

8th most ineresting

Schokolade, originally uploaded by tealeg.

Certainly not a better photo than the 9th..

9th Most intersting flickr photo

I cannot sleep here, originally uploaded by tealeg.

What makes this more interesting that the 10th? I dunno. I like this one better though so maybe they're on to something.

10th most interesting flickr picture

Meltdown, originally uploaded by tealeg.

I don't understand it but Flickr considers this to be my 10th most intersting picture. More to follow.

Friday, 22 February 2008

Two to the five minus one

It was my birthday two days ago. At this age they tend to go with less of a bang. I think this pretty much sums it up:

Thank quantum theory (in the absence of God) then for my wonderful girlfriend who tried to make my day more interesting from 700 miles away by setting me this little puzzle:

... and in doing that proving herself once again to be a very inventive photographer :-)

Tuesday, 1 January 2008

Guten Morgen 2008

So... a new year.. the 30th new year of my life.

A big year for me. Firstly I am now just two months away from moving to Munich with my girlfriend Nicole and I'm both terrified and excited at the same time. I'm not worried about moving to Germany - strangely I just "know" that this will be OK - I'm worried about the future. I like working for my current employer, and I'd like to carry on working for them, but that may not be compatible with living in Munich in the long term. We will see...

Over the Christmas break I've been re-learning Java. It's been 8 years since I really spent any time looking at it. That's odd, because for a lot of the programming world java is the very air they breathe. For me it's just a language that my various employers have never needed me to use, so I haven't got any commercial experience with it. I am perhaps in the odd position of having far more Ruby, Python and Scheme experience than Java! Still I make it a rule to learn a language a year (at least), so Java it is (for the 2nd time!).

... I need Java for a work project, and I guess it will be useful in the job hunt that may await me - it's less boring than I'd imagined, but after years of Python, LISP and Scheme I find it very long winded. Oh well - maybe that's the price I pay for the vast library base Java provides.

Oh.. and I got an Olympus e410 over christmas... can't recommend it enough - the closest thing to a pocket DSLR in existance.. I love it already.