Author Archives: david

Programmer at Large: What’s that noise?

After Sam and I had chatted for a while I returned to a pod to resume work. I settled in and brought up my work space and began to review where I was.

My particular troubles of the moment had all started with a bug report:

Reported-By: jad-nic [上子/Kamiko]
Title: What's that noise??
Bounty: 400 millivote.
Body: Every now and then there's a weird noise coming from behind the interior wall
in Pod 11. It's a sort of WHOOSH followed by a flushing noise and a gurgle. I've heard
it three times now, about a megasecond apart each time [timestamps attached].

It's not a big deal but I keep worrying about it. Could someone check it out and
figure out what it is? Fix it if it's easy or important, but I really just want to
know what's going on.

The bounty wasn’t huge, but it was a pretty decent amount. It was nice to encounter people who actually cared about plumbing.

While reviewing I made a note that I should say hi when we were both awake at the same time. It would get ship off my back a bit, and they worked in hydroponics so we’d have plenty of things I was actually good at to talk about.

Anyway, nobody from the official plumbing team was ever going to look at this – the ship is full of strange noises, and they’ve got much higher priority things to worry about. I don’t know offhand what but it’s basically guaranteed that if you work in plumbing you have high priority things to worry about.

But it sounded interesting (to me) and weird, which makes it exactly the sort of problem I get to work on. I love being a programmer at large, and not just because I have to talk to fewer people this way.

So before I last went to sleep I’d set up some monitoring on the microphones in the wall near the pod to listen for the noise then sample and bucket all the semi-relevant data before and after it. After a fifty megasecond nap I woke up to sift through what it had gathered.

During this time about 70 gigaprocesses in the plumbing system had crashed. A bit on the high side, but well within normal variation.

I’d picked the most plausible candidate – a process category with about ten thousand members, all of which crashed shortly before the noise and which normally didn’t crash in quite such a correlated way – and was now digging in to why it was failing.

Which was easy enough: It was appending data to some buffer on its local disk. The buffer was capped at quite a reasonable size – 512MiB, but the process just tried to grow the buffer past that and crashed when it couldn’t rather than doing anything sensible. Nothing very surprising so far, and the system handled it automatically by restarting the process from a fresh state with an empty buffer, at which point the whole cycle began again.

Unfortunately that left me none the wiser about what this process did, which is why I was now having to learn enough C++ to figure that out.

Subject: C++
Category: Programming language, text based.
Lineage: Pre-diaspora, began as a dialect of C in 1983.
Common Tags: Archaic, Esoteric, Low Complexity, Annoying.
Normalised Rating: Best not if you can avoid it.

The wiki entry on it was less than encouraging. Hopefully I was going to have to learn very much of it.

The relevant line where the process crashed was the following:

client->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(-1 == client->sock) {
    LOG_ERROR << "failed to connect to StatsD";
}

“Wiki, what’s statsd?”

“Historical records suggest that it was a centralised service for metrics aggregation popular in pre-diaspora software. The term subsequently became generic and many cultures use it or a derived word for the general concept.”

OK. So we have two questions now:

Firstly, why can’t it connect to statsd?

Secondly, what does logging an error have to do with appending to a buffer on disk?

Let’s focus on the proximate cause for now and start with the second.

“Ide, show me what this line with LOG_ERROR on it does.”

It expanded the results of the call. Ah. It wasn’t really a log at all.

“Ide, translation note: LOG_ERROR in this context may actually mean that it appends error data to a disk buffer and may not result in any logging occurring.”

“Noted”

“Wiki, what’s a file?”

“In the traditional software practices of pre-diaspora cultures, it was common to arrange a system’s data in a single named hierarchy of disk buffers. The term ‘file’ was used interchangeably for names in this hierarchy and the buffers themselves.”

“What? Why did they organise data that way? Didn’t it get confusing?”

“Historical consensus is that it probably seemed like a good idea at the time and that yes it did.”

“OK. So why is this logging call adding data to a file?”

“Many traditional software practices consider this to be how logging is performed. When problems occurred a human would inspect the contents manually to determine what had happened.”

“Did that work?”

“No.”

“Ugh. Is there a policy on what we do about this sort of archaic logging?”

