Author Archives: david

My kitchen has a new toy

I was talking to a colleague the other day about caramelizing onions and all of a sudden there was a pressure cooker in my kitchen.

OK. There were a few more intermediate steps than that, but that’s pretty much the gist of it:

The gist of the conversation was:

  • how caramelizing onions in a pressure cooker is great
  • pressure cookers are no longer the contrary death traps we remember from days of yore
  • they’re really no larger than a normal sized pot

The last one is particularly important for me due to the limited kitchen space available in London on my budget (ok, the “I’m not going to die horribly” bit is quite important too. But kitchen space dammit).

So when we got back the office I applied my standard impulse buy buying algorithm and on Wednesday a pressure cooker arrived. It’s this one for what it’s worth, which has a few bad reviews about longevity, but I figured I’d rather buy a cheaper one and replace it in a year or two when it turns into a mere pot than buy an expensive one and discover pressure cookers were useless.

It turns out pressure cookers aren’t useless.

I’m still not entirely used to the next day delivery thing, so I had completely failed to anticipate that I would have a pressure cooker and thus decided to make something with whatever I had to hand. The following was the result:

Caramelized onion and red lentil soup

Ingredients:

  • 1 large red onion
  • 3 small white onions
  • a little under half a pack of butter (100g?)
  • a couple liters of chicken stock I’d made the other day
  • a lot of lentils (I honestly just poured what was left of my 2kg bag in. I think this came to somewhere around 500-800g?)
  • a bit of salt
  • a bit of brown sugar
  • 1/2 tsp ground chipotle
  • 3 bay leaves

I am not a precise cook, OK?

Approximate process:

  1. Put all the lentils on to soak in cold water, stirring and changing the water occasionally. This is mostly to clean off a lot of what I guess is mostly lentil dust off them but tends to give them a slightly unpleasant floury flavour.
  2. Slice the onions
  3. put them in the pressure cooker with the butter, salt and sugar
  4. Let it come up to pressure
  5. Wait 5 minutes then get a phone call
  6. Panic and take the pressure cooker off the heat because I still don’t entirely believe it’s not going to explode
  7. Spend about 15 minutes on the phone
  8. Put the pressure cooker back on the heat, leave it for another 10 minutes
  9. Observe that those onions do indeed look very nicely caramelized, and also are swimming in a delicious looking mix of butter and their own juices. I’d probably have put them back on for a little longer, but they were going to cook more in the soup and I was in a hurry.
  10. Add all the rest of the ingredients – stock, lentils, spices, etc.
  11. Let it come back up to pressure (this took a while, mostly due to time it takes to boil that much liquid) then wait another 20 minutes
  12. Observe giant pot full of tasty soup
  13. Serve with crumbled feta and white sourdough bread

This was really good soup. I had seconds despite being full from the firsts and was late to the pub as a result. Totally worth it.

I mean, this would have been tasty without the pressure cooker too, but the novel thing about the pressure cooked soup was that the cooking was really even, much more thorough that I’d normally have got for the amount of liquid lost and took way less time and effort.

More experiments will need to be performed, but I think this pressure cooker and I are going to be friends.

This entry was posted in Food on by .

Open data and fair elections are incompatible

Due to, ah, reasons which will soon become apparent, I’ve been interested in opening up the voting data from elections which use more appropriate voting systems than FPTP. Unfortunately it turns out that this is a bad idea.

You should read the paper. It’s short, well written and very interesting. But the summary of it is that when you’ve got something like Majority Judgment or a ranked voting system like AV there are a lot of redundant bits of information in your vote – so much so that this means that pretty much any individual vote will be unique. Malicious parties can then force you to encode messages in your vote – e.g. by saying “Vote for this person first, then vote for the remainder in this distinctive order”. If they then have access to the anonymised set of votes cast they can look for that distinctive pattern in the results and thus confirm that you have voted as you were told to vote. Its absence proves that you didn’t, and its presence proves that with very high probability you did.

This attack is pretty universal – it holds for almost any voting system that allows you to express a complicated enough set of preferences to produce a fair result. I do however feel the need to point out that there is at least one fair voting system that is immune to this…

P.S. This post represents two new things I’m planning to try with this blog in the near future: More promotion of “this is a thing that I found interesting” that is a little bit better curated than you just reading my pinboard feed and shorter blog posts which just point something out rather than constituting a fully formed essay. We’ll see how this plan goes.

