One recurring but subliminal theme at the recent Compiler Dev Lab (via Devhawk) was how nice it is to do incremental, interactive development. I argue, here, that not only is it nice, it’s actually critically important. The argument is statistical.
If you make ten changes to a program all at once, the number of ways of getting all ten of them right is just one, but the number of ways of getting at least one of them wrong is 1,023. And, if you get even one of them wrong, then you’ve just inserted subtle bugs into your program that you – or even worse, someone else – may not find till much later.
Digest that for a minute. If you make ten lousy changes to a program before trying them out, your chances of getting the whole thing right is just one in a thousand. It never ceases to amaze me, watching programmers at work. They’ll type in ten lines of code and then spend all day debugging them. Whereas, if they had found a way to type them in one at a time, testing as they go, then they would only have had ten ways to mess up, instead of a thousand.
Multiply that kind of inefficiency by 1,000 developers, and suddenly we can see why software engineering in practice is anything but engineering.
Look at it this way: would you solve a jigsaw puzzle by fitting in one piece at a time, or by trying to get ten pieces all in at one go? The latter strategy is a non-starter. You might as well try to solve the puzzle by putting the pieces back in the box and shaking them.
So, what… How are we going to make our changes one at a time instead of in batches? For that, let’s go back to the Compiler Dev Lab.
The most popular talks were those wherein the speaker typed a line of code and then something interesting happened on the screen. F#, Dyalog APL, Iron Python, Monad, all went along this way. As more lines were typed, more and more sophisticated things happened, building exponentially on the things that happened just a line or two prior.
The host for such a development style is a REPL (pronounced “Repple”), which stands for Read-Eval-Print Loop. Such things are commonplace staples of programming languages since the 1950’s, pioneered with Lisp, Forth, Basic, and so on. The alternative is an ECDL (pronounced “Eckdull”), for Edit-Compile-Debug Loop. An ECDL is, in reality, just a semi-interactive simulation of a card punch, card reader, and line printer (those of you under the age of 45 will have no idea what I’m talking about). People who grew up with PL/1, Fortran, C, Java, are comfortable with ECDLs and may never even have seen a REPL.
But, almost any language can be hosted in a REPL or an ECDL, and some development environments, like those for PLT-scheme and Hugs, support both.
But here’s the main point: a REPL helps you make just one change at a time. Make a change, hit return, bango it’s executed. If you made a mistake (which we all do about half the time), you see it right away, NOW, not later, hidden in the weeds with 1,022 other potential mistakes.
The speakers knew that REPLs create an overwhelmingly compelling development experience, and thus, an overwhelmingly compelling presentation experience. After all, what good is a talk about your technology if your audience dozes off? Their knowledge of this is so deep that a couple of them even created specially doctored REPLs just for presentation purposes.
In fact, this style of development is *so overwhelmingly compelling* that these professional compiler developers sometimes mistaked dynamic development for dynamic languages! IronPython is a dynamic language, F# is a static language, but both are hosted in a dynamic development environment. An informal poll for the most popular dynamic language, however, resulted in F#! This goes to show that the dynamism of the development experience is far more important than language dynamism.
So, if you’re creating a language or an environment, please PLEASE design a REPL to go along with it, and help your users solve their jigsaw puzzles one piece at a time.