“Either a separate process converts the buffer into log events periodically or we intercept the calls to write to the buffer and log them directly instead of writing them. Recent consensus is that the latter is preferable.”

The buffer was getting written to, so if we were doing anything about it at all then it had to be the first one.

“OK. Ide, do we have any other processes inspecting this buffer?”

“No, the buffer only grants access rights to the current process.”

I was starting to suspect I was fighting a zombie – a process that had no useful purpose any more but was still shambling around getting in people’s way and occasionally eating their brains.

“Ide, when was the last time someone looked at this process?”

“About 0.97 gigaseconds ago”

0.97 gigaseconds ago… oh no.

“You mean ship launch?

“No, about 5 megaseconds before ship launch.”

“Show me any annotation they left.”

From: nod-sid 1 [Tulela]
Subject: What is this?
Body: I don't know what this is doing. It looks like a zombie? Whatever,
the relevant systems all seem to be working fine and there's like a billion
things still to do for launch. Add figuring this out to the backlog.

Did you just tell me to go waste myself, Tulela? I believe I did, Arthur.

“OK, give me a snapshot of the buffer contents at point of crash.”

As I’d been starting to suspect, the contents looked like the following:

failed to connect to StatsD
failed to connect to StatsD
...
fail

fail indeed.

“Ide, can you automatically convert this code to do actual logging?”

“Yes.”

“OK, do so.”

“Done.”

I sighed. OK, back to the first question. Why can’t it connect to statsd?”

A socket was apparently another word for a network connection. So it was trying to create an outgoing network connection. The most likely explanation was obvious.

“Ide, does this process have rights to create network connections?”

“No.”

Right.

“Ide, show me what’s left if you remove all code that has no effect other than writing to a private disk buffer or can’t run without the process creating a network connection.”

#include <iostream>

int main(){
    std::cout << "Starting up event monitoring system!" << std::endl;
    return 0;
}

Right. Good. It was definitely a zombie and I was going to get to shoot it in the head. That was always satisfying.

So that left just one question: Why was this zombie self-destructing right before the actual event I was interested in?

“Ide, show me the most unusual function on the call stack at point of crash.”

void logAnomalousTemperatureEvent(double t_delta, double time_delta){
    ...
}

So the process crashing was never a cause of the problem at all. It was a symptom.

“Is there a corresponding set of interesting temperature events in our log roughly at the same time as these calls?”

“Yes”

OK. So, in conclusion I had learned two things:

The first was that this was definitely a zombie and was not giving us a useful signal we didn’t otherwise have here, but at least I could kill it.

The second was that this whole thing was otherwise a complete waste of time.

From: vic-taf [Arthur]
Subject: Zombie monitoring service in the plumbing system
Priority: Low
Proposed action: Staged shutdown of service '077a58e24e34b6543da8100c8541a8dd'
Body: This service doesn't do anything and and as far as I can tell has
never done anything except create noise. Development log attached as evidence.

(This chapter is also mirrored at Archive of Our Own. If you liked this and want to read more like it, support my writing on Patreon! Patreon supporters get access to early drafts of upcoming chapters. Although honesty compels me to admit that right at this minute there are no drafts of upcoming chapters available. I’ll probably write more this weekend)

This entry was posted in Fiction, Programmer at Large on by .

Upcoming reduced publishing rate and Patreon

Historically I’ve had a bit of a problem: Blog posts either get finished immediately or die. My drafts folder is more or less a wasteland of things I’ve never finished and am never going to finish, so almost all of my blog posts get written and published in one sitting.

But the recent experiment with Programmer at Large has made me realise the obvious solution that somehow in more than ten years of blogging it never occurred to me before that I could do.

Which is that I can finish the blog post and then not click publish.

Yes I’m embarrassed that I didn’t think of this before too.

The result is that instead of a wasteland of unfinished posts, my drafts folder becomes that place where I have a buffer of things that are ready to publish at any time but if I want to I could spend some time editing and improve a bit first.

Then, when it’s time to publish a post, I can just find an example from the queue which I like and click publish on it. Done. Yay. I can also shortcut and publish something new immediately if I like, but I don’t have to.