This entry was posted in voting on by .

Etiquette for the devil’s advocates

Devil’s advocacy is when you take a position you do not believe in order to have a debate over it to explore the idea. It’s a really useful tool for exploring ideas that you want to think through.

Unfortunately, it has quite a bad reputation, especially amongst feminist circles (who are particularly used to having it used badly against them). Given the way it’s misused, it’s an entirely deserved reputation.

Fundamentally I think there are two major types of misuse that lead to this: The first is that many people who say they are playing devil’s advocate are not, in fact, playing devil’s advocate: They are using the claim that they are playing devil’s advocate in order to avoid being held accountable for their beliefs. Secondly, people fail to realise that often even if they do legitimately want to play devil’s advocate, it is not always going to be welcome.

I think this is a shame given that when it’s used properly it’s an extremely useful technique, so I’d like to propose the following as the basic etiquette required for playing devil’s advocate usefully and politely. It’s mostly “use words honestly” and “behave with common courtesy”, but given the existing usage patterns it seems to be helpful to spell out specific applications

  1. Be honest about your devil’s advocacy. Do not use it as a cover for just arguing for beliefs you actually hold but don’t want to be held accountable for. You are only entitled to play devil’s advocate for a position if you do not hold that position.
  2. Never play devil’s advocate without explicit up front consent from the person you are discussing things with. Something along the lines of “I would like to explore this issue. Do you mind if I play devil’s advocate for a bit?”. Be prepared for the answer “Yes I do”, and if you get it don’t argue. Also remember that, as always, consent can be revoked as well as granted – if someone asks you to stop after previously having agreed then stop.
  3. Don’t even try to play devil’s advocate in emotionally charged situations – e.g. when your position is going to be “I know you’re upset, but have you considered things from your attacker’s perspective?” this is never going to go well and you shouldn’t even try.

If you follow these rules, you’re both dramatically less likely to upset people and more likely to have productive conversations. This seems like a good thing, so I’d encourage you to do so unless you like having useless conversations where you upset people.

PS. Anyone who response to this post with hilarious comments which declare they’re “just playing devil’s advocate” will be responded to solely through the medium of “Your argument is invalid” gifs.

This entry was posted in Uncategorized on by .

New testmachine release

As you might have noticed, testmachine development stalled for a bit there. It wasn’t through a lack of interest – it’s been a mix of illness, busyness and being stuck on a thorny problem.

The thorny problem in question being subprocesses. It’s really important to me to be able to run testmachine programs in a subprocess, because my major use case for it right now is testing intmap, which is full of internal C assertions. One of the major benefits of generating tests with testmachine is that it can find ways to trigger those assertions (fuzzers love assertions), but if the process crashes before they can usefully reduce the test case the results are… unhelpful.

The reason this has been a hard problem is that testmachine is quite stateful, and synchronizing that state across the process boundary is quite painful. I knew how to do it, but it was going to be a lot of work and felt very inelegant.

Fortunately, on Wednesday, I realised I didn’t have to!

Despite the relatively constrained main interface to it, the internals for testmachine are pretty general – there’s a context object which gets passed around and maintains a bunch of state (a number of stacks of variables, and a random number generator), and languages and operations are essentially free to manipulate that state arbitrarily.

Well, I’ve added two constraints to that which have made life vastly easier:

  1. A language may only depend on the heights of each stack, not the values in them
  2. An operation must be able to predict its stack effect without knowing what the values on the stack are (by providing a simulate method)

Given these two constraints the result is that we can simulate the execution of a program in a safe way without invoking any of the dangerous functions – we can run a version of it that calls simulate instead of execute, accurately maps the variable reads and assignments of the program, and provides us with a nice pretty output without having to worry about our program randomly crashing in the midst of its compilation process. We can then run the version that actually executes the code in a subprocess and safely let it crash.

I would expect the new feature to be a little ropey right now. I’m aware of at least one problem with it that I’ve yet to fully resolve (It makes assumptions about how you use the randomness that hold if you use the main interface but are not guaranteed by the internals). But it passes testing, is off by default and is a pretty useful feature, so I’m pushing it out now. Let me know if you have any problems.

This entry was posted in Uncategorized on by .

How to write good software

