Chapter 21: R While Loop
Part 1: What is a While Loop?
A while loop repeatedly executes a block of code as long as a specified condition remains TRUE. Once the condition becomes FALSE, the loop stops and the program continues with the next instructions.
The Basic Syntax
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token keyword">while</span> <span class="token punctuation">(</span>condition<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Code to execute repeatedly</span> <span class="token comment"># Something must eventually change the condition</span> <span class="token punctuation">}</span> |
The condition is checked at the beginning of each iteration. If it’s TRUE, the code block runs. If it’s FALSE, the loop exits immediately.
A Simple Example
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
counter <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>counter <span class="token operator"><=</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Iteration number:"</span><span class="token punctuation">,</span> counter<span class="token punctuation">)</span><span class="token punctuation">)</span> counter <span class="token operator"><-</span> counter <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Crucial! This changes the condition</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span><span class="token string">"Loop finished!"</span><span class="token punctuation">)</span> |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 |
[1] "Iteration number: 1" [1] "Iteration number: 2" [1] "Iteration number: 3" [1] "Iteration number: 4" [1] "Iteration number: 5" [1] "Loop finished!" |
Let’s trace through what happens:
-
Start:
counter = 1, condition1 <= 5is TRUE → enter loop -
Print “Iteration number: 1”
-
counterbecomes 2 -
Check condition again:
2 <= 5is TRUE → continue -
… this repeats until
counter = 6 -
When
counter = 6, condition6 <= 5is FALSE → exit loop
Part 2: Anatomy of a While Loop
Every while loop has three essential components:
1. The Initialization
Before the loop starts, you must initialize any variables that will be used in the condition.
|
0 1 2 3 4 5 6 7 8 |
total <span class="token operator"><-</span> <span class="token number">0</span> <span class="token comment"># Initialize accumulator</span> count <span class="token operator"><-</span> <span class="token number">1</span> <span class="token comment"># Initialize counter</span> user_input <span class="token operator"><-</span> <span class="token string">""</span> <span class="token comment"># Initialize user input variable</span> |
2. The Condition
The condition determines whether the loop continues. It must evaluate to TRUE or FALSE.
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token keyword">while</span> <span class="token punctuation">(</span>count <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token comment"># Simple numeric condition</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>user_input <span class="token operator">!=</span> <span class="token string">"quit"</span><span class="token punctuation">)</span> <span class="token comment"># String comparison</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>is.na<span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Check for missing values</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>found <span class="token operator">==</span> <span class="token boolean">FALSE</span><span class="token punctuation">)</span> <span class="token comment"># Boolean condition</span> |
3. The Update
Inside the loop, you MUST change something that affects the condition, or you’ll create an infinite loop.
|
0 1 2 3 4 5 6 7 8 9 |
count <span class="token operator"><-</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Increment counter</span> total <span class="token operator"><-</span> total <span class="token operator">+</span> new_value <span class="token comment"># Update accumulator</span> user_input <span class="token operator"><-</span> readline<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># Get new input</span> found <span class="token operator"><-</span> check_something<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment"># Update boolean</span> |
Part 3: Real-World Examples
Example 1: Guessing Game
Let’s create a number guessing game to see while loops in action:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<span class="token comment"># Number guessing game</span> secret_number <span class="token operator"><-</span> sample<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># Random number between 1 and 100</span> guess <span class="token operator"><-</span> <span class="token operator">-</span><span class="token number">1</span> attempts <span class="token operator"><-</span> <span class="token number">0</span> print<span class="token punctuation">(</span><span class="token string">"I'm thinking of a number between 1 and 100. Can you guess it?"</span><span class="token punctuation">)</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>guess <span class="token operator">!=</span> secret_number<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Get user input</span> guess <span class="token operator"><-</span> as.numeric<span class="token punctuation">(</span>readline<span class="token punctuation">(</span><span class="token string">"Your guess: "</span><span class="token punctuation">)</span><span class="token punctuation">)</span> attempts <span class="token operator"><-</span> attempts <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Give feedback</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>guess <span class="token operator"><</span> secret_number<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Too low! Try again."</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>guess <span class="token operator">></span> secret_number<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Too high! Try again."</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Congratulations! You got it!"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"It took you"</span><span class="token punctuation">,</span> attempts<span class="token punctuation">,</span> <span class="token string">"attempts."</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
This loop continues until the user guesses correctly. Each iteration:
-
Gets a new guess from the user
-
Increments the attempt counter
-
Provides feedback
-
The condition
guess != secret_numberis checked again
Example 2: Sum Until Target
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<span class="token comment"># Sum numbers until we reach or exceed a target</span> target <span class="token operator"><-</span> <span class="token number">100</span> sum <span class="token operator"><-</span> <span class="token number">0</span> numbers_added <span class="token operator"><-</span> <span class="token number">0</span> current_number <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>sum <span class="token operator"><</span> target<span class="token punctuation">)</span> <span class="token punctuation">{</span> sum <span class="token operator"><-</span> sum <span class="token operator">+</span> current_number numbers_added <span class="token operator"><-</span> numbers_added <span class="token operator">+</span> <span class="token number">1</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Added"</span><span class="token punctuation">,</span> current_number<span class="token punctuation">,</span> <span class="token string">"- Sum is now"</span><span class="token punctuation">,</span> sum<span class="token punctuation">)</span><span class="token punctuation">)</span> current_number <span class="token operator"><-</span> current_number <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Reached target after adding"</span><span class="token punctuation">,</span> numbers_added<span class="token punctuation">,</span> <span class="token string">"numbers!"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Final sum:"</span><span class="token punctuation">,</span> sum<span class="token punctuation">)</span><span class="token punctuation">)</span> |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
[1] "Added 1 - Sum is now 1" [1] "Added 2 - Sum is now 3" [1] "Added 3 - Sum is now 6" [1] "Added 4 - Sum is now 10" [1] "Added 5 - Sum is now 15" [1] "Added 6 - Sum is now 21" [1] "Added 7 - Sum is now 28" [1] "Added 8 - Sum is now 36" [1] "Added 9 - Sum is now 45" [1] "Added 10 - Sum is now 55" [1] "Added 11 - Sum is now 66" [1] "Added 12 - Sum is now 78" [1] "Added 13 - Sum is now 91" [1] "Added 14 - Sum is now 105" [1] "Reached target after adding 14 numbers!" [1] "Final sum: 105" |
Example 3: Validating User Input
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<span class="token comment"># Keep asking for valid input until we get it</span> user_age <span class="token operator"><-</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>user_age <span class="token operator"><</span> <span class="token number">0</span> <span class="token operator">||</span> user_age <span class="token operator">></span> <span class="token number">120</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> user_input <span class="token operator"><-</span> readline<span class="token punctuation">(</span><span class="token string">"Please enter your age (0-120): "</span><span class="token punctuation">)</span> user_age <span class="token operator"><-</span> as.numeric<span class="token punctuation">(</span>user_input<span class="token punctuation">)</span> <span class="token comment"># Check if input is valid</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>is.na<span class="token punctuation">(</span>user_age<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"That's not a number! Please try again."</span><span class="token punctuation">)</span> user_age <span class="token operator"><-</span> <span class="token operator">-</span><span class="token number">1</span> <span class="token comment"># Reset to invalid value</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>user_age <span class="token operator"><</span> <span class="token number">0</span> <span class="token operator">||</span> user_age <span class="token operator">></span> <span class="token number">120</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Age must be between 0 and 120. Please try again."</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Thank you! You are"</span><span class="token punctuation">,</span> user_age<span class="token punctuation">,</span> <span class="token string">"years old."</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
This loop continues until the user provides a valid age between 0 and 120.
Part 4: Infinite Loops and How to Avoid Them
An infinite loop occurs when the condition never becomes FALSE. This is one of the most common while loop bugs.
Classic Infinite Loop Examples
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token comment"># ❌ Forgot to update the counter</span> counter <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>counter <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"This will run forever!"</span><span class="token punctuation">)</span> <span class="token comment"># Missing: counter <- counter + 1</span> <span class="token punctuation">}</span> <span class="token comment"># ❌ Condition that can never become FALSE</span> x <span class="token operator"><-</span> <span class="token number">10</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>x <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"This will also run forever!"</span><span class="token punctuation">)</span> x <span class="token operator"><-</span> x <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># x gets larger, never reaches 0 or below</span> <span class="token punctuation">}</span> <span class="token comment"># ❌ Using assignment instead of comparison</span> continue <span class="token operator"><-</span> <span class="token boolean">TRUE</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>continue <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Note: single = is assignment, not comparison</span> print<span class="token punctuation">(</span><span class="token string">"This assigns TRUE to continue each time!"</span><span class="token punctuation">)</span> <span class="token comment"># continue never becomes FALSE</span> <span class="token punctuation">}</span> |
Safe Ways to Handle Potential Infinite Loops
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<span class="token comment"># 1. Add a maximum iteration safeguard</span> max_iterations <span class="token operator"><-</span> <span class="token number">1000</span> iteration <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>some_condition <span class="token operator">&&</span> iteration <span class="token operator"><=</span> max_iterations<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Do something</span> iteration <span class="token operator"><-</span> iteration <span class="token operator">+</span> <span class="token number">1</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>iteration <span class="token operator">></span> max_iterations<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Warning: Reached maximum iterations - breaking out"</span><span class="token punctuation">)</span> <span class="token keyword">break</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment"># 2. Use a timeout for user input</span> timeout_start <span class="token operator"><-</span> Sys.time<span class="token punctuation">(</span><span class="token punctuation">)</span> timeout_seconds <span class="token operator"><-</span> <span class="token number">30</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>condition <span class="token operator">&&</span> as.numeric<span class="token punctuation">(</span>difftime<span class="token punctuation">(</span>Sys.time<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> timeout_start<span class="token punctuation">,</span> units <span class="token operator">=</span> <span class="token string">"secs"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token operator"><</span> timeout_seconds<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Wait for user input or process</span> <span class="token punctuation">}</span> <span class="token comment"># 3. Always have a plan B condition</span> keep_running <span class="token operator"><-</span> <span class="token boolean">TRUE</span> safety_counter <span class="token operator"><-</span> <span class="token number">0</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>keep_running <span class="token operator">&&</span> safety_counter <span class="token operator"><</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Do something</span> safety_counter <span class="token operator"><-</span> safety_counter <span class="token operator">+</span> <span class="token number">1</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>some_condition<span class="token punctuation">)</span> <span class="token punctuation">{</span> keep_running <span class="token operator"><-</span> <span class="token boolean">FALSE</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Part 5: Breaking and Skipping in Loops
R provides two special statements to control loop execution: break and next.
Using break to Exit Early
The break statement immediately exits the loop, regardless of the condition.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<span class="token comment"># Find the first number whose square is greater than 1000</span> number <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Intentionally infinite</span> square <span class="token operator"><-</span> number<span class="token operator">^</span><span class="token number">2</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Checking"</span><span class="token punctuation">,</span> number<span class="token punctuation">,</span> <span class="token string">"- Square is"</span><span class="token punctuation">,</span> square<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>square <span class="token operator">></span> <span class="token number">1000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Found it!"</span><span class="token punctuation">,</span> number<span class="token punctuation">,</span> <span class="token string">"squared is"</span><span class="token punctuation">,</span> square<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">break</span> <span class="token comment"># Exit the loop</span> <span class="token punctuation">}</span> number <span class="token operator"><-</span> number <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Loop exited at number"</span><span class="token punctuation">,</span> number<span class="token punctuation">)</span><span class="token punctuation">)</span> |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
[1] "Checking 1 - Square is 1" [1] "Checking 2 - Square is 4" [1] "Checking 3 - Square is 9" ... [1] "Checking 31 - Square is 961" [1] "Checking 32 - Square is 1024" [1] "Found it! 32 squared is 1024" [1] "Loop exited at number 32" |
Using next to Skip Iterations
The next statement skips the rest of the current iteration and jumps to the next one.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token comment"># Process numbers but skip multiples of 3</span> number <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>number <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>number <span class="token percent-operator operator">%%</span> <span class="token number">3</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># If divisible by 3</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Skipping"</span><span class="token punctuation">,</span> number<span class="token punctuation">,</span> <span class="token string">"(multiple of 3)"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> number <span class="token operator"><-</span> number <span class="token operator">+</span> <span class="token number">1</span> <span class="token keyword">next</span> <span class="token comment"># Skip to next iteration</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Processing number:"</span><span class="token punctuation">,</span> number<span class="token punctuation">)</span><span class="token punctuation">)</span> number <span class="token operator"><-</span> number <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[1] "Processing number: 1" [1] "Processing number: 2" [1] "Skipping 3 (multiple of 3)" [1] "Processing number: 4" [1] "Processing number: 5" [1] "Skipping 6 (multiple of 3)" [1] "Processing number: 7" [1] "Processing number: 8" [1] "Skipping 9 (multiple of 3)" [1] "Processing number: 10" |
break and next in Nested Loops
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="token comment"># break only exits the innermost loop</span> outer_counter <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>outer_counter <span class="token operator"><=</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"--- Outer loop iteration"</span><span class="token punctuation">,</span> outer_counter<span class="token punctuation">,</span> <span class="token string">"---"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> inner_counter <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>inner_counter <span class="token operator"><=</span> <span class="token number">5</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>inner_counter <span class="token operator">==</span> <span class="token number">3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">" Breaking inner loop at"</span><span class="token punctuation">,</span> inner_counter<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">break</span> <span class="token comment"># This only exits the inner loop</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">" Inner counter:"</span><span class="token punctuation">,</span> inner_counter<span class="token punctuation">)</span><span class="token punctuation">)</span> inner_counter <span class="token operator"><-</span> inner_counter <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> outer_counter <span class="token operator"><-</span> outer_counter <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> |
Output:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
[1] "--- Outer loop iteration 1 ---" [1] " Inner counter: 1" [1] " Inner counter: 2" [1] " Breaking inner loop at 3" [1] "--- Outer loop iteration 2 ---" [1] " Inner counter: 1" [1] " Inner counter: 2" [1] " Breaking inner loop at 3" [1] "--- Outer loop iteration 3 ---" [1] " Inner counter: 1" [1] " Inner counter: 2" [1] " Breaking inner loop at 3" |
Part 6: While Loops with Data Structures
Example: Processing a List Until Empty
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<span class="token comment"># Process tasks from a queue</span> task_queue <span class="token operator"><-</span> list<span class="token punctuation">(</span><span class="token string">"Write report"</span><span class="token punctuation">,</span> <span class="token string">"Email client"</span><span class="token punctuation">,</span> <span class="token string">"Update database"</span><span class="token punctuation">,</span> <span class="token string">"Review code"</span><span class="token punctuation">,</span> <span class="token string">"Team meeting"</span><span class="token punctuation">)</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>task_queue<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Get the first task</span> current_task <span class="token operator"><-</span> task_queue<span class="token punctuation">[</span><span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">]</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Processing:"</span><span class="token punctuation">,</span> current_task<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Simulate work</span> Sys.sleep<span class="token punctuation">(</span><span class="token number">0.5</span><span class="token punctuation">)</span> <span class="token comment"># Pause for 0.5 seconds</span> <span class="token comment"># Remove the processed task</span> task_queue <span class="token operator"><-</span> task_queue<span class="token punctuation">[</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">]</span> <span class="token comment"># Show remaining tasks</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>length<span class="token punctuation">(</span>task_queue<span class="token punctuation">)</span> <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Remaining tasks:"</span><span class="token punctuation">,</span> length<span class="token punctuation">(</span>task_queue<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"All tasks completed!"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Example: Building a Data Frame Incrementally
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
<span class="token comment"># Simulate collecting data until a condition is met</span> set.seed<span class="token punctuation">(</span><span class="token number">123</span><span class="token punctuation">)</span> <span class="token comment"># For reproducibility</span> <span class="token comment"># Initialize empty data frame</span> results <span class="token operator"><-</span> data.frame<span class="token punctuation">(</span> iteration <span class="token operator">=</span> integer<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> value <span class="token operator">=</span> numeric<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> status <span class="token operator">=</span> character<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> stringsAsFactors <span class="token operator">=</span> <span class="token boolean">FALSE</span> <span class="token punctuation">)</span> iteration <span class="token operator"><-</span> <span class="token number">1</span> target_reached <span class="token operator"><-</span> <span class="token boolean">FALSE</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token operator">!</span>target_reached<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Generate some data</span> value <span class="token operator"><-</span> runif<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span> <span class="token comment"># Random number between 0 and 100</span> status <span class="token operator"><-</span> ifelse<span class="token punctuation">(</span>value <span class="token operator">></span> <span class="token number">80</span><span class="token punctuation">,</span> <span class="token string">"High"</span><span class="token punctuation">,</span> <span class="token string">"Normal"</span><span class="token punctuation">)</span> <span class="token comment"># Add to results data frame</span> new_row <span class="token operator"><-</span> data.frame<span class="token punctuation">(</span> iteration <span class="token operator">=</span> iteration<span class="token punctuation">,</span> value <span class="token operator">=</span> round<span class="token punctuation">(</span>value<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> status <span class="token operator">=</span> status <span class="token punctuation">)</span> results <span class="token operator"><-</span> rbind<span class="token punctuation">(</span>results<span class="token punctuation">,</span> new_row<span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Iteration"</span><span class="token punctuation">,</span> iteration<span class="token punctuation">,</span> <span class="token string">"- Value:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>value<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Check if we should stop</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>value <span class="token operator">></span> <span class="token number">95</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Target reached! Value"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>value<span class="token punctuation">,</span> <span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"exceeds 95"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> target_reached <span class="token operator"><-</span> <span class="token boolean">TRUE</span> <span class="token punctuation">}</span> iteration <span class="token operator"><-</span> iteration <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Safety check</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>iteration <span class="token operator">></span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Maximum iterations reached - stopping"</span><span class="token punctuation">)</span> <span class="token keyword">break</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span><span class="token string">"\nFinal Results:"</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>results<span class="token punctuation">)</span> |
Part 7: While Loops vs For Loops
Understanding when to use while vs for loops is crucial for writing clean, efficient code.
When to Use For Loops
Use for loops when you know in advance how many iterations you need:
|
0 1 2 3 4 5 6 7 8 9 |
<span class="token comment"># For loop - we know we want exactly 10 iterations</span> <span class="token keyword">for</span> <span class="token punctuation">(</span>i <span class="token keyword">in</span> <span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Iteration"</span><span class="token punctuation">,</span> i<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
When to Use While Loops
Use while loops when the number of iterations is unknown and depends on a condition:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<span class="token comment"># While loop - we don't know how many iterations we'll need</span> total <span class="token operator"><-</span> <span class="token number">0</span> numbers_added <span class="token operator"><-</span> <span class="token number">0</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>total <span class="token operator"><</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> new_number <span class="token operator"><-</span> sample<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span><span class="token number">20</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token comment"># Random number between 1 and 20</span> total <span class="token operator"><-</span> total <span class="token operator">+</span> new_number numbers_added <span class="token operator"><-</span> numbers_added <span class="token operator">+</span> <span class="token number">1</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Added"</span><span class="token punctuation">,</span> new_number<span class="token punctuation">,</span> <span class="token string">"- Total is now"</span><span class="token punctuation">,</span> total<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Needed"</span><span class="token punctuation">,</span> numbers_added<span class="token punctuation">,</span> <span class="token string">"numbers to reach 100"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Comparison Table
| Aspect | For Loop | While Loop |
|---|---|---|
| Iterations known? | Yes | No |
| Risk of infinite loop | Low | Higher |
| Best for | Iterating over sequences | Conditional repetition |
| Common uses | Processing arrays, fixed ranges | User input, convergence algorithms |
Part 8: Advanced While Loop Patterns
Pattern 1: Convergence Algorithm (Newton’s Method)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<span class="token comment"># Find square root using Newton's method</span> <span class="token comment"># x_{n+1} = (x_n + a/x_n) / 2</span> find_sqrt <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>a<span class="token punctuation">,</span> tolerance <span class="token operator">=</span> <span class="token number">1e-10</span><span class="token punctuation">,</span> max_iter <span class="token operator">=</span> <span class="token number">100</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> x <span class="token operator"><-</span> a <span class="token operator">/</span> <span class="token number">2</span> <span class="token comment"># Initial guess</span> iteration <span class="token operator"><-</span> <span class="token number">1</span> difference <span class="token operator"><-</span> <span class="token number">Inf</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Finding square root of"</span><span class="token punctuation">,</span> a<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Target tolerance:"</span><span class="token punctuation">,</span> tolerance<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>abs<span class="token punctuation">(</span>difference<span class="token punctuation">)</span> <span class="token operator">></span> tolerance <span class="token operator">&&</span> iteration <span class="token operator"><=</span> max_iter<span class="token punctuation">)</span> <span class="token punctuation">{</span> x_new <span class="token operator"><-</span> <span class="token punctuation">(</span>x <span class="token operator">+</span> a<span class="token operator">/</span>x<span class="token punctuation">)</span> <span class="token operator">/</span> <span class="token number">2</span> difference <span class="token operator"><-</span> x_new <span class="token operator">-</span> x x <span class="token operator"><-</span> x_new print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Iteration"</span><span class="token punctuation">,</span> iteration<span class="token punctuation">,</span> <span class="token string">"- Current estimate:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>x<span class="token punctuation">,</span> <span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> iteration <span class="token operator"><-</span> iteration <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>iteration <span class="token operator">></span> max_iter<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Warning: Maximum iterations reached"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token punctuation">}</span> result <span class="token operator"><-</span> find_sqrt<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span> <span class="token comment"># Should approximate sqrt(2) ≈ 1.41421356</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Final estimate:"</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Actual sqrt(2):"</span><span class="token punctuation">,</span> sqrt<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Error:"</span><span class="token punctuation">,</span> abs<span class="token punctuation">(</span>result <span class="token operator">-</span> sqrt<span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> |
Pattern 2: Event-Driven Processing
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<span class="token comment"># Simulate a simple event monitor</span> set.seed<span class="token punctuation">(</span><span class="token number">456</span><span class="token punctuation">)</span> monitor_system <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> system_status <span class="token operator"><-</span> <span class="token string">"normal"</span> alerts <span class="token operator"><-</span> <span class="token number">0</span> max_alerts <span class="token operator"><-</span> <span class="token number">3</span> check_interval <span class="token operator"><-</span> <span class="token number">0.5</span> <span class="token comment"># seconds</span> print<span class="token punctuation">(</span><span class="token string">"Starting system monitoring..."</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span><span class="token string">"Press Ctrl+C to stop"</span><span class="token punctuation">)</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>alerts <span class="token operator"><</span> max_alerts<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Simulate reading system metrics</span> cpu_usage <span class="token operator"><-</span> runif<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span> memory_usage <span class="token operator"><-</span> runif<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">100</span> disk_io <span class="token operator"><-</span> runif<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token number">1000</span> <span class="token comment"># Check for issues</span> current_status <span class="token operator"><-</span> <span class="token string">"normal"</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>cpu_usage <span class="token operator">></span> <span class="token number">90</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> current_status <span class="token operator"><-</span> <span class="token string">"WARNING"</span> alerts <span class="token operator"><-</span> alerts <span class="token operator">+</span> <span class="token number">1</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"ALERT"</span><span class="token punctuation">,</span> alerts<span class="token punctuation">,</span> <span class="token string">"- High CPU usage:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>cpu_usage<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>memory_usage <span class="token operator">></span> <span class="token number">95</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> current_status <span class="token operator"><-</span> <span class="token string">"CRITICAL"</span> alerts <span class="token operator"><-</span> alerts <span class="token operator">+</span> <span class="token number">1</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"ALERT"</span><span class="token punctuation">,</span> alerts<span class="token punctuation">,</span> <span class="token string">"- Critical memory usage:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>memory_usage<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Log normal status occasionally</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>current_status <span class="token operator">==</span> <span class="token string">"normal"</span> <span class="token operator">&&</span> runif<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">0.3</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"System normal - CPU:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>cpu_usage<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%, Memory:"</span><span class="token punctuation">,</span> round<span class="token punctuation">(</span>memory_usage<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"%"</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> Sys.sleep<span class="token punctuation">(</span>check_interval<span class="token punctuation">)</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Maximum alerts ("</span><span class="token punctuation">,</span> max_alerts<span class="token punctuation">,</span> <span class="token string">") reached. Stopping monitor."</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Run the monitor (will stop after 3 alerts)</span> monitor_system<span class="token punctuation">(</span><span class="token punctuation">)</span> |
Pattern 3: Retry with Backoff
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
<span class="token comment"># Function that might fail (simulates network request)</span> unreliable_function <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>runif<span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span> <span class="token operator"><</span> <span class="token number">0.7</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># 70% chance of failure</span> stop<span class="token punctuation">(</span><span class="token string">"Network error: Connection timeout"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span><span class="token string">"Data successfully retrieved!"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Retry with exponential backoff</span> retry_with_backoff <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>fn<span class="token punctuation">,</span> max_retries <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">,</span> base_delay <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> attempt <span class="token operator"><-</span> <span class="token number">1</span> last_error <span class="token operator"><-</span> <span class="token keyword">NULL</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>attempt <span class="token operator"><=</span> max_retries<span class="token punctuation">)</span> <span class="token punctuation">{</span> tryCatch<span class="token punctuation">(</span><span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Attempt"</span><span class="token punctuation">,</span> attempt<span class="token punctuation">,</span> <span class="token string">"of"</span><span class="token punctuation">,</span> max_retries<span class="token punctuation">)</span><span class="token punctuation">)</span> result <span class="token operator"><-</span> fn<span class="token punctuation">(</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span><span class="token string">"Success!"</span><span class="token punctuation">)</span> return<span class="token punctuation">(</span>result<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> error <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> last_error <span class="token operator"><<-</span> e <span class="token keyword">if</span> <span class="token punctuation">(</span>attempt <span class="token operator"><</span> max_retries<span class="token punctuation">)</span> <span class="token punctuation">{</span> delay <span class="token operator"><-</span> base_delay <span class="token operator">*</span> <span class="token punctuation">(</span><span class="token number">2</span><span class="token operator">^</span><span class="token punctuation">(</span>attempt <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token comment"># Exponential backoff</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Attempt failed. Waiting"</span><span class="token punctuation">,</span> delay<span class="token punctuation">,</span> <span class="token string">"seconds before retry..."</span><span class="token punctuation">)</span><span class="token punctuation">)</span> Sys.sleep<span class="token punctuation">(</span>delay<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> attempt <span class="token operator"><-</span> attempt <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"All"</span><span class="token punctuation">,</span> max_retries<span class="token punctuation">,</span> <span class="token string">"attempts failed."</span><span class="token punctuation">)</span><span class="token punctuation">)</span> stop<span class="token punctuation">(</span><span class="token string">"Function failed after "</span><span class="token punctuation">,</span> max_retries<span class="token punctuation">,</span> <span class="token string">" attempts. Last error: "</span><span class="token punctuation">,</span> last_error<span class="token operator">$</span>message<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment"># Try it</span> tryCatch<span class="token punctuation">(</span><span class="token punctuation">{</span> result <span class="token operator"><-</span> retry_with_backoff<span class="token punctuation">(</span>unreliable_function<span class="token punctuation">,</span> max_retries <span class="token operator">=</span> <span class="token number">3</span><span class="token punctuation">)</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Got result:"</span><span class="token punctuation">,</span> result<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> error <span class="token operator">=</span> <span class="token keyword">function</span><span class="token punctuation">(</span>e<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Final error:"</span><span class="token punctuation">,</span> e<span class="token operator">$</span>message<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> |
Part 9: Common Mistakes and How to Avoid Them
Mistake 1: Forgetting to Update the Condition Variable
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token comment"># ❌ This creates an infinite loop</span> x <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>x <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token comment"># Missing: x <- x + 1</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Always update the condition variable</span> x <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>x <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span>x<span class="token punctuation">)</span> x <span class="token operator"><-</span> x <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Crucial update</span> <span class="token punctuation">}</span> |
Mistake 2: Using Assignment Instead of Comparison
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<span class="token comment"># ❌ This assigns TRUE each time, creating an infinite loop</span> keep_going <span class="token operator"><-</span> <span class="token boolean">TRUE</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>keep_going <span class="token operator">=</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Single = is assignment</span> print<span class="token punctuation">(</span><span class="token string">"This runs forever"</span><span class="token punctuation">)</span> keep_going <span class="token operator"><-</span> <span class="token boolean">FALSE</span> <span class="token comment"># This won't help because condition is reassigned!</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Use comparison operator</span> keep_going <span class="token operator"><-</span> <span class="token boolean">TRUE</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>keep_going <span class="token operator">==</span> <span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Double == is comparison</span> print<span class="token punctuation">(</span><span class="token string">"This runs once"</span><span class="token punctuation">)</span> keep_going <span class="token operator"><-</span> <span class="token boolean">FALSE</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Even better, just use the boolean directly</span> keep_going <span class="token operator"><-</span> <span class="token boolean">TRUE</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>keep_going<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Clean and clear</span> print<span class="token punctuation">(</span><span class="token string">"This runs once"</span><span class="token punctuation">)</span> keep_going <span class="token operator"><-</span> <span class="token boolean">FALSE</span> <span class="token punctuation">}</span> |
Mistake 3: Off-by-One Errors
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<span class="token comment"># ❌ This runs 11 times instead of 10</span> count <span class="token operator"><-</span> <span class="token number">0</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>count <span class="token operator"><=</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># When count becomes 10, it's still <= 10</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Count:"</span><span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">)</span> count <span class="token operator"><-</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Runs when count is 0..10 (11 iterations)</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ This runs exactly 10 times</span> count <span class="token operator"><-</span> <span class="token number">0</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>count <span class="token operator"><</span> <span class="token number">10</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Stops when count reaches 10</span> print<span class="token punctuation">(</span>paste<span class="token punctuation">(</span><span class="token string">"Count:"</span><span class="token punctuation">,</span> count<span class="token punctuation">)</span><span class="token punctuation">)</span> count <span class="token operator"><-</span> count <span class="token operator">+</span> <span class="token number">1</span> <span class="token comment"># Runs when count is 0..9 (10 iterations)</span> <span class="token punctuation">}</span> |
Mistake 4: Not Handling Edge Cases
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<span class="token comment"># ❌ What if target is already satisfied?</span> target <span class="token operator"><-</span> <span class="token number">0</span> sum <span class="token operator"><-</span> <span class="token number">0</span> numbers <span class="token operator"><-</span> c<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>sum <span class="token operator"><</span> target<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Condition is FALSE immediately</span> <span class="token comment"># This code never runs!</span> numbers <span class="token operator"><-</span> c<span class="token punctuation">(</span>numbers<span class="token punctuation">,</span> sample<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">)</span> sum <span class="token operator"><-</span> sum <span class="token operator">+</span> numbers<span class="token punctuation">[</span>length<span class="token punctuation">(</span>numbers<span class="token punctuation">)</span><span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Check edge cases before the loop</span> target <span class="token operator"><-</span> <span class="token number">0</span> sum <span class="token operator"><-</span> <span class="token number">0</span> numbers <span class="token operator"><-</span> c<span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>sum <span class="token operator"><</span> target<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>sum <span class="token operator"><</span> target<span class="token punctuation">)</span> <span class="token punctuation">{</span> new_num <span class="token operator"><-</span> sample<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span><span class="token number">10</span><span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">)</span> numbers <span class="token operator"><-</span> c<span class="token punctuation">(</span>numbers<span class="token punctuation">,</span> new_num<span class="token punctuation">)</span> sum <span class="token operator"><-</span> sum <span class="token operator">+</span> new_num <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Target already satisfied!"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Mistake 5: Not Having a Safety Exit
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<span class="token comment"># ❌ If the condition never becomes FALSE, this runs forever</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>some_complex_condition<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Complex processing that might not update the condition properly</span> <span class="token punctuation">}</span> <span class="token comment"># ✅ Always include a safety counter</span> max_iterations <span class="token operator"><-</span> <span class="token number">1000</span> iteration <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>some_complex_condition <span class="token operator">&&</span> iteration <span class="token operator"><=</span> max_iterations<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment"># Complex processing</span> iteration <span class="token operator"><-</span> iteration <span class="token operator">+</span> <span class="token number">1</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>iteration <span class="token operator">></span> max_iterations<span class="token punctuation">)</span> <span class="token punctuation">{</span> print<span class="token punctuation">(</span><span class="token string">"Warning: Maximum iterations reached"</span><span class="token punctuation">)</span> <span class="token keyword">break</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Part 10: Performance Considerations
While Loops Can Be Slow in R
R is optimized for vectorized operations, not loops. While loops can be significantly slower than vectorized alternatives.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<span class="token comment"># Slow while loop approach</span> sum_slow <span class="token operator"><-</span> <span class="token number">0</span> i <span class="token operator"><-</span> <span class="token number">1</span> n <span class="token operator"><-</span> <span class="token number">1000000</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>i <span class="token operator"><=</span> n<span class="token punctuation">)</span> <span class="token punctuation">{</span> sum_slow <span class="token operator"><-</span> sum_slow <span class="token operator">+</span> i i <span class="token operator"><-</span> i <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token comment"># Fast vectorized approach</span> sum_fast <span class="token operator"><-</span> sum<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span>n<span class="token punctuation">)</span> <span class="token comment"># Compare performance</span> system.time<span class="token punctuation">(</span><span class="token punctuation">{</span> sum_slow <span class="token operator"><-</span> <span class="token number">0</span> i <span class="token operator"><-</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span>i <span class="token operator"><=</span> <span class="token number">1000000</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> sum_slow <span class="token operator"><-</span> sum_slow <span class="token operator">+</span> i i <span class="token operator"><-</span> i <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment"># This takes noticeable time</span> system.time<span class="token punctuation">(</span><span class="token punctuation">{</span> sum_fast <span class="token operator"><-</span> sum<span class="token punctuation">(</span><span class="token number">1</span><span class="token operator">:</span><span class="token number">1000000</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment"># This is nearly instantaneous</span> |
When While Loops Are Necessary
Sometimes while loops are the right tool, despite being slower:
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
<span class="token comment"># When you need conditional stopping (can't vectorize)</span> find_first_prime_above <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>n<span class="token punctuation">)</span> <span class="token punctuation">{</span> candidate <span class="token operator"><-</span> n <span class="token operator">+</span> <span class="token number">1</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">TRUE</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>all<span class="token punctuation">(</span>candidate <span class="token percent-operator operator">%%</span> <span class="token number">2</span><span class="token operator">:</span>sqrt<span class="token punctuation">(</span>candidate<span class="token punctuation">)</span> <span class="token operator">!=</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> return<span class="token punctuation">(</span>candidate<span class="token punctuation">)</span> <span class="token punctuation">}</span> candidate <span class="token operator"><-</span> candidate <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment"># When processing depends on previous results</span> collatz_sequence <span class="token operator"><-</span> <span class="token keyword">function</span><span class="token punctuation">(</span>start<span class="token punctuation">)</span> <span class="token punctuation">{</span> sequence <span class="token operator"><-</span> c<span class="token punctuation">(</span>start<span class="token punctuation">)</span> current <span class="token operator"><-</span> start <span class="token keyword">while</span> <span class="token punctuation">(</span>current <span class="token operator">!=</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>current <span class="token percent-operator operator">%%</span> <span class="token number">2</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> current <span class="token operator"><-</span> current <span class="token operator">/</span> <span class="token number">2</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> current <span class="token operator"><-</span> <span class="token number">3</span> <span class="token operator">*</span> current <span class="token operator">+</span> <span class="token number">1</span> <span class="token punctuation">}</span> sequence <span class="token operator"><-</span> c<span class="token punctuation">(</span>sequence<span class="token punctuation">,</span> current<span class="token punctuation">)</span> <span class="token punctuation">}</span> return<span class="token punctuation">(</span>sequence<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Summary: The While Loop Philosophy
While loops are your tool for conditional repetition. Master these patterns:
-
Basic counting – Increment a counter until a limit
-
Input validation – Keep asking until input is valid
-
Convergence algorithms – Iterate until precision is reached
-
Event monitoring – Watch for conditions to change
-
Retry logic – Attempt operations until success
Essential components of every while loop:
-
Initialization – Set up variables before the loop
-
Condition – Clear expression that determines continuation
-
Update – Something inside must affect the condition
-
Safety – Always have a maximum iteration safeguard
Remember:
-
While loops are for unknown iteration counts
-
Always update the condition variable
-
Include a safety counter for production code
-
Consider vectorized alternatives when possible
-
Use
breakto exit early,nextto skip iterations
The while loop is like a faithful worker that continues its task until you tell it to stop. Use it wisely, and it will handle your repetitive tasks reliably. Just remember to always give it a clear stopping condition!
Would you like me to elaborate on any specific aspect of while loops or explore more complex real-world examples?
