The Uncarved Block

Please bear with me while I restore my content. At the height of the covid crisis I missed some emails from my hosting provider which said they were trying to bill me on an expired credit card. As a consequence they deleted my server and my backups.

In an unrelated catastrophe my "offsite" backup is on a computer that was bricked and that I can't get repaired until the lockdown is over.

I am restoring everything at the moment and the journey to get my content back has been an interesting unix exercise which I hope to document once it's all fully back up and running.

Since the source code to my blog (yes I wrote it myself) seems to have been irretrievably lost, I am taking the opportunity to move to using a static site generator (zola) and host on a different provider (AWS). Most of my actual content has now been recovered although the presentation will be even more minimalist than usual while I figure out how to get zola to do everything I want.

At the moment I'm aware of:


People and stuff that have made this website fun to produce

This is a static website hosted on AWS using S3 and Cloudfront. The site is generated using zola, which is a very fast and no-nonsense static site generator written in rust.

I also use AWS to host DNS for my sites and use fastmail for mail hosting, which means mail just works and I don't have to spend any time figuring out why it's broken or why upstream sites aren't accepting my mail. For some time now people hosting their own mail and dns have been at a big disadvantage due to the way in which large network providers have chosen to conduct the war on spam.

My pages are written using the neovim editor, and I use a Planck ortholinear dvorak keyboard.

Note: Amusingly almost all of the above has changed since I wrote the first time I made this page, so I've kept the old one around for comparison.

permalink Updated: 2020-08-12

Set of scala helper classes

Learning scala, I've started to write some generally useful stuff and make it available

permalink Updated: 2020-08-07

Partial Function Application is not Currying

These two related concepts are often confused. Until yesterday I thought they were the same thing myself.

Often you will see in computer books and articles a pattern where a function is applied to some but not all of it's required arguments, resulting in a function of fewer arguments. In python, this looks like this (from PEP 309:

def papply(fn, *cargs, **ckwargs):
    def call_fn(*fargs, **fkwargs):
        d = ckwargs.copy()
        return fn(*(cargs + fargs), **d)
    return call_fn

This is called "partial function application" - it returns a function which acts like the function you pass in but which takes fewer arguments, the others having been "bound in". The author of this code, however, had the (very common) misconception that this is currying, and called his function "curry" as a result. I shared this misconception for some time, and thought that currying and partial application were the same thing. In fact they are to certain extent opposites.

Where partial application takes a function and from it builds a function which takes fewer arguments, currying builds functions which take multiple arguments by composition of functions which each take a single argument. Thus we curry in python like this:

def addN(n):
    return lambda x: x + n

def plus(a, b):
    return addA(b)

Now why would we ever want to do that? Well, in some pure functional languages this is exactly how functions with multiple arguments are built up. In ocaml, a function which takes two ints and returns a float is actually a function which takes an int and returns a function which takes an int and returns a float. In this world, partial application just happens without any extra code:

% rlwrap ocaml
    Objective Caml version 3.09.3

# let add a b=a+b;;
val add : int -> int -> int = <fun>

So the type of add is a function which takes an int and returns a function which takes an int and returns an int.

# let add2=add 2;;
val add2 : int -> int = <fun>

add is a curried function, so here we can partially apply by just calling with a single arg- it returns the function that takes the other arg and returns the result.

# add2 34;;
- : int = 36

...and we can call add2 with a single argument as you would expect. Because ocaml curries add for us, the function has been partially applied. It's interesting to note that in ocaml if you label your function arguments, they can be partially applied in any order.

permalink Updated: 2020-08-07

When life gives you lemons (or not)

Drinking on my own

They checked 3 times that I wanted lemon (not cucumber) in my second $38 Hendricks and tonic even though I very obviously had lemon in my first one. Then they brought cucumber anyway. The obscene price and the cucumber and lemon thing are par for the course here but they are now trying to charge me a second time for the drink I already paid for. I give them the receipt showing I paid for that one.

Settling the bill for this drink has already taken over 10mins with three staff squinting at the machine, my card and the receipt. And I'm not done yet.

During the process I confirm my name twice while they stare in amazement at my credit card. Probably not everyone has credit which stretches to two drinks in this place.

The bar is very full. I can only assume everyone else is stuck here still trying to settle up for drinks they bought days or even weeks ago. Lots of people seem to have Hendricks and tonic (with cucumber) which is a fair indication I'm onto something.

I'm deeply alone, on the last day of a business trip. My friends said they would meet me here then all obviously ended up somewhere else. There is no reception so we are unlikely to connect. I will not see many of them for months. I used to love working with them, now see them very seldom and the thought fills me with a profound sense of sadness.

One bar person comes over to explain the confusion. "You had 2 Hendricks and tonic, one with lemon and one with cucumber."

I finish my drink, get my coat and head out into the cold.

permalink Updated: 2020-08-07

I shouldn't have to explain this to you, but...

One person's struggle to buy food at Newark Liberty International airport

I shouldn't have to explain this to you but...

“That isn't a falafel sandwich. It's some hummus and some pieces of pitta bread."

