Saturday, February 28, 2009

Vim users: subscribe to this blog

Regular Vim tips and tricks: http://dailyvim.blogspot.com/. It already saved me once as I had forgotten the very useful @@ sequence that repeats last used macro.

Nokia Ovi barely usable

What is going on with the world's largest mobile phone company? Their strategy is to become big on the net but, man, for me their Ovi is a huge disappointment.

OK, it works fine from my N82 but with Firefox 3 (Linux) some features don't work at all! Yesterday I was trying to define my mobile phone model for Ovi (which should be automatically determined since I had already created an account using my phone's web browser) and the UI just didn't work. I couldn't press "next". The button wasn't there. And another thing, the UI was _really_ slow - not far from unusable.

So I tried the newest Opera and this time the button appeared and I managed to set my mobile model for the system. Still, the system was painfully slow.

What was positive I managed to upload an image to the system from my phone which was my initial goal. And the sync feature worked.

Today I logged in to Ovi again from my desktop - maybe the slowness was just a temporary problem? Nah, it's still slow.

Considering Ovi, Nokia's web technology is insufficient. They should take example from Google on how to make web apps that are platform independent (in my experience, having experimented Google apps from several software and hardware platforms with no problems) and user friendly in easiness of use and responsiveness.

Friday, February 27, 2009

Vim cheatsheet wallpaper

I decided to put a beautiful vim cheatsheet in good use. Usually the right display is enough for my apps (irssi, shell, browser) and the left display is quite empty. So why not use this gorgerous cheatsheet as the wallpaper?

Thursday, February 26, 2009

Basic's not the answer, write in C

This made me laugh, and so I must link it here.

Sunday, February 22, 2009

A CPS question and answer

Continuation passing style is a hard concept. Recently one fellow pasted the following piece of Haskell code in IRC and asked for its meaning:
cfold’ f z [] = z
cfold’ f z (x:xs) = f x z (\y -> cfold’ f y xs)

cfold f z l = cfold’ (\x t g -> f x (g t)) z l

It is a fold implemented in continuation passing style. Let's see what we can say about the type of cfold'. The function cfold' takes a function f of three arguments. The first argument of f is of some type t, the second argument is of some type t1, and the third argument is another function. The other function takes one argument of type t1 and its return value is the same as cfold's, that is, t1. Finally the return type of f is t1 as well. The second argument z of cfold' is something of type t1. The third argument of cfold' is a list of ts that is pattern matched in the definitions of cfold'. Thus, the type signature of the whole function is cfold' :: (t -> t1 -> (t1 -> t1) -> t1) -> t1 -> [t] -> t1.

Next, what can we say about the definition of cfold'? When the third argument, that is a list, is an empty list, it returns what ever is the value of its second argument of type t1. If the list is non-empty, we return what is returned by calling f when it is given x -- the head of the list (of type t), then z of type t1, and a function from t1 to t1.

At this point we start calling the first argument of cfold', that is f, a continuation. In the second definition of cfold' the control is passed to a continuation f. The continuation is a recipe of what to do next. The continuation is given the head of the list and a base value for the fold. The trailing anonymous function from t1 to t1 allows the continuation to get the result of the fold for the tail of the list.

Now, given the fold implemented in CPS, how do we, for example, multiply the elements of a list together? The continuation must contain that logic. Our continuation was a function of type (t -> t1 -> (t1 -> t1) -> t1). The first argument was the head of the list, the second argument was the base value for the fold, and the third argument was the way to get result of the fold for the tail of the list. So the definition for the continuation must be something like this:
(\x t g -> (*) x (g t))
It says that given the head of the list, x, a base value for the fold, t, and the function g that yields the result of the fold for the tail of the list when it is given t, the result of the whole fold is the list head multiplied by the value of the fold for the list tail.

Now cfold' alone is not describing much. We define cfold that passes the continuation, that does the actual folding, to cfold'.

If we try cfold with the sum function, a base value of zero and a one element list containing the number one, the expression reduces as below:
cfold (+) 0 [1]
(\f z l -> cfold' (\x t g -> f x (g t)) z l) (+) 0 [1]
cfold' (\x t g -> (+) x (g t)) 0 [1]
(\f z (x:xs) -> f x z (\y -> cfold' f y xs)) (\x t g -> (+) x (g t)) 0 [1]
(\x t g -> (+) x (g t)) 1 0 (\y -> cfold' (\x t g -> (+) x (g t)) y [])
(+) 1 ((\y -> cfold' (\x t g -> (+) x (g t)) y []) 0)
(+) 1 0
1

So for a non-empty list, cfold' calls the continuation, that performs the folding, and for an empty list it returns the base value.

Hello, autojump

Now everybody go and install autojump! It has quickly proved itself by improving my directory browsing experience in the shell.

Description:

* I remember the software name was "auto..." something, and all my code is in ~/koodi.

Before:
$ cd ~/koodi/auto<tab> <enter>

Now:
$ j auto <enter>

Tuesday, February 17, 2009

Benchmarking llvm-gcc and gcc

I just compiled llvm-gcc (4.2.1 with LLVM 2.6svn) and did some benchmarking. Given a naive implementation of the Fibonacci sequence (fib.c):
#include <stdio.h>

unsigned long int fib(int n) {
if (n < 3)
return 1;
return fib(n-2) + fib(n-1);
}

int main() {
int i;
for (i=1; i < 46; i++)
printf("fib(%d) = %ld\n", i, fib(i));
return 0;
}
Then we compile with -O3:
llvm-gcc -O3 fib.c -o fib-llvm-gcc
gcc -O3 fib.c -o fib-gcc

And the results:
time ./fib-llvm-gcc
real 0m3.053s
user 0m3.052s
sys 0m0.000s

time ./fib-gcc
real 0m11.176s
user 0m11.173s
sys 0m0.004s


That is something.

What comes to code size (both in x86 assembly), the faster is also the smaller:

wc fib-llvm-gcc.S
108 288 1900 fib-llvm-gcc.S

wc fib-gcc.S
291 738 4485 fib-gcc.S