Parsed Participle

The personal weblog of Faiz Kazi: Mostly oddities in programming, life in Japan, occasionally music.

[ Home | RSS 2.0 | ATOM 1.0 ]

Wed, 13 Aug 2008

Discovering xmonad

As someone who has maintained his set of 'dotfiles' faithfully for a few years now, window-manager choice and configuration has been of great importance. I used FVWM for a few years, finally switching to Sawfish somewhere in 2005. My sawfish configuration mimics what I had set up in my fvwm days rather closely, and sporadic periods of messing around with settings have been the only (enjoyable) disruption to my otherwise very productive computing life (as far as my Desktop environment is concerned).

I switched to Sawfish simply because it's scripting language, librep is a Lisp - one that I had been spending many commuting Zaurus hours on. Life has been very good with this the way it is.

Until I read yesterday's LTU article a post that talks about side-effects in imperative languages that cause closures to capture variables in less-than-desirable ways. It was not the actual post itself, but a link to a series, with one interesting post featuring a tour of Haskell and a rather fabulous example to use as a working demo program: XMonad, a really good window manager written in and extensible in Haskell:

  • Windows are automatically tiled
  • Mouseless
  • Configurable (even in real time), using Haskell

I'm tempted to try it; given todays large displays, arranging windows with your mouse just feels silly.

Imperative-style Iterations and closures don't mix well

The undesirable form of variable capture that Erik Meijer describes is, I think, a lot to do with supporting closures in languages where C-style iteration is still relatively a norm. The for (i = 0; i<10; i++){ /*..*/ } lets you use the i as a block scope variable while it remains a part of the mechanism of the iteration. It's easy to reproduce this in Perl (the language which is many things to many people), if you use the C iteration idiom:
my @arr = ();
for (my $i = 4; $i < 7; $i++) {
    push @arr, sub {
        return $i;
    };
}

for (my $i = 4; $i < @arr; $i++) {
    my $f = $arr[$i];
    print $f->(), "\n";
}
But the idiomatic way does away with this problem; and things are better now that we don't have to get distracted by the iteration mechanism: map and grep where one can:
my @arr = map {
    my $i = $_;
    sub {
        return $i;
    }
} (4..7);

print $_->(), "\n" foreach @arr;
Javascript may not have map/grep, but for Functional-style iterations, libraries do a great job of providing such utilities. Prototype.js comes to mind.
var delayedActions = [4,5,6,7].map(function (n) {
    return function (i) {
        return i;
    };
});
In fact this is where these closure-ish APIs shine - they overcome Javascript's problem (i.e., variables only have function scope) by expressing loops functionally.

Name:


E-mail:


URL:


Comment:




Sections

< August 2008 >
SuMoTuWeThFrSa
      1 2
3 4 5 6 7 8 9
10111213141516
17181920212223
24252627282930
31      

[ Home | RSS 2.0 | ATOM 1.0 ]