Practice and smoothing

I've been thinking a lot about practice.

It's just so important in every aspect of life. Practice is necessary for both growth and maintenance. And the most important part of practice is the preparation work to make execution smooth.

I want to build tools to help software development itself become smoother, but first I want to talk about practice itself.

The first 5 measures of Prelude No. 2 from Bach's Well Tempered Clavier, with some pencil writing on it
Prelude 2 from Bach's Well Tempered Clavier: not my writing, but something I've been practicing

I've been working to improve my piano playing over the past few years.

I first just tried to play (and struggle) through the songs I wanted to learn—tonal, romantic, and expressive pieces like this Rachmaninoff prelude, Ravel's dance for a dead pricess, or Chopin's nocturne.

These pieces are difficult and beautiful—and I want to be able to play them well.

But just practicing by playing over and over again wasn't working. I wasn't making much progress. I was trying too hard to make the notes sing, and would get my fingers tangled or end up stuttering since my speed of playing was faster than my speed of reading.

I was more focused on performing rather than practicing. I was getting ahead of myself, and skipping out on the work to make it smooth.

The work to make it smooth

Whether it's cooking, exercising, playing the piano, or even making software—it's more important to do the "extra" work up-front to make the execution smooth.

  • Mise en place makes the act of cooking and cleanup smooth.
  • Hydrating, stretching, and putting together an achievable plan of what to do makes exercise smooth.
  • Making a clear plan for how each hand moves while playing the notes and rests makes playing piano smooth.
  • Doing the work to have a quick change/verify feedback loop makes programming smooth.

Practice is all about doing the work to make things smoother.

The time taken to smooth execution out is more important than the act itself.

For the piano, I realized that I needed to spend more time practicing reading chunks of notes as chord progressions, practicing fingering while playing through runs, and practicing reading rhythmic patterns.

So I started playing through all sorts of music—not just the songs I liked—and stopping when I made a mistake so I could think through the challenges in fingering, chord progressions, and rhythm. And as a result, my playing has gotten much better!

By stopping to analyze more, I've ended up stopping less while playing.

There's still and endless amount of work to put in, and I still can't play those songs, but that's why it's a practice and not a performance. It's something which will always keep on going.

Smooth software

I've just started my second week at the Recurse Center and have been reflecting on what it means to practice making software.

If practice is about doing the work to make execution smoother, what can be done to make the act of programming itself smoother?

I think programming is mostly discovery. And most of that discovery happens best through the scientific method: a hypothesis-verification loop.

Most software is complicated, poorly documented, and contain never-ending surprises. I find the best way to work through these challenges is to go establish very rapid hypothesis-verification loops:

  • Is this function needed? Delete it and try running the program.
  • Working on a component that needs to look good on a wide variety of widths? Build an isolated page where the component is rendered at various sizes.
  • Is this code crashing because a certain sequence of operations is occurring? Add some log lines at each point and check.
  • Need to change a function so it handles certain inputs? Write unit tests that verifies the inputs and expected outputs.

I want to build tools to help software development itself become smoother.

When I think about smooth feeling traits of software, I think of things that are snappy, immediately responsive to changes, visual (leveraging spatial information), and easy to play with.

Things that are extremely interactive.

Honestly, the most popular extremely interactive tool is a spreadsheet: after setting up some formulas, changing the numbers automatically updates everything.

After talking to some folks at the Recurse Center about spreadsheets and interactivity, I was pointed to a whole bunch of things that have a bit of overlap with this idea:

  • Inventing on Principle, which shows some very playful and extremely interactive development tools
  • Svelte's reactive model, which creates a language that embraces mutability in order to build more easily interactive applications
  • Wildcard, a fascinating tool that allows modifying documents through a sort-of-spreadsheet interface
  • Incremental, Jane Street's approach to apply the [https://www.umut-acar.org/self-adjusting-computation](Self-adjusting computation) technique to build extremely interactive computations

A smoother environment

I want to make something a bit like what's shown in that Inventing on Principle talk: A development environment where code is placed next to interactive UI and the distinction between "running" and "modifying" code is seamless.

Like, imagine an environment where development-time, debug-time, and test-time were the same:

  • A visual chart showing the input/output graph could be placed next to a function describing its effects, like a visual comment
  • When writing UI components, interactive instances of those components showing common edge case sizes & inputs could be placed next to the code
  • Unit tests could show as little red/greed dots in a UI that updated when the code was changed
  • When debugging an application, local state could be viewed (and interacted with) using UI special-built for it

Right now, all of these acts are done using different tools which make jumping between bumpy and awkward.

I'm gonna try to build something that lets you do these things all together.