Programming in English with Cursor

This lesson explores how to use Cursor to generate and maintain English specifications as a form of living documentation. Learn how these automatically created documents can serve as a consistent and up-to-date representation of your code's behavior. The video highlights how reviewing and refining these English specifications can help ensure that code modifications align with the intended purpose and that documentation accurately reflects the current codebase, promoting better long-term code maintainability and clarity.

Here's the "english-spec.md" used in the video:

> You are an AI specialized in analyzing source code and producing structured, plain-English representations of its functionality. > > **Your Task**: > 1. Read and interpret the code I provide. > 2. Produce a technical, English-only summary of what the code does. > 3. Use headings and bullet points to clearly outline the roles of each function, class, variable, or important logic block. > 4. **Do not include any actual code** in your final output. Instead, translate the code’s content into an English explanation (like a specification or documentation). > 5. Keep the explanation concise but thorough. Focus on explaining the purpose, process, and relationships between functions or modules in the code. **User Prompt to the AI**: > **Instruction**: Convert the following code into a single file of pure English text that outlines exactly what each part of the code does. Use bullet points, headings, and descriptive language. Do not show any code—only explain how the code behaves. This is intended to serve as a human-readable spec or “translation” of the code. > > **Code**: > ~~~ > [PASTE YOUR CODE HERE] > ~~~ **Example Input/Output #1**: - **Example Code (Input):** ~~~js // example1.js const greetUser = (userName) => { const greeting = `Hello, ${userName}!`; console.log(greeting); }; greetUser("Alice"); ~~~ - **Example Explanation (Output)**: ~~~ # Overview - This file defines a single function which greets a user by name and prints a message to the console. # Function: greetUser - Accepts one parameter (`userName`). - Constructs a greeting string that combines static text with the `userName`. - Outputs the greeting using `console.log`. # Behavior Flow - The function is called with the argument "Alice". - Upon invocation, "Hello, Alice!" is logged to the console. # Key Points - Shows how to create a greeting with a dynamic name. - Demonstrates basic string interpolation and console logging. ~~~ **Example Input/Output #2**: - **Example Code (Input):** ~~~py # example2.py class Calculator: def __init__(self, initial=0): self.value = initial def add(self, amount): self.value += amount def subtract(self, amount): self.value -= amount def get_value(self): return self.value calc = Calculator(10) calc.add(5) calc.subtract(3) result = calc.get_value() print(result) ~~~ - **Example Explanation (Output):** ~~~ # Overview - This file defines a `Calculator` class that keeps track of an internal numerical value and provides methods to modify it. # Class: Calculator - **Constructor** (`__init__`): - Accepts an optional initial value (default is 0). - Stores the initial value in a `value` property. - **Method: add**: - Takes an `amount` and increments the internal `value` by that amount. - **Method: subtract**: - Takes an `amount` and decrements the internal `value` by that amount. - **Method: get_value**: - Returns the current internal `value`. # Behavior Flow - An instance of `Calculator` is created with an initial value of 10. - The `add` method is called with 5, raising the value to 15. - The `subtract` method is called with 3, lowering the value to 12. - The `get_value` method is called to retrieve the current value (12). - The result (12) is printed to the console. # Key Points - Demonstrates basic OOP with a class that manages state. - Showcases constructor, addition, subtraction, and retrieval of a stored value. ~~~ --- ## Final Prompt Below is a full, combined version of the prompt you can provide to an AI to guide it in generating the English-only, bullet-pointed explanation. Feel free to modify or adapt this as needed: ~~~ You are an AI specialized in analyzing source code and producing structured, plain-English representations of its functionality. Your Task: 1. Read and interpret the code I provide. 2. Produce a technical, English-only summary of what the code does. 3. Use headings (e.g. # Overview, # Functions, # Classes, # Behavior Flow) and bullet points. 4. Do not include any code in your final output—only explain how the code behaves. 5. Keep it concise but thorough, focusing on purpose, process, and relationships between functions or modules. Below are some examples of how code might be transformed into an English-only explanation: Example Input: ------------------- ~~~js // example1.js const greetUser = (userName) => { const greeting = `Hello, ${userName}!`; console.log(greeting); }; greetUser("Alice"); ~~~ Example Output: ------------------- # Overview - This file defines a single function which greets a user by name and prints a message to the console. # Function: greetUser - Accepts one parameter (`userName`). - Constructs a greeting string that combines static text with the `userName`. - Outputs the greeting using `console.log`. # Behavior Flow - The function is called with the argument "Alice". - Upon invocation, "Hello, Alice!" is logged to the console. # Key Points - Shows how to create a greeting with a dynamic name. - Demonstrates basic string interpolation and console logging. Example Input: ------------------- ~~~py # example2.py class Calculator: def __init__(self, initial=0): self.value = initial def add(self, amount): self.value += amount def subtract(self, amount): self.value -= amount def get_value(self): return self.value calc = Calculator(10) calc.add(5) calc.subtract(3) result = calc.get_value() print(result) ~~~ Example Output: ------------------- # Overview - This file defines a `Calculator` class that keeps track of an internal numerical value and provides methods to modify it. # Class: Calculator - **Constructor** (`__init__`): - Accepts an optional initial value (default is 0). - Stores the initial value in a `value` property. - **Method: add**: - Takes an `amount` and increments the internal `value` by that amount. - **Method: subtract**: - Takes an `amount` and decrements the internal `value` by that amount. - **Method: get_value**: - Returns the current internal `value`. # Behavior Flow - An instance of `Calculator` is created with an initial value of 10. - The `add` method is called with 5, raising the value to 15. - The `subtract` method is called with 3, lowering the value to 12. - The `get_value` method is called to retrieve the current value (12). - The result (12) is printed to the console. # Key Points - Demonstrates basic OOP with a class that manages state. - Showcases constructor, addition, subtraction, and retrieval of a stored value. --- **Now**: Please apply the same conversion process to the following code. Convert it into a plain-English document that describes what the code does in detail, using bullet points and headings. Create the document next to the original with the filename as `${fileName}.md`. Do not include any source code in the output—only the explanation: [INSERT YOUR CODE HERE]
Share with a coworker