"Yeah, but you ordered the falafel sandwich."

"I did. That's not a falafel sandwich though."

"See, it says here. You ordered the falafel sandwich."

"Yeah. That doesn't have falafel. And it's not a sandwich."

She looks from the printout to the plate a few times in disbelief. A woman at the next table is trying to attract her attention to get the hummus she obviously ordered, but my server is not the type to be so easily swayed. This isn’t the first technical hitch in the delivery of my meal either. Before the absence of sandwich I was brought a bowl of soup but no spoon. After asking three times they handed over a teaspoon. Now there is a brief impasse after which the non-sandwich is taken away. Time passes. I’m sitting in a restaurant/bar in Liberty International Airport in Newark, New Jersey. Which, you know. New Jersey. But at least I’m leaving.

The setup in this particular place is that there is an iPad at each table which you use to order and pay. I have a headache and they're playing loud Cuban music. The food is not at all cheap, but the whole iPad schtick means they know precisely who ordered what and presumably is so they can get away with not paying their staff- hence the prodigiously awful service.

It’s spring and there’s enough snow falling for me not to be able to really see the runway even though I’m right in front of a window looking directly at it. Planes nearby have snow gathering in drifts on their wings. Other planes seem to be landing and taking off, which is good because I don’t really want to stay in New Jersey.

"Hi. I'm still waiting for a falafel sandwich."

"I thought it was brought to you. "

"No, you brought hummus. And I told you it wasn't a falafel sandwich. Then you took it away."

"I thought it was brought to you. Lemme check."

"You can see that nothing was brought to me. I don’t have any plates. And my cutlery is unused."

"Lemme check, I thought it was brought to you."

She moves diagonally by one table, remaining in my field of view and starts ostentatiously wiping down a table with one hand while texting on her phone with the other. She wants to make it as clear as possible by her actions that she has OTHER THINGS TO DO and is most certainly not in any way checking for my sandwich. I redirect some wine that was ordered by the guy next to me.

Eventually my food comes without her “help". My knife is made of bendy plastic and when I use it to push a piece of lettuce onto my fork it snaps in half for airline safety reasons.

permalink Updated: 2020-08-07

Cold Brew Recipe

Even in hot weather it's important to remain adequately caffeinated. Here's how.

Here's how to make delicious smooth cold-brew coffee:

  1. You need a cafetière (French press for my American friends) and a drip filter (like if you were a hipster making a pourover). A chemex works great for this.
  2. Ok, now grind the coffee fine as though you're making espresso (that's not what you'd use for a regular cafetière coffee I know). I use about 68g of coffee for 800ml cafetière. Your mileage may vary, but err on the side of more coffee rather than too little. 1.5 - 2 tablespoons per cup of coffee is I think the rule for this sort of thing.
  3. Put the ground coffee in the cafetière and pour on regular cold tap water. You might want to use filtered water if your tap water doesn't taste good enough to drink on its own.
  4. Give it a quick stir, wait ten minutes & give it another quick stir. Don't put the top on the cafetière, just put some clingfilm over the top and put the whole thing in the fridge.
  5. Wait 24 hours.
  6. Take the whole thing out of the fridge, remove the clingfilm, give it a quick stir, put the top on the cafetière and press down just like you normally would if you were using the thing to make hot coffee.
  7. You don't want sludge at the bottom of your cup, so pour it through the drip filter into whatever container you want to store the coffee in (I use a water bottle normally) and keep it in your fridge.

You now have a lovely bottle of the coffee equivalent of blue meth in your fridge. Be warned this mix is strong. I like to drink it in two different ways:

  1. Neat in an espresso cup as a replacement for my first espresso of the day.
  2. Over lots of ice diluted about 2 parts cold brew to 1 part water if I want a coffee to take with me.


Short version

  1. Make coffee in a cafetière/French press using cold tap water and a fine grind for the beans (not coarse as would be normal)
  2. Put it in the fridge to brew for 24 hours
  3. Plunge it, then run it through a drip filter

permalink Updated: 2020-08-07

Bullionvault interface

Wrapping the public interface of a gold market in scala goodness

permalink Updated: 2020-08-07

My Biog

Some stuff about me

I trained to postgraduate level as a Jazz bass player, but worked as a programmer to pay for my music postgrad and somehow ended up in a career in computer science. After various roles as a permanent employee and contractor I became the IT director of a dot com company. I then joined Goldman Sachs because the role I was offered sounded very interesting. I stayed there for 8 years, working initially on infrastructure for distributed pricing and risk, then in what would now be called devops, and then on a number of different trading desks. It was indeed a formative experience and I learned a lot although it was very challenging at times.

I eventually left GS and joined Palantir Technologies, a silicon valley software company that focusses on data analysis. Palantir attracts a lot of attention from conspiracy theorists due to work they believe it does for the US government however I worked on the commercial side, focussing on detecting rogue traders. This led to a joint venture they formed with Credit Suisse, called Signac, which I was fortunate enough to be co-head of. Unfortunately due to changes in the regulatory landscape the founding rationale for this startup went away and Credit Suisse and Palantir decided to dissolve this partnership.

