Begin main content

Additions to my holiday reading list

Some additions to my holiday reading list:

07:30 PM, 29 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Accessible Spam

Perl hacker Schlomi Fish recently published an article about the need for accessible Spam, "Spam for Everyone" - The International Campaign for Accessible Spam

The "Spam-for-Everyone" campaign aims to convince spammers that they shouldn't send spam that makes it harder or impossible for disabled people to understand it


12:40 AM, 29 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Holiday reading

I have a few flights and trips over the Christmas week, so I thought I'd compile some reading material for those spare hours. If you're looking for some light ;) reading I thought you might be interested also:

08:20 PM, 20 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Red letter day for Perl

Well it's the 20th anniversary of when Larry Wall first released Perl to the world and to celebrate the Perl community has announced the release of perl 5.10, the biggest new perl release in 5 years.

May we happily program so pragmatically for another 20 :)

07:50 PM, 18 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Email is for old people

Outside of work, SMS and instant messaging are fast becoming the writing tools of choice. Indeed, South Korea - that crystal ball of all our digital tomorrows - has even seen a report that many teenagers have stopped using email altogether. "It's for old people," they say.


According to the poll, mobile texting, instant messaging and the perception that email is "a lot of bother" are all contributing to the end of the email era. Other factors, say the report, are the difficulty of ascertaining if an email has arrived and the lack of immediate response. One young Korean said that texting felt like a ping-pong game and that email was more "like doing homework".

Source: Sydney Morning Herald

There's an opportunity in here somewhere - it shouldn't be too hard to merge IM, SMS and email into one seamless communication. Unfortunately Facebook/Cyworld etc. are always going to be a proprietary impediment.

11:11 PM, 17 Dec 2007 by Mark Aufflick Permalink | Comments (1)

Parallel list processing module for Erlang

While reading the erlang mailing list I came across a (fairly) new module plists containing parallel versions of the erlang lists module and a few throwins (like a mapreduce implementation). The functions operated just like the standard variants plus an optional parameter that allows you to tune how many parallel processes are run and whether to use remote nodes or not.

plists is a drop-in replacement for the Erlang module lists, making most list operations parallel. It can operate on each element in parallel, for IO-bound operations, on sublists in parallel, for taking advantage of multi-core machines with CPU-bound operations, and across erlang nodes, for parallizing inside a cluster. It handles errors and node failures. It can be configured, tuned, and tweaked to get optimal performance while minimizing overhead.


This module also include a simple mapreduce implementation, and the function runmany. All the other functions are implemented with runmany, which is as a generalization of parallel list operations.


11:32 PM, 11 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Serve pre-compressed content with Apache

I wanted to serve compressed static js and css content from an Apache server. I also wanted to pre-compress the files to save time/cpu, and the particular Apache 2 instance had no mod_deflate or mod_gzip installed (dynamic content was being compressed at the application layer).

Serving pre-compressed content turned out to be incredibly easy using mod_rewrite*:

  1. Create a compressed copy of each .js & .css file with a .jsgz/.cssgz extension
    find . -name '*.js' -or -name '*.css' -exec sh -c 'gzip -c {} > {}gz' \;
  2. Add the following to a relevant part of your Apache config file:
    RewriteEngine on
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule (.*)\.css$ $1\.cssgz [L]
    AddType "text/css;charset=UTF-8" .cssgz
    AddEncoding gzip .cssgz
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteRule (.*)\.js$ $1\.jsgz [L]
    AddType "text/javascript;charset=UTF-8" .jsgz
    AddEncoding gzip .jsgz
  3. Test & reload your apache config
    httpd -t
    httpd -k graceful

Voila, correctly served pre-compressed static files. Just be sure to update your compressed versions whenever you update the content.

* ``The great thing about mod_rewrite is it gives you all the configurability and flexibility of Sendmail. The downside to mod_rewrite is that it gives you all the configurability and flexibility of Sendmail.'' -- Brian Behlendorf, Apache Group

07:04 AM, 06 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Australian IT job market

I took part in my first ever podcast last week on a panel discussing the Australian IT job market. Mark Jones hosts the weekly MIS Australia podcast for the AFR and invited me to represent the IT candidate market.

Also on the panel was Jane Bianchini, COO of Candle ICT (which seems to have changed it's name to Clarius in the last week - Moof ;), Carl Sjogreen, senior product manager at Google Australia and Peter Sheahan, an entrepreneur and author about Gen Y.

It was a good experience - I did just manage to get a few words in edgewise!

Use the embedded player or why not visit The Scoop and enjoy weekly panels talking about issues affecting the Australian IT industry.

08:51 PM, 04 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Parallel sorting in Erlang

Of course super-light threads for parallel programming is Erlang's killer feature, so let's apply that to a simple merge sort. Erlang's spawning and message passing interface is fairly straightforward, but a lot of parallel tasks are simple start -> process -> return type tasks, so we can simplify our syntax even further by using some nice helper functions such as Joe Armstrong's parallel map pmap or Anonymous Matthew's parallel eval pareval (via Philip Robinson's blog).

Parallel map makes light work of a massively parallel merge sort:


%% terminal cases for list of less than 2 entries
msort([]) ->
msort([A]) ->

% split list into 2 & mergesort them
msort(L) ->
    Mid = trunc(length(L) / 2),
    {A, B} = lists:split(Mid, L),
    lists:umerge( pmap(fun(I) ->msort(I) end, [A, B]) ).
This gets really interesting in certain cases eg. where acquisition of the data is expensive but randomly accessible.

Instead of passing in a simple list, our sort function could accept a future that would promise to return any requested linear subset of the data. Assuming we know the total length of the source list, no data is needed until we reach the merge phase at the bottom of the recursion stack, and incrementally more data is required as we bubble back up to the final result.

In this example we are doing our network retrieval in parallel with our sorting (which itself is happening in parallel). If the remote data comes from multiple hosts we could parallelise the retrieval by using multiple port instances.

11:58 PM, 02 Dec 2007 by Mark Aufflick Permalink | Comments (0)

Trees in Erlang

Like every man and his dog I've been playing around with erlang (and a smattering of Haskell for good measure :). I thought I'd try to see how I might write a binary tree implementation Erlang.

I must confess it turned out much less elegant than I thought it might - maybe some erlang or other functional gurus can point out a better algorithm.

Now before you all comment, yes I know most of the below isn't tail recursive - but performance isn't really the issue here, and a binary tree implementation in erlang is going to be inefficient anyway if you're making frequent updates, since every recursion will involve copying some of the structure (maybe it optimises that away ... dunno enough about its internals to comment).

-export([find/2, tree_of_squares/1, insert/3]).

-record(node, {key, val, left = nil, right = nil, height = 1}).