So I’m going to do this. It’s going to be great.

What this means for you, dear reader, is the following:

  1. Expect post quality to go up because more editing will be happening
  2. Expect post rate to go down to more or less precisely track the Beeminder goal rate (currently 1.48 posts per week – it’s derived from the monthly Patreon income).
  3. If you want more than that, donate to the Patreon. As well as increasing the publishing rate, I’ll be sharing drafts on the Patreon feed with anyone donating $2 or up. I’ll share these as soon as I have a first draft I’m more or less happy with, so they’ll go up more or less at the level of finished that blog posts currently go up at.

Despite the link to Patreon, this isn’t just me holding my blogging to ransom for money. One of the things I’ve been meaning to work on for a while is my ability to edit prose – I’m much better at writing the initial draft than I am at editing – and this is a great way to start working on that.

This entry was posted in Admin on by .

Programmer at Large: What’s your name?

(Previously. Also, this chapter is mirrored at AO3)

I kicked off down the corridor, caught myself at the entrance and hooked my way into the common area, pausing briefly on the central cable near the entrance to have a look around.

Near me some programmers at arms were having an animated conversation – something about Nash equilibria – while further down there was a larger group hanging off each other in an amiably silent cluster. On the other side of the shaft from them,  two pairs were deep in conversation. I recognised most of the faces, but nobody I was that close to.

Fortunately, I didn’t have to interact with any of them just yet. I was here for a meal, which gave me a solid excuse: I like to eat alone. It’s a registered eccentricity. Sure, it makes people think I’m weird, but having it registered means they don’t think I’m being anti-social.

I pulled my way along the cable to the end of the room, grabbed a pouch from the dispenser,  and bounced back to hook myself on about halfway down – not far enough from people to seem standoffish, not close enough that I might have had to interact with them.

Yes, I know I have a problem. I’m working on it, OK?

The meal had a bit of an odd flavour. The yeast was… well not exactly bad, but there was a musty flavour to it that definitely wasn’t good. I made a note about it and my HUD informed me there was a vote on the subject.

Apparently there had been a harmless contamination of this batch. The vote was whether to dump it and cycle in a new one, or just eat our way through it until it was finished.

I spent some time looking through the predictive models – it wouldn’t really strain us. The reduced resources would mean we’d probably have a couple people go to sleep until they were back up to standard, but we’ve got about 400 megaseconds to destination so there’s plenty of time to go around.

So, why not? We might as well ditch it. I expressed my intended vote and preference strength, my tactical assistant suggested a figure, and I approved it. Done.

As was my meal. Which, sadly, meant that I was going to have to talk to people. I called up the matchmaker and started to ask for suggestions but, thank the Plan, I was saved from having to deal with it by … ugh, let’s go with “Zod-Bim”, sailing in through the doorway.

I sighed slightly and waved at them anyway.

Their response was more enthusiastic. They grinned broadly and practically launched themselves across the room at me. They arrested their momentum by grabbing onto my shirt, hooked in next to me, and then cuddled up close. We cheek-kissed hello.

My HUD made an approving notification at the social contact.

“Arthur! It’s good to see you! It’s been megaseconds!”

(HUD flashed the correction that it had in fact been four hundred kiloseconds. We both ignored it).

“Good to see you too, Zod-Bim”

“Zod-Bim? I have a registered use-name you know.”

“I am not going to call you Ghost Walker 5000.”

“Oh come on. How would you like it if I called you Vic-Taf? I thought we were friends!”

“Arthur is an entirely respectable use name. Ghost Walker 5000 is a terrible cartoon character from an inappropriately antisocial grounder culture.”

“Ghost Walker 5000 is a timeless classic with a lot to teach us!”

I sighed dramatically and buried my head in their shoulder.

“Ghost Walker 5000 is a shallow drama about a hapless individualist who bounces from problem to problem, flails around for a few kiloseconds and then ultimately solves things with violence.”

I solve things with violence.”

“You solve things with tactics. Ghost Walker 5000 hits people with their fists.”

“I hit people with my fists too!”

“Krav Maga practice isn’t the same!”

Zod-Bim sighed dramatically.

