Author Archives: Lou Franco

The Infinity-X Programmer

Forget about the 10-X programmer. I think we’re in a time where AI coding assistants can make you much better than that.

Even if you think I’m crazy, I don’t think it’s a stretch that some programmers, particularly less experienced ones, will get a big relative boost compared to themselves without AI. Meaning, they could become 10x better using Cursor than they would be if they didn’t use AI at all.

The norm is less for experienced devs. I think I’m getting about a 2x or 3x improvement for my most AI-amenable tasks. But when I have to do things on projects where I don’t know the language ecosystem as well, it’s much more. So, it’s less about overall skill, and more about familiarity. As long as you know enough to write good prompts, you get more of a multiple the less you know. For example, for my main project, I might save an hour on a 4-hour task, but a junior dev might save days on that same task. Even if I finish it faster this time, they are still going to improve on that same kind of task until we’re about the same.

But, I also think it’s possible to get very high objective, absolute multipliers against all unassisted programmers with projects that are not even worth trying without the AI assistance.

I’ve started calling this Infinity-X programming. I’m talking about projects where it would take weeks for a programmer to complete, but no one is sure that it’s worth the time or cost. Using tools like Cursor and Replit, I’ve seen instances where a person with some programming ability (but not enough to program unassisted) do it on the side, working on it for fun just because they want to. They get somewhere fast, and now we might approve more work because we can see the value and it feels tractable. I’ve seen this happen a few times in my network lately.

It’s not just “non-programmers”. I’m also seeing this among my very experienced programmer colleagues. They are trying very ambitious side-projects that would be way too hard to do alone. They wouldn’t have even tried. But, now, with AI, they can make a lot of progress right away, and that progress spurs them on to do even more.

Without AI, these bigger projects would be too much of a slog, with too many yak-shaving expeditions, and lots of boring boilerplate and bookkeeping tasks. But, with AI, you get to stay in the zone and have fun, making steady progress the whole way. It makes very big things feel like small things. This is what it feels like to approach infinity.

February 2025 Blog Roundup

I started using Cursor in February. I went from 0 to a usable commit in less than 20 minutes. Here is my progression:

I continue to be impressed by Cursor and use it for almost all programming now.

I wrote about catalysts at work (inspired by an old post: An Unnamed Programmer in Peopleware is One of my Heroes):

I am working on a book about tech debt called Swimming in Tech Debt. I spent some time thinking about swimming:

I continue to write about code reviews

The Central Question of a Code Review

When I prepare code for a pull request, I construct it commit-by-commit in a reading order that convinces you that it is correct. So, when I stage code, I ask myself: “Is the code in this commit obviously correct?” If it’s not, then I probably need to add commits before this one that make the code more clear because I only make explanatory comments on a PR as a last resort.

A PR comment becomes code in a few steps. Step one is that I make comments in the code instead of in the PR. This is better because now anyone reading the code will understand it better. A PR comment isn’t tied to the code unless you think to check the logs and follow that back to the PR.

Step two stems from my belief that a random comment explaining a block of code indicates that that code isn’t clear. This is usually something you can fix with a behavior-preserving refactor. Maybe a variable name is unclear or some code should be extracted into a function. The name of that new function should make the intent of the code inside it easier to see.

But, changing this code might break something, so step three is try to cover this area with unit-tests. When I read a commit with unit tests, I know that all of the cases in the tests are checked, so my job is to think of things that aren’t checked.

It’s tempting to want to fix things in code you are reading, but if they aren’t clarifying the work at hand, that might be a waste of time. By concentrating my efforts on making the PR easier to review, the code will be merged faster if I fix the code.

Supernote Manta: Review at Eight Weeks

I’ve been using the Supernote Manta as my exclusive object for taking notes and reading e-books for eight weeks. This review is a follow-up to Supernote Manta First Impressions and Supernote Manta: Review at Four Weeks.

Before choosing the Manta, my requirements for an electronic writing device were:

  1. It had to be hard to use the machine for anything but reading and writing because I want it to be more like factory equipment.
  2. It had to have a long battery life (like the Kindle).
  3. It had to be easy to get files to and from the device (unlike the Kindle).
  4. It had to be able to read Kindle books.
  5. It had to be readable in sunlight (I live in Florida and read at the beach).
  6. It had to be A5-sized.

It has delivered on all of these requirements, but there are some disappointments (as I mentioned in past reviews), with the main one being that the on-screen keyboard is terrible.

