Archive for março \14\-03:00 2010

Another interesting code using Template Haskell

14/3/2010 (domingo)

While writing the post about performance, I got interested in Template Haskell, specially in the $(lift) construction.  Investigating a little bit about it, I got to the following code:

{-# LANGUAGE TemplateHaskell #-}

import Language.Haskell.TH.Syntax
import X

main :: IO ()
main = print $(lift $ x)

With X.hs:

module X where

import System.IO.Unsafe

x :: Int
x = read $ unsafePerformIO $ putStr "Number: " >> getLine

The result was a surprise to me. It asked for the number in compilation time.

$ ghc --make main
[2 of 2] Compiling Main             ( main.hs, main.o )
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package array-0.3.0.0 ... linking ... done.
Loading package containers-0.3.0.0 ... linking ... done.
Loading package pretty-1.0.1.1 ... linking ... done.
Loading package template-haskell ... linking ... done.
Number: 5
Linking main ...
marcot@zezinho:~/codigo/haskell$ ./main
5

Performance of IORef

13/3/2010 (sábado)

I’ve tried to see how slower can ghc be compared to gcc in compiling a simple
imperative program. I’ve written this small test program in C:

/* loop.c */
#include 

int
main(int argc, char **argv)
{
    int i, j, k, t = 0;
    for(i = 0; i < 1000; i++)
        for(j = 0; j < 1000; j++)
            for(k = 0; k < 1000; k++)
                if(i * i + j * j + k * k % 7 == 0)
                    t++;
    printf("%d\n", t);
    return 0;
}

And a similar version in imperative Haskell, being as similar as possible to
the original C code:

-- loop.hs
import Control.Applicative
import Control.Monad
import Data.IORef

main :: IO ()
main
  = do
    i <- int
    j <- int
    k <- int
    t <- int
    for (i =: 0) (i <: 1000) (inc i)
      $ for (j =: 0) (j <: 1000) (inc j)
        $ for (k =: 0) (k <: 1000) (inc k)
          $ do
            i_ <- readIORef i
            j_ <- readIORef j
            k_  a -> IO ()
(=:) = writeIORef

( IORef a -> a -> IO Bool
i <: v = (< v)  readIORef i

inc :: Enum a => IORef a -> IO ()
inc i = modifyIORef i succ

for :: IO () -> IO Bool -> IO () -> IO () -> IO ()
for preface condition step code
  = preface >> for_ condition step code

for_ :: IO Bool -> IO () -> IO () -> IO ()
for_ condition step code
  = condition >>= flip when (code >> step >> for_ condition step code)

A functional version:

-- functional.hs
main :: IO ()
main
  = print
    $ length
      [i
        | i <- [0 :: Int .. 999]
          , j <- [0 .. 999]
          , k <- [0 .. 999]
          , i * i + j * j + k * k `mod` 7 == 0]

And a version using Template Haskell.

Micro BSP

7/3/2010 (domingo)

I and Rafael Cunha de Almeida got together today with the purpose of closing as much RC-bugs in Debian as we could.  I must say it was better than what I’d expect.

We started with #570348 .  This bug was introduce with an upload that tried to fix #569586 which, in turn, was related to a change in libc6.  It would be easy to introduce an ifdef in the code but, as we tried to read and understand the code, we didn’t see the need of the function that was causing the problem.  It seems to make the same thing as alphasort from dirent.h, with the disadavantage that it was not locale-sensitive.  So we removed the customized alphasort and made it use the library one.

Then we headed to the strange #504947.  As the maintainer didn’t seem satisfied with the new patch system introduced by the last NMU, we simply made a patch that removes the patch system and applies the patch directly in .diff.gz.  Hope it helps.

Searching for another thing to work, we noticed that #571791 was not happening in my box, and asked if anyone could reproduce it.

So we found #571748.  The first thing about this bug we noticed is that its package causes a division by 0 error in popcon, which made us report a bug about it.  We thought that this was a sign that the package was not widely used.  Anyway, we decided to fix this bug, which was very fun indeed!  After a lot of trials, some succesful, some not, we got to a very simple and nice patch, which was submitted.  We also submited other bugs to the same package, that we found while using it.  It’s a cool package, you should try it out to avoid that division by 0 in popcon.