“Fine, be like that. You can have a boring person use name for me. Go ahead, pick one. I don’t care.”

That was not an answer I was expecting. Even with the casual attitude Zod-Bim has on the subject, picking someone else’s use name is a big deal.  I hadn’t thought we were that close friends. I didn’t even know where to start, so I asked the system to suggest a couple names and had a quick look over them to get some ideas.

“I’m waiting…”

“Wait you want it now?

“Well you can’t very well keep calling me Zod-Bim until you’ve picked the perfect name, can you?”

“Ugh. Fine.”

I asked for a couple good suggestions with an affinity to my use name – if I didn’t have time to do it properly I was at least going to make it a bit personal – and picked the third one because I thought it would amuse them.

“How about Sam?”

“Wait, I can be Sam?”

I checked with wiki.

“System thinks so. You couldn’t be sam-sam, but with just one byte there’s no ambiguity.”

“Amazing! I’m Sam now!”

My HUD flashed up a notification that Zod-Bim had added a new use name, along with congratulations on the positive social interaction and a cautionary note about the dangers of pairing. I dismissed it.

“So, Sam, what have you been up to?”

“Oh I have had the worst time of it recently. That lot over there” – they waved to the group near the door – “have been hogging all the war simulator time, so I’m mostly just teaching Krav Maga classes at the moment.”

“Why is that bad? Didn’t you just say you liked hitting people?”

“Yes but these students are terrible. It’s like they learned to fight by watching Lesbian Space Pirates.”

“Didn’t you learn to fight by watching Lesbian Space Pirates?”

“Hey! That’s slander!”

I seized up. They were right, it was totally untrue, and now they were going to hate me and I was going to get voted off the ship at the next destination and-

“You’re right, I’m sorry, I, uh, I’ll go I”

I started to pull away towards the door but Sam grabbed me. At about the same time I finally noticed my HUD was flashing a giant “THAT WAS A JOKE STOP PANICKING THEY AREN’T OFFENDED” symbol in my face.

“Waste it, Arthur, I’m sorry. That was stupid.”

I tried to brush it off, but allowed myself to be pulled back into their embrace.

“No, no, it’s fine. I should have realised that was a joke. I’m the one being stupid.”

I breathed deeply, trying to will my heart rate back down below two beats per second and repeatedly telling myself it was fine, just a false alarm, and trying to relax.

“You’re right. You are being stupid.”

I froze again.

“What?”

“I didn’t learn to fight from watching Lesbian Space Pirates. I learned from bod-qof 11, one of the greatest Krav Maga experts in the crew’s history!”

And relaxed again. I could tell I was being deliberately distracted of course, but I went along with it. They meant well, and if they were trying to help me I probably really hadn’t bothered them and they weren’t going to hate me.

“OK, fine. You didn’t learn to fight from a grounder TV show. I was wrong. I get it.”

They learned to fight from watching Lesbian Space Pirates.”

What?”

“Oh, sure, they had a bit of help from the existing self-defence classes and a few millenia worth of VR martial arts training programs… But they started with Lesbian Space Pirates.”

Voice stress analysis on HUD didn’t give any indicators that they were joking.

“You are joking, right?”

“No! You mean you don’t know about the grand martial history of the Eschaton Arbitrage and how it was all started by the Lesbian Space Pirates?”

“I, uh. Let’s assume that I don’t.”

“Right, that’s it. You’re coming to the next movie night, and we’re showing you the documentary.”

I tensed a bit and they backpedalled slightly.

“Uh, if that’s OK of course.”

“No, no, it’s fine. I’d like that.”

Movie nights aren’t too bad. They count as a group social activity but I mostly don’t have to talk to anyone. The system knows about the loophole of course but as long as I don’t use it too often it’s fine with it.

“Right, good. It’s decided.”

A calendar invite flashed up and I accepted it.

“Anyway, let me tell you about what these useless trainees did…”

(Like this sort of thing? Why not support my writing on Patreon! As well as a warm glow from supporting something they enjoy, backers get access to early drafts of upcoming chapters.)

This entry was posted in Fiction, Programmer at Large on by .

How to make good things

I like to make things that are good. Sometimes I even succeed.