But there are other issues. For context, here is how I currently use the Supernote.

  1. I made a PDF journal using My 2025 Journal PDF for Supernote A5. I write in this daily.
  2. I use the Kindle app on the Supernote for all e-book reading.
  3. I make new notes all of the time for various ad-hoc uses. Each of these becomes the start of new kind of dedicated journal. For example, my wife and I have a monthly “family meeting” to discuss our finances—my notes are now all together in a note file. Previously, they were spread throughout my paper daily journal.

So, I have to manage a bunch of files, which isn’t great on the Supernote. It has a very “functional” file manager, but it’s bare-bones. Now that I have a lot of files, I am running into limitations.

The first problem is that I didn’t think through a folder and file naming strategy before making notes, and now I just have a bunch of randomly named files. I would like to rename them, but the keyboard is so janky, that I have just put it off. On a Mac, this would take less than a minute, but it will just be frustrating on the Supernote.

Related to that, when you take the “New Note” icon, you can’t see the folders or other files. So (as far as I can see), you can’t put the new note in a folder with the shortcut and if you have a naming scheme, you aren’t reminded of it by seeing the other files. This dialog uses the entire screen, so there’s plenty of room to show the folders and files (like any typical “Save as…” dialog).

Another issue is that I can’t reliably lasso an area (select objects by drawing an outline around them). It’s a two-finger gesture in the corner along with using the stylus, but most of the time I do it, the stylus draws the shape instead of lassoing the objects. After a few tries, I do it accidentally—I have not figured out how to do it reliably, but also, I have not investigated this to find out if I am doing the gesture and pen movement as documented. It feels like I am getting worse at this over time.

This all being said, I am very happy with the Supernote. I use it all of the time. As I was writing this post, the Supernote asked to update itself. So, I hope that they addressed some of these issues. The keyboard is mostly a speed issue, so hopefully, not hard to improve.

What To Do If You Have a Tech Interview This Week (or Tomorrow)

Your goal is to be able to answer questions that you can answer. If they ask a question and you have no idea at all, then you might not get an offer. But, if they ask a question that you definitely know, you will feel bad if you flub it.

So, practice. If you have a friend that can do a mock interview, do it. If you have time to practice leetcoding, set it at a level you can do and just practice coding under a little pressure.

You are not trying to learn more algorithms, you are trying to get better at performing what you already know.

See also Professional Performances

How it Feels to “Program” with AI

When I type a prompt into the chat pane in Cursor, it is indistinguishable from programming to me. The part where I tap tap tap on the keyboard and code comes on the screen isn’t programming, that’s typing. The part where I use keyboard shortcuts to navigate the IDE isn’t programming either. Both of those parts (the typing and navigating) is being done by a robot when I prompt Cursor, but the programming is still done by me.

When I look at a ticket in JIRA that says, for example, “add a way to archive a contact” in my React/Node/MySql application, when I estimate, I think

  1. Add an archived field to the contact entity, default to false, set as non-nullable
  2. Generate a migration and run it on my local database
  3. Add DB service functions to archive and unarchive contacts
  4. Write unit tests for those DB service functions
  5. Add GQL mutation functions to archive and unarchive a contact
  6. Add archived to client GQL queries
  7. Add archived to the client-side contact model by running the GQL code generator
  8. Make sure to set up the model’s archived field from the GQL query in Redux
  9. Add a Redux reducer to set the archived field
  10. Add Client-side functions to optimistically update the redux and call the GQL mutation (undoing on error)
  11. Add an “archive”/“unarchive” button on edit on the contact edit dialog (show the one that applies to the contact)
  12. Look at lists that show contacts and decide if they need a way to filter archived contacts out or not

I can tell you from experience, that I can do steps 1, 3, 4, and 5 with a prompt that has basically what that says and at-mentioning the files that will be updated and that serve as a model (I probably have another entity with an archived field). Step 2 is a yarn script for me that compares the schema in my code to the one in my DB. Steps 6, 7, 8, 9, and 10 would be another prompt, and finally I will do 12 & 13 manually or with completions because I might want to adjust the UI.

Before Cursor, I still wrote out that list because I like to Build a Progress Bar for My Work that helps me make an estimate, keep on track, and know if I am not going to make it. When I work with Junior devs, I often develop this list with them to communicate what I want done with more details.

Is this programming? I think so. Instead of TypeScript, I am “programming” in a loosely specified, natural language inspired, custom DSL. I run scripts to generate my migration code from schemas and my client side models from GQL queries, and to me, prompting Cursor is basically the same thing.

Fluent Forever Review

I’m learning German for a trip this spring. Last week, I found out about the book, Fluent Forever [affiliate link] by Gabriel Wyner, which I really love. He also has an app with the same name—it’s fine, but very buggy. It’s hard to recommend the app, but I am convinced his process is going to work for me, and the app is better than trying to his process without it. I bought it after trying it out—despite the bugs. If you read the book, and want to do the process, then you should consider the app.

