Archive for December 2006

Python has optional arguments…

I think the answer to this is currying. It’s not quite as cute:

foo a b = ...

Later becomes

foo = foo1 const
foo1 c a b = ...

If you don’t like sticking c at the front you’ll have to use lambda:

foo a b = \ a b -> foo 1 a b const
foo1 a b c = ...

In some cases you can use flip I suppose. Someone who knows haskell better than me might have better solutions to it…

Oh yes, I have to say that requiring an account is not inviting casual commenters…

darcsweb+lighttpd on Debian

I couldn’t find any information on how to set up darcsweb on lighttpd in general. I was a little disappointed to see that the darcsweb package on Debian only comes with apache and apache2 configurations, nothing for lighttpd. Since Debian is a little special sometimes when it comes to web servers—they like to add convenient configuration “frameworks”—I was afraid that using a “non-supported web server” might be a lot of work. How wrong I was :-)

First enable the CGI module for lighttpd:

# cd /etc/lightttpd/conf-enabled
# ln -s ../conf-evailable/10-cgi.conf

Then create a very short configuration file to enable darcsweb to find its images:

# cd 
# echo 'alias.url += ( "/darcsweb/" => "/usr/share/darcsweb/" )' > \
/etc/lighttpd/conf-available/50-darcsweb.conf

Then enable that “module” as well:

# cd /etc/lightttpd/conf-enabled
# ln -s ../conf-evailable/50-darcsweb.conf

Create your darcs repositories in /var/www/darcs/. I created a repo I called test.

The Debian default configuration of darcsweb will expose all repositories in /var/www/darcs/. This is quite probably not what I wanted so I commented out the auto class and added the following:

class test:
    reponame = 'test'
    repodesc = 'Silly little test repo'
    repodir = '/var/www/darcs/test'
    repourl = 'http://denobula/darcs/test/'
    repoencoding = 'latin1'

That’s it!

C and Haskell sitting in a tree…

A few days ago I thougth I’d take a look at calling C functions from haskell. I wrote up the following set of files:

foo.h:

int foo(int i);

foo.c:

int
foo(int i)
{
    return i * i;
}

Foo.hs:

module Main where

import Foreign.C.Types

main = do
    r <- foo 2
    putStrLn $ show r

foreign import ccall safe "foo.h foo" foo :: CInt -> IO CInt

Compiling the C file was of course no problem:

% gcc -c foo.c

The haskell file offered some resistance:

