Loops: how to spot repeated patterns in AI-generated code (for non-devs)
A guide for people who don’t write code but increasingly need to understand what it's doing
Why this matters now
AI tools can now write, run, and explain code on your behalf. That’s useful. But it also means more and more people (think product managers, marketers, HR pros, analysts, ops leads) will see code as part of their work, review what AI has produced, or need to ask better questions about it.
You don’t need to write code to benefit from understanding it. You need to be able to read it the way you might read a contract, so that you can know (generally) what it’s doing and whether it’s accomplishing what you intended.
Why loops are worth understanding
Code has many sources of leverage. Algorithms determine how efficiently a problem gets solved. Data structures determine how information is organized and retrieved. System architecture determines how everything fits together at scale. Loops are one of the places where that leverage is easily visible, which makes them a good and fairly accessible pattern to learn (a lot started clicking for me once I understood loops).1
Understanding what the loop is iterating over, what it’s doing on each pass, and when it should stop gives you a concrete thing to check before running AI-generated code on real data.
What’s in a loop
A loop is just an instruction that says: do this thing repeatedly until a condition is met.
That’s it. But don’t mistake it with a fruit loop. That’s something else.
The reason loops exist in code is the same reason they exist in real life: you often need to do the same action many times, to many items.
A real-life loop you already run
For every item on my grocery list, check if it’s in the cart. If not, add it. Once I’ve checked everything, stop.
That’s exactly what a loop does in code. It has:
A collection of things to work through (the grocery list)
An action to take (check and add)
A stopping condition (when all items are checked)
How to read a loop when you see one
You don’t need to understand every symbol, but make sure you ask four questions:
What is it looping over? (A list? A number range? A condition?)
What action is it taking on each pass? (Sending something? Calculating something? Filtering something?)
When does it stop? (When the list is exhausted? When a condition flips? After N times?)
Does the output go somewhere? (Is it saving to a database? Printing? Building a new list?)
If you can answer those four questions, you understand the loop and you can start seeing the role it plays within the larger system.
The three core patterns
There are dozens of variations, but almost every loop you’ll encounter in the real world is a version of these three patterns.
Pattern 1: the for loop (“do this for each item”)
This is the most common loop you’ll see. You have a list of things, and you want to do something to each one.
The idea
For every customer in our database, send them a welcome email.
In Python
customers = ["Alice", "Bob", "Camille"]
for customer in customers:
send_email(customer)
In JavaScript
const customers = ["Alice", "Bob", "Camille"];
for (const customer of customers) {
sendEmail(customer);
}In Ruby
customers = ["Alice", "Bob", "Camille"]
customers.each do |customer|
send_email(customer)
endIn SQL
UPDATE customers SET welcome_email_sent = TRUE;What to notice
All three say the same thing, just with slightly different syntax.
There’s a list. There’s a name for each item as you move through it. There’s an action.
The loop handles the repetition automatically. You don’t write sendEmail("Alice"), then sendEmail("Bob"), then sendEmail("Camille"). You write the action once and let the loop apply it to every item in the list that you defined at the top.
For SQL, the pattern is implicit. Rather than writing “for each customer, do X”, you describe the action and SQL applies it to every matching row automatically.
This matters enormously at scale. The same code that sends 3 emails sends 3,000,000. You don’t change anything.
Pattern 2: the while loop (“keep doing this until something changes”)
This pattern runs as long as a condition remains true. You don’t necessarily need to know in advance how many times it will run.
The idea
While there are still support tickets in the queue, assign the next one to an available agent.
In Python
while tickets_in_queue > 0:
assign_ticket_to_agent()In JavaScript
while (ticketsInQueue > 0) {
assignTicketToAgent();
}In Ruby
while tickets_in_queue > 0
assign_ticket_to_agent
endIn SQL
WHILE (SELECT COUNT(*) FROM tickets WHERE status = 'open') > 0
BEGIN
EXEC assign_ticket_to_agent;
ENDWhat to notice
The loop doesn’t know when it will stop. That depends on the data. It keeps checking the condition (tickets_in_queue > 0) at the top of each cycle. Once that becomes false (the queue empties), it stops.
This is the pattern behind many real-time systems like processing orders as they arrive, monitoring for alerts or refreshing a live dashboard.
SQL does have an explicit WHILE loop in this example, but it lives inside a stored procedure (a block of logic saved directly in the database). The data engineer could make other implementation decisions but that’s beyond the scope of this essay.
One thing to watch for: If the stopping condition never becomes false, you get an infinite loop. The code runs forever and nothing else can happen. Yikes! Careful not to prompt your AI agent into one of these bad boys.
Pattern 3: the counted loop (“do this a specific number of times”)
Sometimes you don’t have a list, and you don’t have a changing condition. You just need something done exactly N number of times.
The idea
Send 5 reminder notifications over 5 days.
In Python
for i in range(5):
send_reminder()In JavaScript
for (let i = 0; i < 5; i++) {
sendReminder();
}In Ruby
5.times do
send_reminder
endWhat to notice
Python and Ruby are more readable here.
JavaScript’s version (let i = 0; i < 5; i++) is more complex at first glance. Don’t worry, the meaning is start at zero, keep going while less than five, add one each time. It runs exactly five times.
In SQL, there’s no clean equivalent for running something exactly N times (and the SQL community would largely prefer you didn’t try). Databases are optimized to operate on entire sets of data at once, so the language is designed to discourage you from thinking row by row at all. Most loops should be outsourced to other languages instead.
What changes between languages
You may have noticed that the same idea looks different across Python, JavaScript, Ruby, and SQL. That’s a design decision in the language itself (if you’ve been reading my posts for a little while, you’ll know I never miss a moment to harp on about how everything is a design decision… and this is one of them). Different languages make different tradeoffs between readability, precision, and expressiveness.
For example, Python is very readable and closer to plain English. JavaScript is verbose but explicit. The way you write the code tells you exactly what the function is doing. Ruby prose is elegant and expressive. Poetry? Maybe. In SQL, code is declarative and set-based. The loop is usually hidden or not present.
But the concept of a loop is the same across all of them (generally speaking). What changes is the specific words, brackets, and punctuation the language uses. When AI generates code in any of these languages, it’s translating the same underlying logic into different syntax.
A quick mental model to take away
Let’s go back to the grocery list for a moment:
The for loop is you working through the list top to bottom: for each item, check if it’s in the cart, add it if not. The list determines how many times it runs.
The while loop is you realizing your partner is texting you their half of the list one thing at a time, and you don’t know how many items are on it. You keep going (check item, add item) while there’s still texts coming in. You don’t know when you’ll stop until you get there.
The counted loop is you deciding you only have time for five items before you need to leave. You count as you go. After five, you stop, regardless of what’s left on the list.
Every loop in every language is some version of that.
Want to go deeper? The next concept worth learning alongside loops is conditionals. Those are the ‘if/else’ statements that often live inside loops and decide what to do with each item. Together, loops and conditionals cover a surprising amount of what code actually does.
I’m not going to cover these today but I might in the future. So check back in soon. In the meantime, happy thinking!
In this guide, I’ll show you examples in four common languages: Python (data science, AI, automation), Javascript ( web browsers, frontend, apps), Ruby (backends, developer tools), and SQL (databases, data analysis). I left languages like Java, C#, and React (etc) out because in all honesty, I don’t know them, I’ve never studied them, and most AI-generated code will spit out the four ones above (for the most part).

