Thomas Denney

Student and app developer

Oxford term dates

When I come home for vacations from Oxford I suddenly find myself using real dates again, rather than thinking in terms of "Tuesday of 5th week" or "Sunday of 3rd week". However, during term time there is the occasional need to map between 'Oxford dates' and real dates.

Wolfson College provide a calendar that you can subscribe to that provides each week of each term, which is invaluable when scheduling lectures and tutorials into my calendar. Sometimes, however, I just need to very quickly find out what date an 'Oxford date' falls on, or what 'Oxford date' a regular date falls on.

I have therefore created a very simple Python script that provides this functionality, allowing you to run ./ 2017-02-14 or ./ Tu5 to map between the two. Currently you have to set an environment variable for the start of term (which you can find here), but seen as this only changes three times a year I am currently not bothered about automating it.

Published on January 7, 2017

Comparing the implementation of generics

Generics are a common feature of statically typed programming languages that allow programmers to abstract algorithms and data structures over types. Typically implementations of generics - at the compiler and runtime level - will "instantiate" different concrete instances of generics types by replacing their type parameters with other types. The point at which this instantiation occurs, and whether it occurs per type or not varies between C++, Java, and C#.


C++ implements generic classes, methods, and functions through templates, which are compiled into separate copies for each concrete type used with the generic type. Consider a simple generic class Box:

