Archive for the 'Hobbies' Category

Jan 25 2012

Corpse Reviver

Published by Dougal under Blogging, Computing, Programming

This is one of those traditional “I’m going to start blogging again, I promise” posts. Essentially I’ve installed the WordPress app on my phone so I’ll try to use it from the train and so on. Which also means you’ll have to excuse the typos.

As if to start, this evening I went to a Glasgow TechMeetup. There are Edinburgh equivalents that I never attended so I don’t know how they compare. The format was:

  • beer and pizza at 6.30. Next time I must remember a bottle opener!
  • a welcome about 7pm including an introduction from everyone in the room. There must have been about fifty people in the room so it took about half an hour!
  • a few minutes to chat amongst ourselves, particularly with anyone who sounded interesting or employable.
  • a talk about web design
  • a talk about http caching

The first talk was pretty dull and I was ready to call it a day at that point. Thankfully I didn’t cos the second talk was well worth the entry fee, even if it was free. If you bump into serialseb he gives a great talk - funny and informative.

No responses yet

Apr 13 2011

PyWeek April 2011 post-mortem

Published by Dougal under Friends, Games, Programming

Well, it’s been a while since I wrote in this little box. My new job continues to form and my commute has been easier lately, since I’ve been getting a lift from a colleague who also lives in Edinburgh. I get back home in the evening much earlier, which is nice, though the start is still as early as ever (the alarm goes off at 5.30).

But I didn’t break this hiatus to talk about commuting, I promise. Last week was PyWeek, a twice-yearly programming challenge to write a computer game in the Python programming language. Nick was keen to give it a go, so between me, him and Mat we concocted an idea which was just interesting enough that it might be worth playing.

Due to some unforeseen problems we didn’t get much time to write code, so the game didn’t really come together in time for the deadline. I think, in fact, that the code was broken as zero-hour ticked over. Oh well.

Having started we decided to finish, so we all met on Monday night (for the first time since the challenge started…) and got large chunks of the game completed. It’s now playable, I think, though outrageously taxing and quite awkward for one person to play against themselves. The plan, then, is to iron out some of the kinks and see if we can pitch the difficulty at just the right level to make it addictive. Maybe we’ll get it transferred to an Android/iPhone app in the future?

I’ve known these guys for years but we’ve never actually sat down and written a program together for the fun of it. It was really interesting, especially since we were all basically learning Python from scratch for the purpose, and I was trying to remember what all this OO stuff is supposed to be about. Maybe we’ll tackle it again for the autumn PyWeek with a new game idea, more experience and maybe a bit more time scheduled to the task.

Comments Off

Mar 12 2011

Getting embedded in my new role

I’m in a new job. I’ve done one week, so my life has mostly been on hold while I work out how things will fit together. I’m working for Honeywell Security writing embedded software. Similar to before but in alarm systems instead of networking.

The job requires a hefty commute — at least two hours each way if things go well, but between delayed trains and poor weather it’s sometimes an extra half hour on top of that. Which means I get up at 5.30, leave the house before 6.30 and get home in the evening around 7 o’clock. You can see why the rest of my life has been a bit quiet. I’m having to rethink how I look at the week. The arrival of the weekend is important and precious!

I’m still learning the ins and outs of work but the people are all very friendly and helpful, which makes the travelling more bearable. Spending hours travelling to and from a hateful job would be horrible. I spend an hour on the train each way which has given me more time for other things. I’ve been splitting my travelling activities, so that in the morning I read the freebie Metro for a bit and then do some “thinking” to limber up for the day. Recently I’ve been doing simple program calculation exercises, deriving the fusion rules for fold/unfold or map/map and so on. I’m really interested in the idea of deriving correct and efficient programs from executable specification.