I realised recently that there’s a pattern a lot of my successful attempts (and many of my unsuccessful attempts too. There is no royal road to quality) match that feels different from how other people often seem to go about doing this, so I thought it might be worth writing down and codifying.

As with all such patterns, this post is probably not literally true, but I think it might be quite helpful anyway.

So suppose you want to make something good? What do you do?

“Make” can be a fairly general term here. I use something like this technique for making recommendations to people as much as I do for creating new things. The creative examples are probably more interesting because they’re harder work and easier to get wrong, but I’ll use both for examples.

The system that I have more or less boils down to two main principles:

  • Start with examples of things that are good that you don’t want to make
  • Define rules for your project and stick to them until you can’t feasibly do so

If you want the short, pithy, advice and don’t care about why, you can stop here. The rest of this article is going to be about explaining where these come from, how they help, and how to effectively work with them.

These principles are mostly designed around the desire to take an unstructured creative process and lightly structure it in a way that doesn’t add much cost but tends to improve the outcome.

When trying to make something, I think most people rely on a fairly unstructured process for figuring it out, which results in a plan of attack that looks something like the following:

  1. Decide what “good” looks like for this problem.
  2. Make something good.

It’s not an unreasonable plan of attack, and in many cases it will succeed.

Examples of how applying this strategy looks:

  1. When recommending a book, just suggest a book you really liked.
  2. When writing software, ask people what their problem is and write software that solves that problem.
  3. When writing a story, come up with an idea for it and write that story really well.

All of these more or less succeed or fail on the strength of how well your skills fit the problem and how well you apply them to it: If your taste in books is a good proxy for the person you’re recommending a book to, you will recommend books well. If you’re good at writing software and understanding peoples’ problems you will write software that solves their problems. If you’re a good writer, you will produce a good book.

There’s a lot more to say about it than that, but it’s more or less besides the point of this essay. For now I will take it as read that if you’re good at what you do and you execute it well you will mostly produce something good.

Mostly.

The major problem with this plan of attack for me is novelty.

Often novelty makes the difference between something that is good and something that is merely OK.

Example: I actually really enjoy Elementary as a TV show, but I wouldn’t exactly describe it as good.

Because let’s be honest. We’ve seen this show before.

There’s nothing wrong with making the same thing over and over again. It’s a useful skill building exercise, particularly when you’re starting out, and often as a consumer of stuff I don’t necessarily want new and challenging, you just want something fun that you know you’re going to like.

But even within that some novelty is important:

For learning: Making the same large sort of thing over and over again quickly plateaus as a learning technique. Practising a skill repeatedly only works well if the problem is extremely small so you get fast feedback. At a larger scale if you’re not doing something substantially different you’re learning progressively less and less with each repeat.

For consumption: Even within the brain candy category, I think we overestimate how much we want the same thing over and over again. If we really wanted that we’d just watch reruns or reread the book. You know how an author’s second book is often a lot worse than their first book? It’s probably mostly not. It’s just that the spice that novelty added has worn off and you’re seeing a more “objective” measure of how good their work actually is.

So those are the reasons why novelty is Actually Important. It’s a stronger priority than that for me – I just don’t like retreading well explored ground – but even if you don’t go as far as me on that front novelty is still important.

(side note: This will probably prompt someone to send me a link to prior art for the subject of this post as a hilarious joke. Please do. I don’t read enough on this and I’d like to read more, but it’s hard to separate the wheat from the chaff so I often don’t bother)

So, the key to producing something good is novelty? Great. Let’s make something novel.

Unfortunately just setting out to produce something novel also doesn’t work. If you just seek novelty then you will probably fail at the goal of being good. Novelty is easy: Pick a bunch of random things (use dice or cards or computers because humans are bad at random), throw them together, see what happens.

What will usually happen is it won’t work. I can pick a random book and the person I’ve recommended probably won’t have read it, but they probably also won’t like it. I can implement this Facebook for Dogs in a custom Forth interpreter implemented in C using continuation passing style, but it will probably segfault and even if it doesn’t it’s still Facebook for Dogs. I can write a story about ten random characters saving the world from an attack force of flying cheese graters, but at best you’re going to get an absurdist comedy.