I then joined OakNorth as the CIO of their platform business, which uses data science, tech and credit expertise to transform lending to medium-sized and growth businesses. It's been a very exciting journey so far.

I'm also on the panel of advisors of Antler, a hybrid incubator/vc and am an advisor to a startup called Kamayi. I'm first author on 2 patents in the field of fraud detection and wrote a chapter of "The Regtech Book" published by Wiley Press along with a number of other articles. I'm on the editorial board of the Journal of Digital Banking.

I've spoken at a number of large tech and fintech events both in person and on-line, including AWS Re:Invent, Money 2020, the MAS Fintech festival, the Inovate Finance Global Summit, Wired:Smarter, CogX and many others.

You can see my linkedin profile, and invite me to your network if we know each other. There are quite a few Sean Hunters though so I might not be the one you're thinking of. You can email me if you like and I will try to respond although I can't promise to be too prompt.

permalink Updated: 2020-08-05

I Ching

About the hexagrams on this site

My interest in the I Ching began when I was a music student. Studing John Cage, I learned that he was heavily influenced by the I Ching and used hexagrams as an aid to composition of aleatoric music. I bought a copy of the Richard Wilhelm translation and learned to cast hexagrams via the coin oracle. I revived this interest when I studied Tai Chi Chuan.

Every visitor to the front page of this website is greeted by a pair of I-Ching hexagrams, which are generated by this small python program. The distribution of results in the I-Ching is not uniform, and this page gives the same distribution of lines as the Yarrow Stalk oracle. The second hexagram is the first but with "moving lines" inverted in the traditional fashion. This website uses, and I incorporate the I-Ching reading into the Cheetah template for the homepage. The relevant snippet of template code looks like this:

#import ching
#set $hexes = $ching.get_hexagram_pair
#set $hex1 = int($ching.get_hexagram_number($hexes[))][0]
#set $hex2 = int($ching.get_hexagram_number($hexes[))][1]
#set $name1 = $ching.get_hexagram_name($hexes[)][0]
#set $name2 = $ching.get_hexagram_name($hexes[)][1]
#echo '<img id="hex1" alt="%d: %s" src="/static/images/iching/Iching
-hexagram-%02d.png" />' % (hex1,name1 ,hex1) #
#echo '<img id="hex2" alt="%d: %s" src="/static/images/iching/Iching
-hexagram-%02d.png" />' % (hex2,name2 ,hex2) #

...and the lovely hexagram graphics are in the public domain. I downloaded them from the wikipedia.

permalink Updated: 2020-08-04

The quest to get a mac to do exactly what I want

It all started because I use a weird keyboard. When I don't have this

keyboard plugged in, I want my laptop keyboard map to use dvorak, but since my keyboard is dvorak in hardware, when it's plugged in, the laptop's keyboard map needs to be switched to qwerty otherwise I get a kind of "double dvorak" and everything goes down an extremely strange rabbit hole. Now normally it wouldn't be that much of a hassle to just change it when I'm plugging or unplugging my keyboard, but I found myself in a situation when I kept having to take my laptop to one or other meeting, meaning that I would be plugging and unplugging the keyboard and flipping the setting multiple times a day.

As a nerd, this grates. The computer should just know that if I have that keyboard plugged in I want the keyboard mapping to be qwerty and otherwise I want it to be dvorak. Happily, this is where hammerspoon comes in. Hammerspoon is a framework that allows you to program all kinds of little customizations for mac. Here's how you do the keyboard tweak I wanted:

-- Watch for planck keyboard add/remove and set the keyboard layout
function usbDeviceCallback(data)
    -- Skip internal memory card as it spams an event on suspend/resume
    if (data["productName"] ~= "Internal Memory Card Reader") then
        hs.alert(data["productName"] .. " " .. data["eventType"])

    if (data["productName"] == "Planck") then
        if (data["eventType"] == "added") then
            --when we add the planck, change the hardware layout to
            --dvorak and turn the OS key layout to qwerty
        elseif (data["eventType"] == "removed") then
            --when we remove the planck, change the hardware layout to
            --qwerty. It's up to the OS to give me dvorak
usbWatcher =

...but of course this turned out to be a gateway drug for all kinds of further customizations. How about a thing that starts the annoying WeWork printer client thing whenever I'm at WeWork? (Yup. Done). Automatically tweaks my brightness taking into account my battery percentage and the ambient brightness of the room I'm in? (Yup. Easy peasy). Set a default layout of windows whenever I plug my laptop into an external monitor? (Sure) I've now also got it so I can do almost all window movement and resizing via the keyboard.

Any case, my full config is unavailable right now but I'll try to get it back when my personal mac is brought back to life. Feel free to take from it anything that's usable. The grid resizing thing has a minor bug that I've not been annoyed enough to fix yet, where on certain sizes of monitor it doesn't realise your window is on at the bottom, so you need to move it up to resize. Other than that it's tickety-boo. I highly recommend checking hammerspoon out if you can code a little and want to tweak a Mac to behave exactly the way you want.

permalink Updated: 2017-06-23