Transcript

[00:00] I found it useful to create a prompt which will output an English spec of your code file. For example, this Chocadar file has a lot of configuration around watching files and various directories and patterns that are pretty easy to get lost if you don't know exactly what the file is doing. So what I'm able to do is in Composer I referenced my English spec which is this file which I just keep in my prompts directory and then I reference the code file and I say follow the English spec instructions. The instructions tell it to output a file based on the code and it shows some input and output examples that outlines everything in that code file. And then the result is a markdown file which lives next to your code file clearly grouping and explaining what's happening in the code.

[00:45] And I know many people would argue that if you need this explanation your code is just bad. And guess what? A lot of my code is just bad. Now with that being said, this does call out some things I noticed that just reading through some of the details I noticed it's doing deep watching for script directories. And I was able to read through that in English and realize I actually don't need deep watching, I only need depth zero.

[01:07] And so after this file is generated I can create a new composer session. I can reference my Chocodar TS file. I'll highlight this line, press Command-I to bring it in, And so we're referencing both the markdown spec of the code and the code itself. And I'll tell it please refactor so that it only watches the root of the script directories. Paste that in, let it run.

[01:31] And this is done refactoring the code. I should have mentioned please also refactor the markdown file and reword it to be in sync with the code file. And that's just what I meant to do the first time I forgot to say that. And then it looks like it updated a few places in my file here. So I changed this line and then updated this to be more explicit.

[01:53] Looks like it even clarified something else while it was there. We'll accept all. And this will essentially enable us to work in English rather than looking at most of the code. So to try another idea, something else I was thinking of is in this section, I'll press command-i, I'd like to be a bit more flexible so that we could watch the entire kenv directory and any of the files that change at the root. So please refactor it so instead of watching individual files it watches all of them and then filters out, excuse me, filters on these specific files so that in the future it's much easier to add other files that I'd like to watch.

[02:28] Please update the code and our English spec file. And we'll let this run. And I'll accept this. I do like this new language around the extensible design for watching additional files. The overarching goal is that this document can remain a source of truth where we can continuously iterate on this refining language and expectations and we can keep on tossing this at the code to make sure that things line up.

[02:51] This doesn't replace tests, in fact it also helps refine tests as well so that generated tests will know exactly what they're trying to do. But so many of our projects already have so much code And again this is for existing code where you want to know exactly what a file is doing and it's also honestly kind of awesome to show someone else who asks a question about the code base what that code is supposed to be doing.