Failure

This one was a pretty mild failure, but I'm aiming to be more strict about these things to avoid spoiling my failure signal. I'd been going to bed pretty late recently, and I wanted to switch around to going to bed early. In theory I still had time to write my post before my deadline but I woke up too late. The whole point of setting myself up to post in advance (as per my recent prototypes) is to allow a buffer for these kinds of missteps, but I used that buffer up with last week's Unix post, which took way longer than I thought.

The immediate failure could be prevented by paying more attention to the impact that changing my sleep patterns has on my posting schedule, and in particular not relying on posting when I wake up. In general, I think these kind of minor failures are best avoided by sticking to my posting in advance habit, which should be easier now that I've removed the minor inconveniences associated with it.

Prototype Wrapup #21

Last week I made 5 prototypes, and this week I made 7. I'm pretty happy about that, but I'm aware that, as previously, the progress is easy to lose if I don't maintain the conditions that led to it. I'm still feeling good about prototype size, but I haven't put that much effort into making and releasing small projects which I think is key to keeping this working. Still, I remain cautiously optimistic.

Monday

This was part 3 of CouchDB scheduling (parts 1 and 2 were last week), and it actually works! I used it to write First class the day before, which was a good feeling. It is somewhat damning of Rust that it took over three hours to make a fairly simple web tool, whereas the same thing would have taken me at most an hour in Javascript, Ruby, Python, or really any popular web development language. I think the mismatch between Rust's focus on type safety and the web's total ignorance of it is partly responsible, but I also think there's a lack of library maturity that should right itself as the ecosystem expands.

Tuesday

In order to actually run the Couch scheduler, I needed to give it permission to access my server. I didn't want to use my regular account, so I made something to generate random user id/passwords the same way Cloudant does. Here again I ran into some substantial issues with Rust's web stack. The JSON encoder can't encode structs that contain a "type" field, because that's a reserved word. So I just generated the string myself. I hear a better JSON encoder is coming, but depends on unstable Rust because of some compiler feature etc etc.

Wednesday

Since my prototypes had picked up recently, I thought it would be nice to track them on my stats page. This turned out to be fairly complicated because I needed to recursively read out files and directories. I just threw more and more Promises at it until it worked, and although the result is fairly gross it worked well. I even got it to guess the project language based on (non-gitignored) file extensions.

Thursday

To make a ringtone loop in Android you need to make it an Ogg file and set some special Ogg metadata. I thought it'd be interesting to write something to do this. In the end it didn't work very well, because ever library that deals with Ogg metadata is either awful or incomplete. I very nearly used inline C++ in Rust before I decided I wasn't desperate enough. In the end I went with incomplete over awful and made something that sets a different metadata field.

Friday

As part of my Unix explanation post I spent a bit of time reading back through old Unix history. A hidden gem that I hadn't heard about was the face server, which would store and retrieve "ikons": small visual representations of people's faces. I thought it'd be cool to reproduce the look of these faces using Floyd-Steinberg dithering. My first attempt used Rust's image library, but I found myself fighting against its pixel representation too much to get anything to work.

Saturday

I had been meaning to set up my Ubuntu/Android side-by-side system again on my tablet. I'd previously wiped the tablet it was on and, since this was the third time I'd needed to write the bind-mount/chroot script that gets the whole thing running, I figured I'd count it as my prototype this time and commit the sucker.

Sunday

Part 2 of Floyd-Steinberg. This time I decided to avoid the clever typed representation used by the image library and just work on the raw pixels. This was much easier, though I ended up doing a fair bit of fiddling around with number types; the pixel data uses unsigned 8-bit numbers, but to calculate the accumulated error I needed signed numbers. To top it off, the numbers have to be multiplied by a fraction, so in the end I used signed 32-bit integers and did integer multiplication and division (the other option was to use floating point numbers). I'd forgotten how tricky math is in languages with actual number types.

Code DIY

a crossed wrench and computer keyboard

I've been watching a lot of YouTube DIY videos lately. Not because I'm looking to learn anything in particular, I just enjoy watching people make stuff. There's something really satisfying about following along as experts do what they're good at. These days it's mostly videos from Matthias Wandel, but I can trace the feeling back to the old Junkyard Wars series. I'm also a particular fan of Adam Savage's One Day Builds.

It'd be really interesting to try to replicate this experience with software projects. While there are a lot of tutorial videos, I find them too heavy on education and light on entertainment. What I'd really like to see is a focus on interesting projects: take some idea and run it from concept to completion in a day. You'd document the steps, but not with the goal of completely explaining every technical detail, more like giving a general idea of the process and the tools involved.

