There's a concept in test-driven development called red-green-refactor, which describes three distinct stages that your tests and code go through. The first step is to write your tests in such a way that they describe what you want your code to do. Your code isn't written yet, so the tests start off failing (red). The second step is to write just enough code to pass the tests (make them green). The final step is to rewrite your code so that it is nicer and solves the problem better, while still passing the tests. This is called refactoring.
In writing, you hear very similar advice, though not given in exactly the same terms. It's generally considered useful to write an outline before you start, so that you can structure your ideas without worrying about how exactly to write them. Then you should write. Usually, the best way to write is not to worry too much about getting everything perfect the first time, just spill your thoughts out as quickly as you can. In the third step, editing, you refine those thoughts and make sure you're expressing them the best way.
Why do this? In both cases, it's about separating out the different components of the task so you can focus on them individually. Tests and outlines both describe your goal without going into details, which allows you to focus on design. Writing, of either code or words, is best done without trying to do everything perfectly. Realistically, you can write more fluidly if you're not worrying about polish and minor details. More importantly, you learn a lot from the first draft that you can use in refinement. Finally, refactoring (or editing) is a deliberate process that is much easier to do with detachment once you're no longer stuck on just getting the thing done.
This is particularly relevant to me because I write a lot of both code and words. For a long time, I've wanted to find a way to make that writing easier and faster, and to give it a bit more structure. Test-driven development is something I know helps me to write more structured code. In particular, I find the way you write code when you have already gone to the trouble of thinking through the problem (with your tests) is qualitatively different; it's more structured and you tend to feel a greater degree of control over what you're doing. I'd love to find a way to bring that quality to my writing.
To test this idea, I thought I would just try writing something in the red-green-refactor style. To make it a bit more interesting, I figured I could record what I'm writing and have it play back. This should give you some idea of what it looks like to write to an outline and refactor later. I couldn't find any existing tools to do this, so I wrote my own. You can click the "replay" button below and adjust the speed slider to control how quickly it replays.
I've found it pretty useful to extend the red-green-refactor idea to writing. Certainly, it's been easier to write this particular post than others because I had a structured starting point and could focus on writing and editing separately. This let me get into a flow that wasn't interrupted by thinking about what I wanted to say, or whether what I was saying was polished enough. It strikes me that there might be other areas where this idea could be useful too. Really, anywhere where you would benefit from focusing on one goal at a time rather than trying to satisfy them all at once.
This is a loop I made using Tabletone. I hadn't been doing much music recently, but I enjoy it and I thought it would be worth getting back in the habit, especially given my recent thoughts on dabbling.
It's got a bit of a slow rock type vibe but with some weird synths and jungle drums in there. I also went for some sweet Hendrix-style lead guitar sound which I think came out reasonably well.
Man, I'd forgotten how hard steel strings are on your fingers.
The concept of hobbies is kind of interesting. A hobby is something you do because you enjoy doing it, but then that's also true of both enjoyable work and pure entertainment. A hobby is also something you usually don't expect to become your main activity or make much (if any) money, but if you ask an artist who is also working whether art is their hobby, they tend to get pretty ornery. Similarly, you might volunteer at a soup kitchen and enjoy it very much, but you wouldn't call it a hobby. I would argue that the definition of a hobby is something that could turn into a serious pursuit, but doesn't.
There are many people, myself included, who pick up an instrument for a while, mess around a bit, maybe take some lessons or learn a few songs on their own, and have a good time playing. However, they never go further than that. If you ask them "are you a musician?" they would say no. If you ask them "are you going to join a band or record an album?" they would also say no. Even given a direct opportunity for it to turn more serious, they would turn it down. Why? Because they're just messing around, this isn't meant to be a serious thing.
I question the wisdom of this limitation. If you enjoy something, why hold yourself back from the possibility that it could be something more than a frivolous pastime? Is your worst case scenario really that you play the guitar for fun, eventually get good at it, and then people enjoy your guitar music? That's a pretty mild worst case! Maybe you've already got other pursuits that take priority, but just because you're a part-time guitarist doesn't mean that you can't be a good one, or that you should deliberately avoid opportunities for it to go anywhere.
Dabbling is, it seems to me, another kind of liability shield. If you can find a way to separate what you do from what a professional does, if you can make it not serious in some qualitative way, you become immune to professional-level criticism. "Hey, your guitar playing sucks" – "joke's on you, I don't even really play the guitar for real". Problem solved. By cutting yourself off from the possibility of success, you also cut yourself off from the possibility of failure.
But what a sacrifice to make, to eliminate the chance that your pastimes could become important enough that people would judge you by them. And what a waste to take something you enjoy and cripple it out of fear that it could mean too much and make you vulnerable.
A year ago, I wrote Computers are special, about the reason why computing is qualitatively different from other disciplines. I said that computers are special because they provide an abstract unit of action which is transformative for the same reason that currency as an abstract unit of value is transformative. I'd like to take another angle on why computers are special, less in terms of relevance or practicality and more in terms of the power of computers as a theoretical construct.
It's common in programming to talk about software vs hardware, without really acknowledging how weird that is. If you're a builder, there's no software vs hardware, no "abstract building" that you make and later on figure out how to implement it in the real world. Sure, there's architecture, but even architects are fundamentally grounded in reality: the laws of physics, the properties of the materials, and the resources available. You can abstract as far as you want, but you can't abstract away the rules of the universe. At least, not in the universe we live in.
With software, on the other hand, you can create the truly abstract. I remember in high school I used to play text-based adventure games where you would type "north", "south", "east", "west", "up" and "down" to move around in 3 dimensions. One day, out of nowhere, I realised that you could have 4-dimensional space by just adding two more words (and an extra level to the array that stored all the world data). And, well, once you're there there's no reason the space needs to be Euclidean, you may as well be in a giant 4d hyperpretzel where you move twice as far in positive directions as negative directions.
I think one of the most difficult things to come to terms with once you get really into software is just how limitless it is. Mostly we use it for fairly mundane stuff because that's where the money is and that's what tends to be most useful. However, the real power of computability theory (and the point I was making in Computers are special) is that with an abstract unit of action you can really do anything, up to and including things that no human could even comprehend in their entire lifetime. There are infinitely many more programs that could be created than there are human thoughts to create them. It's dizzying.
A lot of what programming requires, at a high level, is managing that unbounded complexity. You need to tear big chunks out of the infinite possibilty space and whittle them into useful shapes. A lot of this work is done for you, and there are a great many problems that can be solved just by applying these existing forms, but sometimes you need to make your own. Doing this well is a very curious skill: you need to come up with something imaginary and, in a sense, arbitrary, but it still has to be useful. You can tell the difference between a good idea and a bad one because the useful one helps you with your other ideas.
The most similar thing I can think of is philosophy. I don't know if anyone has a great definition of philosophy, but I think of it as the study of ideas and thinking about ideas. There are lots of jokes of the anything-goes-in-philosophy variety but, as far as I've seen, philosophers are fairly serious about their ideas being useful. Not necessarily useful in terms of helping you do your shopping, but useful in terms of helping you think of or think about other ideas. That might sound circular or useless, but in programming at least you can definitely tell the difference, and useful ideas are amazingly valuable.
It's for this reason that I think of programming as applied philosophy. You create these abstract concepts, these ideas, intended to run on abstract machines that don't (and usually can't) exist in reality. It's no exaggeration to say that you're working directly in idea-space, and your main limitation is how well you can manipulate ideas and keep them clear in your head. Philosophy and mathematics have this quality too, but the difference is that they stop there.
With computers, your concepts leave idea-space and take a physical form. Your abstract machine is implemented on top of a physical machine, the software and the hardware come together, and your ideas turn into reality. That is why computers are special.
I've been vaguely following the US elections, which always leaves me with a sense of incredulity about the two-party system there as enforced by their lack of preferential voting. In many other countries, including Australia, you vote for multiple candidates in order, so you don't have to worry about whether your preferred candidate has the votes to win. If they don't, your votes are automatically redistributed to the next candidate according to your preferences.
Without preferences, you often suffer the spoiler effect, where a third-party candidate not only can't win, but actually hurts their own cause by running because they divert votes from their nearest political allies. Of course, this is a widely known problem covered in much more entertaining detail in CGP Grey's video on preferential voting. Despite this, there's very little motive to change the system because the people in power lose the most by changing it.
However, maybe the will of the incumbent political parties isn't necessary to change the system. Much like in my Copyright 2.0 idea, you can sometimes implement a new and better system on top of the flawed old one. Runoff voting works by repeatedly eliminating candidates, but there's no necessity that all the eliminations happen at the same time. In fact, the US presidential election could be thought of as the last step in a runoff voting system where all the other candidates have already been eliminated.
So what if all the independent parties got together and held one big preferential pre-election primary? Any registered voter could cast a vote for any party, just like in the real election. You'd do a proper preferential runoff calculation, and parties that were eliminated in this primary would drop out from the actual race. Once you're down to the final two parties, they contine on to the election. Smaller parties would want to be involved because it gives them a feasible shot at the election. Once established, the bigger parties would want to be involved because it's in their interest to win votes and eliminate the smaller parties.
It would be a pretty substantial undertaking logistically, but I can't see any theoretical reason why it wouldn't work. I think there are a lot of people and groups who want to see the US transition to preferential voting, including those with the resources to make something like this happen. Up until now the main dialogue has been about how to push that change through the existing political process, but maybe the better path is to go around it.