<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Iteration on IT Comparison</title><link>https://comparison.metacog.co.kr/tags/iteration/</link><description>Recent content in Iteration on IT Comparison</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Sun, 02 Aug 2026 23:45:29 +0900</lastBuildDate><atom:link href="https://comparison.metacog.co.kr/tags/iteration/index.xml" rel="self" type="application/rss+xml"/><item><title>Recursion vs Iteration: Two Ways to Repeat Work</title><link>https://comparison.metacog.co.kr/posts/2026-08-02-recursion-vs-iteration-two-ways-to-repeat-work/</link><pubDate>Sun, 02 Aug 2026 23:45:29 +0900</pubDate><guid>https://comparison.metacog.co.kr/posts/2026-08-02-recursion-vs-iteration-two-ways-to-repeat-work/</guid><description>&lt;h2 id="overview"&gt;Overview&lt;/h2&gt;
&lt;p&gt;Both techniques repeat a computation until some condition is met, but they do it through fundamentally different mechanisms. &lt;strong class="kw"&gt;Recursion&lt;/strong&gt; repeats by having a function call itself on the call stack, while &lt;strong class="kw"&gt;iteration&lt;/strong&gt; repeats by looping over the same stack frame. The choice affects memory usage, readability, and how deep a computation can safely go.&lt;/p&gt;
&lt;h2 id="comparison-diagram"&gt;Comparison Diagram&lt;/h2&gt;
&lt;div class="compare-diagram"&gt;
&lt;svg viewBox="0 0 640 360" xmlns="http://www.w3.org/2000/svg"&gt;&lt;defs&gt;&lt;marker id="arrA" markerWidth="8" markerHeight="8" refX="4" refY="4" orient="auto"&gt;&lt;path d="M0,0 L8,4 L0,8 z" style="fill:var(--compare-a)"/&gt;&lt;/marker&gt;&lt;marker id="arrB" markerWidth="8" markerHeight="8" refX="4" refY="4" orient="auto"&gt;&lt;path d="M0,0 L8,4 L0,8 z" style="fill:var(--compare-b)"/&gt;&lt;/marker&gt;&lt;/defs&gt;&lt;line x1="320" y1="20" x2="320" y2="340" style="stroke:var(--border)" stroke-width="1.5" stroke-dasharray="4 4"/&gt;&lt;text x="160" y="36" text-anchor="middle" style="fill:var(--primary)" font-size="18" font-weight="bold"&gt;Recursion&lt;/text&gt;&lt;text x="480" y="36" text-anchor="middle" style="fill:var(--primary)" font-size="18" font-weight="bold"&gt;Iteration&lt;/text&gt;&lt;text x="160" y="58" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;call stack&lt;/text&gt;&lt;rect x="60" y="66" width="200" height="32" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="160" y="87" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;f(n)&lt;/text&gt;&lt;rect x="60" y="104" width="200" height="32" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="160" y="125" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;f(n-1)&lt;/text&gt;&lt;rect x="60" y="142" width="200" height="32" rx="4" style="fill:var(--compare-a-soft);stroke:var(--compare-a)" stroke-width="1.5"/&gt;&lt;text x="160" y="163" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;f(n-2)&lt;/text&gt;&lt;rect x="60" y="180" width="200" height="26" rx="4" style="fill:none;stroke:var(--border)" stroke-width="1.5" stroke-dasharray="4 3"/&gt;&lt;text x="160" y="197" text-anchor="middle" style="fill:var(--secondary)" font-size="13"&gt;...&lt;/text&gt;&lt;line x1="278" y1="70" x2="278" y2="200" style="stroke:var(--compare-a)" stroke-width="1.5" marker-end="url(#arrA)"/&gt;&lt;text x="160" y="230" text-anchor="middle" style="fill:var(--secondary)" font-size="12"&gt;new frame per call&lt;/text&gt;&lt;text x="160" y="300" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;O(n) stack memory&lt;/text&gt;&lt;text x="160" y="318" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;risk: stack overflow&lt;/text&gt;&lt;text x="480" y="58" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;loop body (single frame)&lt;/text&gt;&lt;rect x="390" y="140" width="180" height="40" rx="4" style="fill:var(--compare-b-soft);stroke:var(--compare-b)" stroke-width="1.5"/&gt;&lt;text x="480" y="165" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;while / for&lt;/text&gt;&lt;path d="M 560 185 C 560 225 400 225 400 185" style="stroke:var(--compare-b);fill:none" stroke-width="1.5" marker-end="url(#arrB)"/&gt;&lt;text x="480" y="245" text-anchor="middle" style="fill:var(--secondary)" font-size="12"&gt;i++, same frame reused&lt;/text&gt;&lt;text x="480" y="300" text-anchor="middle" style="fill:var(--content)" font-size="13"&gt;O(1) stack memory&lt;/text&gt;&lt;text x="480" y="318" text-anchor="middle" style="fill:var(--secondary)" font-size="11"&gt;no growth per cycle&lt;/text&gt;&lt;/svg&gt;
&lt;/div&gt;
&lt;h2 id="comparison-table"&gt;Comparison Table&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Recursion&lt;/th&gt;
&lt;th&gt;Iteration&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Core mechanism&lt;/td&gt;
&lt;td&gt;Function calls itself with a smaller subproblem&lt;/td&gt;
&lt;td&gt;Explicit loop (for/while) repeats a block of code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Termination condition&lt;/td&gt;
&lt;td&gt;A base case stops further calls&lt;/td&gt;
&lt;td&gt;A loop condition evaluates to false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;State storage&lt;/td&gt;
&lt;td&gt;Held implicitly in parameters and locals of each stack frame&lt;/td&gt;
&lt;td&gt;Held explicitly in variables updated each pass&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory usage&lt;/td&gt;
&lt;td&gt;O(n) call stack space, one new frame per call&lt;/td&gt;
&lt;td&gt;O(1) auxiliary space, the same frame is reused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failure mode&lt;/td&gt;
&lt;td&gt;Stack overflow on deep or unbounded recursion&lt;/td&gt;
&lt;td&gt;Infinite loop if the condition never turns false&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance overhead&lt;/td&gt;
&lt;td&gt;Function-call overhead per level unless tail-call optimized&lt;/td&gt;
&lt;td&gt;No call overhead, just a branch/jump back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best-fit problems&lt;/td&gt;
&lt;td&gt;Tree/graph traversal, divide-and-conquer, backtracking&lt;/td&gt;
&lt;td&gt;Linear, bounded repetition like counting or array scans&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="key-differences"&gt;Key Differences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Recursion breaks a problem into &lt;strong class="kw"&gt;self-similar subcalls&lt;/strong&gt;; iteration repeats a block via an explicit loop.&lt;/li&gt;
&lt;li&gt;Recursion grows the &lt;strong class="kw"&gt;call stack&lt;/strong&gt; by one frame per call; iteration reuses a single frame.&lt;/li&gt;
&lt;li&gt;Deep recursion risks &lt;strong class="kw"&gt;stack overflow&lt;/strong&gt;, while iteration&amp;rsquo;s main failure mode is an infinite loop.&lt;/li&gt;
&lt;li&gt;Some languages apply &lt;strong class="kw"&gt;tail-call optimization&lt;/strong&gt; to turn tail recursion into iteration under the hood.&lt;/li&gt;
&lt;li&gt;Recursion maps naturally onto &lt;strong class="kw"&gt;trees and graphs&lt;/strong&gt;; iteration suits flat, bounded repetition.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="when-to-use-each"&gt;When to Use Each&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Recursion&lt;/strong&gt;&lt;/p&gt;</description></item></channel></rss>