Speeding up development by using the REPL

posted: July 13, 2019

tl;dr: A REPL can provide near-immediate feedback, to make sure your code does what you intend it to do...

One of the joys of programming in an interpreted language is running code as it is being written. When it takes hardly any time to shift from writing code to running code, you might as well run code as often as needed to solve the task at hand as quickly as possible. This is where a REPL (Read-Evaluate-Print-Loop) tool can be extremely helpful.

The languages I use the most these days are Python and JavaScript. For client-side JavaScript, it is very easy to run code in the browser as it is being written, and to debug it using the developer tools built into the major browsers. For server-side JavaScript, a.k.a. Node.js, there is a basic REPL which is invoked by typing ‘node’. For Python, the CPython interpreter has a very feature-rich REPL which is often used to teach the language itself, so most Python programmers are familiar with it. Here’s how I use the REPLs.

My development environment when writing server-side code relies upon three primary tools: a text editor (I use Visual Studio Code); a browser, to check online documentation and scour the Internet for solutions to challenging problems; and the REPL. My development workflow is to first think through my solution to the task at hand, and to look for built-in libraries and third-party libraries that can help. I may experiment or prototype various solutions by writing a little bit of code. When I’ve chosen the approach I’m going to use, the REPL comes into use.

Python’s feature-rich REPL executes code and lets you peek inside the interpreter

I like my code to be runnable at all times, except for brief interludes when I am introducing new features and modifications. I also like to start small and simple, often with the most challenging section first, and build up from there. I am far from the only person who likes this methodology: it is what Linus Torvalds did when writing Linux. To simplify the story, he started with a program that could print “A” and “B” and worked up from there. As I write my code in the text editor, I will often save and run it, adding small blocks and functions as I go. I may comment out or skip blocks of already-debugged code as necessary, all with the aim of keeping the code runnable.

Often I have a question about how the language actually behaves, in some subtle aspect of syntax, or with a function or method that I’m not terribly familiar. Maybe I want to make sure a slice operator is grabbing exactly the characters in a string that I want, or maybe I am trying out a regex pattern. This is where the REPL is invaluable. I’ll write a few lines of code in the REPL, usually with much shorter variable names than my actual program, or I’ll cut-and-paste code directly from the text editor into the REPL, and then run it to see how it actually behaves. I will sometimes look up the online documentation to see how the code should behave, but often I can learn what I need to do by trying some examples, including corner cases, in the REPL. Once I am satisfied that the code is behaving properly, I’ll then enter it in my actual program in the text editor.

Node’s REPL provides the basics of code execution

If someone asks me a question about the language that I can’t answer or am unsure about, my go-to response is “I don’t know, let’s try it in the REPL and see what happens.”

Python’s feature-rich REPL provides other ways to better understand code than just by executing it. The REPL’s help system provides built-in documentation without having to search the official Python documentation. It can be used to explore objects, such as easily finding all the methods and attributes which are available for use. Because the REPL is using the actual interpreter that will be running your code, it is effectively the ultimate source of truth about how the language actually behaves; all other documentation, while often helpful, is an approximation.

I’ll use the REPL to explore and verify small bits of code, but I’ll build up my code a block at a time or a function/method at a time in the text editor. I typically follow the scaffolding pattern when writing code: I’ll put additional debug print/log statements in the code to check on the internal state, and then once I run the code enough to develop confidence that it is working the way it should, I’ll remove most or all of the scaffolding. One of the benefits of experience is knowing what scaffolding to throw away and what to keep, and knowing how many lines of code you can write before you have to run your code again to make sure it still works.

When I have to program in a language that doesn’t have a REPL, I find myself having to write, save, and then compile and execute small pieces of code that I would otherwise put in a REPL. I may have become addicted to the REPL, but I believe it really does speed up development time by providing fast, definitive answers to the coding questions I have.