Author Archives: david

Make your menu definitions less irritating

Anyone who has written a non-trivial amount of Swing will know the pain of menu definitions. They’re amazingly verbose.

Metascope used a reasonably large number of menus, and this verbosity had started to bother me, so I came up with a few syntactic hacks to clean it up. A “DSL” if you prefer. The result was relatively terse in comparison (only one superfluous line of code and two superfluous lines for the braces per menu item! In Java terms that’s practically a one liner).

Here’s essentially the same idea ported to Scala, with a few additional cute hacks and taking advantage of Scala’s first class functions to make it terser yet.

Some sample code:

val frame = new JFrame(){}

frame.setJMenuBar(new MenuBar{
new Menu("File"){
"Save" does { }
"Open" does { }
---
"Quit" does { System.exit(0) }
}
new Menu("Edit"){
"I like kitties" is true toggles (x => if(x) println("I like kitties") else println("I appear to be lying"))
new Menu("A sub menu"){
"There are no kitties in this submenu" does { }
}
}
});

frame.setSize(500, 500);
frame.setVisible(true);

The rest of the code to make this work is available here.

This entry was posted in programming and tagged , on by .

QDBM Bindings

“So”, I thought to myself, “I feel like learning how to use the Haskell Foreign Function Interface. I think I’ll write a binding to a C library”

As one does.

Seeing as both my Haskell and my C are less than stellar this proved to be an interesting challenge, but I rose to it and put together a basic set of bindings for QDBM‘s Depot library. It’s only lightly tested and very incomplete, but seems to work and if you want something along these lines it will probably do the job. You can get it from my misc HG repository. The resulting code is extremely imperative to use, but otherwise not too bad.

This post is a literate Haskell file with a demo of how to use it.

We’re going to write a bulk file importer. It will get its data from stdin and will read a bunch of records formated as “key = value”, ignoring blank lines and lines starting with #. It will import them into a qdbm Depot database file, printing out a message for every value it overwrites.

> module Main where
> import qualified Data.ByteString as ByteString
> import Data.ByteString (ByteString)

The library is based around strict ByteStrings, both because of the way it interoperates with C and for performance reasons.

> import qualified Data.ByteString.Char8 as Char8
> import Data.ByteString.Char8 (pack, unpack)

In order to convert between ByteStrings and normal Haskell Strings

> import System.Environment
> import System.IO
> import Text.Printf

Just some random useful imports

> import QDBM.Depot

And of course we need to import the QDBM module itself.

> main = do args <- getArgs
>           case args of 
>             [dbname, importfile] -> importInto (pack dbname) importfile
>             x -> putStrLn "Expected usage: bulkimport dbname importfile"

Boring, and woefully inadequate, argument processing.

>   where importInto dbname importfile = 
>           do db <- openDepot dbname Write

Open a handle on the database in write mode.

>              eachLine importfile $ processLine db

I’m pretty sure the Haskell Cabal will want my blood for writing a foreach in Haskell. But anyway, this should be fairly self explanatory.

>              closeDepot db

Finally, close the database file

>         parseRecord line = let (start, end) = Char8.break (=='=') line in (start, ByteString.drop 1 end)

Split the line around the first = in order to get the key and value. We should probably do better error handling here. Oh well.

>         processLine db line = if (not (ByteString.null line) && Char8.head line /= '#')
>                                then do currentValue <- get db key 
>                                        case currentValue of 
>                                           Nothing -> put db key value 
>                                           Just currentValue | currentValue == value -> return ()
>                                           Just currentValue -> printf "Replacing value for key %s. Value %s -> %s\n" (show key) (show currentValue) (show value)
>                                else return ()
>           where (key, value) = parseRecord line                  

For each line, we first check if it’s empty or starts with #. If it is, we ignore it. Else we look up the relevant key in the database. If it’s there already and with a different value with print a warning message. Else we put the new value into the database.

> eachLine :: FilePath -> (ByteString -> IO ()) -> IO ()
> eachLine file f = do handle <- openFile file ReadMode
>                      catch (eachLineInHandle handle) (const $ hClose handle)
>   where eachLineInHandle handle = ByteString.hGetLine handle >>= f >> eachLineInHandle handle
> 

Simple utility function for operating over the lines of a file.

And that’s about it. It’s fairly grotty code, but hopefully conveys the idea of how to use the basics (not that that would really have been hard to figure out). There are a few other functions in the module, but they should be fairly self explanatory.

This entry was posted in programming and tagged on by .

SBinary progress

If things have seemed a little quiet on the SBinary front, do not despair! It’s not because I’ve abandoned it. Partly I’ve been very busy recently, but I’ve also been held up with various issues on the implementation. One was waiting on Scala 2.7.1 as it fixes an issue I had with implicits, and another was a feature that I’ve decided to defer to 0.3 (to do with modifiers for binary instances. In particular I wanted to get sharing based on identity working properly, but I kept running into issues)

Anyway, I’ve spent most of today working on it and things are going pretty well. You can expect a 0.2 release at some point after 2.7.1 goes final. It will feature:

  • A revised API that I think is nicer to work with. It replaces the use of DataInput and DataOutput with custom Input and Output types. These define read and write methods for reading and writing things with Binary instances, plus a few other useful methods.
  • Improved generic methods for defining binary instances. In particular the length encoding has got a revamp and asUnionN has become significantly less irritating to work with.
  • A certain amount of experimental support for lazy IO via Streams. I’m not totally convinced this is a good idea, but it’s sufficiently useful that I’m going to provide it anyway with a big red warning sticker.
  • A much larger set of data types handled out of the box. It should cover most of the types available form the Scala standard library that it reasonably can (it can’t handle things like functions, etc)