I have a thesis on how to write good software that I would like to persuade you of. It’s not an easy process to follow – indeed, much to my shame, I have never successfully followed it, but I think that if more people tried to follow it it would gradually become easier to achieve, and at the end of it what we would have would be a much better software ecosystem.

It’s a bit of a complicated thesis though, so I’m going to have to ease you into it. Lets start with two hopefully uncontroversial premises:

  1. Anything you do that you did not set out to achieve is achieved by accident
  2. You are more likely to achieve things if you do them deliberately than you are if you do them accidentally

In particular, if writing good software is not your goal then it is something that happens by accident. Thus if writing good software is not your goal, you are less likely to write good software.

This seems fairly plausible as a starting point.

But now I would like you to ask yourself: When waas the last time that writing good software was your goal?

Thought of it? OK.

Now I’d like to ask you this:

Was it really your goal?

Consider the following three scenarios:

  1. I could spend time working on making our software more reliable for our existing users, or I could spend time exploring this cool new feature that adds way more valuable IP and will probably add like 2% to our acquisition price.
  2. I could spend time on making our software more reliable for our existing users, but actually our existing users are pretty much a captive audience, but if I add this feature we can capture 10% of the market from our competitor software.
  3. I could spend time on making our software more reliable for our existing users, but actually I’ve written just about all the papers I can on this idea, so if I want to have something to write about I’ll have to go do something else.

Which branch of these decisions do you think people are likely to take? Which branch do you think would produce better software?

Sure, sometimes adding that feature will produce better software because it will radically change the utility of your system, but if you’re making these decisions over and over again, you’re probably going to be producing some pretty awful software.

Sure you might want to produce better software, but ultimately that isn’t your goal. Or at least it’s not your organisation’s goal. You can subvert the organisation’s goal to a certain degree, but if you subvert it too far then you’re not doing your job and you get fired. There is room for a certain amount of individual subversion, but as a group it only goes so far before the corporate overmind realises that its drone are deviating the company realises one of its teams are off-mission and they step in to do something about it.

A long time ago when I was young and naive and working for a company I shall not name I had a conversation with a colleague I shall refer to as B. It went roughly as follows:

Me: We write really buggy software. We should probably not do that.

B: Why?

Me: Well, bugs are bad. They make users unhappy.

B: Great. That means they’ll pay us to fix the bugs.

To the best of my knowledge this was not an official company policy, but it was still remarkably educational in terms of how incentives work.

This is the thing: When your goal is to make money, you will generally speaking do the thing that causes you to make money. While the idea of a corporate obligation to maximize profits is nonsense, nevertheless generally speaking behaviours which cause you to make more money will be tolerated and behaviours which cause you to make less won’t. You can add other constraints, such as morality and good taste, but generally those constraints will be rubbed away at the edges by the structure of your incentives.

Further, money breeds money – by increasing your wealth you increase your capabilities, which increases your ability to make more money. So by constraining yourself you are in danger of ceding the playing field to someone who hasn’t – if they decide they want your share of the market they will usually out-compete you by being able to throw money at the problem.

Sometimes this is not harmful to the goal of producing good software. It can be the case that the best way to make money is to write good software.

But normally the best way to make money is to write good-ish software. You know that thing where getting 80% of the way there takes 80% of the work and then the remaining 20% takes the other 80% of the work? Well, it turns out that users are probably not going to pay twice as much for something which is only 25% better (100% / 80% = 125%). Especially now that we’ve been doing this for decades and have conditioned them to believe that this is just what software is like. And investors and acquiring companies? They literally couldn’t care less. You think they use your software? Nah. They just care about the IP, the talent, and the data you’ve built up. Turns out none of that relies on quality software.

“But David!”, you cry. “What about open source? Doesn’t open source solve these problems? Can’t we write quality open source software?”

So first off, it’s worth noting that regardless of whether we can write quality open source software, the reality seems to be that we don’t. Consider Linux on the desktop vs OS X or even Windows. Sure, I use and sorta like it, but I don’t think I could keep a straight face if I tried to tell you it was higher quality.

But secondly… this is one of the major misconceptions of open source. You know what a successful large open source project looks like? It looks like one where a great deal of money has been spent on its development. Successful large scale software development needs a whole bunch of people spending a lot of time working on it, and it turns out that people need to eat. And it turns out that in order to eat you generally need money. So open source development succeeds not as a way for individuals to collaborate on making quality software, but as a way for corporations to collaborate on mutually making more profits. This makes the incentive structure of open source remarkably similar to the incentive structure of  proprietary software.

