Depressing Sun Sep 30 22:28:12 CEST 2007

After the most expensive car check and maintenance in my car owner history few weeks ago, my car died. Right in the middle of nowhere. And even worse, on my way to ICFP07.

Unfortunately, most of my planning rests on having a car, as my accommodation is not within Freiburg. Taking a plane/train to Freiburg and renting a hotel is simply way over my budget. I hope to have a working car by tomorrow, so I can make at least 50% use of my registration. Otherwise the registration fee will become a write-off in my books.

As I got home (from the middle of nowhere -- story on its own), I was so frustrated that I started to hack C. Here is an updated XFT patch (aka anti-aliasing support) for ion-3rc-20070927. Check the changes the patch does to your system.mk.

Yes, yes, I will switch to XMonad soon.


Posted by clemens | Permalink

Liskell Task List Fri Sep 28 18:05:59 CEST 2007

Liskell apparently has its first developer (next to me). I was surprised to see a post on liskell-devel by Jason Miller that implements a macro to give Liskell better syntactic support for monads. In pure Liskell, programming with monads looks like

(>>= (getEnv "HOME") 
     (lambda (homepath) 
       (>>= (readFile (++ homepath "/.foobarrc"))
            (lambda (content) 
              (process content)))))
As you can see the indention level piles up when you have a cuple of expressions. Jason proposed an alternative syntax,
(do
  (<- homepath (getEnv "HOME"))
  (<- content  (readFile (++ homepath "/.foobarrc")))
  (process content))
He also posted the resulting macro code. I'm surprised and glad that someone obviously can make sense of Liskell, even -- shame on me -- with the little documentation I have made available.

At the moment, I'm pondering about the future of Liskell. The simple question how to support 'eval' lead to a series of other questions. I shouldn't be surprised that an eval/apply mechanism magically complicates things just as any potentially self referential construct does. But before I start to chat about trouble with supporting eval, the benefits from eval are just too obvious from the Lisp world, that Task #1 is to support eval at compile-time and run-time.

When using eval, you want the expression to evaluate in the current module's compiler state, otherwise you would only be able to use bare naked Liskell primitives expression without any syntax backed by parse tree transformers. My current train of thinking goes into the direction of modelling a compiler/universe state that pervades the boundary between compile- and run-time. I might solve this by borrowing from Lisp again. In the Lisp world, there are rarely object files nor linked libraries (packages) as we have them in Haskell. The usual way of conducting business is that you fire up a Lisp process and start to load Lisp source files until you have all the code in the Lisp process you need. Usually loading also compiles the code. When done, you dump the hole process state to disk and reload it whenever you need to restart the application. So, most Lisp dialects statically link the code in the process image and -- more important -- there is no distinction between compilation- and run-time. The state of the Lisp process next to all the loaded code is also dumped and reloaded, hence saved.

This method can not be ported to Haskell easily. There is only a limited state concept in a Haskell compiler. The source code visible state -- I don't mean compilation/optimization/code generation options here -- is only the scope or environment. Importing modules and defining new top-level function/variables modifies the environment. But we can only extend the environment with more knowledge and also this knowledge that must not contradict existing knowledge (redefine functions or give multi-line equations with different types).

As I was coding my little toy Scheme compiler, I recognized that I wanted to modify the compiler state when certain modules were imported. I had in mind that SchemeCore would bring in the basic Scheme syntax constructs such as (define-scheme ...). define-scheme defines functions and variables with Scheme semantics separated in its own Scheme sub-universe that Liskell code can enter via runScheme. runScheme runs the SchemeMonad that supports a global mutable environment, IO and also continuations -- so callCC should be implementable here. Next to SchemeCore, I wanted to create modules of Scheme code. When importing these modules, they should modify the Scheme compiler state (not the Liskell/Haskell compiler state) so that the Scheme functions compiled become part of the global mutable environment. To make this vision reality, here is Task #2: Liskell should feature an extensible mutable compiler state (LiskellMonad?)

The LiskellMonad -- 'the universe monad' that might replace and embed IO -- should support another feature I love about Lisp: hot code swapping or code replacement as the Erlang camp calls it. The LiskellMonad should support to replace top level definitions with new code. To keep things tidy, the basic idea is to revert all evaluated WHNF to thunks that in some way depend on expression changed. This approach guarantees a consistent universe. Without reverting to thunks, you might have two top-level expressions (define x (f 3)) and (define y (f 3)) that end up with different WHNF, for instance whenever x was evaluated before your change to the function f. Of course, we can't allow that to happen in a pure universe. Task #3: allow mutable top-level definitions.

What we can't get right (at least not without a bit more work) is crossing IO monad boundaries with that concept. Whenever you write the result of (f 3) to a file and change the function f later on, Liskell does not rerun the code that wrote the file content (and also the user would be pretty surprised if it would do so). So by definition, IO is a bit out of reach at the moment, but for a subclass of IO operations we might be able to do it. These operations must not have any visible side effects to the 'outside world', such as putStr. If we exclude those operations, the only operations remain that affect the 'inside world'. These IO operations could be rerun quite easily, just think of Prelude.readFile, executing this twice won't cause unintented behaviour. I'm not sure at the moment whether this idea makes sense beyond Prelude.readFile, but it would have an appealing similarity to STM's way of rerunning code.