%% find/1
find(SearchKey, Node) whenSearchKey == Node#node.key ->
  {ok, Node#node.val};

find(_, nil) ->

find(SearchKey, Node) whenSearchKey < Node#node.key ->
  find(SearchKey, Node#node.left);

find(SearchKey, Node) ->
  find(SearchKey, Node#node.right).

%% tree_of_squares/1 : make a tree where key = val and contains
%% squares of all numbers from 1 to Maxtree_of_squares(Max) ->
  tree_of_squares(Max, nil).

tree_of_squares(0, Tree) ->

tree_of_squares(Max, Tree) ->
  insert(Max * Max, Max * Max, tree_of_squares(Max - 1, Tree)).

%% insert/3 : return a new tree made from inserting (or updating)
%% a node of Key, Val into existing tree or new tree (nil)
insert(Key, Val, nil) ->
       #node{ key = Key, val = Val };

insert(Key, Val, Node) whenKey == Node#node.key ->
       Node#node{ val = Val };

insert(Key, Val, Node) whenKey < Node#node.key ->
       balance(Node#node{ left = insert(Key, Val, Node#node.left)});

insert(Key, Val, Node) ->
       balance(Node#node{ right = insert(Key, Val, Node#node.right)}).

%% height/1 : return the height of the tree
height(nil) ->
height(Node) whenNode#node.left == nil, Node#node.right == nil ->

height(Node) ->
       height(1, Node#node.left, Node#node.right).

height(Acc, Left, Right)
 whenLeft == nil;
      Right#node.height > Left#node.height ->
       Acc + Right#node.height;

height(Acc, Left, _) ->
       Acc + Left#node.height.

%% balance/1 : return a new tree which is the balanced version of Tree
%% note also that balance is trusted to always return the root height set
%% correctly
balance(nil) ->

balance(Node) whenNode#node.left == nil, Node#node.right == nil ->
       Node#node{ height = height(Node)};

balance(#node{ left = L, right = R} = Node) whenL#node.height ==
R#node.height ->
       Node#node{ height = height(1, L, R)};

balance(#node{ left = L, right = R} = Node)
 whenR == nil ;
      L#node.height + 1 > R#node.height ->

balance(#node{ left = L, right = R} = Node)
 whenL == nil ;
      R#node.height + 1 > L#node.height ->

swing_left(#node{right = #node{ left = RL, right = RR } = Right} = Node)

 whenRR == nil ; RR == nil, RL == nil ;
      RL#node.height > RR#node.height ->

       move_left(Node#node{right = move_right(Right)});

swing_left(Tree) ->

swing_right(#node{left = #node{ left = LL, right = LR} = Left} = Node)

 whenLL == nil ; LL == nil, LR == nil ;
      LR#node.height > LL#node.height ->

       move_right(Node#node{ left = move_left(Left)});

swing_right(Tree) ->

 whenNode == nil ;
      Node#node.left == nil, Node#node.right == nil ->

move_left(#node{ right = #node{ left = RL } = Right} = Node) ->

       OldRoot = Node#node{ right = RL },
       NewRoot = Right#node{ left = OldRoot#node{ height = height(OldRoot)}},
       NewRoot#node{ height = height(NewRoot) }.

 whenNode == nil ;
      Node#node.left == nil, Node#node.right == nil ->

move_right(#node{ left = #node{ right = LR } = Left } = Node) ->

       OldRoot = Node#node{ left = LR},
       NewRoot = Left#node{ right = OldRoot#node{ height = height(OldRoot)}},
       NewRoot#node{ height = height(NewRoot) }.
tree_of_squares is just to easily create an interesting tree to play with, for instance:

1> c(tree).
2> T = tree:tree_of_squares(7).
Then you can try to find a node:
3> tree:find(1, T).
4> tree:find(2, T).
Not very interesting when the key = val - let's insert and update some entries:
5> T2 = tree:insert(5, bar, tree:insert(4, foo, T)).
6> tree:find(5, T2).
Fun huh!

An implementation of red-black trees is left as an exercise for the reader ;)

07:58 AM, 30 Nov 2007 by Mark Aufflick Permalink | Comments (2)

Computer Science

Computer Science is no more about computers than astronomy is about telescopes.

--E. W. Dijkstra

Great quote from the introduction of Algorithms with Perl

11:32 PM, 22 Nov 2007 by Mark Aufflick Permalink | Comments (0)

Apple Bric-A-Brac

While stuck in Apple-reminiscing mode (I'm reading Revolution in the Valley) I thought I'd see if someone in Apple was cool enough to have a server running on

Unfortunately it seems noone at Apple is nearly that cool:

Failed to resolve the name of server to connect

11:19 PM, 18 Nov 2007 by Mark Aufflick Permalink | Comments (0)

Round Rects are everywhere in Leopard

I love a good Round Rect as much as the next guy (see Round Rects Are Everywhere) and I am really happy about menus being rounded in Leopard. I dunno what it is, it just makes me feel nice every time I drop open a menu!

06:36 AM, 18 Nov 2007 by Mark Aufflick Permalink | Comments (0)

Todo items - do they ever get done?

I was browsing around the various google sites tonight to see what had changed, and I thought I'd punch my name into google code, the search index for source code.

There are surprisingly few results, but even worse is that the second search result is:

v_name varchar2(4000); -- XXX aufflick fix this

So any prospective collaborator or employer discovers that I have an un-done todo dating back to March 5 2003! And there's not even any comments suggesting what needs fixing. Oh well, it's in use in hundreds of production systems with tens of thousands of users, so I guess it doesn't really need fixing after all!

04:28 AM, 15 Nov 2007 by Mark Aufflick Permalink | Comments (0)

Parsing ini files with sed

A while back I found this neat sed pipeline for extracting an ini file section into shell script variables:


eval `sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \
    -e 's/;.*$//' \
    -e 's/[[:space:]]*$//' \
    -e 's/^[[:space:]]*//' \
    -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" \
   < $INI_FILE \
    | sed -n -e "/^\[$INI_SECTION\]/,/^\s*\[/{/^[^;].*\=.*/p;}"`
You now have variables in the scope of your shell script derived from the key/value pairs in that section of the ini script. REALLY handy. Thought it might help someone else if I recorded it here. I got it from this thread on

NB: the eval is a ksh builtin. I imagine using declare in bash will achieve the same, but I haven't tested it.

NB2: it seems Solaris sed isn't quite up to the task - the above requires gnu sed.

01:07 AM, 08 Nov 2007 by Mark Aufflick Permalink | Comments (2)

Leopard a touch spotty

I've come across a few more (very minor) Leopard glitches.

Help - I'm pinned under this heavy scrollbar!

The first is that if you have a Finder window with no horizontal scrollbar, and you then click on a file that's right at the bottom of a file list and which, by displaying it's preview, forces a horizontal scrollbar, then the file list doesn't get pushed up. That results in the image on the right - notice how you can just see the blue highlight of the X11 file poking above the horizontal scroll bar?

One potatoTwo potato

The second is with the dock and X11 (not sure if it's an issue with the app or the dock). If you put X11 in the dock, and then start it (from the dock), the icon you put in the dock bounces forever and a new X11 icon pops on the bottom of the dock (like it does for apps that are not in the dock already). you can see above I even sometimes get two extra icons. Note that I'm not starting any additional instances of X11 or any X apps besides the initial default xterm.

Update: The multiple X11 icons also appear in the Command-Tab bezel.

Update 2: It seems there are some pretty massive changes to X11 in Leopard. For the better Apple has switched to, but that (and other) changes have been major and some bugs have slipped through. The change to launchd is interesting - while non-intuitive (in an X11 way) it makes X11 apps more intertwined with the main OS.

Anyhoo, thankfully the maintainer is on the ball and has posted an update to solve the two most glaring issues - the faulty three-button emulation (critical on a laptop) and multi-monitor support. Go to for more. I still get some really wacky behaviour when my monitor resizes (eg. by plugging my 22" crt into my 12" powerbook) but it's better.

07:44 PM, 28 Oct 2007 by Mark Aufflick Permalink | Comments (0)

Leopard glitch unmounting disk images

I've found what seems to be a recurrant glitch on my new Leopard install - disk images just don't unmount via the Finder. Download and mount any .dmg and no matter how many times you drag them to the trash, click the eject icon in the sidebar or right click->eject, they stubbornly stay mounted.

It seems to be a Finder issue rather than with the disk image driver since a simple umount /Volumes/DiskImageName makes them disappear pronto.

Update: Further, Finder also gets terribly confused in some circumstances where you mount two (different) images with the same volume info. I got into one state where there was one volume showing in the sidebar that wasn't even mounted. A swift relaunch of the Finder sorted that out...

Update 2: Seems after relaunching the finder the original issue itself went away.

07:32 AM, 28 Oct 2007 by Mark Aufflick Permalink | Comments (1)

TimeMachine takes you back to a time before teh Internet

So I easily got an Amazon S3 storage bucket mounted under Leopard, but it turns out Time Machine doesn't support network mounts.

Well it's not that it can't, it actually does - but it won't show you any disks that it doesn't think are local (eg. disks served by Airport Express apparently work fine), so Apple evidently have decided that my net connection isn't fast enough for backups so I'm best off not even trying :(

So let's start hacking :) The TimeMachine preference pane binary has the following methods:

@interface AppleTMPref (Private)
- (BOOL)_isSupportedNetworkMountPoint:(id)fp8;

@interface AppleTMSettings : NSObject
- (BOOL)isNetworkBackup;

@interface TMBonjourBrowser : NSObject
    NSNetServiceBrowser *_browser;
    NSMutableArray *_netServices;
    NSImage *_serverImage;

- (id)init;
- (void)dealloc;
- (id)_dictionaryFromAirPortDiskData:(id)fp8;
- (BOOL)_isLocalNetService:(id)fp8;
- (id)_volumesFromNetService:(id)fp8;
- (id)bonjourDisks;
- (void)netServiceBrowser:(id)fp8 didFindService:(id)fp12 moreComing:(BOOL)fp16;
- (void)netServiceBrowser:(id)fp8 didRemoveService:(id)fp12 moreComing:(BOOL)fp16;
- (void)netServiceDidResolveAddress:(id)fp8;
- (void)netService:(id)fp8 didNotResolve:(id)fp12;


@interface SnapshotUtilities : NSObject

+ (BOOL)mountPointIsNetworkVolume:(id)fp8;
Time to crack out F-Script...

05:30 AM, 28 Oct 2007 by Mark Aufflick Permalink | Comments (2)

Leopard Amazon S3 network storage

Ok so I'll write this up better later, but here are the steps I followed to successfully mount an Amazon's S3 network storage bucket under Leopard:

  1. create an amazon web services account
  2. sign up for amazon S3
  3. download MacOS X S3 Browser
  4. install MacFUSE Core for OSX 10.5
  5. get your Amazon S3 key ID & secret (you'll get an email from Amazon with an url about that after signing up)
  6. login and create an Amazon S3 bucket using the S3 Browser you downloaded (I called my bucket "12inch-timemachine" for backing up my 12" Powerbook)
  7. download s3fs.cpp from the s3fs project
  8. you'll need to add the following line to the top of the file somewhere:
    #define __off_t off_t
    (props to Roberto Saccon for figuring this out)
  9. compile s3fs.cpp with the following incantation:
    g++ -Wall -D__FreeBSD__=10 -D_FILE_OFFSET_BITS=64 -I/usr/local/include/fuse -L/usr/local/lib -lfuse -pthread -lcurl -lcrypto `xml2-config --cflags --libs` -ggdb s3fs.cpp -o s3fs
  10. create the file /etc/passwd-s3fs with your amazon s3 key id and secret separated by a colon ie:
    example-id:example-secret-key (note that you'll want to be careful about the permissions on this file)
  11. mount the S3 bucket as an OSX directory like so eg:
    mkdir ~/s3
    ./s3fs your-bucket-name ~/s3 -ovolname=Flubber
    where Flubber can be whatever you want the mounted volume to appear named as
  12. you can now access the mounted volume at your mount point (in the above example ~/s3) or as a Finder Volume which you can see by going to "Computer" in the Finder's "Go" menu. Not sure why it doesn't show up in the Sidebar)

Update: It seems Leopard, by default, doesn't show network volumes on the desktop by default. You can turn that on in finder preferences, but your volume still won't show up in the sidebar (under either Devices or Shared). A simple solution is to us the local option like so:

./s3fs your-bucket-name ~/s3 -olocal,volname=Flubber
Unfortunately that still doesn't allow it to work with time machine. You also get a folder icon on the desktop instead of a disk icon, but it's in the sidebar under Devices now. The icon even has a working eject icon which is handy, but it leaves an annoying folder icon in the sidebar.

Update 2: the ping_diskarb option seems to help keeping the Devices icon current:

./s3fs your-bucket-name ~/s3 -olocal,ping_diskarb,volname=Flubber

Update 3: The previous must be in my imagination:

On Mac OS X 10.5.x, both these options [ping_diskarb, noping_diskarb] are no-ops

05:18 AM, 28 Oct 2007 by Mark Aufflick Permalink | Comments (7)

Leopard Finder Cocoa?

I don't remember hearing about this, but default Cocoa text shortcuts (eg. emacs keys like Ctrl-a for home, Ctrl-e for end) work in Finder now.

03:44 AM, 28 Oct 2007 by Mark Aufflick Permalink | Comments (0)

Leopard - first usability suck

Well I rushed out and bought Leopard, mostly for the garbage collected goodness of Objective-C 2.0.

The look and feel changes are mostly nice, but I have found one minor tweak that irritates me no end - and doesn't make sense to me from an HCI point of view.

If you have opened a drop down menu, and you decide you are happy with the existing selection, it used to be that you could "dismiss" the menu and leave it as it is by clicking anywhere on the screen outside the menu.

Now you need to either click on the selected option to re-select it, or if there happen to be unavailable options in the menu (ie. greyed out) you can click them as well.

Now that sucks from an HCI standpoint in two ways. First, to execute this relatively common action you now need to click in a quite small area instead of simply flicking your wrist and clicking. Secondly it is inconsistent with the menus in the menu bar, where you can click anywhere outside an open menu to dismiss it.

Update: It seems to have been another "glitch" because after a reboot I can no longer replicate it. Little bugs happen - at least it's not a change in the ui thinking.

03:35 AM, 28 Oct 2007 by Mark Aufflick Permalink | Comments (2)

Kimi Raikkonen - Champion of the World!

The perfect outcome I was daring to hope for!! My prediction was for Lewis and Alonso to take each other out on the first corner, but it seems somehow fitting for Alonso to miss out on the championship by simply fading away.

Kimi really deserves this championship. He's driven fantastically all season in what was a new car and new tyre for him. After years of unreliability with McLaren it must feel all the sweeter.

Well done Kimi, great job. Have a vodka for me :)

02:38 PM, 21 Oct 2007 by Mark Aufflick Permalink | Comments (0)

Mount Amazon S3 on your Mac

Roberto Saccon has successfully used a FUSE based S3 driver to mount an Amazon S3 bucket as a regular Mac volume.

That + time machine in the upcoming MacOS X 10.5 will make for a very cost effective and scalable backup solution.


01:14 AM, 21 Oct 2007 by Mark Aufflick Permalink | Comments (0)


Mark Webber qualifying 5th at Inter Lagos - brilliant! Massa on pole - even better (although I would have preferred to see Kimi in P2).

By the way sorry everyone for the dearth in technical posts - been a bit busy lately with a few things (including working on my lap time down at Wakefield park - 1:24 is my best so far :).

11:28 PM, 20 Oct 2007 by Mark Aufflick Permalink | Comments (0)


I said at the start of the race that Mark Webber would be great in the wet.

Even the ITV boys thought he had a chance at Lewis for a win once the safety car period ended. If not, a dead certain second place - bettering his previous best of third.

Even throwing up in his own helmet didn't stop him.

But Sebastian Vettel smashing into him did.


Pity that Webber couldn't get a 10 place boost instead of Vettel recieving a 10 place penalty for the next race.

07:46 AM, 01 Oct 2007 by Mark Aufflick Permalink | Comments (0)


TitleSemi from TramTown may not likeRatatouille (the new Pixar flick), but I loved it. 7/10

11:21 PM, 09 Sep 2007 by Mark Aufflick Permalink | Comments (0)

If I read one more article about cracking the iPhone...

Nation leaders representing 56% of the world's GDP are in Sydney, and The Sydney Morning Herald website leads with "Code crack opens the iPhone floodgates"??

According to "one member of a group of Australians", "there are at least 30 or 40 people in Australia" using iPhones.

Using phrases like "thumbing their noses" and "much-ballyhooed", is this really Australia's premier journalistic talent? This could be an article straight from The Onion (which always has had fancier prose that it's Australian equivalent The Chaser) but unfortunately it's deadly serious.

Maybe I'll have to turn to mX for my serious editorial content.

07:02 AM, 04 Sep 2007 by Mark Aufflick Permalink | Comments (0)

Heroes of software design

I've just finished reading an interview by Grady Booch (a pre-eminent computer scientist himself) interviewing Andy Hetzfeld and Bill Atkinson titled The Oral History of MacPaint.

Bill Atkinson is probably one of my biggest heroes of software design (Steve Wozniak and Burrell Smith being my heroes of hardware). Another one of my heroes of software (or really computing) design is Douglas Engelbart. In my mind the time frame from one to the other was huge, but it's really only 15 years or so - and Bill met Douglas Engelbart - astonishing!

So, I said at '68, the windows and mouse were invented by Englebert, and I actually went to visit Englebart. It was a wonderful visit, and I think he gave a really good argument which was that when you design for the beginner, sometimes you shortchange the experienced user. If you were designing only for a walk-up-and-use-it experience, you would never design a bicycle because it takes a while to learn to use a bicycle, although it gives you good power. So, he was designing more for a professional knowledge worker, and he's willing for people to learn this five-key chord thing and lots of new ways of working with stuff.

Now very few of the facts in the interview were news to me like that, but discussed as such a compact timeline of the birth of the GUI and desktop application as we know it (taking in the foundational elements of Engelbart's NLS and Xerox Parc's Smalltalk) makes a number of things really stand out. Those notes are below, along with some nice little one liners I have quoted or paraphrased.

  1. The entire design of what is used productively today on every PC in the world was designed by technology people. I mean *really* technical people, but people who also really cared about the purpose - how it would help peoples' lives. Today many environments don't allow their technology people to design a newsletter without some sort of external designer or consultant, and by organising this way we discourage technology people from becoming engaged and involved - instead restricting themselves to mechanical implementation.

  2. Sometimes you do a lot of work just to throw it away - but the later things you do wouldn't have happened any other way. And you never know which is going to be the important thing that flops, the thing that just flops, or the thing that succeeds - so you have to put your all into it anyway. The Lisa was a total flop. Everyone knows that. But Apple spent a lot of time investing in the Lisa product, and the legacies of that were Bill Atkinson's (and other's) familiarity with the 68000, the foundations of QuickDraw, the testbed hardware for the mouse driven GUI, etc.

  3. You're never too busy for a fun outing. Imagine if Steve Jobs et al had been "too busy" to take a tour around Xerox Parc. They would be forgiven for saying their filofax was full.

  4. Your biggest competitor is not a big corporate, it's a three person research team

  5. Computer processing cycles aren't valuable. People's time is valuable.

  6. If you find yourself thinking "what would anyone use that for?" think harder ("Apple was offered lock, stock and barrel exclusive
    rights on a spreadsheet for $50,000, and they turned it down. ... What would anyone use it for? They could have owned the whole spreadsheet concept.")

  7. Sometimes the crazy genius is right instead of the conservative committee.

  8. Sometimes your boss is wrong and he'll thank you later for ignoring him (Steve Jobs insisted that "the Mac would only be 128K ever, and that it was not okay to have it expandable to 512. Actually, Burrell went behind Steve's back to make it so there was one trace you could cut, and you could stick in the 512K chips. Steve later had to apologize and say he was wrong. ")

  9. Think about things a lot. Try some things. Try different things.

  10. Some mistakes you make will stick around for a very long time (Atkinson: Well, a design I regret is the double click.)

  11. Sometimes a non-optimal solution is the best one.

  12. Brain surgeons are really smart.

  13. Code should be beautiful (Atkinson: I would spend time rewriting whole sections of
    code to make them more cleanly organized, more clear.)

  14. Code comments shouldn't have to say what something does - instead should say why it is being done.

  15. Employ great graphic designers and writers.

  16. Having to teach somebody how a piece of software works forces you to clean it up.

  17. Sometimes you make a product better by leaving features out.

  18. technology is very cool, and
    there's beauty in the software, but software is ultimately a human experience.

  19. If you want to get it smooth, you've got to rewrite it from scratch at least five times.
    And have a lot of user testing. Because you can't see the things that you can't see.

Footnote: It's interesting that Grady starts using the word 'heroes' part way through the interview, because I had already come up with the title for this blog before I got that far.

10:41 AM, 21 Aug 2007 by Mark Aufflick Permalink | Comments (0)

Benchmarking a 1986 Mac

86 Mac Plus Vs. 07 AMD DualCore. You Won't Believe Who Wins

Classic - literally.

For the functions that people use most often, the 1986 vintage Mac Plus beats the 2007 AMD Athlon 64 X2 4800+: 9 tests to 8! Out of the 17 tests, the antique Mac won 53% of the time! Including a jaw-dropping 52 second whipping of the AMD from the time the Power button is pushed to the time the Desktop is up and useable.


Is this to say that the Mac Plus is a better computer than the AMD? Of course not. The technological advancements of 21 years have placed modern PCs in a completely different league of varied capacities. But the "User Experience" has not changed much in two decades. Due to bloated code that has to incorporate hundreds of functions that average users don't even know exist, let alone ever utilize, the software companies have weighed down our PCs to effectively neutralize their vast speed advantages. When we compare strictly common, everyday, basic user tasks between the Mac Plus and the AMD we find remarkable similarities in overall speed, thus it can be stated that for the majority of simple office uses, the massive advances in technology in the past two decades have brought zero advance in productivity.

I wouldn't say zero - the pivot table alone has improved savvy spreadsheet users efficiency a lot, and they didn't mention that Word 3 didn't have any real table support. But that's not really the point. It's still outrageous how little improvement the average user of office productivity software has gained from the billions expended on so-called software development.

07:17 AM, 21 Aug 2007 by Mark Aufflick Permalink | Comments (0)

Incongruous search terms

I have commented before about interesting search terms I see in my web server stats. You'll be pleased to know that Mel Kaye and magic mug cake are still frequent contenders for the top search terms.

I noticed a disturbing search term this month though:

evolution of programming languages in power point

What are they thinking??!

Of course should they be interested in programming languages they will find a feast in this blog: perl, SQL, ruby, emacs elisp, smalltalk, java, C, 6502, arm,NLS, Cocoa/Objective-C, future issues for theoretical computer science and even visual basic! I'm sure there's more there, and erlang and haskell are sure to follow...

But *never* will there be a good thing to be said about powerpoint on this blog :)

10:13 PM, 19 Aug 2007 by Mark Aufflick Permalink | Comments (0)

Keyspan remote + EyeTV + iTunes

People who know me know all about switching all of my home entertainment off discrete units to a spare Powerbook. I tell anyone who will listen how great it is!

All you need is a mac, some powered speakers, and a screen. Now this is nothing new - people have been doing it with Mac Minis ever since they were released. I prefer a laptop since some things are just easier to do with a keyboard and mouse - and I can do them without stopping playback on the main display.

One thing that was missing was unifying control - by that I mean sitting on my couch, using one remote to do everything without getting up. What point is home entertainment if you can't drive it from your couch?!

There's a bunch of projects that aim to do this, but I wanted something simple. No on-screen menu, just the standard features from a remote.

So I bought the excellent Keyspan Express remote. I would have preferred an RF remote (rather than infra-red), but the affordable RF models have less buttons.

Then the challenge was to use the limited number of buttons to achieve an understandable (to non-technical people) set of functions that would let you do most things.

Over some coming posts I'll explain what actions I chose for what reasons, but the curious can take a look at some applescripts in the mean time.

07:09 PM, 04 Aug 2007 by Mark Aufflick Permalink | Comments (3)

1 degree

1 degree - A News Limited Initiative1 degree - A News Limited Initiative

Everyone's favourite media mogul is turning down the thermostat 1 degree, which will save 5% on heating usage.

The video is worth watching. Even Rupert realises that acting on climate change is "simply good business". No overt attempt to pretend a moral high ground.

Carbon neutral by 2010 - tough ask for a company with a carbon footprint of 641,150 tonnes, but Rupert isn't known for missing his targets.

And perhaps this is the real momentum building. While democratic government waits for an overwhelming majority others will step in. Global business, aid groups, the courts, churches. It gets interesting from here.

09:49 PM, 24 Jul 2007 by Mark Aufflick Permalink | Comments (0)

Australian blog search

I seem to have been Listed in - whatever that is.

Only Australia could turn out blogs named Frugal Bastard and elliot's artwank :)

02:17 AM, 23 Jul 2007 by Mark Aufflick Permalink | Comments (0)

Aussie blogger - will blog for bandwidth

Ross Dawson discusses an SMH article which quotes his discussion (still following?) of the state of blogging in Australia, tying it in with bandwidth:

"Of the top 25,000 blogs globally, around 9000 are in English", says Mr Dawson. Of those, only 75 originate in Australia. But there are 420 million native English speakers in the world. "With Australia's population of 21 million, we comprise 5 per cent of English speakers. But with 75 blogs out of 9000, we comprise less than 1 per cent of English blogs. We are underrepresented by a factor of six or so."


"I think one key reason is lack of bandwidth in Australia, and of its high cost. Australian internet connections are slower than they are in the rest of the world, and Australia is almost unique in capping usage at quite low levels."

There should be some adjustment in interpreting those numbers for local vs. global readers.

You could only make such a simplistic percentage comparison for countries of a similar size.

For instance a widely read blog on local Californian politics will probably rate in the top 25,000 blogs globally - since California has such a huge population. A widely read blog on local NSW politics could easily have a higher percentage of the available readership, be more influential etc. - and yet not rate a mention in the top 25,000 blogs.

Now I'm not saying that the general observation is wrong - but these figures don't back it up as clearly as it may first appear.

As for bandwidth - blogging doesn't take a lot of bandwidth. Price is a far more important factor. Very cheap always on internet is going to promote more blogging than very high bandwidth internet that doesn't reduce the cost of the cheapest plans.

But even with cost, I don't think that the key issues are so simple. As a nation we seem to be underrepresented in entrepreneurship in general, and I think blogging is simply literary entrepreneurship.

Solving that chestnut is a rather difficult socio/economic/politic/educational issue - beyond the scope of this Australian blogger at the moment ;)

Original linker: Corporate Engagement.

02:09 AM, 23 Jul 2007 by Mark Aufflick Permalink | Comments (0)


I just spent a few evenings in autohell trying to configure the cvs trunk of GNU Smalltalk.

I wish I could document my story, but there were just too many twists and turns (many which ended with the distinct feeling of darkness and that one was likely to be eaten by a grue ;).

Instead I will just document some things I found useful. Firstly, install the latest autoconf and automake package your packaging tool has (MacPorts in my case). Secondly, consider the following your personal arsenal:

  • autoupdate --verbose
  • find . -name | xargs perl -pie 's/AM_CONFIG_HEADERS/AC_CONFIG_HEADERS/'
  • autoreconf --verbose

09:46 AM, 19 Jul 2007 by Mark Aufflick Permalink | Comments (1)

Simple javascript DOM visitor

I had a need to alter a bunch of ids and names after I cloned a dom node, so I cooked up the following dom node visitor:
function domVisitor(el, f) {
  if (el) {
    for (var i=0 ; i < el.childNodes.length ; i++) {
      domVisitor(el.childNodes[i], f);
So all you need to do is pass in the cloned node (or whatever) along with an anonymous function to do your bidding. The function will be called for the full tree under the node passed in.

04:38 AM, 05 Jul 2007 by Mark Aufflick Permalink | Comments (0)

Philosophies of copyright and law, and the new GPL v3

Groklaw posts the transcript of an excellent speech by Eben Moglen, one of the co-authors of the GPL v3 open source software license, a Professor at Columbia Law School in New York and the founder of the Software Freedom Law Center.

He begins with a surprisingly striking analogy:

I ask you to imagine briefly a world in which arithmetic has become property. ... Once we have reduced arithmetic to property, you'll have only as much arithmetic as you can afford, the consequence of which is that the gateways to material collaboration in the world, successful activity in relation to the physical and constructed environment, will depend very largely upon one's ability to acquire sufficient surplus amounts of mathematics.
Then invoking the famous words of Richard Stallman,

Why is software property? It should be knowledge to be shared, like math, like physics. It's unethical, to deprive people of information evidently available to them about the artefacts of digital society with which they are daily in contact -- it's evidently immoral to deprive them of knowledge. You've given the knowledge to the computer sitting next to them. They're using it -- the knowledge is playing a potentially determinative role in their lives. You've already delivered it to them -- all you haven't done is to deliver them the ability to know.

and also paraphrased John Dewey (who I had never heard of):

the education and expansion of the human mind depends upon the opportunity to experiment with the world.

talks quickly about the history of copyright in the US, and then turns to the new license itself.

He also has an interesting discussion comparing the pragmatic commercial foundations of US law and UK/Commonwealth common lay with what is happening online today:

But I would present to you the possibility that the UCC and the GPL 3 are in themselves a pair -- a pair, organizing an idea about the method of the creation of 21st century law. 21st century law is born in the street in the same way 21st century television is born in the street, not sent to you from the top of a broadcast tower, but upward from the cellphone and the portable camera put through YouTube.

21st century law is like 21st century music -- not made in an expensive recording studio or legislature, rented by the hour by people with the power to rent studios and legislatures, but made in every laptop in every den in every corner living room, in every garage, where a musician and a computer are, which is pretty much everywhere a musician is.


Of course, the idea that law might be something we all do together, it's got a long history stretching back far beyond the Free Software movement, stretching, in fact, back to beyond democracy. One of the characteristics that the continental Europeans noted of the English speakers, North Britains and South Britains, similarly in the course of the 16th, 17th, and 18th centuries, was that English-speaking people had an almost personal relationship to the common law. A man might be an artisan or a yeoman farmer, but he believed the law to be in some sense his own. He was familiar with the courts, he served on juries, the language of the law was in his mouth. Even beyond the language of literature and religion, it was in his mouth. It was, if not folk law in some forests-of-Germany sense, community law. The law of us, and to be not of this law was to be not of us in some fundamental way.

This is a must read for anyone technically or legally inclined or engaged in 21st century society.

02:47 PM, 02 Jul 2007 by Mark Aufflick Permalink | Comments (0)

Tape measures

I wonder if there is anyone in the world who has access to a tape measure who has *not* done this:



Source: xkcd - the best nerdy cartoon in the world.

11:19 PM, 01 Jul 2007 by Mark Aufflick Permalink | Comments (2)

Guaranteed crash for Safari

  • Have some tabs open;
  • type something into a text box in a web page;
  • close that tab, but of course the window is still open because of the other tabs
  • Edit->Undo is still available since the Cocoa UndoManager works, by default, per window;
  • Undo ->Crash :)
  • That's something to watch out for when you break the window instance == document instance that Cocoa assumes.

    Note that this is with the Safari 3 beta - but I'd be willing to bet the same behaviour occurs in Safari 2. Can anyone confirm/deny?

09:09 AM, 27 Jun 2007 by Mark Aufflick Permalink | Comments (0)

Non-orthogonality of Perl

When it comes to switching between objects and natives, Perl OO is not quite as orthogonal (or DWIM) as I would like. For instance, assuming I have a class:

package MyArray;
sub push { ...}

Then I can treat an instance of that object as an object with a method push, or as a kindof array (kindof, because of course an actual array would have @ for its sigil):

# these are equivalent:
push $instance, 1;

I don't, however, have the orthogonal behaviour with an actual array ref:

# this works:
push @$arrayref, 1;
# this doesn't:
# nor, of course, does this:

What I would like is more DWIM than real orthogonality, but if Perl's not DWIM then it's nothing! I guess I'm just wishing for real native array objects like Ruby (sigh).

11:54 PM, 24 Jun 2007 by Mark Aufflick Permalink | Comments (3)

What are you *really* competing with?

Dan Bricklin (co-creator of VisiCalc) has always been a hero of mine. So many assumptions of current software come from his simple innovations. His key focus was simplicity and ease of use. I love this quote from one of his business school professors, giving him feedback on his prototype:

You're competing against the back of an envelope. It's got to be really easy to use.

-- Source: Founders at Work

What is your product competing with?

10:05 PM, 14 Jun 2007 by Mark Aufflick Permalink | Comments (0)

Syncing my google calendar to my cellphone

Better than receiving an sms, GooSync bridges between my google calendar and SyncML which means I can bi-directionally sync it with the calendar built into my SonyEricsson phone.

It works pretty well. They support Google's new auth method that means you don't need GooSync to store your details. Unfortunately they don't have that working with Google Apps domains (which I use), so I have to use their other solution which involves them storing your details in their database (apparently encrypted - although obviously reversible somehow... I think they encrypt it with your GooSync password).

The auto-config sms didn't seem to work (I received the settings, but they failed to apply on my Z800i) but it was easy to manually enter the appropriate settings. Then the first sync failed, but all subsequent sync's have worked fine. I've set my phone to sync once a day so I'll see how that goes and report back on the bandwidth used.

02:57 AM, 14 Jun 2007 by Mark Aufflick Permalink | Comments (0)

Final release candidate of JRuby

Thomas Enebo has just posted JRuby 1.0.0RC3 which sounds like the final release candidate before 1.0.

This will likely be our final release candidate before our 1.0 release. People are encouraged to try out this release to help us find any remaining showstopper issues. We have spent a lot of time over the last month squashing compatibility bugs and we have confidence that applications 'will just work' (tm)*. Please try your applications and libraries against JRuby and give us feedback.

Sources: ruby-dev mailing list, Tom's Ruminations.

I never thought I would get so excited about a technology that's even remotely Java-related ;)

02:52 AM, 03 Jun 2007 by Mark Aufflick Permalink | Comments (0)

F1 Safety Car Drivers

The BBC has a great article on F1s professional safety car drivers.

"It looks boring on the TV when the safety car comes out" Maylander tells BBC Sport. "It looks really, really slow, I know."

The thing is, it isn't.

Maylander's safety car is a Mercedes CLK 63 AMG, capable of reaching 62mph in 4.5 seconds (about twice the time it takes an F1 car), with modified brakes, tyres and aerodynamic parts; Maylander fondly describes it as "a small race car".

"The top speed I can reach, on Silverstone's long straight for example, is 155mph - but it looks like 60mph compared to the F1 cars," the German said.

It sounds pretty fun (and hair-raising), but they have so sit in the car, harnessed in, helmet on, for the whole race. And they need to be damn good drivers too - as Bernd Maylander (one of the two drivers) said, they would look pretty stupid if they went off!

10:46 PM, 01 Jun 2007 by Mark Aufflick Permalink | Comments (0)

Simplicity is good, but what is it?

Rob Tannen writes an excellent article on boxes and arrows titled "Simplicity: The Distribution of Complexity".

So, given a fixed set of elements (e.g. navigation choices), there are multiple attributes of simplicity than can be addressed to varying degrees. The success or failure of a design is largely dependent on achieving the right balance among these attributes of simplicity. An infamous example of this was BMW's i-Drive controller, designed to operate a range of automotive systems from a single control. The resulting user experience was confusing and complex as BMW relied too much on mechanical simplicity (a single, clickable rotary control) at the cost of perceptual and cognitive simplicity.

It's an excellent article, go check it out.

01:32 AM, 29 May 2007 by Mark Aufflick Permalink | Comments (0)

Power and heat means the end of lazy programming

Software developers have gotten away with being sloppy because of the abundance and rate of growth of compute cycles. However, the problems of large numbers start to intrude: just as power and heat become factors in the presence of tens of millions of transistors, power and heat become architectural considerations in the presence of teraflops of computation and petraflops of storage.

-- Grady Booch, Power As A Limiting Factor

03:31 AM, 28 May 2007 by Mark Aufflick Permalink | Comments (0)

What kind of developer are you?

Mel Riffe reckon's he's a gardener or garbo*. What about you?

* Garbo is Aussie slang for a garbage/rubbish/trash/waste collector

11:06 PM, 27 May 2007 by Mark Aufflick Permalink | Comments (2)


It was only last year, as I was playing around with Smalltalk that I discovered the joy of an object database.

Naturally as I began playing with JRuby I wondered about object database options for it. One of the great things about the Java linkup is the wealth of available libraries and products and sure enough I found a number of open source OO database options. GOODS (which I have used with Smalltalk) is an option, but like some others it relies on a bytecode pre-processor, which makes me nervous given how JRuby plays with the bytecode.

Playing with db4o (which has both GPL and commercial licenses) has been pretty successful for the very little time I have invested.

Unsurprisingly I discovered that trying to store a pure Ruby object yielded an ObjectNotStorableException exception. In JRuby extending Java classes is easy. I haven't discovered how to properly extend the constructor, so I ended up with the following class:

require'java'class Song<java.lang.Objectattr_writer:name,:artist,:durationdef to_s"Song: #@name--#@artist (#@duration)"endend
Creating a song object and storing it in a db4o database is simple:

I can then pull song objects out of the database using QBE:

# make an unconstrained template object for""song_proto.artist=""song_proto.duration=0results=db.get(song_proto)results.each{|s|putss}
Unfortunately I don't get a good look at the objects since they appear as a generic proxy object. to_s yields:

(G) org.jruby.javasupport.proxy.gen.Object$Proxy0

Ruby has no concept of casting or blessing the object into a different class, so I suspect that I'll have to take care of that by wrapping the db4o api with some Java to do the casting.

I can confirm that something like the objects I'm storing are ending up in the database file with the venerable strings command. Surprisingly the database binary file contains strings that look exactly like that generated by to_s. Perhaps it stores a stringified version of each object? Or perhaps to_s is proffered by JRuby as a default serialisation method.

Anyway, as I said I haven't invested much time on this (too busy watching the Monaco F1 right now...) and getting it useable may be a bit of work.

One weird thing is that the first time I run code like the above for a particular database file I get an ObjectNotStorableException exception. The db file is created though, and further runs work as described above.

11:09 AM, 27 May 2007 by Mark Aufflick Permalink | Comments (2)

Software Busting

I was browsing in Borders yesterday and couldn't help thumbing through a Mythbusters coffee table book. I found the following great quote:

Whenever an engineer builds something that's over-complicated, that's the mark of an inferior design. Simple is always better.

&#8212;Jamie Hyneman, Mythbusters

While you can't really rate Mythbusters for statistical significance, I think Jamie's on the button with this quote.

09:50 AM, 27 May 2007 by Mark Aufflick Permalink | Comments (0)

Closure candy

I love seeing someone first use closures for a real problem. If they're a long time programmer who has never used them before it takes a while, their probability filter tries to stop the neurons from connecting, and then with a spark the simple beauty emerges like a glorious dawn.

Share the joy with Jeremy Stell-Smith.

07:49 AM, 24 May 2007 by Mark Aufflick Permalink | Comments (0)

Can we build it? Yes we can!

With apologies to Bob the Builder.

There's a great discussion brewing over at Lars' blog about how to keep in a design frame of mind and not get bogged down in implementation details.

Some good ideas coming out, and some mediocre ones from me as well. Come and join in!

07:43 AM, 24 May 2007 by Mark Aufflick Permalink | Comments (0)

Camping with JRuby and NetBeans 6.0

Camp Beans!NetBeans 6.0 is shaping up as a very good Ruby development environment, and JRuby is quickly becoming a viable platform.

If you're looking for a different kind of beans with a different kind of camping, you might want to check out Big Jim's Camping Beans :)

I love what Thoughtworks Studios have done in Mingle, making it so easy to deploy by using an embedded java database (derby), JRuby and Ruby on Rails.

I also love the concepts why has used in Camping and I figured the three combined would be great for developing small (possibly embedded) websites.

Here's my somewhat ugly bullet point steps to the sample Camping Blog using NetBeans 6.0, JRuby and derby.

  • Install NetBeans 6 - M9 is the latest version at the time of writing (caveat emptor - I already logged a few bugs)

  • Unless you have Java 6, copy derbyclient.jar into {Net Beans}/ruby1/jruby-0.9.8/lib
    • If you're a Mac, you will find the {Net Beans} directory in "Show Package Contents"/Resources
    • You can get derbyclient.jar from your JDK directory if you did a full Java 5 installation, or you can get it in the full derby distribution from

    • Install the camping gem (NetBeans Tools menu->Ruby Gems->Install New...)

    • Start the derby server in NetBeans (Tools menu->Java DB->Start)

    • Make a new "Ruby Application" project (be sure to call the main file blog.rb instead of main.rb)

    • Paste why's example blog.rb into your blog.rb

    • after the line that says require 'camping/session' add:
      gem 'ActiveRecord-JDBC'
      require 'active_record/connection_adapters/jdbc_adapter'

    • Create a file in your home directory called .campingrc with the following:
      adapter: jdbc
      driver: org.apache.derby.jdbc.ClientDriver
      url: jdbc:derby://localhost:1527/sample
      username: app
      password: app

    • In Project Properties->Run, add a configuration called camping, and add the path to the camping startup script into the ruby options field. I added:
      "/Developer/NetBeans 6.0 6.0 M9/ruby1/jruby-0.9.8/bin/camping"
      , I haven't been able to simplify it with environment variables unfortunately.

    • Click the Run button (or use the Run menu)

    • Point your browser to http://localhost:3301/
    • And that's all there is to it! Note that instead of bothering to make a new database, I used one of the sample derby databases, but you can administer the derby databases in the Runtime window/tab of NetBeans.


      JRuby Tutorial - Going Camping
      The curse of camping

12:35 AM, 24 May 2007 by Mark Aufflick Permalink | Comments (0)

NetBeans 6.0 with Ruby support

NetBeans 6.0 is very cool for a lot of reasons, which I'll blog later.

But the jaw-droppingly cool thing is ... wait for it ... the OS X version is distributed as a shar archive!

If you don't know what a shar archive is, then I you probably weren't a Unix/Internet nerd in the 80s/early 90s (which is probably for the best).

08:34 AM, 22 May 2007 by Mark Aufflick Permalink | Comments (0)

War on Moisture

This is a hilarious Saturday Night Live sketch around the whole liquids on planes thing :)

Found via Pensieri di un lunatico minore.

Update: The YouTube video has been removed, but you can still watch it thanks to the Consumerist:

09:09 PM, 20 May 2007 by Mark Aufflick Permalink | Comments (0)

Cross platform native text/graphics for smalltalk

Pango and Cairo bindings for Cincom Smalltalk&#8212;now that's a kick ass cross platform application development environment!

10:01 PM, 16 May 2007 by Mark Aufflick Permalink | Comments (0)

Umbrello on Mac OS X

Update: You can now download and install a (currently beta) MacOS native KDE4 environment (including Umbrello) from the Mac KDE team. See my newer blog post for more info.

Umbrello is a great open source UML modelling tool. Unlike Argo UML it supports (a subset of) UML 2.0.

Being native code based on the KDE libraries it's much faster than Java tools (like Argo UML), but that also makes it less portable. I've never seen a workable installation of Umbrello on Windows. There are some partial attempts using KDE 4, and apparently it's possible with Cygwin.

It's pretty easy to install on Mac OS X, as long as you don't mind a bit of commandline work.

First you need Apple's developer tools and Then you need an installation of MacPorts which will do most of the hard work for you. There's no port for Umbrello, but it will install the myriad required libraries. Simply run:

sudo port install qt3 kdelibs3

and let it do the hard work.The whole process could take a few hours depending on your Mac model.

(I actually had to provide a bit of manual intervention, fetching hicolor-icon-theme-0.10.tar.gz from since the main site ( was down. I'm sure that will be fixed by the time you read this.)

Now to install Umbrello itself. Download the latest version from and follow the "Source Code" instructions on You will need to specify the qt and jpeg directories and turn off aRts support. If that makes no sense to you, the instructions boil down to:

tar jxf umbrello-1.5.7beta1.tar.bz2

cd umbrello-1.5.7beta1

./configure --prefix=/opt/local --with-qt-includes=/opt/local/include/qt3/ --with-qt-libraries=/opt/local/lib/qt3/ --with-extra-libs=/opt/local/lib --with-extra-includes=/opt/local/include --without-arts


sudo make install

Now you have a working Umbrello! Simply start and run /opt/local/bin/umbrello (you might want to add it to the "Applications" menu of via the "Customize Menu..." option).

It shouldn't be too long before we can have a native Trolltech has released a MacOS native Qt and it's certainly something that the KDE people are looking at.

Update: Umbrello 1.5.7 is now released - update your download accordingly.

Leopard Update: A kind anonymous poster gives this ./configure line for building in Leopard, but I haven't tried it yet:

For anyone having problems compiling umbrello in Leopard, use use this ./configure combo:

env LDFLAGS=-Wl,-dylib_file,/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib:/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib ./configure --prefix=/opt/local --with-qt-includes=/opt/local/include/qt3/ --with-qt-libraries=/opt/local/lib/qt3/ --with-extra-libs=/opt/local/lib --with-extra-includes=/opt/local/include --without-arts

08:19 AM, 14 May 2007 by Mark Aufflick Permalink | Comments (25)

GOODS OO Database

I played with GOODS a little while aback with Smalltalk. Now I *love* relational databases. There are so many real world business problems that relational databases map very well and provide fast access to. I also rail against simplistic object-relational mapping with other developers semi-regularly!

But if what you want to do is store and retrieve objects, then an OO database is, at least in some cases, the most appropriate tool. We all love garbage collection in ram (well - I do anyway!), why not let it take care of your persisted objects? And who would say no to the database automatically upgrading accessed objects when your class gets new or different instance variables?

While it's not quite with the theme of the intended use patter of GOODS, I'm going to play with Pogo - a Perl API for GOODS. Unfortunately I don't yet have it compiling on Mac OS X but it compiles fine on my Linux box.

One of the problems with mapping a Perl or Ruby class to an OO database is that we can't reliably introspect the instance variables (let alone their type). I'm not quite sure how to handle that yet - whether there should be an API to make promises about your object. Another problem is that variable types aren't fixed. The biggest of this class of problem is that, especially in Perl, it's not uncommon to be able to use an object or a primitive (string etc.) interchangably eg. you might provide an URL object that can be used like a string in string context, but in reality it's a reference to an object - ideally we'd like the whole object to be stored.

Being more Smalltalk like Ruby may be better suited, but unfortunately there's no Ruby bindings for GOODS and I don't have the time or the in-depth understanding of the Ruby object internals to pull that off right now. There are a few references to a (now defunct) source forge project ruby-goods, but sourceforge's CVS archive shows no files.

I'll keep you posted!

12:21 PM, 13 May 2007 by Mark Aufflick Permalink | Comments (0)

Cool design gear

j-me Shoe RackI found a site where you can buy small run design products by small design firms (they may prefer 'boutique' or similar ;). I especially like this shoe rack (which I think I saw linked on trend hunter), but there are lots of other great designs as well.

Their product selection is of a similar vein to Top 3 by design (for my Australian readers). Check it out: GENERATE.

Update: Along a similar vein I'm pretty excited about a forthcoming venture: Skrifter - The best of Denmark for your Home & Family. More news as it comes to hand :)

12:19 AM, 09 May 2007 by Mark Aufflick Permalink | Comments (0)

Joost and Randomness

Random Good Stuff has been in my must-read rss list for a long time. I mean who doesn't like random good stuff like geeky clock radios, portable BBQs and Donald Trump selling steaks?!

In the 2007 netosphere it doesn't get much more good than Joost and guess who is giving away invites?

01:26 AM, 07 May 2007 by Mark Aufflick Permalink | Comments (0)

Congratulations TramTown

The boys at TramTown (Semi and DB) have just notched up 4 years and 3,005 posts on their blog.

Well done! Maybe May should feature a "best of TramTown" series :)

They have kept remarkably true to their initial post:

This is a blog where Semi and DB are going to put pointers to things that interest them and may interest others. We expect a bias towards our town, Melbourne, Australia. We expect to see posts about: theatre, audio, politics, motor racing and any other thing that tickles our respective fancies.

That's what's good about aiming low.

09:35 PM, 30 Apr 2007 by Mark Aufflick Permalink | Comments (0)

F1 Street Circuit for Singapore?

Wouldn't that be fantastic! I first heard of this in an Singapore briefing:

A local property tycoon is bargaining to bring Formula One to Singapore. Ong Beng Seng has been in talks with Bernie Ecclestone, the head of Formula One, about hosting a race from next year. Any Singaporean event would probably resemble the grand prix held in Monaco, which is raced on city streets rather than on a purpose-built track. The government has thrown its weight behind Mr Ong's proposal, in the hope the race will bring tourist dollars and good publicity. An announcement is expected by the end of April.

Lee Kuan Yew, Singapore's founding father, showed little interest in bringing Formula One to Singapore when he was prime minister in the 1980s, preferring disk-drive factories instead. He has sportingly described this as a mistake.

It's nearly the end of April&#8212;I can't wait to find out. If it's on next year, I'm there!

02:21 AM, 29 Apr 2007 by Mark Aufflick Permalink | Comments (0)

CollabNet buys SourceForge Enterprise Edition Business

CollabNet and VA Software Sign Asset Purchase Agreement for Acquisition of SourceForge Enterprise Edition Business by CollabNet

...and gains an extra intra-word capital letter :)

This is quite interesting, especially from my point of view as my team was about to shift two big projects from collabnet cvs to sourceforge subversion - might need to wait and see what happens here.

The 'enterprise' source/project tracking business is surprisingly big (especially given how easy it is to run your own cvs server and how little added value the above companies add to that).

What's especially interesting though, is that the above press release makes a lot of noise about:

growing our core online media assets, comprised of,,,,, and Together, these sites attract over 32 million unique visitors a month.

Hopefully they will still make fast subversion servers...

02:00 AM, 26 Apr 2007 by Mark Aufflick Permalink | Comments (0)

Booklet Printing

I have re-figured this out so many different times (and no doubt in different ways) that I thought I'd blog it if only for my benefit.

The scenario is this. You have a pdf or postscript file and you want to print it out as a booklet (ie that folds in the middle). If it's big (ie. a booklet rather than a book) you want the pages grouped into bundles of 16 or so pages.

The incantation I just successfully used was:

pdf2ps foo.pdf | psbook -s16 | psnup -2 >

Note that this output postscript doesn't include the tumbling commands. In my case it's no big deal since I'm sending the data to the printer via it's web page interface which allows me to specify double siding (head to toe). If you don't have that option then you can pipe the output through pstops with the appropriate options before sending it to the printer.

e2 has a great page (An introductory guide into the fascinating (and highly anal retentive) world of bookbinding.) about binding your own book - even down to the stitching. Neat!

10:53 PM, 19 Apr 2007 by Mark Aufflick Permalink | Comments (0)

Microsoft PR Tactics

It's been almost a year since my last SCO litigation related post, but frankly since I started commenting on the SCO lawsuits four years ago it's just gotten more boring.

What continues to be interesting, however, is the insight into Microsoft from their dealings with SCO that get exposed in the court room. The latest installment, courtesy GrokLaw of course, is the following internal Microsoft email (emphasis added):

As discussed in our PR meeting this morning. David & I have spoken with Maureen O'Gara (based on go ahead from BrianV) and planted the story. She has agreed to not attribute the story to us

11:55 PM, 18 Apr 2007 by Mark Aufflick Permalink | Comments (0)


Good friend Lars Pind and his business partner Christina Wodtke have just finished the release of Om Malik's new site Found|READ, powered by the collaborative platform PublicSquare.

FoundRead sounds interesting. Here's Om's blurb:

Mulling over this for a few days, it dawned upon me, that the lessons I am learning, thousands have learnt before, and might actually have a wider (and better) perspective on trials and tribulations of being a founder of a business. Not just a tech start-up, just any business. Why isn't there a resource that captures this tribal wisdom? What if we could
build one &#8212; one that can be shared by one-and-all?

While there are some excellent resources such as Reddit-powered YCombinator start-up site, Startupping, Venture Hacks ... what I envisioned was a digital salon &#8212; where the conversations were started, experiences shared, questions asked and answered &#8212; with us writers playing the role of a salon keeper, a.k.a. conversation lubricant.


FoundREAD is a shared resource, where anyone can contribute, either through their posts, or experiences or comments. You can choose to contribute freely or anonymously. Just like a GPS system helps us drive through a maze of freeways, the founders and entrepreneurs help their peers navigate the twisted, confusing roads of company building.

11:43 PM, 18 Apr 2007 by Mark Aufflick Permalink | Comments (0)

Embedding GraphViz in LaTeX documents

I have to say I'm loving using LaTeX for my Uni papers. It is so delightfully straightforward and powerful.

I am embedding some GraphViz diagrams in my documents, but I didn't want a round trip to a different editor buffer and the shell to edit/compile/insert the diagram.

Based on graphviz.tex code by Derek Rayside I have created a custom LaTeX function that will automatically compile and embed inline GraphViz code (man those wacky capitilisations are getting boring!)

You embed a graph like so:

   \digraph[scale=0.5]{MyGraph}{rankdir=LR; a->b; b->c}
Be careful not to have any double newlines or your dot file will have some bogus \par comments in it (which I should replace with newlines in the function...). Another possible enhancement would be to add a dynamic dot command to set the maximum diagram height & width to the current page/column dimensions.

You need my graphviz.sty and you need the following in your document preamble:

Remember to run texhash if you install the style in a system-wide location. Note this assumes pdflatex. Modifying the command for regular latex is an exercise left for the reader. Update: Derek now has an updated version available on GitHub (which didn't exist in 2007 :).

08:09 AM, 25 Mar 2007 by Mark Aufflick Permalink | Comments (8)

Simple Smalltalk/Seaside Blog

Given my current business, I'm unlikely to build a new site using Seaside any time soon (despite professing my web development epiphany last year), but I wanted to get the following links on record for my, and your, future enjoyment.

First is a screencast titled Screencast: How to Build a Blog in 15 Minutes with Seaside, second is a followup by the same author Mapping Seaside Blog to PostgreSQL with Glorp.

The simple blog makes use of the Seaside web framework and Magritte Meta-programming framework (no doubt such a package is unnecessary in Lisp...).

03:11 AM, 18 Mar 2007 by Mark Aufflick Permalink | Comments (2)

Silence is golden

I have been rather silent on this blog for a while. You may think that I have just had nothing to say, but you should know by now that that has never stopped me blogging before!

And unlike Lars I have not been on 2 weeks of yoga and ayurveda (although I'm sure that would do me a lot of good). It may be that Lars' positive Karma will make up for the negative Karma I am creating by studying a Master in Law and Legal Practice.

It's keeping me rather busy - that and developing my nth web framweork (why do I enjoy that so much!) in Perl for my employer - so I apologise for fewer and shorter tidbits.

Just don't tell me you prefer it that way.

09:45 PM, 16 Mar 2007 by Mark Aufflick Permalink | Comments (0)

Good intentions

Courtesy of a comment on an Edward Tufte forum I learned of the USA EPA's 2001 Improving Air Quality With Economic Incentive Programs.

Its second page reads:

This page unintentionally left blank.


04:49 AM, 14 Mar 2007 by Mark Aufflick Permalink | Comments (0)

French Chocolate, made in Belgium

Memo to self, make a visit to Jeff de Bruges cholocates on King Street (Sydney).

05:37 PM, 20 Feb 2007 by Mark Aufflick Permalink | Comments (0)

Rest in peace Robert Adler, co-inventor of the remote

Robert Adler, who designed the first non-visible light remote control.

Various sources have credited either Polley, another Zenith engineer, or Adler as the inventor of the device. Polley created the "Flashmatic," a wireless remote introduced in 1955 that operated on photo cells. Adler introduced ultrasonics, or high-frequency sound, to make the device more efficient in 1956.

Zenith credits them as co-inventors, and the National Academy of Television Arts and Sciences awarded both Adler and Polley an Emmy in 1997 for the landmark invention.

Source: The Age, via Tram Town.

02:19 AM, 19 Feb 2007 by Mark Aufflick Permalink | Comments (0)

Lisp enlightenment

My favourite web-comic, xkcd, has just featured a strip that speaks my views perfectly :)


12:19 AM, 18 Feb 2007 by Mark Aufflick Permalink | Comments (0)

Patent Office Orders Re-Examination of Blackboard Patent

Phew. At least the US patent system isn't totally broken. The re-examination was triggered by an official request of the Software Freedom Law Center:

SFLC, provider of pro-bono legal services to protect and advance Free and Open Source Software, had filed the request in November on behalf of Sakai, Moodle, and ATutor, three open source educational software projects. The Patent Office found that prior art cited in SFLC's request raises "a substantial new question of patentability" regarding all 44 claims of Blackboard's patent.


A re-examination of this type usually takes one or two years to complete. Roughly 70% of re-examinations are successful in having a patent narrowed or completely revoked.

Source: Groklaw

01:36 AM, 26 Jan 2007 by Mark Aufflick Permalink | Comments (0)

Agile contracts

mue has the seed of a great idea in his post How to get an agile contract?.

The key observation is that there can be a conflict between agile methodologies and traditional project based contracts.

Since most clients won't wear an infinitely open ended (by the hour) contract and most developers can't afford to iterate past the end of an agreed number of payments there needs to be some flexibility in the billing relationship.

How you codify that into a contract or set of contracts is an interesting challenge. I don't do too much freelance work these days - when I did it was either of two extremes: pre-agreed price per project or simple hourly billing.

Does anyone have any examples of agile project contracts that worked well (or didn't)?

11:36 PM, 24 Jan 2007 by Mark Aufflick Permalink | Comments (0)

MacOS X State of the Union

Last night I watched the OSX State of the Union presentation (on the ADC iTunes) from MacWorld. Nothing really new, but it was a good watch as per usual.
    * 64 bit to framework level in leopard
    o nothing new there

    * multicore
    o OS frameworks higly threaded with fine grained locking
    o cpu and i/o prioritisation support
    o new NSOperation and NSOperationQueue to provide OS support for simple concurrent processing

    * memory management
    o garbage collection added to the ObjC runtime - hooray! (although hardly breaking news)
    + garbage collection is opt in (at the application level)
    + all objects collected
    + release method is a noop!
    + not mark and sweep - generational, which makes use of the fact that new objects are more likely to be able to quickly be released than old long running objects

    * graphics
    o the buzzword is "cinematic experiences"
    o core animation looks pretty damn cool - it's even integrated with the new cocoa widgets
    o resoloution independant user interfaces by 2008 - hooray, just like X11 in 1988 ;)

    * developer tools
    o the new interface builder is also very cool :)

Update: Gah - now I realise why this doesn't sound new, because it's from August 2006 I assumed it was from Macworld, but it turns out that I just got an email because Apple decided to release it to all ADC members. At least they did I guess.

12:43 PM, 24 Jan 2007 by Mark Aufflick Permalink | Comments (0)

Apple feels compelled to charge you money

The charge for the forthcoming 802.11n wireless software by Apple has been discussed for a while. I have no problem with it - one thing Apple has consistently been ahead of the pack with is wireless technology, and being ahead of the pack costs money.

But the rationale offered as to why they are charging it is completely nonsensical:

The nominal distribution fee for the 802.11n software is required in order for Apple to comply with generally accepted accounting principles for revenue recognition, which generally require that we charge for significant feature enhancements, such as 802.11n, when added to previously purchased products
(Lynn Fox - Apple spokesperson)

I had to read that a few times. Firstly, when did a "generally accepted ... principle" require anyone to do anything? Secondly, since when did Apple start publicly admitting that it was doing something because "well that's what everyone else does"?? Perhaps Apple should start making OS X more complex so as to comply better with the generally accepted principle that computers are hard to use?

I'm speechless.

Update: Seems it is not going unnoticed by the press: WSJ: Apple Gets a Bruise by Blaming A $1.99 Fee on Accounting Rules

09:30 PM, 22 Jan 2007 by Mark Aufflick Permalink | Comments (0)

Sybase, ANSI compliant? Phooey.

As previously discussed in this blog, I don't enjoy having to program with Sybase.

Here's another nail in it's coffin in my mind - full join.

Appendix A: Compatibility with Other Sybase Databases.

So, Adaptive Server Anywhere supports Ansi full join, as does IQ (Sybase's data warehouse product), but their flagship Adaptive Server Enterprise (mmmm, Enterprise) doesn't?

Instead I have to distinct union together the left and right outer join...

Could be worse - I could be using Mysql (which also has no full join).

Of course, Postgresql does have full outer joins (so does Oracle 9i for the record).

Update: Oh, and a blank string coerces to a date of 1/1/1900. Brilliant.

Update: brillant. Like MySQL, Sybase would rather silently ignore your bugs than report them:

  • commit: If no transaction is currently active, the commit or rollback statement has no effect on Adaptive Server.

11:05 AM, 18 Jan 2007 by Mark Aufflick Permalink | Comments (0)

The Road to Enlightenment Is Littered with Irritating, Superfluous Parentheses

Arto Bendiken has posted a wonderful Q&A on how he got started with Lisp, with the same title as this post.

His path is not dissimilar to mine except that I had the good fortune to get hooked on dynamic languages early on, which is possibly why I have been slower to get from B to C with Lisp (less need when you can implement many list based and functional idioms in Perl).

I almost want to like Smalltalk more than Lisp, but I suspect that is because of the OO ingrained in me and also my worship of Xerox Parc, Douglas Engelbart, etc. My gut instinct, however, tells me that Lisp is just that one level higher.

I'm very interested in any languages/dialects that implement the power of Lisp with less noise. I'm sure it's possible, but it just hasn't been "discovered" yet. On the other hand, perhaps it's not. Perhaps the endless, nested, streams of braces and symbols are the purest representation of code. Like logic DNA.

Update: In Arto's post he mentions the Lisp machines. I would suggest that in a not dissimilar way that Squeak is a software embodiment of the Alto Smalltalk Machine, Emacs is a rough embodiment of a Lisp machine. Some people even use Emacs as their entire windowing system.

11:16 AM, 15 Jan 2007 by Mark Aufflick Permalink | Comments (0)

Einstein's Puzzle

I can't believe I've never come across this before. It took me a bit under 30 minutes using pen and paper (but I was distracted by work a few times...). Probably would have been quicker to write a Prolog program (but it's much more satisfying by hand :) See how you go:

The Brit lives in the red house.
The Swede keeps dogs as pets.
The Dane drinks tea.
The green house is to the left of the white house.
The owner of the green house drinks coffee.
The man who smokes Pall Mall keeps birds.
The owner of the yellow house smokes Dunhill.
The man living in the house right in the center drinks milk.
The Norwegian lives in the first house.
The man who smokes Blends lives next to the man who keeps cats.
The man who keeps horses lives next to the man who smokes Dunhill.
The man who smokes Blue Master drinks beer.
The German smokes Prince.
The Norwegian lives next to the blue house.
The man who smokes Blends has a neighbor who drinks water.

Who keeps the fish?

Email or meebo me for the answer (comments with the answer will be deleted!).

Wikepedia has some information on the history of this puzzle. Excerpt:

The Zebra Puzzle is a well-known logic puzzle.

It is often called "Einstein's Puzzle" or "Einstein's Riddle" because it is said to have been invented by Albert Einstein as a boy, with the common claim that Einstein said "only 2 percent of the world's population can solve this". It is also sometimes attributed to Lewis Carroll. However, there is no known evidence for Einstein's or Carroll's authorship.

There are several versions of this puzzle. The version below is quoted from the first known publication in Life International magazine on December 17, 1962. The March 25, 1963, issue contained the solution given below and the names of several hundred solvers from around the world.

The version of the puzzle given in Wikipedia is tougher because two pieces of information are missing. Naturally someone has already written Prolog and Lisp solutions for it :)

10:38 AM, 15 Jan 2007 by Mark Aufflick Permalink | Comments (0)

Great emacs blog

Someone asked me a while back to post more emacs tips. Well, I haven't posted much of anything over the summer break, but I did just find a new blog minor emacs wizardry by the author of a smalltalk/lisp blog that I read occasionally, programming musings.

I learned an amazing feature of the dired mode, that with the command wdired-change-to-wdired-mode command you can make the directory view editable. Eg. if you do a search and replace in the buffer (using normal commands), the files will be renamed. Cool!

There's also a neat emacs lisp fragment to keep an eye on open memory allocations in your Objective-C code (Define your own keywords). Mind you, I can't wait for the Objective-C garbage collector that will be standard in OSX 10.5 :)

Possibly the most useful productivity addition (especially for an emacs-using team - if I can find one these days...) is linkd.el which allows you to embed internal and external hyperlinks in emacs so you can, eg, put links in your code comments to relevant files, sections, or web pages.

Update: For GTD (Getting Things Done) fans out there, I linked through to a page on using the emacs org-mode for implementing GTD. By an Australian no less :)

12:39 AM, 15 Jan 2007 by Mark Aufflick Permalink | Comments (2)

Finer grained rss feeds

Well I'm nearly back from my blogging holiday (far too much cricket on TV for blogging ;) so in preparation I have turned off "link-splicing" in my rss feed which means that the rss feed for my blog ( ) will give you blog articles only.

You can separately subscribe to my bookmarking via's builtin rss feed:

11:49 AM, 13 Jan 2007 by Mark Aufflick Permalink | Comments (0)


Blog Categories

software (41)
..cocoa (23)
  ..heads up 'tunes (5)
..ruby (6)
..lisp (4)
..perl (4)
..openacs (1)
mac (21)
embedded (2)
..microprocessor (2)
  ..avr (1)
electronics (3)
design (1)
photography (26) and white (6)
..A day in Sydney (18)
..The Daily Shoot (6)
food (2)
Book Review (2)


Icon of envelope Request notifications

Syndication Feed


Recent Comments

  1. Mark Aufflick: Re: the go/Inbox go/Sent buttons
  2. Unregistered Visitor: How do make a button to jump to folder
  3. Unregistered Visitor: Note I've updated the gist
  4. Unregistered Visitor: umbrello is now an available port on macPorts
  5. Unregistered Visitor: Updated version on Github
  6. Unregistered Visitor: Modification request.
  7. Unregistered Visitor: Accents and labels with spaces
  8. Unregistered Visitor: Mel Kaye - additional info
  9. Unregistered Visitor: mmh
  10. Mark Aufflick: Thank you