The tricky part would be making the code interesting even for people who don't know a lot about code. The real strength of those DIY videos is the way they strike a balance between being technical enough for a technical audience, but entertaining enough for a casual audience. Historically, that's not been a strength of software, but I think it could be done. You'd need to put effort into it in all of the stages: selecting interesting projects, explaining what you're doing well, and editing tightly to keep it compelling. Difficult, but not impossible.

And if you could pull it off it would be a really interesting contribution to the field. I think a lot of people don't engage with programming because you just hit this terrifying wall of interconnected ideas. There's so much to learn all at once before you get anything that works, and the tools are very unforgiving. This would be a chance to bring some shallow culture to creating software, to make it familiar enough to outsiders that it stops being threatening.

Plus if people will watch AIs play fighting games for hours, surely the bar can't be that high.

The apple's taste

a virtual apple

It's easy sometimes to end up lost in abstract ideas. Maybe time and free will are illusions, and what we're experiencing is just the inside of some monstrous simultaneous equation the size of a universe. Or maybe we're a simulation created by some advanced intelligence in a lab experiment, and they don't want to turn us off because it would be rude. Or maybe it's pure physics, and all the rules and labels we put on the world are arbitrary because everything's just particles wobbling at other particles. Interesting to think about! But... would the answer change anything?

In programming, it doesn't take much thrust to reach abstraction escape velocity. What if instead of representing a blog post as simple text, I represented it as a structured series of ideas with the words attached at the end? And then I could also represent the relationships between ideas, like one following on from another, generalising another, or being part of some larger collection. Everything could be made up of a mesh of ideas and relationships, which is way more interesting than just text. But is it more useful?

I've also found business people to sometimes get infected with a kind of blind fervor for some ideologically appealing concept without having any real idea of how it will actually work. We're going to remake publishing so it's social! Our interface needs to be super-intuitive, but also pop! It's kind of a greeting-card-generator-meets-Facebook-meets-Uber-but-with-cryptocurrency. Also agile! These are all definitely words, but how would you turn them into actions?

The problem with any of these lofty ideas is that, eventually, the rubber has to hit the road. You can have the greatest conceptual framework the world has ever known, but at the end of the day someone will have to sit down and press some keys on a keyboard. When they do that, which keys will they press? If your framework helps answer that question, fantastic! If not, even if it is a very interesting framework, you may have to concede that it's not actually contributing anything.

You're holding an apple, and as you bite into it you suddenly realise that you and the apple are really just parts of the same universe. The carbon in your body mixes with the carbon in its body, and who's to say those bodies were ever really separate in the first place? Your brain is you, your arm is you, the apple may as well be you too. And the ground, and the sky, and everything. We're all just debris from the same cosmic explosion, slowly making our way to the same final silence. Wow, what a moment.

But does the apple taste any different?

Papercuts

A letter opener in a stone

The Ubuntu project once realised that the main problem with Desktop Linux adoption wasn't usually that there was one big issue, but lots and lots of smaller issues. They started a project that they called One Hundred Papercuts. A papercut was a minor issue that most users would encounter in everyday use of Ubuntu. They set out to find and fix these issues, and ended up discovering thousands of them.

Why was this necessary? I mean, it's not as if the developers didn't know about these bugs; they used Ubuntu more than anyone else and were usually intimately familiar with its issues. But, in a sense, that was the problem: when you do something often enough, the minor inconveniences tend to stop being noticable. Either you work around them, or you just ignore them and eventually forget about them. This might be fine if you're already a committed enthusiast, but for a new user this assault of minor incoveniences is a great reason to go back to whatever OS you came from.

The funny thing is, it's actually the people who use a system the most that are most affected by its papercuts. If it takes a few minutes extra to copy a file once per month, who cares? But if you're doing it several times an hour, those minutes add up very quickly. This means power users are in the perfect position to improve the system. However, instead of adapting the system to their needs, they often adapt themselves to the system. It takes someone new and maladapted to even realise there's something wrong.

Beyond computers, there are a lot of things in our lives that could be called papercuts, that are bad in minor enough ways that we ignore them rather than fix them. But as our actions become associations and associations become habits, it becomes less and less likely that we'll ever change them.

So I think it's worth following Ubuntu's example by taking inventory of these papercuts and setting out to fix some of them. You don't even need to fix everything, even hitting a few of your most frequent inconveniences should be enough to make your life easier.