The Recurse Center testimonial
The Recurse Center is a three month long programmers’ retreat that I have been attending in New York City. The following is a testimonial about my experience.
There are eight elements of the Recurse Center.
First, it is unusually supportive and safe. You can ask a question to clarify something you feel you ought to know, because you will get a gentle, illuminating answer. You can write a piece of code that you worry is shitty, then shape it into something beautiful with a fellow Recurser. You are isolated from all the people whose opinion might matter to you: your friends, your family, potential employers, the internet. In short, there are no negative consequences to showing your weaknesses.
Second, it is structured. If you feel awkward in social situations, you find that you always have a place. When you program on RC days, there is always a desk to sit at. At the social gatherings, you discover that everyone at RC is kind and inclusive. No one is ever left standing on their own.
Third, RC is an uncontrollable situation. You are guided towards the things that it is important for you to work on. This invisible hand is the aggregate of the projects that other people are working on, the fellow students who walk up and offer to work with you on your project, the subjects covered in the RC library, the languages your fellow students discuss at lunch, the juicy problem your deskmates are wrestling with, and the gentle guidance of the faculty. This invisible hand plainly shows you what you have been avoiding learning, what you thought was too hard, what you didn’t know you needed to know, what you didn’t know interested you.
Fourth, it is a place where programming is the most important thing in the world. Imagine Florence in the fifteenth century, except, instead of painting, everyone is inventing how to program, and instead of being surrounded by Donatello and Ghiberti and Botticelli and Raphael, you are working with the startlingly sharp programmers who no one has heard of, yet. The fact that it is socially acceptable to think about programming and talk about programming and work on programming means that programming is uppermost in your mind. Which means that you get better at it very fast. (This element was copped from Paul Graham’s essay on aesthetic taste: paulgraham.com/taste.html)
Fifth, there are almost no constraints on what you work on. Your project doesn’t have to make money, doesn’t have to build your portfolio of open source code, doesn’t have to be useful, doesn’t have to appeal to some particular community, doesn’t have to be cool, doesn’t have result in something commensurate with the effort you put in. There is one constraint: work at the edge of your programming capabilities. Which is to say: work on something that makes you a better programmer.
Sixth, there are people who are better than you and people who are worse than you. Even if you are the most inexperienced programmer in the whole of RC, you certainly know more than others about a particular operating system. Even if you are the most experienced programmer, you certainly know less than others about a particular language.
Seventh, you get to talk to and work with people who have truly brilliant minds. Some are fellow students at RC. Some are drafted in as speakers or co-programmers. All are your peers.
Eighth, and most importantly, RC is an expression of the faculty: Sonali, Nick, Dave, Alan and Tom. They are the people you’d want teaching you because they explain things clearly and they know a lot. They are the people you’d want to be friends with because they are nurturing and fun and funny. They are the people you’d want to have with you if you got into trouble because they would impose themselves on the situation and start fixing it. In short, they examine their environment and make it better.
And:
Having David Nolen explain the ClojureScript compiler was one of the intellectual highlights of my life.
The hours at RC feel precious.
This is the fastest period of learning in my life.
I’m coming back.
The Recurse Center
I am spending the summer in New York City. I am attending the Recurse Center, a three month programme where the aim is to make yourself a better programmer. As a student, I spend most of my time sitting in a room with other clever people, either collaborating or working alone on open source projects. I am creating Isla, a programming language for children, and an accompanying environment for using Isla to write old school text adventure games.
Taxi Driver
I love this shot. Even though Travis Bickle is supposedly God’s lonely man, we know him as the subject of a Hollywood film. But, earlier in the film, in this shot, he is just another unremarkable guy, alone in the early morning, in the distance, swigging from a bottle of whiskey.
And I love how, in the “Are you talking to me?” scene, you can hear the everyday noise of people outside as Travis Bickle goes mad inside:
Tool
Tool and Mogwai made me realise that musicians are allowed to do anything they want.
But Tool had a stronger effect because they were my first real exposure to metal, which meant they were able to crystalise the most consistently important concept in my musical taste: beauty is harsh.
I first heard Mogwai in 1997, when I was about sixteen. I was lying in bed in the dark listening to The Breezeblock, Mary Ann Hobbs’s late night music programme on Radio One. She played Like Herod, a twelve-minute track from Mogwai’s first album, Young Team. I hadn’t heard music like that before: instrumental by default, symphonically structured, spoken word, moods rather than songs, occasional vocals that were accents, rather than scaffolding, and incongruous shifts in instrumentation and tone from section to section. I thought that Mogwai had, somehow, invented all this stuff. It wasn’t until 2002 that I realised that Slint had already got most of the way there by 1991.
I first heard Tool in 1998, when I was seventeen. My friend, Harry, lent me their 1996 album, Aenima, and I took it home and played it through the speakers built into the monitor of my Mac. I played it a lot over the next five or six years on my CD Walkman.
Aenima took me much further than Young Team. It was the first piece of modern music in which I heard the non-standard time signatures. It was the first record I heard that combined anger and sadness and melody into beauty. It was the first record I heard that had an overarching theme. The first record I heard that had continuity between songs. It made me consciously seek out weird, extreme music, music that would broaden my horizons and maybe give my brain more versions of that moment in Third Eye when Maynard James Keenan sings, “So good to see you, I missed you so much”: the joyous/agonising high of a sound that is simultaneously sad and beautiful, melodic and abrasive.
Most importantly, it was the record that made me fully aware of the fact that music doesn’t just come from some obscured, instinctual, idiot savant place in the brain. It is intentional art, just like novels and films and paintings. It is - can be - a series of conscious decisions, some of which the musician is unsure of. This is excellently illustrated in Third Eye by the two moments when Maynard James Keenan sings, “Prying open my third eye.” The first time, it stops the song with the long, arrhythmic pauses between repetitions. The second time, it is in parallel with a polyrhythmic drum beat, and repeated many more times, and totally cathartic.
Fourteen years later, poor Harry still hasn’t had his CD back.
Springs, weights and the morning light
Tom Klein Peter wrote a wonderful series of essays about being the lead dev at Audiogalaxy. The excerpt below is one of my favourite pieces of writing about programming. It combines an analogy of springs and weights that illustrates the way programming can change the way you think about systems, and a description of the loveliness of the light in the morning after a night spent hacking that illustrates how the demands of your art can show you the world in a new way.
In short, it demonstrates how a part life of productivity and a part life of fun can enrich each other to produce something that makes your head explode with associative pyrotechnics.
As we worked through the bugs, the uptime turned into minutes, then hours, and eventually the service virtually never crashed. With hundreds of instances deployed, we got so much traffic that we were able to remove all the bugs we were likely to run into. We had one or two machines that would crash every month or two with inscrutable core files. Because it was always the same machine, I eventually attributed this to faulty memory. The idea that you could write software that was more reliable than hardware was fascinating to me.
In fact, almost everything about the scale of the software fascinated me. I found that a system with hundreds of thousands of clients and thousands of events per seconds behaved like a physical machine built out of springs and weights. If one server process stalled for a moment, effects could ripple throughout the cluster. Sometimes, it seemed like there were physical oscillations – huge bursts of traffic would cause everything to slow down and back off, and then things would recover enough to trigger another burst of load. I had never even imagined that these sorts of problems existed in the software world and I found myself wishing I had taken control theory more seriously in college.
Keeping up with the traffic at this time was difficult, but in retrospect, it was really a lot of fun. I had graduated from UT in December of 2000 and moved downtown within walking distance of both 6th Street and the office. I spent the summer on a completely nocturnal cycle, partially because of the Texas heat, but mainly because restarting services was easier at 3 in the morning. I was tired of staying up late to deploy new code, so I just changed my schedule. Audiogalaxy users had led me to a set of live trance mixes from clubs in Europe which turned me into a diehard electronica fan, and driving around Texas to catch DJs on the weekend was much easier if staying up until 8am was normal. I bought some turntables and a lot of vinyl. And a couch. The light in my apartment when I got home in the morning was very lovely.
Andro.js
Today, I am releasing Andro.js, a JavaScript library that helps you compose objects from fragments of behaviour.
The problem
Over the last few months, I have been writing a new JavaScript game. It is a 2D platformer that involves leaping about, stabbing, shooting and blowing stuff up - that much is certain. But it also has a puzzle element that is almost totally undefined.
When I began working on this puzzle element, I experimented with objects with different capabilities: objects that would light up, or play a sound, or leap into the air. Soon, it became clear that I needed a way to give a single object multiple capabilities. Then, I needed a way for these capabilities to interact, like: make this cube light up and leap into the air when it is touched by the player.
A common approach to defining the behaviour of game objects is to use components. These are chunks of code that are installed in the object, each to handle a separate task: artificial intelligence, collision detection and so forth. When the game loop ticks, each game object gets an update call and, in turn, calls an update function on each of its components, so that they can do their work. This is nice because you separate concerns, which means your code is easier to read, easier to reuse, and easier to reason about. Further, the components have total control over their game objects, so you can still do powerful stuff.
I thought about using a component-based approach, but it seemed like it didn’t really fit the way the game objects actually worked. If I were to program a leap into the air capability, what type of component would it be? Logic? And if I wanted my object to only leap when it was touched by the player, how would I organise the code then? Could I shove the leaping and touch detection into some sort of vague Collision Detection component? Or would components somehow talk to one another? I wanted to organise the code by its function, rather than its approach.
A solution
I needed to be able to write very malleable, tightly focused fragments of code that could be reused and recombined as I changed my mind, and I was willing to sacrifice some code clarity to get this.
It seemed that mixins were a promising approach. A mixin is a bundle of attributes and functions that are written onto an object, thus conferring a set of capabilities. A traditional mixin puts these attributes and functions into the namespace of the object. Any clashes: boom. That seemed too dangerous to me. I decided to put each mixin in its own namespace.
Another potential danger was how these mixins would interact. Their reusability would be limited if they had to call each other’s functions by name. Further, direct interaction would make things into a wild free-for-all that was impossible to reason about, with behaviours walking into rooms and issuing orders and walking out to cause chaos elsewhere. I quelled the potential chaos (somewhat) by deciding that the behaviours should only interact via events.
Finally, I had a plan: mixins in their own namespaces communicating via an event emitter. I wrote Andro.js to enact this plan.
An example of Andro.js in use
I require the andro.js
file. I instantiate Andro
. I define the game object as a constructor called Cube
. It has a touch
function that, when called, emits a touch
event to all behaviours (mixins) attached to the cube.
var Andro = require('andro').Andro;
var andro = new Andro();
function Cube {
this.touch = function(contact) {
andro.eventer(this).emit("touch", contact);
};
};
I define the firstTouchBehaviour
mixin. This binds to the touch
events emitted by its owner and keeps track of the number of things currently in contact. When the owner goes from being untouched to being touched, firstTouchBehaviour
emits a FirstTouch:newlyBeingTouched
event.
var firstTouchBehaviour = {
touchCount: 0,
setup: function(owner) {
andro.eventer(owner).bind(this, "touch", function(contact) {
if(contact === "added") {
if(this.touchCount === 0) {
andro.eventer(owner).emit("FirstTouch:newlyBeingTouched");
}
this.touchCount++;
} else if(contact === "removed") {
this.touchCount--;
}
});
}
};
I define soundBehaviour
. This binds to the FirstTouch:newlyBeingTouched
event. Each time this event occurs, soundBehaviour
makes a noise: “Rarrrrrwwwwwwwwwwwwwwww”.
var soundBehaviour = {
setup: function(owner) {
andro.eventer(owner).bind(this, "FirstTouch:newlyBeingTouched", function() {
console.log("Rarrrrrwwwwwwwwwwwwwwww");
});
}
};
I now put everything together. I instantiate cube
, set it up for use with Andro.js and augment it with firstTouchBehaviour
and soundBehaviour
. Finally, I simulate two touches upon the cube. On the first, it roars. On the second, it does not.
var cube = new Cube();
andro.setup(cube);
andro.augment(cube, firstTouchBehaviour);
andro.augment(cube, soundBehaviour);
cube.touch("added"); // rarrrww
cube.touch("added"); // silence
Limiting mentalness
The approach Andro.js takes exchanges a measure of one’s ability to reason about the code for a measure of malleability. Though the modes of expression are constrained to events and mixins, you can still express yourself into one hell of a mess.
As I’ve worked on my new game, I’ve discovered some guidelines that avoid most of the mess. First, all my behaviours have only one responsibility. Second, most either emit information about state, or act upon information received. Third, behaviours do not meddle with the state of their owner objects.
Was this all a mistake, my beloved?
It’s hard to express something at the same time as you’re figuring out what you’re trying to say. Andro.js has enabled me to design some complex game objects. For example, one type of object can simultaneously flash, be a note in a step sequencer, and play a sound when struck that is conferred to it by a nearby object. The code for the behaviours is clean and readable. But, I have rewritten it four times. So, I wonder if there are superior approaches.
I keep on thinking about Arc. Paul Graham has said it is a language designed for exploratory programming. And I keep on thinking about GOOL, the dialect of LISP that Andy Gavin invented to script the game objects in Crash Bandicoot.
These are both languages designed to solve the problem I have been grappling with. Is the logic of game objects in fact a microcosm of all of programming, as complex a problem as any that might be solved by a programming language? Or is it usually a limited problem that is easier to solve when you limit the tools at your disposal? And if that is so, is mixins+events a good approach, or is there a better one?
The rules of Ninja, as I learnt them last night
-
Players stand in a circle, each an arm’s length apart from their neighbours.
-
Someone shouts, “One! Two! Three! Ninja!”
-
On, “Ninja!”, the players adopt a ninja-like pose and remain still.
-
The person who counted everyone in now makes their first move. Their aim is to use their hand to touch the hand of another player, thus killing them. The player’s move must be made in one smooth motion. They may only take one a maximum of one step. The player being attacked may move their upper body in defence.
-
The next player then makes their move, and so on around the circle.
A video of one of the games we played at the Bocoup offices:
Scruffy Slut
About a week ago, Kanen Flowers interviewed me on his show, Scruffy Thinking. I am very honoured. We talked about my latest record, using emacs, Pistol Slut, Kanen’s alien snuff movie, BBEdit, dressing like a teenaged boy and landing in Bangkok for a two day layover and only finally leaving a year and a half later. To listen, go to the Scruffy Thinking podcast on iTunes. Here is a post about the show on the Scruffy Thinking site.