% ghc -c Foo.hs
Foo.hs:9:8: parse error on input `import'

It took me a round on haskell-cafe before I found out that ghc needs to be told to use the foreign function interface, -ffi or -fffi:

% ghc -c -fffi Foo.hs

Linking is a snap after that:

% ghc -o foo foo.o Foo.o
% ./foo
4

It’s also possible to build and link it all in one go:

% ghc --make -fffi -o foo foo.c Foo.hs

Now, that’s pretty nice, however it’d be even nicer to use cabal to do the building. At the same time I decided to put c2hs to use. It seemed to be a lot easier than having to create the import statements manually. I ended up with the following:

csrc/foo.h:

#ifndef _FOO_H_

int foo(int);

#endif

csrc/foo.c:

#include "foo.h"

int
foo(int i)
{
    return i * i;
}

I couldn’t get cabal to accept Foo.chs as the file containing the Main module in my project. So I ended up putting all the relevant code in Foo and then have a dummy Main.

src/Foo.chs:

module Foo where

#include "foo.h"

import Foreign.C.Types

main = do
    r <- {# call foo #} 2
    putStrLn $ show r

Here’s the dummy Main.

src/Main.hs:

module Main where

import qualified Foo

main = Foo.main

The cabal file is rather straight forward. It took me a round on haskell-cafe to find out how to let the compiler know that I need the foreign function interface without putting compiler directives in the source file.

cnh.cabal:

name: cnh
version: 0.1
build-depends: base

executable: cnh
main-is: Main.hs
hs-source-dirs: src
include-dirs: csrc
c-sources: csrc/foo.c
extensions: ForeignFunctionInterface
other-modules: Foo

Nothing special is needed in the Setup.hs:

#! /usr/bin/env runhaskell

import Distribution.Simple
main = defaultMain

Make it executable and you can build in two easy steps:

% ./Setup.hs configure && ./Setup.hs build

Epilicious moved to darcs

I’ve switched from bzr to darcs for all my version management needs. I’ve decided to also move my already existing projects to darcs. First out is epilicious. From now on the following should be used to get the release and development branches respectively:

% darcs get http://therning.org/magnus_darcs/epilicious
% darcs get http://therning.org/magnus_darcs/epilicious.dev

I decided not to take any history with me, I could have used tailor but decided not to, after all this is a very small project. Also, I’m keeping the old history for the time being, it’s in the old place:

% bzr get http://www.therning.org/magnus_bzr/epilicious/
% bzr get http://www.therning.org/magnus_bzr/epilicious.dev/

del.icio.us, WTF is happening?

I haven’t had much trouble with del.icio.us before. My little epiphany plugin has worked fine. The two utility programs I wrote to test it (one makes a backup of all your bookmarks on del.icio.us the other restores them) worked fine too. Now all of a sudden it seems it’s all going downhill. A few days ago I received an email from a user saying that syncing failed for him, he got error code 500. I had never received a 500 and the API documentation doesn’t mention it either.

Short interlude here. del.icio.us asks of developers that programs using the del.icio.us API wait at least 1 second between requests. Otherwise requests will be throttled by responding with error code 503.

So, guessing a little I made my use of the API a little less aggressive. I waited a second for every request, not only after having been throttled. That solved the problem. All’s well again, right? No!!!

Yesterday I was playing around a bit with epilicious again. Moving to darcs and some refactoring. To test my changes I cleaned out my del.icio.us account using delbackup. It failed with a code 500. So, I modified the code, treating 500 in the same way as 503—wait a second. Then I received a 999 and I was locked out from del.icio.us and asked to “hold off for a few minutes and try again later, in a gentler fashion”. WTF?

I modified the code again, waiting 2 seconds for 503, 10 seconds for 500, and 15 seconds for 999i. Then I waited for the lock-out to end and I tried again. Locked out again! Tiring!

So, now I’ve modified the code again, now waiting 2 seconds before each request, 2 seconds if I ever get a 503, 10 seconds for a 500, and 15 seconds if I get a 999.

Now I’m instead waiting an awfully long time to get something done, and what happens then? I get locked out since I’m obviously not waiting long enough after receiving a 999.

I am clearly waiting long enough between requests! Has del.icio.us introduced some new arbitrary, undocumented limitation on using the API?

If anyone knows anything that I could stick as an option next to using del.icio.us I would love to hear about itii. Two requirements:

  1. Web API, preferably as easy as del.icio.us API (even better, a compatible API)
  2. Use https for connections

Dear lazyweb, any suggestions?

  1. It’s not as silly as it sounds to wait when receiving a 999. From some testing I concluded that receiving a 999 doesn’t result in being locked out immidiately.[back]
  2. I know of scuttle but I’m having problem finding basic information about it, e.g. what URI is the API on? I’m also not sure it provides API access over https[back]

Some epilicious comments…

I just received a trackback for my epilicious page. James (who I don’t know at all) apparently tried out epilicious, but didn’t end up using it, instead he wrote deliciony. So, anyone who’s looking at epilicious, but finds it not quite to their liking, maybe it’s worth checking out.

I just have to tell you James that I would have loved hearing what makes you say that epilicious is “prone to bugs” and exactly what you tried getting it to do. Without knowing that I can’t improve on it. Especially since I’m having no problems at all with epilicious and haven’t had for months now. But hey! Since I’m the author of the thing I would have made some changes if it weren’t delivering for me. :-)

Thought on Ubuntu’s OpenWeek

Why doesn’t Ubuntu OpenWeek have a session explaining free?

Stingy, English builders

We went looking at a few other homes here in Cambourne yesterday. It’s amazing what the English put up with when it comes to housing. There are so many things that you have to pay extra for that the “default” home is practically useless. I’ve already talked about useless bathrooms but now they’ve managed to go and make the “default” bathroom in a shiny new, £200.000+ home even more useless—there’s no longer a hand-held shower, the “new basic standard” is a tap. And the prices for “upgrades” are extortionate. Now if the housing market in the UK isn’t in dire need of a serious price adjustment then I don’t know what is.