Even at milder levels, novelty can often be a trap: You get recommendations that are more weird than good, half-baked prototypes, or stories where the core idea doesn’t really work. (I have done all these things).

So you need to find a way to produce things that are both novel and good. Neither suffices on their own.

You can’t optimise for two things simultaneously, so you need to figure out a way to combine them. One way would be to allow the two to trade off against each other – some amount of novelty can be sacrificed for some amount of goodness – but I mostly find that produces results where you’re not very satisfied with it on either front.

Instead the way I like to think about this is that novelty should never be the goal, but it can reasonably be a constraint. You are not trying to produce something maximally novel, you are trying to produce something maximally good which is also novel enough.

This matches what we’re trying to do much better: Goodness is the priority, but novelty is a necessity.

And the way to work for this is not to seek novelty, but to have a process that produces novelty automatically while you work on making it good. Fortunately, I have one of those to share with you.

The basic starting point is to take this idea of novelty as a constraint and modify the starting procedure as follows:

  1. Decide what “good” looks like here.
  2. Make something good that is also novel.

Note: This is a bad plan.

The problem with this plan is that the constraint “it should be novel” is too fuzzy. Fuzzy constraints are the enemy – they either get compromised on as you work or you constantly second guess yourself about them. If you try to follow the above plan you will usually end up with something where you’re not really sure it’s good and you’re not really sure it’s novel (regardless of how good or novel it actually is if you’re anything like me on this front). You end up with something mostly like the attempt to optimise for the combination of both but with more self-doubt.

The following refined plan is better:

  1. Decide what “good” looks like here.
  2. Decide how what you make will be novel.
  3. Make something good that is also novel in the prescribed way.

This is better. It solves the fuzzy constraints problem by making them non-fuzzy.

But it’s still not great. The problem is that it forces you to perform most of your novelty up front when you least understand the problem. That’s not really how creativity works – often the most interesting ideas will only occur to you after you’ve been bashing your head against the problem for a while.

But you can get around that quite easily: The idea is to not come up with a specific novel feature out of thin air, but instead to create constraints that when satisfied will automatically produce novelty.

That is, instead of deciding how what you make is going to be novel, you invert it. You decide how it won’t be like the prior art.

You do this by producing a set of principles with which the work must comply, generated by something that looks roughly like the following algorithm:

  1. Pick some prior art you like.
  2. Find something about it you don’t want to emulate. If there’s something about it you actively don’t like then that’s great, use that. If not just find some other way it would be interesting to be different from it.
  3. Create a simple rule that splits the space of possibilities on an interesting axis and avoids that thing.

Iterate this, each time picking prior art that satisfies the rules you have so far, until you’re bored of doing this or you can’t think of anything you like that doesn’t satisfy those rules.

Here are some examples of me doing this:

  1. Recommending fantasy that is not like Tolkien and doesn’t contain elves.
  2. It is really annoying when QuickCheck and similar fail in erratic ways, so Hypothesis takes as a core design constraint that when you rerun a failing test it should immediately fail with the same error as before.
  3. In Programmer at Large, in order to avoid it being like just about every other nerd power fantasy book (which, to be clear, is a genre that I totally read and enjoy as a nerd with power fantasies), the protagonist is specifically designed to not be especially brilliant or competent and just be run of the mill good at their job.

An important thing to note is that you are not picking prior art that is bad. You are picking prior art that is good. It’s easy to pick on examples you hate, but it won’t produce nearly as interesting results. Just trying to avoid being bad is a recipe for mediocrity. The key here is that we’re trying to be good but different.

This solution almost works, but it has two failure modes that it needs adapting to avoid:

  1. You might fail to produce something that is both good and satisfies the rules (either because you couldn’t satisfy all the rules at all, or because you could but the result wasn’t very good).
  2. You produced something good that satisfied the constraints but it turns out to not be all that novel and in fact is quite similar to something that already exists in ways that annoy you.

The second is only really a failure mode in the sense that you’ve produced something no better than the original method: You’ve still produced something good, even if it isn’t novel enough. You might be happy with that. One worry is that you could have produced something significantly less good than you otherwise have without the constraints, but I don’t usually find that’s a problem – often solving in a constrained problem domain is just a good way to make you think about the problem harder and produces results that are better even when they’re not novel. The relation between creativity and constraints is so well trodden at this point that it’s practically a cliche.

