For Loops and Iterables
A for loop in Julia iterates over anything that implements the iteration protocol — ranges like 1:10, arrays, dictionaries, strings, and custom types alike — using the syntax for i in 1:10 ... end (the keyword in can be swapped for = or ∈, which are all equivalent). Iterating a Dict yields key => value pairs that can be destructured directly in the loop header, as in for (k, v) in scores, and enumerate(collection) and zip(a, b) are the idiomatic ways to get indices or iterate two collections in lockstep without manual index bookkeeping.
Cricket analogy: A scorer working through an over ball-by-ball, from ball 1 to ball 6, mirrors for i in 1:6 — each ball is visited in strict sequence just as Julia iterates a range.
1:10 creates a UnitRange, not an array — it doesn't allocate memory for all ten values up front. Iterating it in a for loop, or even indexing into it, computes each value on demand, which is why ranges are the idiomatic, zero-cost way to express a sequence in Julia.
While Loops and Loop Control
A while loop repeats as long as its condition remains true, checked before each iteration, making it the right tool when the number of iterations isn't known in advance — for example, reading lines from a stream until EOF, or running a numerical solver until it converges within a tolerance: while abs(x_new - x_old) > tol ... end. Because the condition must eventually become false, it's easy to write an infinite loop by forgetting to update the loop variable inside the body.
Cricket analogy: A bowler keeps bowling overs in a spell until the captain signals a change, not for a fixed pre-known number of overs — just like a while loop runs until its condition flips, not a fixed count.
break exits the innermost loop immediately, and continue skips the rest of the current iteration and moves to the next one — both work the same in for and while loops. A common pattern is searching a collection and breaking as soon as a match is found: for x in data; x == target && (found = true; break); end. Julia does not support labeled break/continue to jump out of an outer loop from within a nested one; instead, refactor the nested loops into a function and use return, or wrap the search in a helper.
Cricket analogy: A fielder chasing a boundary stops running the moment the ball crosses the rope — there's no point continuing — just like break exits a loop the instant its condition is met.
Comprehensions as a Loop Alternative
Array and generator comprehensions are often the more idiomatic replacement for a simple accumulation loop: [x^2 for x in 1:10 if isodd(x)] builds a filtered, transformed array in one expression, and dropping the brackets for (x^2 for x in 1:10) creates a lazy generator that's iterated without materializing the full array — useful when feeding results directly into sum(...) or for without allocating memory for the intermediate collection.
Cricket analogy: A stats analyst pulling 'strike rate of every batter who scored over fifty' directly from a season's data in one query, rather than looping and appending manually, mirrors a Julia comprehension building a filtered array in one expression.
Why Julia Loops Are Fast
Unlike Python, loops in Julia are compiled to fast machine code and are not something to avoid for performance — a hand-written for loop is often as fast as, or faster than, a vectorized one-liner, because Julia's JIT compiler specializes the loop body for the concrete types involved. The main performance pitfall is type instability: if a loop variable's type can change between iterations (e.g., starting an accumulator as total = 0 when the loop later adds Float64 values), the compiler can't infer a concrete type and falls back to slower, boxed operations — initializing total = 0.0 instead fixes it.
Cricket analogy: A specialist death-over bowler who's practiced one exact yorker delivery thousands of times executes it faster and more reliably than someone improvising a new variation each ball, just as Julia's JIT specializes a loop body for one concrete type instead of handling many types generically.
# for loop over a range, and over a Dict with destructuring
scores = Dict("Ana" => 91, "Ben" => 78, "Cy" => 85)
for (name, score) in scores
println("$name scored $score")
end
# while loop until convergence
x_old, x_new, tol = 1.0, 0.0, 1e-8
while abs(x_new - x_old) > tol
x_old = x_new
x_new = (x_old + 2 / x_old) / 2 # Newton's method for sqrt(2)
end
# comprehension replacing an accumulation loop, correctly type-stable
squares_of_odds = [x^2 for x in 1:10 if isodd(x)]
total = 0.0 # NOT total = 0 (avoids type instability)
for v in squares_of_odds
total += v
end
Avoid using non-constant global variables inside performance-critical loops — Julia can't specialize on a global's type since it might change, which silently produces the same kind of slow, boxed code as a type-unstable local. Wrap loop-heavy code in a function instead of running it at global scope.
- for loops work over any iterable: ranges, arrays, Dicts (as key=>value pairs), strings, and custom iterators.
- enumerate and zip avoid manual index bookkeeping when you need indices or parallel iteration.
- while loops check their condition before each pass and suit unknown iteration counts.
- break exits the innermost loop immediately; continue skips to the next iteration.
- Julia has no labeled break/continue; refactor nested search loops into a function with return instead.
- Comprehensions like [x^2 for x in 1:10 if isodd(x)] replace simple accumulation loops idiomatically.
- Loops are fast in Julia when type-stable; initialize accumulators with the right concrete type (0.0, not 0) to avoid boxing.
Practice what you learned
1. What does `for (k, v) in scores` do when scores is a Dict?
2. Why might `total = 0` before a loop that later does `total += 1.5` hurt performance?
3. What's the key difference between for and while loops in Julia?
4. What does `(x^2 for x in 1:10)` (no brackets) produce?
5. Does Julia support labeled break to exit an outer loop from a nested inner loop?
Was this page helpful?
You May Also Like
Conditionals in Julia
Learn how Julia evaluates truthiness, structures if/elseif/else blocks, and uses short-circuit and ternary operators for concise control flow.
Functions in Julia
Learn Julia's function syntax, multiple return values, keyword and optional arguments, and the mutating-function naming convention.
Anonymous Functions and Closures
Learn Julia's -> syntax for anonymous functions, do-block syntax, and how closures capture variables from their enclosing scope.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics