Blog » Reviving Genius
objective-c macOSIn my recent foray into learning Dutch for my relocation to the Netherlands – I'm sure there'll be much to blog about – I fell victim to the siren song of the Green Owl again.
It's too tempting - you get showered with instant feedback, encouragement in-app rewards, social stuff etc. To be fair it is fun, and you really feel that you're doing something useful.
…except.
I last used it in earnest it to 'learn' German before a trip to Berlin. I racked up a 150+ day streak or something nuts like that, a good 15 mins per day which they deem pretty high, and then turned up utterly unable to speak or read anything of actual utility
die Frau ist kein Klavier
am Dienstag spreche ich nicht mit dem Apfel
Now I don't think it was always like this, but it's for another blog post to enumerate the all of the ways it's been enshittified but suffice to say it's just not for me anymore.
Flashcards and Anki
On the other end of this gamification spectrum is just hard flashcards. Learn the thing on the other side of this card. Your reward is the number of stuff you've learned, and if you 'break your streak', that's on you - you're just not learning anything.
Now, people swear by Anki.
I've friends who've learned all the world flags, taught themselves to recognise basically any painter by their style etc. Really cool stuff. I think though, for whatever way I ingest language and information, it's not so good for me.
Specifically I think I'm missing clear right/wrong feedback (rather than judging if I was 'good' or 'bad' at remembering it), as well as the mechanics of actually having to type out the answer.
In school and univeristy I found that unless I was actually taking notes, and actually writing text, or even typing, I was just not engaging enough.
And so, when flipping over Anki cards and saying them in my head, it just sort of feels like temporarily stimulation of short-term memory.
Despite the spaced repetition, nothing seems to go in,a nd so I've just not been able to build a good habit with it.
(I think there are cards where you have to type the answer in, but truth be told I haven't really dug into that)
Now though this brings me to my holy grail, white whale app, from years gone by.
Genius
Genius was a spaced repetition app originally written by John R Chang for his own needs. It uses a comparatively simple (to Anki) but still very effective spaced repetition app for learning flashcard-like associations.
And, it was so simple. You have 2 columns to enter the things you want to learn (the cue), and you're quizzed on them (the answer).
Plus, it had just the right amount of instant-gratification, reward conditioning sounds in the form of the OS X Basso, Blow, Funk.

Alas, development stopped sometime around 2008, and despite an impressive run, it no longer runs on macOS:
/Volumes/Genius/Genius.app/Contents/MacOS
❯ file Genius
Genius: Mach-O universal binary with 2 architectures: [ppc:
- Mach-O executable ppc] [i386:
- Mach-O executable i386]
Genius (for architecture ppc): Mach-O executable ppc
Genius (for architecture i386): Mach-O executable i386
Yes, PowerPC, and i386 (32 bit) only. We're a few architectures past that!
Reviving Old Software
As an aside, I've been really impressed by some recent really cool software/tech conservation, poeple are doing.
See stuff like MattKC and co's Lego Island decompilation where they have reverse-engineered and entirely reimplemented whole swathes of the game. Or the Frogger source code recovery
Or on the hardware side, the saving of the world's largest CRT TV from a closing-down soba restaurant in Osaka (this is seriously a good watch).
Anyway I figured, if feckin Lego Island can be decompiled, and people can save code from ancient proprietary magnetic tapes, surely it's not beyond the wit of man, me, to get Genius to work again.

Maybe I can be that developer :)
Source Code
The homepage is https://genius.sourceforge.net. With some clicking about, you'll find the link to the source code, an SVN repo. I'd only ever heard of SVN from my elders in university - something about locking, a 'check out' being an actual 'check out' as one aquires an exclusive lock on a library book.
I'm not interested in plumbing those depths, but luckily git-svn
is.
So after much waiting, I ended up with a neat git repo. It's jarring to pop open a familiar git log and see commits from 2004:
commit 5d5624365ab06b08bb83257e78d1bc44bbca7664
Author: jrc <jrc@f73e0bdd-8638-0410-8bb3-c52e70a1423d>
Date: Sat Nov 6 02:29:42 2004 +0000
loc 1
commit a2045bf7f2d5ed93f73893edce72665ea260453e
Author: jrc <jrc@f73e0bdd-8638-0410-8bb3-c52e70a1423d>
Date: Sat Nov 6 02:28:42 2004 +0000
*** empty log message ***
commit 1d9e71e3fafe91d182a244b3bf5fc1173348dfcb
Author: jrc <jrc@f73e0bdd-8638-0410-8bb3-c52e70a1423d>
Date: Tue Oct 19 21:53:33 2004 +0000
This commit was generated by cvs2svn to compensate for changes in r2,
which included commits to RCS files with non-trunk default branches.
commit 62485d30ab237f05d04e2791a9e6871b9adbf701
Author: (no author) <(no author)@f73e0bdd-8638-0410-8bb3-c52e70a1423d>
Date: Tue Oct 19 21:53:33 2004 +0000
New repository initialized by cvs2svn.
I love how everything repeats itself. I wonder what was in the CVS source.
Bulding for macOS
As it turns out, it was surprisingly easy to get the project to build!
The .xcodeproj
format still seems to be entirely forwards-compatible, and it opened up completely fine on the latest developer tools, on my arm64 macbook.
Building failed, as it was unable to locate the old OS X 10.4 SDK it was hard-coded to require.
But changing this to the latest tooling let the obj-c compiler actually run, with a compiler error!
GeniusAssociationEnumerator.m:265:87 Incompatible function pointer types sending
'int (id, id, void *)' to parameter of type
'NSInteger (* _Nonnull)(id _Nonnull, id _Nonnull, void * _Nullable)'
(aka 'long (*)(id _Nonnull, id _Nonnull, void * _Nullable)')
Looks like type checking got a little bit more strict.
A single line change fixed the build:
//! randomly returns NSOrderedAscending or NSOrderedDescending
-NSComparisonResult RandomSortFunction(id object1, id object2, void * context)
+int RandomSortFunction(id object1, id object2, void * context)
{
BOOL x = random() & 0x1;
return (x ? NSOrderedAscending : NSOrderedDescending);
As an aside, surely it's really confusing reading Objective-c diffs when they use +/-
to denote private/public methods?
…and it ACTUALLY BUILT.

It looks a bit janky, but it works!
The next hurdle was getting Xcode to read the old nib
files for the UI. I've admittedly little idea how it works, but they seem so old that even Xcode can't convert them. Fortunately there is ibtool
, which has an --upgrade
option to replace them.
After a little bit of messing about in Interface Builder and swapping out the bundled lower-resolution UI PNGs for new macOS vector icons, we get a fairly snazzy, retina-ready, modern looking mac app. And it's completely, fully, functional.
Projects like this are certainly fun, and valueable in their own right. I've learned a relative ton (compared to my zero knowledge) about mac development, took a nice trip down memory lane with the different architectures, etc.
However ultimately Genius was written to aid memorisation, and now I'm happily using it to do just that, just as I did back in 2008.


You can browse the 'new' source code at https://github.com/shawa/genius.