And last but not least, the packaging issue is not solved for Liskell. Simon Peyton-Jones suggested to make Liskell a user of GHC API. GHC API needs to be modified to make a good host for Liskell, and as we all know, forming good APIs takes time and a fair bit of discussion. As Liskell is too experimental to flesh out a stable set of API requirements, I think that it is the best option to distribute Liskell as a modification to GHC. These modifications are confined to the 'ghc' package. Creating a fork of this package is the best option for the moment. Liskell can shared base/rts and all the other core and auxiliary packages with a GHC installation.

I hope I can work through this task in the next few months. If you have any reading suggestion with respect to existing design, I would be happy for a few pointers.

Ah and yes, for the next few days, I will be in Freiburg attending ICFP07.


Posted by clemens | Permalink

Stabilizing Firefox for beta quality plugins (Flash) Tue Sep 25 20:54:32 CEST 2007

Using the recent Adobe Flash plugin in Firefox is a two edged sword. On one hand, it gives you the never ending joy of useless YouTube videos, but on the other hand it crashes your browser every 24h on average (only if you are also using Flashblocker which reduces flash content activation by 80%, namely all the annoying ads).

Presumably because of Flash, nspluginwrapper was invented to wrap up software of vendors that are incapable of producing 64-bit version of their product. nspluginwrapper works by providing a proxy to Firefox that acts as regular plugin, but actually spawns off a separate process that runs in 32-bit mode that links in the shared object of the plugin. We can use this construction to remove Flash from the intimate dlopen embracement of Firefox and move all negative side effects of beta quality software into a subprocess. The following trick works for all 32-bit browsers, whether the rest of your distro is amd64 based or native i386. If you are using a 64-bit browser, it's likely that you know nspluginwrapper anyway, so this blog entry is about 32-bit to 32-bit.

Grab a copy nspluginwrapper (at least 0.9.91.5). Untar it. Compile it under an i386 environment. If you don't have this at your disposal, here is it precompiled from my local Gentoo installation: nspluginwrapper-0.9.91.5.tbz2. This is compiled for the amd64 arch layout of Gentoo. Under native i386, just create a link from lib32 to lib in /usr.

Now grab a copy of libflashplayer.so. Drop it into a directory that is not part of your default Firefox plugin path and that does not contain the substring 'netscape' in its absolute path. So, /opt/netscape/plugins/libflashplayer.so is wrong twice, /usr/lib32/nsbrowser/plugins/libflashplayer.so is wrong only with respect to the default plugin path, and /usr/lib32/nsbrowser/wrapped-plugins/libflashplayer.so is correct.

The reason why the path must not contain 'netscape' is that libflashplayer.so presumes its part of a netscape installation when it sees 'netscape' in its path and malfunctions for Flash movies as on YouTube and Google Video under nspluginwrapper and Opera.

Invoke /usr/lib32/nspluginwrapper/i386/linux/npconfig -i /usr/lib32/nsbrowser/wrapped-plugins/libflashplayer.so. As super user, this creates npwrapper.libflashplayer.so in /usr/lib32/nsbrowser/plugins. Invoking this as normal user drops this file into ~/.mozilla/plugins. You are now read to go with your new shielded Firefox. Check that it contains a Section 'Shockwave Flash' under about:plugins referring to the npwrapper.libflashplayer.so file. If it refers to libflashplayer.so directly, you have a copy of libflashplayer.so laying around in a plugin path.

Flash might still cause lock ups in this setting. I presume Flash is getting stuck in an endless loop keeping Firefox busy even through the proxy. However, when that happens just kill the nspluginwrapper subprocess called npviewer. After that Firefox should refresh and you can just hit reload on Flash sites (instead of killing firefox and reloading all websites). Good luck.


Posted by clemens | Permalink

QT RLE hits ffmpeg SVN Tue Sep 11 15:31:53 CEST 2007

My last drive-by-software-hacking turned out to be useful at the end. I hacked up a basic QT RLE (aka Animation) encoder for ffmpeg, sent the patch to ffmpeg-devel but without further intentions to work on merging. Thanks go to Alexis Ballier for stepping up and refining my patch until it was polished enough.

With recent version of ffmpeg, you can create a 1280x1024 screencast for your running X session at display :0.0 with

ffmpeg -f x11grab -s 1280x1024 -i :0.0 -f oss -i /dev/dsp -vcodec qtrle /tmp/lala.mov

after running configure

./configure --enable-gpl --enable-x11grab --enable-libfaad --enable-libfaac

Unfortunately rgb555 encoding was removed, so you are only able to create videos rgb32 video streams (aka 24-bit color depth).


Posted by clemens | Permalink