This also tends to mean that in the first failure mode the case to worry about is not really “I produced something that satisfied these constraints but it wasn’t very good”. It’s not that that doesn’t happen, but it tends to happen much less often than you might expect. The real thing to worry about is that you’ve made life too hard for yourself to come up with any solution to all the rules – either because none exists or because it’s too hard to find.

With both of these failure modes you can solve this problem by restarting the process and changing the rules – if you couldn’t satisfy them, figure out some relaxed or different rules. If satisfying them produced something very novel you now have a couple new examples to try to exclude!

Depending on how hard the process is, this might be a perfectly reasonable thing to do. If you’re recommending a book or working on a problem you can solve in an afternoon, this is probably fine. With larger things you can also use whatever is left over from the first iteration as as raw material to stop you from having to start completely from scratch.

But even when restarting isn’t that expensive, it’s probably still best not to do it two much.

The “not actually novel” trap is hard to avoid when you don’t have a good idea of what exists. The best fix for this is familiarity with the prior art, but you can also outsource this – if you can’t think of examples satisfying your rules, ask other people for some! Then become familiar with those examples.

For avoiding the trap of creating too restrictive rules, I find that it’s useful to maintain an existence proof as you build your rules: An example that satisfies all the rules you’ve got so far. This can be an existing thing, or a sketch concept of how you could satisfy the rules. When you add a rule you either pick one that the existence proof satisfies or one where you can find a new example satisfying it and all the existing ones.

The reason why this works and isn’t the same as just solving the problem as you go is this: Your existence proof doesn’t have to be good. In many ways it’s often better if it’s bad because that gives you a starting point for the next part of the creative process: Why is this bad and can I fix that?

Instead you can just solve it through brute force: Solve the problem directly in front of you and do the simplest thing that can possibly work without thinking about the bigger picture. All you’re trying to do is show that a solution is possible, not find a good one right now.

I think of a lot of the early versions of Hypothesis as being like this. The modern implementation of Hypothesis only became possible because it passed through a number of intermediate solutions that were kinda awful but demonstrated that a solution was possible.

So, to put this all together:

  1. Maintain lists of rules along with accompanying reference examples, which starts empty, and an existence proof, which is any example of the thing you’re trying to create that satisfies all the rules (regardless of whether it is good or not).
  2. Come up with an example of something you like that satisfies all the existing rules. This might be your existence proof or it might be something else. If you can’t think of one, ask people. If they can’t think of one either, proceed to step 4.
  3. Come up with a simple rule that excludes the example you came up with, along with an existence proof that it can be satisfied along with all your existing rules (this may be your existing existence proof). Add the rule to your list along with this as its reference example, update your existence proof if necessary, then go back to step 2.
  4. Try to create something good that satisfies all the rules.
  5. If you created something good, check if you still think it’s novel. If it’s not, go back to step 2 with it as the example. If its, stop. You’re done. Congratulations, you made a good thing!
  6. If you failed to create something good, try to figure out what the rule or rules at fault were and see if you can modify them in such a way that they still exclude their reference examples but avoid the blockage you encountered. Then go back to step 2.

I very rarely (never, I think, though now that I’ve written it down I might try it) actually sit down and followed the above steps. I’ve probably never even done something that perfectly executed those steps implicitly – I’m much worse at searching the existing literature than that would imply, even though the results are usually better for it when I do – but I think they capture a core process pretty well nevertheless.

And that process is extremely beneficial. It forces you onto a path which seeks out novelty, and by doing so through creating constraints it does a very good job of inspiring the levels of creativity that are required to create that novelty.

It’s also another technique that is very good for learning while doing. The focus on rules and constraints forces you to learn a lot about how the problem space fits together. Although it elides a lot of details in the steps (how do you produce something good within the constraints? How do you come up with a rule?), by giving you more focused questions to answer and explicitly exploring the shape of the problem I suspect you’ll learn a lot better than just seeking to produce something good will.