template<typename T>
class Box {
    Box(T value) { _value = value; }
    T _value;

Later when a function declares an instance of Box it is required to supply the name of a concrete type for the type parameter T:

Box<int> intBox(42);
Box<std::string> stringBox("Hello, world!");

For each compilation unit - generally a single C++ source file - instances are created by replacing T with the appropriate type and then compiling the generated code. The generated code is then type checked, to ensure that all used methods, fields, and operators are accessible. For example, the STL function std::sort is generic across all types, but will only compile when used with a type that overloads the < operator. It is an unfortunate disadvantage that C++ has no way of dictating this in the type system, but this is coming in the future with concepts.

A big advantage of the C++ approach is that there is no runtime performance cost compared to handwritten code, but it does come at the hefty disadvantage of compile time and code size. As each compilation unit includes copies of all the generic instances it uses, it is necessary for a linker to eliminate the redundant copies. For example, if both a.cpp and b.cpp used Box<int>, then implementations of Box<int> would feature in a.o and b.o, but if the two were linked together into program then a spare copy could be removed. Programmers can avoid this by declaring explicit instantiations in a header file and then forcing all of them to be implemented in a single object file, but this becomes awkward as the code size grows.

Slightly unique to C++ is the option to provide alternative specializations of generic classes for types where it may be more efficient to do so. For example, the STL specializes std::vector<bool> to represent boolean values with a single bit.


The initial release of Java in 1995 did not include generics. The Generic Java project, started in 1998, was integrated into the language in 2004. As a result of the relatively late inclusion of generics, the authors of Generic Java were conscious that it would be necessary to maintain compatibility for existing code that used non-generic interfaces for classes, such as common collections, that could now be implemented using generics.

Prior to the introduction of generics, collections APIs used Object, Java's root reference type, as their element type. The Generic Java project therefore chose to 'erase' the generic type parameters by replacing them with Object in order to compile the generic class, and introduce the appropriate casts in client code. The following generic code:

public class Box<T> {
    public T value;
    public Box(T value) {
        this.value = value;
//Client code
Box<Integer> intBox = new Box<Integer>(42);
Integer intFromBox = intBox.value;

Is therefore compiled to:

public class Box {
    public Object value;
    public Box(Object value) {
        this.value = value;
//Client code
Box intBox = new Box(new Integer(42));
Integer intFromBox = (Integer)intBox.value;

A consequence of type erasure is that it restricts the type parameters to reference types, and as such it is not possible to create an instance of Box<int>, for example. In order to get around this, Java provides boxed classes which contain a field for Java's eight primitive value types. In Oracle's HotSpot JVM, this comes with the disadvantage that a Java object contains a header of one or two words, and to access any field at least one pointer traversal is required. There is therefore the initial cost of allocating memory on the heap for boxed instance, the memory cost of the object's header, the cost of traversing at least one pointer to get the boxed value, and the cost of garbage collecting the instance. In many cases it is difficult to efficiently use generics with primitive types.

Project Valhalla a recent effort to "incubate advanced Java VM and language features", supports the introduction of value types and generic specialisation to the language in order to make these cases more efficient.

Furthermore, without reflection it is not possible to create new instances of the generic argument either, i.e. object creation via new T() is not possible.


Most C++ compilers compile to native code "ahead of time" (AOT), whereas Java byte-code is compiled "just in time" (JIT) by a virtual machine, but .NET software can be compiled using either method. Typically, however, execution is via the JIT-compiled Common Language Runtime. At runtime, generic types are instantiated as they are required, so generics can be used with value and reference types. A single instance is shared for all reference types - effectively using type erasure like Java - but separate instances are created for value types. Rather than completely erasing types at compile time, the metadata section of .NET "portable executables" encodes the generic parameters of a type or method, allowing these to be replaced, and the method can then be JIT compiled. After an instance has been compiled it will be reused, and the generated native code remains in memory whilst the application is executed.

For most types found in .NET applications (references), this approach will offer similar performance to Java, as appropriate casts between the base reference type and the expected reference type must be inserted. Meanwhile, the .NET approach offers a significant advantage for value types as a separate instantiation is natively compiled for each value type used by the program, which avoids the need for boxing or unboxing, hence offering better performance.

Despite using type erasure for reference types, .NET allows new T() in generic methods by automatically using reflection methods, provided that a given type has the default constructor available.

As well as providing a JIT-environment for .NET applications, Microsoft provides a tool that compiles .NET bytecode assemblies to native code. This improves performance of .NET applications by removing the need for JIT compilation, and also reduces memory requirements.

Unlike native C++, .NET executables typically consist of multiple assemblies that are dynamically linked at runtime (either by the JIT or OS services). Suppose an assembly A.dll exposes the generic type List<T>, which is instantiated as List<string> and List<int> in both B.dll and C.dll, and that D.exe links to both B.dll and C.dll.

In the JIT environment the bytecode for List<T> will only be included in A.dll, but the native environment presents a greater challenge. The first option would be to include native code for List<string> and List<int> in the natively compiled B.dll and C.dll, but this violates .NET's principal that equal types should be identical.

In order to counteract this problem, Kennedy and Syme introduce further rules for the "home" of a particular instantiation:

  • The assembly that defines a generic type includes the instantiation for all reference types, like Java. In the case described above A.dll would include List<ref>
  • If an assembly needs a value type instantiation, then include it in the assembly. B.dll and C.dll would therefore require their own implementations of List<int>, but they could both use the implementation of List<ref> in A.dll for List<string>, as string is a reference type in .NET
  • At link time do not link to a generic type if an equal instantiation has already been linked to. The implementation of List<int> in C.dll would therefore be ignored if B.dll had already been linked in D.exe, thus resolving the identity issue


Generics are a useful addition to many programming languages, and there are further efforts to add higher-order "kinds" (a generalisation of parametrized types) to functional programming languages such as Haskell. The compilation techniques described above are used by main other programming languages, although recent languages such as Go remain resistant to their addition, citing increased compilation time and executable size as drawbacks.

The native code generated by compilers for statically typed languages is unlikely to change due to the stability of computer architectures, OS calling conventions, and memory layouts. Recent research and development into generics instead focusses on adding restrictions to the types that can be used with generics to increase type safety and programmer productivity whilst reducing the complexity of the compiler.

Published on November 13, 2016

Automating the Wikipedia game

In the Wikipedia game, you typically click the random article button and aim for another Wikipedia article by clicking on the fewest links possible. At a recent Oxford CompSoc event we wrote bots to automate this process.

Before the event I wrote up a few Python scripts to play the game by using the MediaWiki API. There is an API call to fetch a list of links for a given page, but it unfortunately lists them alphabetically rather than in the order they appear. I therefore used the general API for fetching the MediaWiki markup for the page and scraped the links instead. This meant I could use a simple strategy of clicking the first link to get to Philosophy, and then using a known route from there to our goal page. Effectively this just performed a depth first search on the graph of links.

Most people chose to use and adapt this strategy, often by prioritising certain frequently linked to articles and using known routes from those articles, although at least a couple of people experimented with backlinks.

Whilst my "philosophy" strategy tended to reach the goal article within around forty links, the best strategy used a breadth-first search (capped at the first five links of an article) with certain well known routes used to reach the goal at the end. This was still a largely uninformed search, but by "knowing" the category of a Wikipedia article you could almost certainly reduce the number of clicks that you need.

Everyone stuck to search strategies and the Wikipedia API, rather than using the brute force approach of downloading a dump of all Wikipedia's text, and running Dijkstra's on it locally.

Published on October 20, 2016

Minor site update

Over the past few days I've been migrating from Squarespace to a self-hosted site. If I've done this correctly, you should only notice a few minor visual changes.

The server now runs on DigitalOcean, with a NodeJS backend written in TypeScript. I'd hoped to avoid writing any server side code, either by generating a static site with Jekyll or by using a CMS, but Squarespace has irregular URLs. For example, dates can be written with any number of digits. I didn't fancy learning whichever CMS happens to be cool today, so writing a little NodeJS wasn't onerous.

Writing in TypeScript and using Visual Studio Code made my life a lot easier. They work great together, especially with IntelliSense and debugging. I would recommend doing the following:

  • If you're using any NPM modules, make sure you have DefinitelyTyped definitions

  • If there isn't a DefinitelyTyped definition, make sure you import via let module = require('module') rather than import module = require('module') because otherwise TypeScript will throw an error

  • Use tsc --watch to auto-recompile files

If you notice any broken URLs, please contact me so that I can fix them.

Published on August 31, 2015

Keep Calm 4 for Android

I've just shipped a major update to Keep Calm for Android.

  • Photo backgrounds
  • Change the foreground colour
  • Material Design

Aside from new features, I'm now also including ads again - photo backgrounds and text colours had previously been 'pro' features before I removed Keep Calm Pro from Google Play.

Published on March 3, 2015

Play Time 2

Play Time 2, my music statistics app for iOS, has just received a major update. You can now view how you listen to your music over time, view interactive graphs for your listening habits of individual songs, albums, and artists, and view more statistics than ever before. Play Time 2 is available for $0.99 from the App Store today.

Play Time, Over Time

Play Time, Over Time

Play Time, Over Time

Each time you launch Play Time it records the total play count of every song in your music library. As these change you'll be able to see how the total play time of any song, album, or artist, or your whole library, change over time. The graph itself is interactive and you can view the total play time at any point in time.

New statistics

New statistics

New statistics

Previously you could only view a handful of statistics about your music library, however you can now view average play time, duration, play count, title length, and rating as well as word counts in song titles. Songs, albums, and artists also show fun facts related to their play time. For example, I've spent about the same amount of time listening to Daft Punk as the gestation period of a mouse.

Interactive charts

Year vs Play Time

Year vs Play Time

There are now interactive charts that allow you to view:

  • Rating vs play time (if you rate your music you'll probably find that yours looks very similar to everyone elses!)
  • Year vs play time
  • Genre vs play time

Other new features

  • Support for new iPhones and the iPad with settings that sync via iCloud
  • Share any chart or statistic by tapping on it
  • CSV data export (works with Numbers/Excel/Google Drive on your iOS device or on your computer) in case you want to do even more analysis
  • Gravitational ratings (you'll get it when you see it)
  • Searching
  • Song/album/artist rankings
  • Completely redesigned UI with a new icon
  • The app is so much faster, its not even funny

You can download Play Time from the App Store for $0.99.

Published on February 17, 2015

Circle Draw 2

Today I've released Circle Draw 2 which refreshes the UI and adds support for newer iPhones.

More importantly, however, the critical cats that score the circles are now higher resolution.

You can download the free update to Circle Draw from the App Store today.

Published on February 9, 2015

Apps that include an app extension and a framework must support arm64

Yesterday I was finally shipping an update to one of my apps, but each time I tried submitting to iTunes Connect I got back error -9000:

Invalid architecture: Apps that include an app extension and a framework must support arm64

Googling didn't reveal too much (the project was set up fine to build for both 32-bit and 64-bit), but the following seemed to fix the issue:

  • Going through project.pbxproj and manually replacing IPHONEOS_DEPLOYMENT_TARGET = 7.0; with IPHONEOS_DEPLOYMENT_TARGET = 8.0; (I had set 8.0 in the UI, no idea why the file hadn't updated)
  • Ensuring that the 'Build Active Architectures Only' was set to NO for release builds (again, I had set this in the UI, but checked it in the project.pbxproj file)
  • Deleting an old static library from the Frameworks group. This is the weird one, but I suspect it was what was causing the issue. The app had previously linked to a static library that had been 32-bit only, but I had long since deleted it. The app itself didn't link against it, but there was still a link showing up for it in the Xcode project (it showed in red though, it didn't actually exist)

The phrasing of the error isn't great; there ought to be an 'or' rather than an 'and' in there (my app only contains a framework, not an extension).

Published on February 8, 2015

Word Finder 2

After two years of no updates I have now updated Word Finder with new features, significant performance enhancements, and support for new iPhones. Word Finder allows you win (cheat?!) many common word games with wild card search, anagram search, Boggle search, and Letterpress search.

  • A brand new query execution engine that ensures all queries now execute instantly (the old version could take several seconds)
  • Search history
  • Easy entry mode for Boggle and Letterpress grids and improved entry for anagrams
  • Sorting options
  • Save your favourite words
  • View definitions for thousands of words via Wiktionary or the built in Apple dictionary
  • Modernised user interface

You can download the latest version of Word Finder for free from the App Store.

Published on February 2, 2015

Nim on iOS

The Nim programming language is simple, clean language with a style that will be familiar to Python programmers, but has the performance benefit of compiling down to C. The C the compiler generates is different depending on whether you have 32-bit or 64-bit code, which makes compiling for iOS (which has to target both 32-bit and 64-bit) awkward.

In this blog post I'll summarise how you can use Nim for components of your app. I've got a working version of this project available on GitHub.

Firstly, if you haven't already, grab the compiler and compile it (don't worry, this is easy). Then create a new Objective-C project in Xcode. I've called mine nim-ios-demo:

Creating a new project

Creating a new project

Next you'll want to create two directories: scripts and src. Your folder structure should look like this:

Creating script folders

Creating script folders

The src folder is where you'll be placing your Nim source files. In scripts you need to place my script (I modified it from work by Grzegorz Hankiewicz). This script compiles the Nim source files to C and creates the merged 32-bit/64-bit files. You need to add this script as a build phase in Xcode:

Script build phase

Script build phase

There are two minor changes that you'll need to make to the script to use it in your project:

  • Set the PROJECT_DIR variable
  • Set the PATH_TO_NIM variable

Add your Nim source files in the 'src' directory. In this example I'm going to use a very simple function:

# Saved as backend.nim in the src directory
proc hello*(name: cstring): cstring {.exportc.} =
    result = "Hello " & $name

You can optionally add this to your Xcode project, but make sure that you don't have Xcode set to copy or compile it! Note that we need the asterisk after the function name so that it gets exported, and {.exportc.} ensures that the name doesn't get mangled. We also have to use cstring rather than string (Nim's native string type) but they get bridged automatically at no cost.

Build your project. This will run the Nim compiler and generate the C files you need to include in Xcode. Go ahead and add the contents of src/build/nimcache to your project:

Adding to the project

Adding to the project

If you build now you'll get a lot of warnings (50+). If you want to avoid these, add the -w flag to the files in their compile stage:



Before you can use the Nim function you'll need to configure the Garbage Collector. Add the call to NimMain in main.m:

#import <UIKit/UIKit.h>
#import "AppDelegate.h"
#import "backend.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));

For my example, I've created a simple app that echoes the user's name. To call the function, you'll need to import backend.h:

#import "ViewController.h"
#import "backend.h"

@interface ViewController ()
- (IBAction)textChanged:(UITextField *)sender;
@property (weak, nonatomic) IBOutlet UILabel *label;


@implementation ViewController

- (IBAction)textChanged:(UITextField *)sender {
    char * helloName = hello((char*)sender.text.UTF8String);
    self.label.text = [NSString stringWithUTF8String:helloName];


By using [NSString stringWithUTF8String:] we can copy the contents of the string, which ensures that when Nim cleans up the memory later (helloName) we don't lose the string.

Finally, you can build and run the app:

Once you're up and running it is trivial to add new Nim code to your project. So far I've been very impressed with the language, and I may even use it in the future in my apps.

Published on January 27, 2015