Mar 18, 2016
An alternative worldview to 'modularity'
It's a common trope among programmers that a single computer contains enough
bits that the number of states it can be in far exceeds the number of atoms in
the universe. See, for example, this
3-minute segment from a very entertaining talk by Joe Armstrong,
the creator of the Erlang programming language. Even if you focus on a single
tiny program, say one that compiles down to a 1KB binary, it's one of 21024
possible programs of the same length. And 1KB is nothing these days; larger
programs get exponentially larger spaces of possibility.
The conventional response to this explosion of possibilities is to observe
that the possibilities stem from a lack of structure. 10 bits encode 210
possibilities, but if you divide them up into two sub-systems with 5 bits each
and test each independently, you then only have to deal with twice 25
possibilities — a far smaller number. From here stem our conventional
dictums to manage complexity by dividing systems up into modules, encapsulating
internal details so modules can't poke inside each other, designing their
interfaces to minimize the number of interactions between modules, avoiding
state within modules, etc. Unfortunately, it's devilishly difficult to
entirely hide state within an encapsulated module so that other modules can be
truly oblivious to it. There seems the very definite possibility that the
sorts of programs we humans need to help with our lives on this planet
intrinsically require state.
So much for the conventional worldview. I'd like to jump off in a different
direction from the phenomenon of state-space explosion in my first paragraph.
Read more →
Sep 6, 2015
“You can know the name of a bird in
all the languages of the world, but when you're finished, you'll know absolutely
nothing whatever about the bird."
I've been teaching programming using my new UI for just
about six weeks now, and it's been miraculous and endlessly fascinating to
watch a young mind up close. I'm still processing many of my observations and
lessons, but I want to describe how one of my students learned something I
never meant to teach: consistent indentation.
The only thing I did to help him learn indentation was this: I never ever
brought it up. Mostly because I just don't
consider it very important, especially at such an early stage. When I
wrote programs to demonstrate features I indented as I normally would, then
I'd hand over the keyboard, and ignore the fact that my student was abutting
each line of code with the left margin.
Read more →
Jul 21, 2015
An experimental UI for teaching programming
Six months ago I fell into a little gig to teach two students programming, and it's been an eye-opening experience. Where I was earlier focused on conveying codebases to programmers, I've lately been thinking a lot harder about conveying programming to non-programmers. I think the two might be special-cases of a grand unifying theory of software representation, but that's another story. For now I don't have a grand unifying theory. What I have is a screenshot:
Let me describe the tool and the problems that it tries to address. When I started out teaching I picked an existing platform that I'd always liked. But quickly I started noticing many limitations. Today's platforms are great for experienced programmers and one can do great things with them, but they are very alien to noobs, who suddenly have to learn many different things at once.
Read more →
Oct 3, 2014
Literate programming: Knuth is doing it wrong
Literate programming advocates this: Order your code for others to read,
not for the compiler. Beautifully typeset your code so one can curl up in bed
to read it like a novel. Keep documentation in sync with code. What's not
to like about this vision? I have two beefs with it: the ends are insufficiently
ambitious by focusing on a passive representation; and the means were insufficiently
polished, by over-emphasizing typesetting at the cost of prose quality.
Elaboration, in reverse order:
Read more →
Sep 9, 2014
Consensual hells: Geopolitics for individuals
My third guest post at ribbonfarm.com.
Apr 9, 2014
Consensual Hells: The legibility tradeoff
My second guest post has just been published over at ribbonfarm.com,
on the subject of building capture-resistant organizations. Tl;dr - constrain
individual discretion at the top, and empower it on the fringes. But the
direct ways to do that won't work. What will? Read on →
Feb 12, 2014
Consensual Hells: From cognitive biases to institutional decay
I've just published the first of a series of guests posts over at ribbonfarm.com. Check it out.
Oct 7, 2013
A new way to organize programs
If you're a programmer this has happened to you. You've built or known a
project that starts out with a well-defined purpose and a straightforward
mapping from purpose to structure in a few sub-systems.
But it can't stand still; changes continue to roll in.
Some of the changes touch multiple sub-systems.
Each change is coherent in the mind of its maker. But once it's made, it
diffuses into the system as a whole.
Soon the once-elegant design has turned into a patchwork-quilt of changes.
Requirements shift, parts get repurposed. Connections proliferate.
Veterans who watched this evolution can keep it mostly straight in their
heads. But newcomers see only the patchwork quilt. They can't tell where one
feature begins and another ends.
What if features could stay separate as they're added, so that newcomers could
see a cleaned-up history of the
Read more →
Oct 6, 2013
How I describe my hobby to programmers
(I still haven't found a way to describe it to non-programmers.)
Wart is an experimental, dynamic, batshit-liberal
language designed to eventually be used by small teams of hobbyists writing
potentially long-lived software. The primary goal is to be easy for anyone to
understand and modify. This goal goes for both code written in Wart, and
the code implementing Wart.
$ git clone http://github.com/akkartik/wart
$ git checkout c73dcd8d6 # state when I wrote this article
$ cd wart
$ ./wart # you'll need gcc and unix
ready! type in an expression, then hit enter twice. ctrl-d exits.
Read more →
Aug 13, 2013
The trouble with 'readability'
We programmers love to talk about the value of readability in software. But
all our rhetoric, even if it were practiced with diligence, suffers from a
giant blind spot.
Douglas Crockford on programming style. For the first half he explains why
readability is important: because our brains do far more subconsciously than
we tend to realize. The anecdotes are interesting and the presentation is
engaging, but the premise is basically preaching to the choir. Of course I
want my code to be readable. Sensei, show me how!
But when he gets to ‘how’, here is what we get: good names,
comments and consistent indentation. Wait, what?! After all that discussion
about how complex programs are, and how hard to understand, do we really
expect to make a dent on global complexity with a few blunt, local
rules? Does something not seem off?
Here's a paean to the software quality of Doom 3. It starts out with this
utterly promising ideal:
“Local code should explain, or at
least hint at, the overall system design.”
Unfortunately we never hear about the 'overall system design' ever again.
Instead we get.. good names, comments and indentation, culminating in the
author's ideal of beauty:
“The two biggest things, for me at
least, are stylistic indenting and maximum const-ness.”
I think the fundamental reasons for the quality of Doom 3 have been missed.
Observing superficial small-scale features will only take you so far in
appreciating the large-scale beauty of a program.
Kernighan and Pike's classic Practice
of Programming takes mostly the code writer's part. For reading you're
left again with guidelines in the small: names, comments and indentation.
I could go on and on. Everytime the discussion turns to readability we skip
almost unconsciously to style guides and whatnot. Local rules for a
fundamentally global problem.
This blind spot is baked into the very phrase
code’. ‘Code’ isn't an amorphous thing that you manage
by the pound. You can't make software clean simply by making all the
‘code’ in it more clean. What we really ought to be thinking about
is readable programs. Functions aren't readable in isolation, at
least not in the most important way. The biggest aid to a function's
readability is to convey where it fits in the larger program.
Nowhere is this more apparent than with names. All the above articles and more
emphasize the value of names. But they all focus on naming conventions and
rules of thumb to evaluate the quality of a single name in isolation.
In practice, a series of locally well-chosen names gradually end up in overall
cacophony. A program with a small harmonious vocabulary of names consistently
used is hugely effective regardless of whether
its types and variables are visibly distinguished. To put it another way,
the readability of a program can be hugely enhanced by the names it
Part of the problem is that talking about local features is easy. It's easy to
teach the difference between a good name and a bad name. Once taught, the
reader has the satisfaction of going off to judge names all around him. It's
far harder to show a globally coherent design without losing the reader.
Simple superficial rules can be applied to any program, but to learn from a
well-designed program we must focus on what's unique to it, and not
easily transferred to other programs in disparate domains. That again
increases the odds of losing the reader.
But the largest problem is that we programmers are often looking at the world
from a parochial perspective: “I built this awesome program, I
understand everything about it, and people keep bugging me to accept their
crappy changes.” Style guides and conventions are basically tools for the
insiders of a software project. If you already understand the global picture
it makes sense to focus on the local irritations. But you won't be around
forever. Eventually one of these newcomers will take charge of this project,
and they'll make a mess if
you didn't talk to them enough about the big picture.
Lots of thought has gone into the small-scale best practices to help
maintainers merge changes from others, but there's been no attempt at learning
to communicate large-scale organization to newcomers. Perhaps this is a
different skill entirely; if so, it needs a different name than