(Just to show you what I’m talking about, this is the fold/unfold fusion rule. Let us say there are two functions, foldr and unfoldr defined as follows:

foldr f z     [] = z
foldr f z (x:xs) = f (foldr f z xs)
 
unfoldr g s = case g s of
                Nothing     -> []
                Just (x,s') -> x : unfoldr g s'

The function foldr combines a list of elements according to the function f and unfoldr creates a list of elements from the seed s. We might use foldr to define a product function which combines the elements of the list by multiplying them together:

product = foldr (*) 1

And we might create a list of elements from 1 to n with an unfold.

enumTo n = unfoldr step 1
  where step s = if s>n then Nothing else Just (s, s+1)

The observant reader will have noticed that combining these two separate functions will give us factorial, the product of numbers from 1 to n — first we create the numbers 1 to n, then we multiply them all together.

factorial = product . enumTo

The inefficiency is that enumTo works on producing a list which is consumed by product. The elements are inserted into a list only to be removed straight away. Can we omit the redundant list production? It turns out we can, and we can do it for all cases where foldr operates on the result of unfoldr. The product and enumTo are specific instances of a general method which we can use to fuse production and consumption of values.

This fusion rule can be demonstrated by algebraic manipulation of the programs we’ve defined so far. We’ll call the unfoldr and then foldr by the name hylo, with the naive implementation shown:

hylo f z g = foldr f z . unfoldr g

The equational style here facilitates some nice rearrangements which help to assert their correctness from step to step. Let’s see how this works — each line will be justified by some comment in braces:

  hylo f z g s
= { definition from above }
  foldr f z (unfoldr g s)
= { definition of unfoldr }
  foldr f z (case g s of
                  Nothing     -> []
                  Just (x,s') -> x : unfoldr g s')
= { push foldr into result }
  case g s of
       Nothing     -> foldr f z []
       Just (x,s') -> foldr f z (x : unfoldr g s')
= { foldr on empty lists }
  case g s of
       Nothing     -> z
       Just (x,s') -> foldr f z (x : unfoldr g s')
= { foldr on non-empty lists }
  case g s of
       Nothing     -> z
       Just (x,s') -> f x (foldr f z (unfoldr g s'))
= { definition of hylo }
  case g s of
       Nothing     -> z
       Just (x,s') -> f x (hylo f z g s')

Each step should be clearly equivalent to the one before and the one after, but by the end we have a definition for hylo which doesn’t construct a useless list.

hylo f z g s = case g s of
                 Nothing     -> z
                 Just (x,s') -> f x (hylo f z g s')

Naturally we can use the original definitions of product and enumTo to create an optimised factorial using this logic. The result is that factorial doesn’t create a redundant list either:

factorial n = hylo (*) 1 step
  where step s = if s > n then Nothing else Just (s,s+1)

I think this is beautiful result despite its obvious simplicity. However this has been a long digression, so I’ll stop now. But if you found it interesting I encourage you to check out work on “program calculation”, “program derivation”, “algebra of programming”, “origami programming” and so on.)

My evening journeys have been spent unwinding with a book, though the evening trains are noisier. I’m reading Brighton Rock right now and it’s good though the story makes me feel quite uncomfortable at times. One of the characters seems close to doing something wild and dangerous and it’s a fight between “must find out what happens” and “can’t bear to read any more” on a daily basis.

I hope week two will be easier and I will start to feel like my routine is falling into place. Watch this space.

3 responses so far

Feb 05 2011

Not smart enough

Published by Dougal under Comics, Programming

comicstrip

The sufficiently smart compiler is one that removes any need for engineering judgement/ability on the part of the programmer. The sufficiently aesthetic compiler does the same for artistic judgement.

Comments Off

Feb 04 2011

Parser troubles sorted

Published by Dougal under Programming

My troubles with parsing the ComicBake script format have been resolved, in particular by checking out John Goerzen’s ConfigFile package, which uses the same parser combinators to read INI files.

The code in ScriptParser.hs is slightly reduced and hopefully more robust and flexible than it was before. It certainly now recognises optional (Thinking) keyword, though right now the option is ignored later in the compilation process.

One advantage of finalising the parser is that I have a much better idea what the file format is. It helped to crystallise some of the fuzzy areas in my mind. This is the inevitable result of any programming endeavour — vague ideas are made exact or abandoned altogether.

I’ve updated the README to describe the key/value format used for defining metadata, and ensured that the old comics all still build properly. The new parser just skips comments which were previously meaningful if they don’t have the correct keyword specified. So I didn’t need to rewrite my examples.

Also I just noticed that I’ve made 150 commits to this repository. I doubt that means anything but I’m surprised it’s so many. I suppose at one point I was being quite good about lots of little commits for independent changes. Lately I’ve just been working on hulking great code bombs which can’t be split up until after they’re done, and by then it hardly seems worth it.

Comments Off

Feb 03 2011

Calculating the number of weekdays between two dates

Published by Dougal under Programming

Thinking about calculating the number of working days between two dates. (Note, I haven’t actually executed any of this code, just thought about it. It could be quite wrong.)

workingdays :: Day -> Day -> Integer
workingdays start end = undefined

For this scenario I assume that end is no earlier than start. (Obviously we can deal with this situation using some wrapper function to sort the dates if the result depends on this order.)

If start and end are the same day we define this as “zero working days”.

workingdays :: Day -> Day -> Integer
workingdays start end | start == end = 0
                      | otherwise    = undefined

If start and end are both the same day of the week then there will be a whole number of “working weeks” between the dates, eg one Monday to the next Monday is one working week. A working week is 5 days, so the number of working days is the number of working weeks times five.

We determine if two dates occur on the same day of the week by checking the number of days between them. Any number which is a multiple of seven (0, 7, 14, 21, …) indicates the two dates are a whole number of weeks apart. Multiples of seven produce a remainder of zero when divided by seven, so we divide the span by seven and check the remainder.

workingdays :: Day -> Day -> Integer
workingdays start end | start == end = 0
                      | is_sameday   = 5 * wholeweeks
                      | otherwise    = undefined
    where is_sameday = diffDays start end `mod` 7 == 0
          wholeweeks = diffDays start end `div` 7

At this point we notice that the first scenario is a simplified case of the second, where the two dates occur on the same day of the week with exactly no weeks between them. We can just collapse them into one calculation.

workingdays :: Day -> Day -> Integer
workingdays start end | is_sameday = 5 * wholeweeks
                      | otherwise  = undefined
    where is_sameday = diffDays start end `mod` 7 == 0
          wholeweeks = diffDays start end `div` 7

If the two dates don’t fall on the same day there may be some fraction of a working week between the two. The number of days leftover in the last week is the remainder when the number of weeks is calculated, which we’ve already worked out once. Rather than doing it twice we’ll separate it out into whole weeks and days.

workingdays :: Day -> Day -> Integer
workingdays start end | days == 0 = 5 * weeks
                      | otherwise = 5 * weeks + partweek
    where (weeks,days) = diffDays start end `divMod` 7
          partweek     = undefined

The bit we don’t know yet is the number of working days which make up the last part-week. The value of partweek is between zero and days with an upper limit of 5 because there can only be 5 working days between any two dates less than a week apart. At this point we’d be as well to just count them.

workingdays :: Day -> Day -> Integer
workingdays start end | days == 0 = 5 * weeks
                      | otherwise = 5 * weeks + partweek
    where (weeks,days) = diffDays start end `divMod` 7
          partweek     = length $ filter weekday $ enumFromTo newstart end
          newstart     = addDays (7 * weeks + 1) start

We count the number of weekdays from the day after the first day, since that day doesn’t count. At this point it probably hasn’t escaped you that we’ve got more repetition. We could remove the first case (for whole weeks) because partweek will evaluate to zero in that case.

If there is a nicer way to calculate the remaining part of the week I haven’t spotted it. I feel sure there must be something better than just looping over the remaining days, though maybe I am wrong.

Comments Off

Feb 02 2011

Implementation-defined file format and parser: tut tut.

Published by Dougal under Programming

In the last few days I’ve been snatching some moments to rewrite the awful, ugly parser in ComicBake into something readable and adaptable. While doing this I’ve been slowly rewriting the format of the accepted scripts. All of the improvements have been fairly subtle but sometimes with large improvements in usability and ease of implementation.

The big one is the comments. Previously the first N comments were hard-coded to contain the comic title, author and other information, prefixed with the “comment delimiter”, a double-dash symbol. I’ve adopted a key-value style instead which means comments can be included (or omitted) as necessary from the header without problem:

Old style:

-- Pandemic
-- Board games
-- Dougal Stanton
-- January 2011

New style:

-- title: Pandemic
-- series: Board games
-- author: Dougal Stanton
-- date: January 2011

At the moment I’m only storing the title and author names but it’s possible to tag anything now and use it later if necessary. The tags can be re-ordered as desired and if you miss them altogether I just use an empty string.

I’m also experimenting with adding directions to indicate speech/thought bubbles. At the moment the code uses this format but it may change:

Garfield: (Thinking)
    I hate Mondays

Sadly I’ve realised that the language is still ambiguous about divisions between scenes. A scene may end when a new one starts, or when the file ends. Getting it to manage both is proving awkward. I don’t want to add more syntactic elements just to make it easier to parse, so I’ll have to see how other languages which define loosely-grouped sections (eg, INI files) are parsed.

3 responses so far

Jan 26 2011

Both hands on the ground, both feet in the air?

Published by Dougal under Culture, Hobbies

For about six months now I (and then Helen) have been going to Capoeira Angola classes run by Mão no Chão group. Suffice it to say we are neither of the people in this photograph in fact, it’s just one I found on Flickr.

Leninho esquivando do golpe de m. Goiano

Continue Reading »

2 responses so far

Jan 22 2011

ComicBake with comic publishing capabilities!

Published by Dougal under Programming

Version 0.2 of ComicBake has just been pushed to the online repository. The changes since 0.1 were mostly internal reorganisation though there were some useful additions:

  • Rounded corners for speech bubbles
  • Use estimated box size for layout to prevent accidental overlaps and increase accuracy of inter-bubble spacing.
  • Publish to Flickr

The last one is the most important new addition. Now, once you’re happy with the look of the comic you can push it to Flickr. The client remembers logins between invocations so once you’ve authorised it to upload everything will work smoothly.

To this end I’ve split apart the function of the comicbake tool into build and publish sub-commands. Build works as before and is the default behaviour if you don’t specify a command.

To make and upload a previously scripted comic you now do this (making use of the default comicstrip.png file name):

$ comicbake build -i scripts/mycomic.script
$ comicbake publish --title="My great comic"

There are still plenty of issues to work out with this interface, and further work needed elsewhere, but ultimately I’m pretty happy with how things are working out.

Comments Off

Jan 16 2011

A look at Lightweight Static Capabilities (part 1)

I started to look at the Lightweight Static Capabilities paper over lunch on Friday. This is far too big an paper to consume in half an hour and I’m a long way from understanding it all. I thought the best way to increase my understanding was to write down my thoughts on and understanding of each section as I come to it. (The examples here are given in Haskell-like syntax, with fewer obscure operators. Conseuqently I’ve used the type name List a instead of [a] and cons instead of infix :.)

The area the paper looks at is labeled “lightweight dependent typing” — dependent typing without dependent types, essentially. Dependent type systems allow the programmer to specify types based on the values, so the programmer can ensure that lists will necessarily be non-empty and denominators necessarily non-zero, among other useful examples. The paper looks at ways of creating type safe “capabilities” without dependent types.

I will take the paper a little bit at a time, and as I read on I might have to correct previous misreadings/misinterpretations. The first motivating example given on page 2 provides a program to reverse a list, building up the result in an accumulator.

reverse :: List a -> List a -> List a
reverse ls acc = if nil ls
                    then acc
                    else reverse (tail ls) (cons (head ls) acc)

The standard list destructors head and tail are partial functions. They are not defined for the empty list and will produce a runtime error if accidentally applied to the empty list. For this reverse function we can be reasonably certain that it won’t blow up at runtime, but it’s a very simple function and we can’t get the same assurances in all situations. Let’s call these standard head and tail functions by more explicit names:

unsafeHead :: List a -> a
unsafeTail :: List a -> List a

In order to provide static guarantees that all uses of head and tail are safe a new type called FullList is introduced which is a rebranded standard list type. The key element is that head and tail can only operate on FullList types, and a guarantee is provided that values in this type are non-empty lists. With this static assurance we can actually use our unsafe functions from earlier:

-- unfull converts a FullList to an ordinary List type
head :: FullList a -> a
head = unsafeHead . unfull
 
tail :: FullList a -> List a
tail = unsafeTail . unfull

The FullList type becomes a one-use token which the value has when it moves through the program. This token can only be created in one place (which we can lock inside a separate module). We can easily control under what conditions this token is assigned:

module (FullList, unFull, full) where
 
newtype FullList a = Full { unFull :: List a }
 
full :: List a -> Maybe (FullList a)
full ls = if null ls then Nothing else Just (Full ls)

To verify that head and tail are always “safe” we must only verify that a FullList is always non-empty. The paper goes deeper into the formal verification than I’m comfortable talking about (at least at the moment) but it should be reasonable to say that there is only one line of code, the definition of full, which needs examined.

This is the kernel of trust concept that the paper revolves around. Shrinking down this kernel means it’s easier to examine and verify; and from there the type system extends our trust to the rest of the program.

From the user perspective, the type system forces us to check that lists are not empty before invoking head or other unsafe list operations:

reverse :: List a -> List a -> List a
reverse xs acc = case full xs of
            Nothing -> acc
            Just ls -> reverse (tail ls) (cons (head ls) acc)

Ideally we’d be doing this anyway so there isn’t a greater burden — but it does provide us with compilation errors if we forget to do it. (From personal experience the use of an option type like Maybe makes it much harder to forget these things, even before getting the compiler error. And calling fromJust or other unsafe extraction method feels immoral.)

This takes us up to Section 2.1, with only one omission. The paper at this point switches from explicit wrapping and unwrapping of option types to continuation-passing style. The option types are straightforward but slow things down. Depending on how things go I might follow suit and use continuation-passing from here on, but it might prove a better learning experience to convert to option types. We’ll see when I come to write up the next section.

3 responses so far

Next »