Ultimately regardless of how closely you follow the specific steps, I think the ideas here are important, and thinking in terms of them will help many and possibly most creative processes.

(And if you found this useful, and would like me to keep making good things on this blog, you’d be very welcome to donate to my Patreon for supporting my blogging to say so regardless of whether that’s novel)

This entry was posted in Open sourcing my brain on by .

Programmer at Large: What is this?

GNU GENERAL PUBLIC LICENSE
Version 9, 21 January 2089

Copyright (C) 2089 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

I stared at the words on my HUD. It wasn’t the point. I knew it wasn’t the point. But still… I had to ask.

“Wiki, what is this?”

“It’s the software license that the code is provided under. The GNU General Public License, or GPL, was a series of licenses widely used in pre-diaspora civilisations on Earth.”

“Elaborate. What’s a software license?”

“In large contiguous civilisations with strong contract law it is common that rather than selling software you sell licenses, which grant the buyer the rights to use the software in a particular way.”

“I don’t understand. Why would you ever buy that instead of the software?”

“Typically the software is not made available for purchase.”

“Why?”

“Because the sellers feel that that would limit their ability to sell licenses – the purchasers could simply turn around and undercut them.”

“No but why were they able to do that at all? Why didn’t they immediately get out-competed by people who were selling software?”

“I don’t have a short answer to that question. There is currently a 650 millivote bounty on this question, and I can provide you with several detailed ethnographic studies on the subject if you wish to attempt one?”

“No, never mind”

“OK. Would you like to leave a bounty?”

“Sure. Add, say, 5 millivotes to the bounty.”

“Done”

“What does the license require?”

“It requires that if you provide the software to anyone then you must provide the source code.”

“Sorry, what?”

“I don’t understand. What are you confused by?”

“How were people providing the software without providing the source code? Isn’t the software the same as the source code?”

“At the time that this license was popular it was common that the version of the software that would be provided with a license was in a purely binary form that allowed the software to be executed but not easily modified.”

“You mean they were just providing people with build artifacts?

“That’s correct.”

My skin crawled. You can’t crew an interstellar trader without some exposure to local cultures, and the nature of software archaeology is that you often have to understand the historical context in which things were written, but it’s rare to run into such direct evidence of outright perversion.

“Do people still do that?”

“Approximately 30% of planetary civilizations we visit engage in this practice, but it is commonly understood that it does not make sense for interstellar trade so we rarely encounter the practice directly.”

“Wow.”

The wiki is silent. It’s programmed not to respond to simple exclamations like that.

“Are we compliant with the terms of the license?”

“As far as we can be. Many of the terms of the license refer to concepts that no longer exist or apply to us, and the rest are automatically satisfied by modern software practices. It is generally felt that the creators of the license would be very happy with how we use the software.”

“But we wouldn’t be compliant if we deleted the license header?”

“That is correct.”

“Would it matter if we did it anyway?”

“No entity who could enforce the license still exists. However, the last experiment at removing it globally caused 4,197 build steps to fail, and a 11253CE vote in our inherited constitution declared them to be important cultural heritage which should be preserved.”

“OK, fine, but what if-“

At this point my distraction alarm pinged. I’d passed some threshold of deviance from my intended task and it was making sure I was aware of that.

I could override it – this was a lot more interesting than the mess I was supposed to be looking in to, and I didn’t really feel like spending the time it would take to learn whatever ancient grounder language this C++ was right now – but it was right, I was way off track.

Which probably meant my mind was wandering and it was time to take a break. I waved my HUD into casual mode and exited my pod to head for the common area.

Editor’s note: Obviously this is fiction. I’ve had some ideas for this floating around in my head for a while, and this is the first one that I made properly work. They’re essentially little slice of life scenes from a programmer aboard an interstellar trading ship loosely modelled off the Qeng Ho from Vernor Vinge’s A Deepness in the Sky, about what it’s like to work on a legacy code base that’s more than ten thousand years old. I’ll probably keep writing them, but I have no idea how often. Patreon contributions to encourage me to do so will of course affect that, but I’ll probably write at least a few regardless. I’ll also be mirroring this series on Archive of Our Own.

This entry was posted in Fiction, Programmer at Large on by .