As promised, this release should still be binary compatible with the last one.

This entry was posted in programming and tagged , , , on by .

Code for you to play with

As you might have noticed, I have a slightly silly number of google code projects. Most of these are crap or abandoned, although (I think!) there are a few good ones there. Rather than spamming the world with endless open source projects each with their own separate sites, I’m moving to using freehg.org for such things. You can find my code at http://freehg.org/u/DRMacIver/.

Right now what’s there is an alternative collections API for Scala that I’m tinkering with (it’s currently very basic, and the implementations that are there are more to explore the API than intended for serious use) and some random little Haskell projects I’ve written.

In the best spirit of open source, almost everything there is undocumented, uncommented and lacking a working build script. You can consider anything there that doesn’t come with an explicit license to be released under the WTFPL.

This entry was posted in programming and tagged , on by .

Monadic card shuffling

Because it’s what all the cool kids do, this is a post in literate Haskell. Assuming wordpress doesn’t screw things up too horribly, you should just be able to cut and paste it into your text editor and compile it.

How do you shuffle a pack of cards?

Easy. Throw it up in the air and then pick them up again. Done.

Ok, you don’t do that in practice, because it makes a mess. But in principle it would give you a fair shuffling of the cards. Conceptually it’s equivalent to doing “pick a card, any card” until you run out of cards, and using the resulting order you picked them in. But while tidy, that’s far too boring.

Nevertheless, it’s a pretty good way of shuffling. It’s more or less equivalent to one of the standard ways of shuffling a list/array/favourite sequential data structure, the Fisher-Yates shuffle. This has a very easy to follow imperative implementation, but the purely functional ones… not so much. Oleg has an implementation, although he doesn’t call it by this name. However, I found this implementation a little scary and (more importantly) not that easy to use.

Here’s one which is structured according to a custom monad (sorry) which emulates the “pick a card, any card” structure of shuffling the list. It seems likely that the monad has other uses, but I can’t think of any at the moment. Mostly I’m just posting this as a cute way to solve the problem.

>{-# LANGUAGE GeneralizedNewtypeDeriving#-} 

We’ll need this to derive the monad instance for our sample.

> module Sample (
>   Sample,

We’ll define a type Sample a b. This should be interpreted as an action which can add items to and random draw items from a bag of elements of type a and results in a b.

>   takeSample, 

Given a Sample we run it by providing it with a source of randomness.

We define a sample with the following primitives:

>   draw,

We can draw an item from it at random. This returns Nothing if the bag is empty, else Just someItem

>   place,

We can put an item into the bag.

>   placeAll,
>   drawAll,

And we provide some useful functions for bulk add and remove. placeAll puts a list of items into the bag. drawAll draws all the remaining items from the bag in a random order.

> shuffle

And using the combination of placeAll and drawAll we’ll define a shuffle function.

> ) where
>
> import Control.Monad.State
> import System.Random
> import qualified Data.Sequence as Seq
> import Data.Sequence (Seq, (<|), (|>), (><))
> newtype Sample a b = Sample (State (StdGen, Seq a) b) deriving Monad

A Sample consists of two things. A random generator with which to make choices and a collection of elements (we assume it’s a StdGen rather than an arbitrary generator, mainly because I’m being lazy) and a bag of elements to draw from. We allow repetitions, and in order to allow us to draw from any point we model it as a Data.Sequence rather than a list (which has O(log(k)) indexing).

We want to chain actions with respect to this sampling together, so we model it as a state monad.

> takeSample :: StdGen -> Sample a b -> b
> takeSample g (Sample st) = evalState st (g, Seq.empty)

Given a Sample, we set it running with a source of randomness and an empty bag.

> draw :: Sample a (Maybe a)
> draw = Sample $ do (gen, sample) <- get
>                    if (Seq.null sample) 
>                      then return Nothing
>                      else do let (i, gen') = randomR (0, Seq.length sample - 1) gen
>                              let (x, sample') = remove i sample
>                              put (gen', sample')
>                              return $ Just x

Draw takes an element from the sequence, returns the result of that and chains through the new generator and the remaining elements.

>  where
>    remove :: Int -> Seq a -> (a, Seq a)
>    remove 0 xs = (x, u) where (x Seq.:< u) = Seq.viewl xs
>    remove i xs | i == Seq.length xs = (x, u) where (u Seq.:> x) = Seq.viewr xs
>    remove i xs = (x, u >< v)
>      where (u', v) = Seq.splitAt i xs
>            (u Seq.:> x)  = Seq.viewr u' 

This is just a helpful method for removing an element from inside a sequence.

> place :: a -> Sample a ()
> place x = Sample $ do (gen, sample) <- get
>                       put (gen, x <| sample)

To place an element we just append it to the beginning of the sequence.

> placeAll :: [a] -> Sample a ()
> placeAll xs = Sample $ do (gen, sample) <- get
>                           put (gen, Seq.fromList xs >< sample)

Similarly for placing multiple elements, although we use sequence concatenation rather than appending them one by one.

> drawAll :: Sample a [a]
> drawAll = do el <- draw
>              case el of 
>                   Nothing -> return []
>                   Just(x) -> do xs <- drawAll
>                                 return $ x : xs

drawAll simply draws from the bag until it finds nothing left. Pretty self explanatory.

> shuffle :: StdGen -> [a] -> [a]
> shuffle gen xs = takeSample gen $ placeAll xs >> drawAll 

And finally, we can implement shuffle. And it’s a one liner. In order to shuffle a bunch of elements we simply put them all in the bag, then take them all out again in a random order. Ta da!

This wasn’t really very hard to do directly, but I found that creating the right abstraction to build it out of helped clarify the logic a lot.

This entry was posted in programming and tagged on by .