Challenging the status quo of Software Engineering
Programmers are much enamored with their programming languages. Some so much so that it often defines what programmers are; you may hear “I am a Java programmer”, for instance. This runs deeper than we think. Often without realizing it, we are tied not only to the language but also its implementation. The implementation, rather than the language itself, imposes a workflow on how we write programs in the language, one that we usually do not see beyond.
For some time now, the most popular workflow of mainstream languages has been the familiar “edit, compile, run” (ECR) cycle. It has become so ingrained in many of us that we have forgotten other workflows, or worse never learned that any others exist. It was not always so. Popular languages of the past and present have included a different workflow, the “read, eval, print loop” (REPL). For myself, my first programming language was BASIC. My first programming prompt was a REPL.
Often when judging the merits of a language, we focus on the features of the language itself, rather than its implementation and workflows. This is dangerous, since the features of the language are only a part of what makes a programmer productive. The workflow of how you interact with a language is as much important as the language itself. Since many of us are used to only one workflow, more often than not that venerable “edit, compile, run” cycle, we have stopped looking for innovation in how we interact with programming languages.
With ECR, everything is a program. In order to get the computer to do something, you must edit a whole program (whether new or a modified old one), compile it, run it, rinse, lather, and repeat. This is a lot of effort for tasks that are very small. This is also a lot of effort when you need to experiment or tweak with small bits of code. Sometimes you only want to know the output of one function for one input. Sometimes you just need to get the base64 encoding of a string.
A REPL allows you to interact with the language one statement at a time. You can interact out of nothing, if you are just getting started on an idea, or you can interact with an existing program, one statement at a time. Feedback is usually instant. Writing a program with a REPL still means writing a program. But if you need something done that only requires one statement, then one statement is all you need. You cannot use just one statement with ECR. Small tasks become difficult with ECR, causing them more often than not to be skipped.
There’s no reason to not ship a REPL with modern compiled languages such as C# or Java. Mono in fact ships C# REPL, and BeanShell exists for Java. But merely providing a REPL is no guarantee that the masses will use it. Long exposure to the ECR for a generation of programmers has lulled us to sleep. Programmers used to the ECR in compiled languages are often amazed at REPL demos in their favorite language 1, but immediately go back to ingrained habits. We are too enamored with our tools, and the mindsets they put us into.
The natural question that a Software Futurist might ask is, is there anything available more advanced than the REPL? The answer is yes. There is a slight variant of the REPL, the “notebook” interface. A notebook interface allows you to go back in your command history to change a statement and see the changed output. The REPL was designed in the days of teletypes- think of the REPL as like a long fixed interaction with the computer printed on paper. The Notebook interface allows you to go back to any point and make changes. While this seems like a minor advance, it really does make iterative development easier. Notebooks have long been a staple of mathematical systems, like Mathematica, but has been working its way into other languages like Python.
While the notebook has advantes over a REPL, it is not a fundamental shift. For that, as we often do we have to look to the past rather than the future – Smalltalk.
Smalltalk implementations offer what is called “the Image“. It is a fundamentally different paradigm than ECR or the REPL. With the Image, you start a running instance of a complete environment. The Image contains the live objects of your program, as well as the development environment. You make changes to these live objects, or make new live objects, interactively with the development environment. This can be done textually, or graphically depending on what tools you choose to use and what is available at the time. Think of it as “sculpting” a collection of live objects. Once the live objects have reached a point you consider ready, you can freeze the Image, copy it and deploy it wherever you like. In Smalltalk, you work primarily with objects, rather than primarily with text.
It remains to be seen if Image based programming is an advance on the REPL. Certainly it is essentially unknown outside the Smalltalk world, itself a fringe language by today’s standards. It is likely hampered by its all or nothing nature; the entire development environment must be implemented in Smalltalk, inside the Image. Entire ecosystems of supposedly language agnostic tools are thus unable to interact with it – source control tools, documentation generators, indexers. But as least the Image is a creative idea, one designed after the lessons of both ECR and the REPL. I haven’t seen such originality in other interaction paradigms. It’s originality that’s desperately needed if we are to design tools that will make any real leaps in productivity in the future.
Subtext is another post-REPL environment, where code and data are edited in an environment with immediate feedback. He states in his manifesto “The language is the IDE” (emphasis mine)