One reason Wyner’s process resonates with me is because it is centered on Spaced Repetition flash cards, which I already use for other things. I use Anki for spaced repetition practice, but his process isn’t easy to implement in Anki.

Wyner recommends building very custom flashcards that don’t use translation. So, I wouldn’t put an English word on one side and the German translation on the other. Instead, he recommends using an image in place of an English word. He wants you to associate the new language with an image so that you map the word directly to a concept, and don’t have to mentally translate through your native language. Since, I am thinking about how to Apply Program Language Learning Techniques to Learn a Foreign Language, and I never translate between programming languages, this makes sense to me.

Each card in his system is personal to you. He doesn’t supply pre-made cards—he wants you to build them. Building them is part of the process. For example, when I made the card “Großmutter,” I spent at least 10 minutes looking at pictures of my grandmother before I found the perfect one. To represent a concept, sometimes I need to combine several images. That time helps cement the concept before I have even tested my memory with the card. Also, I know what I mean by the image—this would be hard to do with someone else’s images.

The Fluent Forever app helps you build cards, implements a spaced-repetition algorithm, speaks the words (to teach pronunciation), and has many other helpful features. Like I said, if you want to learn this way, the app is better than trying to replicate it with Anki or paper (although the book does show you how to do it). It’s also cheaper than the popular language learning apps. The book, though, is worth a read if you want to learn a language.

Swimming in Tech Debt Book Update

I am aiming to be done with my book, Swimming in Tech Debt, by the end of May 2025. But, very soon, I will start to post edited excerpts. Until now, all of my posted excerpts have been first drafts, but I’ve been working with a professional editor who is helping me make the manuscript better. If you want to read those excerpts, sign up here:

Push, Kick, and Swim (through Tech Debt)

My swimming workouts are in a pool, so each lap starts with me pushing off the pool wall, kicking underwater for a bit, and then turning that momentum into a freestyle swim until I get to the opposite wall and start again. The speed of my lap is determined by the efficiency of my strokes, but the push and kicks overcome the water resistance and generate the initial momentum. That push-off is analogous to how I incorporate tech debt payments into my work and is the core idea in my book, Swimming in Tech Debt.

In a single lap, most of the distance is covered by swimming, and that’s the same in my programming. Most of what I do will be directly implementing the feature or fixing the bug, but I start with a small tech debt payment to get momentum. That small payment is improving the area I am about to change, which makes it easier and faster to do that change.

After the push comes underwater kicking, which is so effective that its use is limited to 15 meters in competitions. After that, the swimmer must begin normal strokes. The same principle applies to tech debt payments. They are effective, but they are not the goal. If all you do is pay down debt, you won’t deliver anything of real value. Paying tech debt makes me happy, so I have to limit how much time I spend on it and get back to my task.

Finally, while I am swimming, no matter how tired I am or how slow I am going, I know I’ll get to the other side eventually. When I do, I get to push and kick again to get some extra momentum. Similarly, when I am stuck on a coding task, I sometimes switch to an easy and productive task (like adding a test) while my brain works on the problem in the background. I know I will do this if I have to, so I keep coding on the main problem for as long as I can. I finish my lap.

Then, I push and kick to start a new lap. That cadence of pushes, kicks, and then a nearly full lap of coding is how I finish the task at hand but leave a series of tech debt payments in my wake.

Swimming to Focus on a Problem

Yesterday, I wrote about how I use Swimming as Meditation. The extreme solitude afforded by the sensory depravation and the rhythmic repetition of strokes, kicks and breaths keep my mind in the present. Usually I try to think about nothing, but sometimes I decide to use the time to solve a problem.

I start the swimming session with a question. I will keep asking myself the question over and over. It’s similar to Natalie Goldberg’s suggestion in Writing Down the Bones to start your writing practice by repeatedly finishing the sentence “I remember…” She is using this as a prompt to keep you writing. I am using a question as a prompt to generate ideas.

One I use often is “What should I blog about today?” The last time I swam, since I am trying to learn German, I asked myself to name German words I know. The questions that work best can be repeatedly asked and answered—meaning, they prompt me to make a list. It’s hard to have a complex string of thoughts that I can remember without being able to write anything down.

Because I can’t write them down, if I have any good ideas, I have to just keep repeating them to myself until I am done swimming. I try to come up with mnemonics that will make sure I remember them. I number them and incorporate them into my stroke counting. That’s usually good enough to keep it top of mind until I can get to my phone.

It seems like it might be hard to swim and think, but actually it’s easier. If I am doing a 30 minute swim, then I will definitely think for 30 minutes. There is literally nothing else to do.