There’s of course a second type of open source – the small single (or at most several) person project which does one very specific thing. Most commonly exemplified in the ecosystem of libraries that most programming languages have.

Given the average quality of those ecosystems, we’re still not producing much evidence that we can write good software this way.

The thing is, in order for this to result in good software, the author must:

  1. Have enough free time to work on it
  2. Care enough about the problem that they will devote as much of their free time as they need to to work on it
  3. Actually want to write quality software rather than just software which scratches their own itch
  4. Actually be good at writing quality software
  5. Understand the user base of their software well enough that their idea of quality lines up with their users’ ideas of quality

It definitely happens. There are some pretty good libraries out there maintained by one or two developers apiece. But these people are basically unicorns, and relying on an adequate supply of unicorns is probably a sign that your approach is in trouble.

And even if we could solve this problem it still wouldn’t be good enough, because most problems are too large to be solved by individuals and need teams working on it.

So how do you write good software? You get together teams of talented people, you give them the capability to work on it without worrying about where their next meal is from, and you give them the goal of producing good software. You do this without them having to worry about their project drying up due to lack of funding, or the source of their funding telling them yes it’s very nice that they want things to work but maybe could they make them work now?

So, now that we’ve smashed the capitalist structure of dominance done away with the corrupting influence of financial incentives produced an environment in which people can focus on the task of writing quality software, are we done?

Oh, if only.

Lets recall a line I slipped into a bullet point list up above. In order to write quality software you need to “Understand the user base of their software well enough that [your] idea of quality lines up with [your] users’ ideas of quality”.

How well do you think that currently happens?

The answer is that it happens in exactly one case: When your users are exactly like you. Sure, you can, do and should talk to your users and find out what they’re like, and in the course of doing so you may educate yourself into seeing through their eyes to some degree, but ultimately your vision of what quality software looks like is deeply tied in with your view of the world.

One of the core features of the feminist concept of privilege is that your view of the world is intrinsically shaped by who you are and what you’ve experienced. If you’ve not experienced a problem, or don’t know anyone who has experienced that problem, then you probably don’t see that problem as acutely as those who have (and may not see it at all). This is how we end up with software that only works in certain time zones, or doesn’t handle foreign languages, or imposes a real name policy, or asks for your gender as “Male or Female?”. The authors didn’t experience those problems, so didn’t think they mattered.

(This is also a function of financial incentives: e.g. If < 1% of our users are non-binary and we can save effort on data modelling and do a bunch of “charming” gendered things for ad targeting if we just ask male/female, which way does the path of more money lie? Unicode is hard, and if we’re not interested in the foreign market, which way does the money lie? But we’ve already solved that problem, right?)

As we’re fond of smugly declaring as an industry, software is eating the world. More and more things are getting automated, and more and more automation is going to be just a function of software.

What does this mean? It means that our user base is everyone. Even if they’re not using our software, they’re using things that are using our software, or they’re using things that will be “disrupted” by our software.

Good software is software that makes lives better. If your software is making things worse it doesn’t matter how solid an execution it is. You may have written the best spyware engine in the world, but I’m not going to think well of you for it and I’m not going to call your software good.

So in order to write good software you need to understand your users. And your users are everyone.

So what do you do?

Well, I’ll tell you what you don’t do. You don’t assemble your team of software developers from a group that looks remarkably similar to the top end of the existing structures of social dominance. Because if you do then what you are developing is software that solves peoples’ problems in direct proportion to how well society already solves their problems.

Good software is not software which reinforces the entrenched power structure.

Look around your software company. If the team is any like the ones I’ve worked in, it’s mostly white, mostly male, mostly middle class. If you’re lucky you’re working in a team which is at least not perpetuating this problem, but the problem is so endemic in our entire industry that right now software absolutely is mostly written by the people who are socially more or less at the top (and mostly in service to the people who are actually at the top).

So in order to produce good software we need to stop doing that. Good software is produced by teams who represent the people they’re building software for.

So now that we’ve formed a socialist utopia removed the financial incentives that prevent writing good software and smashed the patriarchy solved the fundamental lack of representation in our industry, can we write good software?

Well, maybe. At the very least, now we can start to learn how.

This entry was posted in Uncategorized on by .