[{"data":1,"prerenderedAt":5009},["ShallowReactive",2],{"page-\u002Flua\u002F04-control-flow":3},{"id":4,"title":5,"body":6,"description":5000,"extension":5001,"meta":5002,"navigation":220,"path":5003,"seo":5004,"stem":5007,"__hash__":5008},"content\u002Flua\u002F04-control-flow.md","Lua 04 — Control Flow, Dispatch Tables & Iterator Protocols",{"type":7,"value":8,"toc":4976},"minimark",[9,14,83,94,479,486,2444,2450,3538,3542,4016,4029,4198,4204,4972],[10,11,13],"h1",{"id":12},"_04-control-flow-dispatch-tables-iterator-protocols","04 — Control Flow, Dispatch Tables & Iterator Protocols",[15,16,17,18,22,23,22,26,29,30,29,33,22,36,39,40,43,44,46,47,29,50,53,54,57,58,61,62,65,66,70,71,74,75,78,79,82],"p",{},"Lua's control flow is minimal: ",[19,20,21],"code",{},"if","\u002F",[19,24,25],{},"elseif",[19,27,28],{},"else",", ",[19,31,32],{},"while",[19,34,35],{},"repeat",[19,37,38],{},"until",", numeric ",[19,41,42],{},"for",", generic ",[19,45,42],{}," (iterator protocol), ",[19,48,49],{},"break",[19,51,52],{},"goto","\u002Flabels, and ",[19,55,56],{},"return",". No ",[19,59,60],{},"switch",", no ",[19,63,64],{},"continue",", no ternary expression. Production Lua replaces these with ",[67,68,69],"strong",{},"table dispatch"," (O(1) switch), ",[67,72,73],{},"custom iterators"," (the ",[19,76,77],{},"for k, v in iter() do"," protocol), and ",[67,80,81],{},"goto for state machines",".",[84,85,87,22,89,22,91,93],"h2",{"id":86},"ifelseifelse-statement-not-expression",[19,88,21],{},[19,90,25],{},[19,92,28],{}," — Statement, Not Expression",[95,96,98],"code-wrapper",{"language":97},"lua",[99,100,104],"pre",{"className":101,"code":102,"language":97,"meta":103,"style":103},"language-lua shiki shiki-themes github-light github-dark","-- if is a STATEMENT — no value, can't use inline in expressions\nlocal x = 10\nif x > 5 then\n  print(\"big\")\nelseif x > 0 then\n  print(\"medium\")\nelse\n  print(\"small\")\nend\n\n-- No ternary. `and`\u002F`or` short-circuit is the closest, but with a trap:\nlocal x = false\nlocal result = x and \"yes\" or \"no\"  -- \"no\" (correct here)\n\nlocal y = nil\nlocal result2 = y and \"yes\" or \"no\"  -- \"no\" (correct here)\n\n-- TRAP: if the \"true\" branch value is itself falsy, or returns the wrong thing\nlocal z = true\nlocal bad = z and nil or \"fallback\"  -- \"fallback\" — BUG: wanted nil when z is true!\n-- Because: z and nil → nil (falsy), so `or \"fallback\"` → \"fallback\"\n\n-- Safe ternary: wrap in a table to force truthiness\nlocal safe = z and {nil} or {\"fallback\"}  -- always a 1-element table\nlocal value = safe[1]  -- nil or \"fallback\" (unwrapped correctly)\n\n-- Production: just use if\u002Felse. It's clearer and has no trap.\nlocal value\nif z then value = nil else value = \"fallback\" end\n","",[19,105,106,115,133,149,165,179,191,197,209,215,222,228,240,267,272,285,307,312,318,331,357,363,368,374,410,432,437,443,451],{"__ignoreMap":103},[107,108,111],"span",{"class":109,"line":110},"line",1,[107,112,114],{"class":113},"sdCPZ","-- if is a STATEMENT — no value, can't use inline in expressions\n",[107,116,118,122,126,129],{"class":109,"line":117},2,[107,119,121],{"class":120},"svdQ7","local",[107,123,125],{"class":124},"ssxIu"," x ",[107,127,128],{"class":120},"=",[107,130,132],{"class":131},"snvgF"," 10\n",[107,134,136,138,140,143,146],{"class":109,"line":135},3,[107,137,21],{"class":120},[107,139,125],{"class":124},[107,141,142],{"class":120},">",[107,144,145],{"class":131}," 5",[107,147,148],{"class":120}," then\n",[107,150,152,155,158,162],{"class":109,"line":151},4,[107,153,154],{"class":131},"  print",[107,156,157],{"class":124},"(",[107,159,161],{"class":160},"sJ6F3","\"big\"",[107,163,164],{"class":124},")\n",[107,166,168,170,172,174,177],{"class":109,"line":167},5,[107,169,25],{"class":120},[107,171,125],{"class":124},[107,173,142],{"class":120},[107,175,176],{"class":131}," 0",[107,178,148],{"class":120},[107,180,182,184,186,189],{"class":109,"line":181},6,[107,183,154],{"class":131},[107,185,157],{"class":124},[107,187,188],{"class":160},"\"medium\"",[107,190,164],{"class":124},[107,192,194],{"class":109,"line":193},7,[107,195,196],{"class":120},"else\n",[107,198,200,202,204,207],{"class":109,"line":199},8,[107,201,154],{"class":131},[107,203,157],{"class":124},[107,205,206],{"class":160},"\"small\"",[107,208,164],{"class":124},[107,210,212],{"class":109,"line":211},9,[107,213,214],{"class":120},"end\n",[107,216,218],{"class":109,"line":217},10,[107,219,221],{"emptyLinePlaceholder":220},true,"\n",[107,223,225],{"class":109,"line":224},11,[107,226,227],{"class":113},"-- No ternary. `and`\u002F`or` short-circuit is the closest, but with a trap:\n",[107,229,231,233,235,237],{"class":109,"line":230},12,[107,232,121],{"class":120},[107,234,125],{"class":124},[107,236,128],{"class":120},[107,238,239],{"class":131}," false\n",[107,241,243,245,248,250,252,255,258,261,264],{"class":109,"line":242},13,[107,244,121],{"class":120},[107,246,247],{"class":124}," result ",[107,249,128],{"class":120},[107,251,125],{"class":124},[107,253,254],{"class":120},"and",[107,256,257],{"class":160}," \"yes\" ",[107,259,260],{"class":120},"or",[107,262,263],{"class":160}," \"no\"  ",[107,265,266],{"class":113},"-- \"no\" (correct here)\n",[107,268,270],{"class":109,"line":269},14,[107,271,221],{"emptyLinePlaceholder":220},[107,273,275,277,280,282],{"class":109,"line":274},15,[107,276,121],{"class":120},[107,278,279],{"class":124}," y ",[107,281,128],{"class":120},[107,283,284],{"class":131}," nil\n",[107,286,288,290,293,295,297,299,301,303,305],{"class":109,"line":287},16,[107,289,121],{"class":120},[107,291,292],{"class":124}," result2 ",[107,294,128],{"class":120},[107,296,279],{"class":124},[107,298,254],{"class":120},[107,300,257],{"class":160},[107,302,260],{"class":120},[107,304,263],{"class":160},[107,306,266],{"class":113},[107,308,310],{"class":109,"line":309},17,[107,311,221],{"emptyLinePlaceholder":220},[107,313,315],{"class":109,"line":314},18,[107,316,317],{"class":113},"-- TRAP: if the \"true\" branch value is itself falsy, or returns the wrong thing\n",[107,319,321,323,326,328],{"class":109,"line":320},19,[107,322,121],{"class":120},[107,324,325],{"class":124}," z ",[107,327,128],{"class":120},[107,329,330],{"class":131}," true\n",[107,332,334,336,339,341,343,345,348,351,354],{"class":109,"line":333},20,[107,335,121],{"class":120},[107,337,338],{"class":124}," bad ",[107,340,128],{"class":120},[107,342,325],{"class":124},[107,344,254],{"class":120},[107,346,347],{"class":131}," nil",[107,349,350],{"class":120}," or",[107,352,353],{"class":160}," \"fallback\"  ",[107,355,356],{"class":113},"-- \"fallback\" — BUG: wanted nil when z is true!\n",[107,358,360],{"class":109,"line":359},21,[107,361,362],{"class":113},"-- Because: z and nil → nil (falsy), so `or \"fallback\"` → \"fallback\"\n",[107,364,366],{"class":109,"line":365},22,[107,367,221],{"emptyLinePlaceholder":220},[107,369,371],{"class":109,"line":370},23,[107,372,373],{"class":113},"-- Safe ternary: wrap in a table to force truthiness\n",[107,375,377,379,382,384,386,388,391,394,397,399,401,404,407],{"class":109,"line":376},24,[107,378,121],{"class":120},[107,380,381],{"class":124}," safe ",[107,383,128],{"class":120},[107,385,325],{"class":124},[107,387,254],{"class":120},[107,389,390],{"class":124}," {",[107,392,393],{"class":131},"nil",[107,395,396],{"class":124},"} ",[107,398,260],{"class":120},[107,400,390],{"class":124},[107,402,403],{"class":160},"\"fallback\"",[107,405,406],{"class":124},"}  ",[107,408,409],{"class":113},"-- always a 1-element table\n",[107,411,413,415,418,420,423,426,429],{"class":109,"line":412},25,[107,414,121],{"class":120},[107,416,417],{"class":124}," value ",[107,419,128],{"class":120},[107,421,422],{"class":124}," safe[",[107,424,425],{"class":131},"1",[107,427,428],{"class":124},"]  ",[107,430,431],{"class":113},"-- nil or \"fallback\" (unwrapped correctly)\n",[107,433,435],{"class":109,"line":434},26,[107,436,221],{"emptyLinePlaceholder":220},[107,438,440],{"class":109,"line":439},27,[107,441,442],{"class":113},"-- Production: just use if\u002Felse. It's clearer and has no trap.\n",[107,444,446,448],{"class":109,"line":445},28,[107,447,121],{"class":120},[107,449,450],{"class":124}," value\n",[107,452,454,456,458,461,463,465,467,470,472,474,477],{"class":109,"line":453},29,[107,455,21],{"class":120},[107,457,325],{"class":124},[107,459,460],{"class":120},"then",[107,462,417],{"class":124},[107,464,128],{"class":120},[107,466,347],{"class":131},[107,468,469],{"class":120}," else",[107,471,417],{"class":124},[107,473,128],{"class":120},[107,475,476],{"class":160}," \"fallback\" ",[107,478,214],{"class":120},[84,480,482,483,485],{"id":481},"numeric-for-precise-semantics","Numeric ",[19,484,42],{}," — Precise Semantics",[95,487,488,805,813,924,931,941,1049,1785,1789,1971,1981],{"language":97},[99,489,491],{"className":101,"code":490,"language":97,"meta":103,"style":103},"-- for v = e1, e2, e3 do ... end\n-- e1=start, e2=limit, e3=step (default 1)\n-- Evaluates e1, e2, e3 ONCE before the loop (then iterates with integer\u002Ffloat math)\n\n-- Integer loop: exact, stops when v > limit (for positive step)\nfor i = 1, 5 do print(i) end     -- 1 2 3 4 5\nfor i = 5, 1, -1 do print(i) end -- 5 4 3 2 1\nfor i = 0, 10, 2 do print(i) end -- 0 2 4 6 8 10\n\n-- Float loop: CAUTION — floating point error accumulates\nfor i = 0.1, 1.0, 0.1 do print(i) end\n-- Prints: 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 — but only by luck\n-- 0.1+0.1+0.1 = 0.30000000000000004 in float — loop may stop early or late\n\n-- SAFE float loop: use integer counter, compute float from it\nfor i = 1, 10 do\n  local x = i * 0.1  -- 0.1, 0.2, ... 1.0 (exact multiplication, no accumulation)\n  print(x)\nend\n\n-- Loop variable is local to the loop body — fresh each iteration (for closures)\nlocal fns = {}\nfor i = 1, 3 do\n  fns[i] = function() return i end  -- each captures its own i (per-iteration local)\nend\nprint(fns[1](), fns[2](), fns[3]())  -- 1 2 3 (NOT 3 3 3)\n",[19,492,493,498,503,508,512,517,549,581,612,616,621,650,655,660,664,669,686,705,712,716,720,725,737,754,776,780],{"__ignoreMap":103},[107,494,495],{"class":109,"line":110},[107,496,497],{"class":113},"-- for v = e1, e2, e3 do ... end\n",[107,499,500],{"class":109,"line":117},[107,501,502],{"class":113},"-- e1=start, e2=limit, e3=step (default 1)\n",[107,504,505],{"class":109,"line":135},[107,506,507],{"class":113},"-- Evaluates e1, e2, e3 ONCE before the loop (then iterates with integer\u002Ffloat math)\n",[107,509,510],{"class":109,"line":151},[107,511,221],{"emptyLinePlaceholder":220},[107,513,514],{"class":109,"line":167},[107,515,516],{"class":113},"-- Integer loop: exact, stops when v > limit (for positive step)\n",[107,518,519,521,524,526,529,531,534,537,540,543,546],{"class":109,"line":181},[107,520,42],{"class":120},[107,522,523],{"class":124}," i ",[107,525,128],{"class":120},[107,527,528],{"class":131}," 1",[107,530,29],{"class":124},[107,532,533],{"class":131},"5",[107,535,536],{"class":120}," do",[107,538,539],{"class":131}," print",[107,541,542],{"class":124},"(i) ",[107,544,545],{"class":120},"end",[107,547,548],{"class":113},"     -- 1 2 3 4 5\n",[107,550,551,553,555,557,559,561,563,565,568,570,572,574,576,578],{"class":109,"line":193},[107,552,42],{"class":120},[107,554,523],{"class":124},[107,556,128],{"class":120},[107,558,145],{"class":131},[107,560,29],{"class":124},[107,562,425],{"class":131},[107,564,29],{"class":124},[107,566,567],{"class":120},"-",[107,569,425],{"class":131},[107,571,536],{"class":120},[107,573,539],{"class":131},[107,575,542],{"class":124},[107,577,545],{"class":120},[107,579,580],{"class":113}," -- 5 4 3 2 1\n",[107,582,583,585,587,589,591,593,596,598,601,603,605,607,609],{"class":109,"line":199},[107,584,42],{"class":120},[107,586,523],{"class":124},[107,588,128],{"class":120},[107,590,176],{"class":131},[107,592,29],{"class":124},[107,594,595],{"class":131},"10",[107,597,29],{"class":124},[107,599,600],{"class":131},"2",[107,602,536],{"class":120},[107,604,539],{"class":131},[107,606,542],{"class":124},[107,608,545],{"class":120},[107,610,611],{"class":113}," -- 0 2 4 6 8 10\n",[107,613,614],{"class":109,"line":211},[107,615,221],{"emptyLinePlaceholder":220},[107,617,618],{"class":109,"line":217},[107,619,620],{"class":113},"-- Float loop: CAUTION — floating point error accumulates\n",[107,622,623,625,627,629,632,634,637,639,642,644,646,648],{"class":109,"line":224},[107,624,42],{"class":120},[107,626,523],{"class":124},[107,628,128],{"class":120},[107,630,631],{"class":131}," 0.1",[107,633,29],{"class":124},[107,635,636],{"class":131},"1.0",[107,638,29],{"class":124},[107,640,641],{"class":131},"0.1",[107,643,536],{"class":120},[107,645,539],{"class":131},[107,647,542],{"class":124},[107,649,214],{"class":120},[107,651,652],{"class":109,"line":230},[107,653,654],{"class":113},"-- Prints: 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 — but only by luck\n",[107,656,657],{"class":109,"line":242},[107,658,659],{"class":113},"-- 0.1+0.1+0.1 = 0.30000000000000004 in float — loop may stop early or late\n",[107,661,662],{"class":109,"line":269},[107,663,221],{"emptyLinePlaceholder":220},[107,665,666],{"class":109,"line":274},[107,667,668],{"class":113},"-- SAFE float loop: use integer counter, compute float from it\n",[107,670,671,673,675,677,679,681,683],{"class":109,"line":287},[107,672,42],{"class":120},[107,674,523],{"class":124},[107,676,128],{"class":120},[107,678,528],{"class":131},[107,680,29],{"class":124},[107,682,595],{"class":131},[107,684,685],{"class":120}," do\n",[107,687,688,691,693,695,697,700,702],{"class":109,"line":309},[107,689,690],{"class":120},"  local",[107,692,125],{"class":124},[107,694,128],{"class":120},[107,696,523],{"class":124},[107,698,699],{"class":120},"*",[107,701,631],{"class":131},[107,703,704],{"class":113},"  -- 0.1, 0.2, ... 1.0 (exact multiplication, no accumulation)\n",[107,706,707,709],{"class":109,"line":314},[107,708,154],{"class":131},[107,710,711],{"class":124},"(x)\n",[107,713,714],{"class":109,"line":320},[107,715,214],{"class":120},[107,717,718],{"class":109,"line":333},[107,719,221],{"emptyLinePlaceholder":220},[107,721,722],{"class":109,"line":359},[107,723,724],{"class":113},"-- Loop variable is local to the loop body — fresh each iteration (for closures)\n",[107,726,727,729,732,734],{"class":109,"line":365},[107,728,121],{"class":120},[107,730,731],{"class":124}," fns ",[107,733,128],{"class":120},[107,735,736],{"class":124}," {}\n",[107,738,739,741,743,745,747,749,752],{"class":109,"line":370},[107,740,42],{"class":120},[107,742,523],{"class":124},[107,744,128],{"class":120},[107,746,528],{"class":131},[107,748,29],{"class":124},[107,750,751],{"class":131},"3",[107,753,685],{"class":120},[107,755,756,759,761,764,767,769,771,773],{"class":109,"line":376},[107,757,758],{"class":124},"  fns[i] ",[107,760,128],{"class":120},[107,762,763],{"class":120}," function",[107,765,766],{"class":124},"() ",[107,768,56],{"class":120},[107,770,523],{"class":124},[107,772,545],{"class":120},[107,774,775],{"class":113},"  -- each captures its own i (per-iteration local)\n",[107,777,778],{"class":109,"line":412},[107,779,214],{"class":120},[107,781,782,785,788,790,793,795,797,799,802],{"class":109,"line":434},[107,783,784],{"class":131},"print",[107,786,787],{"class":124},"(fns[",[107,789,425],{"class":131},[107,791,792],{"class":124},"](), fns[",[107,794,600],{"class":131},[107,796,792],{"class":124},[107,798,751],{"class":131},[107,800,801],{"class":124},"]())  ",[107,803,804],{"class":113},"-- 1 2 3 (NOT 3 3 3)\n",[806,807,809,810,812],"h3",{"id":808},"edge-case-for-with-nan-or-inf-limits","Edge case: ",[19,811,42],{}," with NaN or inf limits",[95,814,815],{"language":97},[99,816,818],{"className":101,"code":817,"language":97,"meta":103,"style":103},"for i = 1, math.huge do\n  if i > 100 then break end  -- infinite loop without break: math.huge as limit\nend\n\n-- NaN limit: loop body never executes (NaN comparisons are always false)\nfor i = 1, 0\u002F0 do print(\"never\") end  -- 0\u002F0 = NaN; i \u003C= NaN is false; no iterations\n\n-- Zero step: infinite loop (v never changes)\n-- for i = 1, 5, 0 do print(i) end  -- INFINITE LOOP — never terminates\n",[19,819,820,837,861,865,869,874,910,914,919],{"__ignoreMap":103},[107,821,822,824,826,828,830,832,835],{"class":109,"line":110},[107,823,42],{"class":120},[107,825,523],{"class":124},[107,827,128],{"class":120},[107,829,528],{"class":131},[107,831,29],{"class":124},[107,833,834],{"class":131},"math.huge",[107,836,685],{"class":120},[107,838,839,842,844,846,849,852,855,858],{"class":109,"line":117},[107,840,841],{"class":120},"  if",[107,843,523],{"class":124},[107,845,142],{"class":120},[107,847,848],{"class":131}," 100",[107,850,851],{"class":120}," then",[107,853,854],{"class":120}," break",[107,856,857],{"class":120}," end",[107,859,860],{"class":113},"  -- infinite loop without break: math.huge as limit\n",[107,862,863],{"class":109,"line":135},[107,864,214],{"class":120},[107,866,867],{"class":109,"line":151},[107,868,221],{"emptyLinePlaceholder":220},[107,870,871],{"class":109,"line":167},[107,872,873],{"class":113},"-- NaN limit: loop body never executes (NaN comparisons are always false)\n",[107,875,876,878,880,882,884,886,889,891,893,895,897,899,902,905,907],{"class":109,"line":181},[107,877,42],{"class":120},[107,879,523],{"class":124},[107,881,128],{"class":120},[107,883,528],{"class":131},[107,885,29],{"class":124},[107,887,888],{"class":131},"0",[107,890,22],{"class":120},[107,892,888],{"class":131},[107,894,536],{"class":120},[107,896,539],{"class":131},[107,898,157],{"class":124},[107,900,901],{"class":160},"\"never\"",[107,903,904],{"class":124},") ",[107,906,545],{"class":120},[107,908,909],{"class":113},"  -- 0\u002F0 = NaN; i \u003C= NaN is false; no iterations\n",[107,911,912],{"class":109,"line":193},[107,913,221],{"emptyLinePlaceholder":220},[107,915,916],{"class":109,"line":199},[107,917,918],{"class":113},"-- Zero step: infinite loop (v never changes)\n",[107,920,921],{"class":109,"line":211},[107,922,923],{"class":113},"-- for i = 1, 5, 0 do print(i) end  -- INFINITE LOOP — never terminates\n",[84,925,927,928,930],{"id":926},"generic-for-the-iterator-protocol","Generic ",[19,929,42],{}," — The Iterator Protocol",[15,932,933,934,936,937,940],{},"The generic ",[19,935,42],{}," loop: ",[19,938,939],{},"for var_1, ..., var_n in explist do ... end"," desugars to:",[99,942,944],{"className":101,"code":943,"language":97,"meta":103,"style":103},"do\n  local f, s, var = explist      -- iterator function, state, initial control variable\n  while true do\n    local results = f(s, var)     -- call: f(state, prev_control_var)\n    var = results[1]              -- (but using actual MRV: var1, var2, ... = f(s, var))\n    if var == nil then break end  -- loop ends when first return value is nil\n    -- loop body with var1, ..., varn in scope\n  end\nend\n",[19,945,946,951,966,976,995,1013,1035,1040,1045],{"__ignoreMap":103},[107,947,948],{"class":109,"line":110},[107,949,950],{"class":120},"do\n",[107,952,953,955,958,960,963],{"class":109,"line":117},[107,954,690],{"class":120},[107,956,957],{"class":124}," f, s, var ",[107,959,128],{"class":120},[107,961,962],{"class":124}," explist      ",[107,964,965],{"class":113},"-- iterator function, state, initial control variable\n",[107,967,968,971,974],{"class":109,"line":135},[107,969,970],{"class":120},"  while",[107,972,973],{"class":131}," true",[107,975,685],{"class":120},[107,977,978,981,984,986,989,992],{"class":109,"line":151},[107,979,980],{"class":120},"    local",[107,982,983],{"class":124}," results ",[107,985,128],{"class":120},[107,987,988],{"class":131}," f",[107,990,991],{"class":124},"(s, var)     ",[107,993,994],{"class":113},"-- call: f(state, prev_control_var)\n",[107,996,997,1000,1002,1005,1007,1010],{"class":109,"line":167},[107,998,999],{"class":124},"    var ",[107,1001,128],{"class":120},[107,1003,1004],{"class":124}," results[",[107,1006,425],{"class":131},[107,1008,1009],{"class":124},"]              ",[107,1011,1012],{"class":113},"-- (but using actual MRV: var1, var2, ... = f(s, var))\n",[107,1014,1015,1018,1021,1024,1026,1028,1030,1032],{"class":109,"line":181},[107,1016,1017],{"class":120},"    if",[107,1019,1020],{"class":124}," var ",[107,1022,1023],{"class":120},"==",[107,1025,347],{"class":131},[107,1027,851],{"class":120},[107,1029,854],{"class":120},[107,1031,857],{"class":120},[107,1033,1034],{"class":113},"  -- loop ends when first return value is nil\n",[107,1036,1037],{"class":109,"line":193},[107,1038,1039],{"class":113},"    -- loop body with var1, ..., varn in scope\n",[107,1041,1042],{"class":109,"line":199},[107,1043,1044],{"class":120},"  end\n",[107,1046,1047],{"class":109,"line":211},[107,1048,214],{"class":120},[95,1050,1051,1269,1273],{"language":97},[99,1052,1054],{"className":101,"code":1053,"language":97,"meta":103,"style":103},"-- ipairs: stateless iterator over array part (1..n)\n-- f = ipairs iterator fn, s = the table, var = current index (starts at 0)\nlocal function ipairs_iter(t, i)\n  i = i + 1\n  local v = t[i]\n  if v ~= nil then return i, v end  -- return (index, value) — nil v ends loop\n  return nil                         -- first return nil → loop terminates\nend\nlocal function my_ipairs(t) return ipairs_iter, t, 0 end\n\nfor i, v in my_ipairs({10, 20, 30}) do print(i, v) end\n-- 1 10 \u002F 2 20 \u002F 3 30\n\n-- pairs: iterate ALL keys (array + hash), order undefined\n-- Uses next() as the iterator: next(t, k) returns (next_key, next_value) or nil\nfor k, v in pairs({a = 1, b = 2}) do print(k, v) end  -- a 1 \u002F b 2 (or b 2 \u002F a 1)\n",[19,1055,1056,1061,1066,1079,1094,1106,1130,1140,1144,1166,1170,1209,1214,1218,1223,1228],{"__ignoreMap":103},[107,1057,1058],{"class":109,"line":110},[107,1059,1060],{"class":113},"-- ipairs: stateless iterator over array part (1..n)\n",[107,1062,1063],{"class":109,"line":117},[107,1064,1065],{"class":113},"-- f = ipairs iterator fn, s = the table, var = current index (starts at 0)\n",[107,1067,1068,1070,1072,1076],{"class":109,"line":135},[107,1069,121],{"class":120},[107,1071,763],{"class":120},[107,1073,1075],{"class":1074},"sIsaT"," ipairs_iter",[107,1077,1078],{"class":124},"(t, i)\n",[107,1080,1081,1084,1086,1088,1091],{"class":109,"line":151},[107,1082,1083],{"class":124},"  i ",[107,1085,128],{"class":120},[107,1087,523],{"class":124},[107,1089,1090],{"class":120},"+",[107,1092,1093],{"class":131}," 1\n",[107,1095,1096,1098,1101,1103],{"class":109,"line":167},[107,1097,690],{"class":120},[107,1099,1100],{"class":124}," v ",[107,1102,128],{"class":120},[107,1104,1105],{"class":124}," t[i]\n",[107,1107,1108,1110,1112,1115,1117,1119,1122,1125,1127],{"class":109,"line":181},[107,1109,841],{"class":120},[107,1111,1100],{"class":124},[107,1113,1114],{"class":120},"~=",[107,1116,347],{"class":131},[107,1118,851],{"class":120},[107,1120,1121],{"class":120}," return",[107,1123,1124],{"class":124}," i, v ",[107,1126,545],{"class":120},[107,1128,1129],{"class":113},"  -- return (index, value) — nil v ends loop\n",[107,1131,1132,1135,1137],{"class":109,"line":193},[107,1133,1134],{"class":120},"  return",[107,1136,347],{"class":131},[107,1138,1139],{"class":113},"                         -- first return nil → loop terminates\n",[107,1141,1142],{"class":109,"line":199},[107,1143,214],{"class":120},[107,1145,1146,1148,1150,1153,1156,1158,1161,1163],{"class":109,"line":211},[107,1147,121],{"class":120},[107,1149,763],{"class":120},[107,1151,1152],{"class":1074}," my_ipairs",[107,1154,1155],{"class":124},"(t) ",[107,1157,56],{"class":120},[107,1159,1160],{"class":124}," ipairs_iter, t, ",[107,1162,888],{"class":131},[107,1164,1165],{"class":120}," end\n",[107,1167,1168],{"class":109,"line":217},[107,1169,221],{"emptyLinePlaceholder":220},[107,1171,1172,1174,1176,1179,1181,1184,1186,1188,1191,1193,1196,1199,1202,1204,1207],{"class":109,"line":224},[107,1173,42],{"class":120},[107,1175,1124],{"class":124},[107,1177,1178],{"class":120},"in",[107,1180,1152],{"class":131},[107,1182,1183],{"class":124},"({",[107,1185,595],{"class":131},[107,1187,29],{"class":124},[107,1189,1190],{"class":131},"20",[107,1192,29],{"class":124},[107,1194,1195],{"class":131},"30",[107,1197,1198],{"class":124},"}) ",[107,1200,1201],{"class":120},"do",[107,1203,539],{"class":131},[107,1205,1206],{"class":124},"(i, v) ",[107,1208,214],{"class":120},[107,1210,1211],{"class":109,"line":230},[107,1212,1213],{"class":113},"-- 1 10 \u002F 2 20 \u002F 3 30\n",[107,1215,1216],{"class":109,"line":242},[107,1217,221],{"emptyLinePlaceholder":220},[107,1219,1220],{"class":109,"line":269},[107,1221,1222],{"class":113},"-- pairs: iterate ALL keys (array + hash), order undefined\n",[107,1224,1225],{"class":109,"line":274},[107,1226,1227],{"class":113},"-- Uses next() as the iterator: next(t, k) returns (next_key, next_value) or nil\n",[107,1229,1230,1232,1235,1237,1240,1243,1245,1247,1250,1252,1255,1257,1259,1261,1264,1266],{"class":109,"line":287},[107,1231,42],{"class":120},[107,1233,1234],{"class":124}," k, v ",[107,1236,1178],{"class":120},[107,1238,1239],{"class":131}," pairs",[107,1241,1242],{"class":124},"({a ",[107,1244,128],{"class":120},[107,1246,528],{"class":131},[107,1248,1249],{"class":124},", b ",[107,1251,128],{"class":120},[107,1253,1254],{"class":131}," 2",[107,1256,1198],{"class":124},[107,1258,1201],{"class":120},[107,1260,539],{"class":131},[107,1262,1263],{"class":124},"(k, v) ",[107,1265,545],{"class":120},[107,1267,1268],{"class":113},"  -- a 1 \u002F b 2 (or b 2 \u002F a 1)\n",[806,1270,1272],{"id":1271},"custom-iterator-reverse-range-stateless","Custom iterator: reverse range (stateless)",[95,1274,1275,1425,1429],{"language":97},[99,1276,1278],{"className":101,"code":1277,"language":97,"meta":103,"style":103},"-- Stateless: no closure allocation per iteration — pure function + state + control\nlocal function rev_iter(t, i)\n  i = i - 1\n  if i >= 1 then return i, t[i] end  -- return (index, value); nil ends loop\n  return nil\nend\n\nlocal function reverse_ipairs(t)\n  return rev_iter, t, #t + 1  -- f, s, initial_var (start one past end)\nend\n\nfor i, v in reverse_ipairs({\"a\", \"b\", \"c\"}) do print(i, v) end\n-- 3 c \u002F 2 b \u002F 1 a\n",[19,1279,1280,1285,1296,1308,1331,1337,1341,1345,1357,1377,1381,1385,1420],{"__ignoreMap":103},[107,1281,1282],{"class":109,"line":110},[107,1283,1284],{"class":113},"-- Stateless: no closure allocation per iteration — pure function + state + control\n",[107,1286,1287,1289,1291,1294],{"class":109,"line":117},[107,1288,121],{"class":120},[107,1290,763],{"class":120},[107,1292,1293],{"class":1074}," rev_iter",[107,1295,1078],{"class":124},[107,1297,1298,1300,1302,1304,1306],{"class":109,"line":135},[107,1299,1083],{"class":124},[107,1301,128],{"class":120},[107,1303,523],{"class":124},[107,1305,567],{"class":120},[107,1307,1093],{"class":131},[107,1309,1310,1312,1314,1317,1319,1321,1323,1326,1328],{"class":109,"line":151},[107,1311,841],{"class":120},[107,1313,523],{"class":124},[107,1315,1316],{"class":120},">=",[107,1318,528],{"class":131},[107,1320,851],{"class":120},[107,1322,1121],{"class":120},[107,1324,1325],{"class":124}," i, t[i] ",[107,1327,545],{"class":120},[107,1329,1330],{"class":113},"  -- return (index, value); nil ends loop\n",[107,1332,1333,1335],{"class":109,"line":167},[107,1334,1134],{"class":120},[107,1336,284],{"class":131},[107,1338,1339],{"class":109,"line":181},[107,1340,214],{"class":120},[107,1342,1343],{"class":109,"line":193},[107,1344,221],{"emptyLinePlaceholder":220},[107,1346,1347,1349,1351,1354],{"class":109,"line":199},[107,1348,121],{"class":120},[107,1350,763],{"class":120},[107,1352,1353],{"class":1074}," reverse_ipairs",[107,1355,1356],{"class":124},"(t)\n",[107,1358,1359,1361,1364,1367,1370,1372,1374],{"class":109,"line":211},[107,1360,1134],{"class":120},[107,1362,1363],{"class":124}," rev_iter, t, ",[107,1365,1366],{"class":120},"#",[107,1368,1369],{"class":124},"t ",[107,1371,1090],{"class":120},[107,1373,528],{"class":131},[107,1375,1376],{"class":113},"  -- f, s, initial_var (start one past end)\n",[107,1378,1379],{"class":109,"line":217},[107,1380,214],{"class":120},[107,1382,1383],{"class":109,"line":224},[107,1384,221],{"emptyLinePlaceholder":220},[107,1386,1387,1389,1391,1393,1395,1397,1400,1402,1405,1407,1410,1412,1414,1416,1418],{"class":109,"line":230},[107,1388,42],{"class":120},[107,1390,1124],{"class":124},[107,1392,1178],{"class":120},[107,1394,1353],{"class":131},[107,1396,1183],{"class":124},[107,1398,1399],{"class":160},"\"a\"",[107,1401,29],{"class":124},[107,1403,1404],{"class":160},"\"b\"",[107,1406,29],{"class":124},[107,1408,1409],{"class":160},"\"c\"",[107,1411,1198],{"class":124},[107,1413,1201],{"class":120},[107,1415,539],{"class":131},[107,1417,1206],{"class":124},[107,1419,214],{"class":120},[107,1421,1422],{"class":109,"line":242},[107,1423,1424],{"class":113},"-- 3 c \u002F 2 b \u002F 1 a\n",[806,1426,1428],{"id":1427},"custom-iterator-stateful-closure-based","Custom iterator: stateful (closure-based)",[95,1430,1431],{"language":97},[99,1432,1434],{"className":101,"code":1433,"language":97,"meta":103,"style":103},"-- Closure-based: returns a single function that maintains state internally\n-- Simpler to write, but allocates a closure per iteration start\nlocal function range(start, stop, step)\n  step = step or 1\n  local i = start - step\n  return function()\n    i = i + step\n    if (step > 0 and i \u003C= stop) or (step \u003C 0 and i >= stop) then\n      return i\n    end\n  end\nend\n\nfor x in range(1, 5) do print(x) end       -- 1 2 3 4 5\nfor x in range(10, 2, -2) do print(x) end  -- 10 8 6 4 2\n\n-- Generator: fibonacci sequence (infinite — caller controls termination)\nlocal function fib()\n  local a, b = 0, 1\n  return function()\n    a, b = b, a + b  -- parallel assignment: RHS evaluated first\n    return a\n  end\nend\n\nlocal f = fib()\nfor i = 1, 10 do\n  io.write(f(), \" \")\nend\n-- 1 1 2 3 5 8 13 21 34 55\n",[19,1435,1436,1441,1446,1458,1472,1488,1497,1510,1552,1560,1565,1569,1573,1577,1609,1646,1650,1655,1666,1682,1690,1708,1716,1720,1724,1728,1741,1757,1775,1779],{"__ignoreMap":103},[107,1437,1438],{"class":109,"line":110},[107,1439,1440],{"class":113},"-- Closure-based: returns a single function that maintains state internally\n",[107,1442,1443],{"class":109,"line":117},[107,1444,1445],{"class":113},"-- Simpler to write, but allocates a closure per iteration start\n",[107,1447,1448,1450,1452,1455],{"class":109,"line":135},[107,1449,121],{"class":120},[107,1451,763],{"class":120},[107,1453,1454],{"class":1074}," range",[107,1456,1457],{"class":124},"(start, stop, step)\n",[107,1459,1460,1463,1465,1468,1470],{"class":109,"line":151},[107,1461,1462],{"class":124},"  step ",[107,1464,128],{"class":120},[107,1466,1467],{"class":124}," step ",[107,1469,260],{"class":120},[107,1471,1093],{"class":131},[107,1473,1474,1476,1478,1480,1483,1485],{"class":109,"line":167},[107,1475,690],{"class":120},[107,1477,523],{"class":124},[107,1479,128],{"class":120},[107,1481,1482],{"class":124}," start ",[107,1484,567],{"class":120},[107,1486,1487],{"class":124}," step\n",[107,1489,1490,1492,1494],{"class":109,"line":181},[107,1491,1134],{"class":120},[107,1493,763],{"class":120},[107,1495,1496],{"class":124},"()\n",[107,1498,1499,1502,1504,1506,1508],{"class":109,"line":193},[107,1500,1501],{"class":124},"    i ",[107,1503,128],{"class":120},[107,1505,523],{"class":124},[107,1507,1090],{"class":120},[107,1509,1487],{"class":124},[107,1511,1512,1514,1517,1519,1521,1524,1526,1529,1532,1534,1536,1539,1541,1543,1545,1547,1549],{"class":109,"line":199},[107,1513,1017],{"class":120},[107,1515,1516],{"class":124}," (step ",[107,1518,142],{"class":120},[107,1520,176],{"class":131},[107,1522,1523],{"class":120}," and",[107,1525,523],{"class":124},[107,1527,1528],{"class":120},"\u003C=",[107,1530,1531],{"class":124}," stop) ",[107,1533,260],{"class":120},[107,1535,1516],{"class":124},[107,1537,1538],{"class":120},"\u003C",[107,1540,176],{"class":131},[107,1542,1523],{"class":120},[107,1544,523],{"class":124},[107,1546,1316],{"class":120},[107,1548,1531],{"class":124},[107,1550,1551],{"class":120},"then\n",[107,1553,1554,1557],{"class":109,"line":211},[107,1555,1556],{"class":120},"      return",[107,1558,1559],{"class":124}," i\n",[107,1561,1562],{"class":109,"line":217},[107,1563,1564],{"class":120},"    end\n",[107,1566,1567],{"class":109,"line":224},[107,1568,1044],{"class":120},[107,1570,1571],{"class":109,"line":230},[107,1572,214],{"class":120},[107,1574,1575],{"class":109,"line":242},[107,1576,221],{"emptyLinePlaceholder":220},[107,1578,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1604,1606],{"class":109,"line":269},[107,1580,42],{"class":120},[107,1582,125],{"class":124},[107,1584,1178],{"class":120},[107,1586,1454],{"class":131},[107,1588,157],{"class":124},[107,1590,425],{"class":131},[107,1592,29],{"class":124},[107,1594,533],{"class":131},[107,1596,904],{"class":124},[107,1598,1201],{"class":120},[107,1600,539],{"class":131},[107,1602,1603],{"class":124},"(x) ",[107,1605,545],{"class":120},[107,1607,1608],{"class":113},"       -- 1 2 3 4 5\n",[107,1610,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641,1643],{"class":109,"line":274},[107,1612,42],{"class":120},[107,1614,125],{"class":124},[107,1616,1178],{"class":120},[107,1618,1454],{"class":131},[107,1620,157],{"class":124},[107,1622,595],{"class":131},[107,1624,29],{"class":124},[107,1626,600],{"class":131},[107,1628,29],{"class":124},[107,1630,567],{"class":120},[107,1632,600],{"class":131},[107,1634,904],{"class":124},[107,1636,1201],{"class":120},[107,1638,539],{"class":131},[107,1640,1603],{"class":124},[107,1642,545],{"class":120},[107,1644,1645],{"class":113},"  -- 10 8 6 4 2\n",[107,1647,1648],{"class":109,"line":287},[107,1649,221],{"emptyLinePlaceholder":220},[107,1651,1652],{"class":109,"line":309},[107,1653,1654],{"class":113},"-- Generator: fibonacci sequence (infinite — caller controls termination)\n",[107,1656,1657,1659,1661,1664],{"class":109,"line":314},[107,1658,121],{"class":120},[107,1660,763],{"class":120},[107,1662,1663],{"class":1074}," fib",[107,1665,1496],{"class":124},[107,1667,1668,1670,1673,1675,1677,1679],{"class":109,"line":320},[107,1669,690],{"class":120},[107,1671,1672],{"class":124}," a, b ",[107,1674,128],{"class":120},[107,1676,176],{"class":131},[107,1678,29],{"class":124},[107,1680,1681],{"class":131},"1\n",[107,1683,1684,1686,1688],{"class":109,"line":333},[107,1685,1134],{"class":120},[107,1687,763],{"class":120},[107,1689,1496],{"class":124},[107,1691,1692,1695,1697,1700,1702,1705],{"class":109,"line":359},[107,1693,1694],{"class":124},"    a, b ",[107,1696,128],{"class":120},[107,1698,1699],{"class":124}," b, a ",[107,1701,1090],{"class":120},[107,1703,1704],{"class":124}," b  ",[107,1706,1707],{"class":113},"-- parallel assignment: RHS evaluated first\n",[107,1709,1710,1713],{"class":109,"line":365},[107,1711,1712],{"class":120},"    return",[107,1714,1715],{"class":124}," a\n",[107,1717,1718],{"class":109,"line":370},[107,1719,1044],{"class":120},[107,1721,1722],{"class":109,"line":376},[107,1723,214],{"class":120},[107,1725,1726],{"class":109,"line":412},[107,1727,221],{"emptyLinePlaceholder":220},[107,1729,1730,1732,1735,1737,1739],{"class":109,"line":434},[107,1731,121],{"class":120},[107,1733,1734],{"class":124}," f ",[107,1736,128],{"class":120},[107,1738,1663],{"class":131},[107,1740,1496],{"class":124},[107,1742,1743,1745,1747,1749,1751,1753,1755],{"class":109,"line":439},[107,1744,42],{"class":120},[107,1746,523],{"class":124},[107,1748,128],{"class":120},[107,1750,528],{"class":131},[107,1752,29],{"class":124},[107,1754,595],{"class":131},[107,1756,685],{"class":120},[107,1758,1759,1762,1764,1767,1770,1773],{"class":109,"line":445},[107,1760,1761],{"class":131},"  io.write",[107,1763,157],{"class":124},[107,1765,1766],{"class":131},"f",[107,1768,1769],{"class":124},"(), ",[107,1771,1772],{"class":160},"\" \"",[107,1774,164],{"class":124},[107,1776,1777],{"class":109,"line":453},[107,1778,214],{"class":120},[107,1780,1782],{"class":109,"line":1781},30,[107,1783,1784],{"class":113},"-- 1 1 2 3 5 8 13 21 34 55\n",[806,1786,1788],{"id":1787},"iterator-with-coroutine-see-ch11-for-full-coroutines","Iterator with coroutine (see ch11 for full coroutines)",[95,1790,1791],{"language":97},[99,1792,1794],{"className":101,"code":1793,"language":97,"meta":103,"style":103},"-- Coroutines enable complex iteration (e.g., tree traversal) as a simple for-loop\nlocal function tree_preorder(node)\n  return coroutine.wrap(function()\n    local function visit(n)\n      if not n then return end\n      coroutine.yield(n.value)        -- yield each value\n      for _, child in ipairs(n.children or {}) do\n        visit(child)                   -- recurse, yields propagate up\n      end\n    end\n    visit(node)\n  end)\nend\n\n-- Usage: iterate tree like an array, no stack management needed\nfor value in tree_preorder(root_node) do\n  print(value)\nend\n",[19,1795,1796,1801,1813,1827,1839,1856,1873,1898,1909,1914,1918,1925,1932,1936,1940,1945,1960,1967],{"__ignoreMap":103},[107,1797,1798],{"class":109,"line":110},[107,1799,1800],{"class":113},"-- Coroutines enable complex iteration (e.g., tree traversal) as a simple for-loop\n",[107,1802,1803,1805,1807,1810],{"class":109,"line":117},[107,1804,121],{"class":120},[107,1806,763],{"class":120},[107,1808,1809],{"class":1074}," tree_preorder",[107,1811,1812],{"class":124},"(node)\n",[107,1814,1815,1817,1820,1822,1825],{"class":109,"line":135},[107,1816,1134],{"class":120},[107,1818,1819],{"class":131}," coroutine.wrap",[107,1821,157],{"class":124},[107,1823,1824],{"class":120},"function",[107,1826,1496],{"class":124},[107,1828,1829,1831,1833,1836],{"class":109,"line":151},[107,1830,980],{"class":120},[107,1832,763],{"class":120},[107,1834,1835],{"class":1074}," visit",[107,1837,1838],{"class":124},"(n)\n",[107,1840,1841,1844,1847,1850,1852,1854],{"class":109,"line":167},[107,1842,1843],{"class":120},"      if",[107,1845,1846],{"class":120}," not",[107,1848,1849],{"class":124}," n ",[107,1851,460],{"class":120},[107,1853,1121],{"class":120},[107,1855,1165],{"class":120},[107,1857,1858,1861,1864,1867,1870],{"class":109,"line":181},[107,1859,1860],{"class":131},"      coroutine.yield",[107,1862,1863],{"class":124},"(n.",[107,1865,1866],{"class":1074},"value",[107,1868,1869],{"class":124},")        ",[107,1871,1872],{"class":113},"-- yield each value\n",[107,1874,1875,1878,1881,1883,1886,1888,1891,1893,1896],{"class":109,"line":193},[107,1876,1877],{"class":120},"      for",[107,1879,1880],{"class":124}," _, child ",[107,1882,1178],{"class":120},[107,1884,1885],{"class":131}," ipairs",[107,1887,1863],{"class":124},[107,1889,1890],{"class":1074},"children",[107,1892,350],{"class":120},[107,1894,1895],{"class":124}," {}) ",[107,1897,950],{"class":120},[107,1899,1900,1903,1906],{"class":109,"line":199},[107,1901,1902],{"class":131},"        visit",[107,1904,1905],{"class":124},"(child)                   ",[107,1907,1908],{"class":113},"-- recurse, yields propagate up\n",[107,1910,1911],{"class":109,"line":211},[107,1912,1913],{"class":120},"      end\n",[107,1915,1916],{"class":109,"line":217},[107,1917,1564],{"class":120},[107,1919,1920,1923],{"class":109,"line":224},[107,1921,1922],{"class":131},"    visit",[107,1924,1812],{"class":124},[107,1926,1927,1930],{"class":109,"line":230},[107,1928,1929],{"class":120},"  end",[107,1931,164],{"class":124},[107,1933,1934],{"class":109,"line":242},[107,1935,214],{"class":120},[107,1937,1938],{"class":109,"line":269},[107,1939,221],{"emptyLinePlaceholder":220},[107,1941,1942],{"class":109,"line":274},[107,1943,1944],{"class":113},"-- Usage: iterate tree like an array, no stack management needed\n",[107,1946,1947,1949,1951,1953,1955,1958],{"class":109,"line":287},[107,1948,42],{"class":120},[107,1950,417],{"class":124},[107,1952,1178],{"class":120},[107,1954,1809],{"class":131},[107,1956,1957],{"class":124},"(root_node) ",[107,1959,950],{"class":120},[107,1961,1962,1964],{"class":109,"line":309},[107,1963,154],{"class":131},[107,1965,1966],{"class":124},"(value)\n",[107,1968,1969],{"class":109,"line":314},[107,1970,214],{"class":120},[84,1972,1974,1976,1977,22,1979],{"id":1973},"while-and-repeatuntil",[19,1975,32],{}," and ",[19,1978,35],{},[19,1980,38],{},[95,1982,1983,2125,2133],{"language":97},[99,1984,1986],{"className":101,"code":1985,"language":97,"meta":103,"style":103},"-- while: check before each iteration (may run zero times)\nlocal i = 1\nwhile i \u003C= 5 do\n  print(i)\n  i = i + 1\nend\n\n-- repeat-until: check AFTER each iteration (runs at least once)\n-- Until condition is checked with access to loop-body locals\nlocal input\nrepeat\n  io.write(\"Enter y\u002Fn: \")\n  input = io.read()\nuntil input == \"y\" or input == \"n\"  -- can see `input` (body-local visible to until)\n\n-- CRITICAL: until condition sees locals from the LAST iteration of the body\n-- But NOT from a prior iteration (each iteration's locals are fresh)\n",[19,1987,1988,1993,2003,2015,2022,2034,2038,2042,2047,2052,2059,2064,2075,2087,2111,2115,2120],{"__ignoreMap":103},[107,1989,1990],{"class":109,"line":110},[107,1991,1992],{"class":113},"-- while: check before each iteration (may run zero times)\n",[107,1994,1995,1997,1999,2001],{"class":109,"line":117},[107,1996,121],{"class":120},[107,1998,523],{"class":124},[107,2000,128],{"class":120},[107,2002,1093],{"class":131},[107,2004,2005,2007,2009,2011,2013],{"class":109,"line":135},[107,2006,32],{"class":120},[107,2008,523],{"class":124},[107,2010,1528],{"class":120},[107,2012,145],{"class":131},[107,2014,685],{"class":120},[107,2016,2017,2019],{"class":109,"line":151},[107,2018,154],{"class":131},[107,2020,2021],{"class":124},"(i)\n",[107,2023,2024,2026,2028,2030,2032],{"class":109,"line":167},[107,2025,1083],{"class":124},[107,2027,128],{"class":120},[107,2029,523],{"class":124},[107,2031,1090],{"class":120},[107,2033,1093],{"class":131},[107,2035,2036],{"class":109,"line":181},[107,2037,214],{"class":120},[107,2039,2040],{"class":109,"line":193},[107,2041,221],{"emptyLinePlaceholder":220},[107,2043,2044],{"class":109,"line":199},[107,2045,2046],{"class":113},"-- repeat-until: check AFTER each iteration (runs at least once)\n",[107,2048,2049],{"class":109,"line":211},[107,2050,2051],{"class":113},"-- Until condition is checked with access to loop-body locals\n",[107,2053,2054,2056],{"class":109,"line":217},[107,2055,121],{"class":120},[107,2057,2058],{"class":124}," input\n",[107,2060,2061],{"class":109,"line":224},[107,2062,2063],{"class":120},"repeat\n",[107,2065,2066,2068,2070,2073],{"class":109,"line":230},[107,2067,1761],{"class":131},[107,2069,157],{"class":124},[107,2071,2072],{"class":160},"\"Enter y\u002Fn: \"",[107,2074,164],{"class":124},[107,2076,2077,2080,2082,2085],{"class":109,"line":242},[107,2078,2079],{"class":124},"  input ",[107,2081,128],{"class":120},[107,2083,2084],{"class":131}," io.read",[107,2086,1496],{"class":124},[107,2088,2089,2091,2094,2096,2099,2101,2103,2105,2108],{"class":109,"line":269},[107,2090,38],{"class":120},[107,2092,2093],{"class":124}," input ",[107,2095,1023],{"class":120},[107,2097,2098],{"class":160}," \"y\" ",[107,2100,260],{"class":120},[107,2102,2093],{"class":124},[107,2104,1023],{"class":120},[107,2106,2107],{"class":160}," \"n\"  ",[107,2109,2110],{"class":113},"-- can see `input` (body-local visible to until)\n",[107,2112,2113],{"class":109,"line":274},[107,2114,221],{"emptyLinePlaceholder":220},[107,2116,2117],{"class":109,"line":287},[107,2118,2119],{"class":113},"-- CRITICAL: until condition sees locals from the LAST iteration of the body\n",[107,2121,2122],{"class":109,"line":309},[107,2123,2124],{"class":113},"-- But NOT from a prior iteration (each iteration's locals are fresh)\n",[806,2126,2128,2130,2131],{"id":2127},"break-and-the-missing-continue",[19,2129,49],{}," and the missing ",[19,2132,64],{},[95,2134,2135],{"language":97},[99,2136,2138],{"className":101,"code":2137,"language":97,"meta":103,"style":103},"-- break exits the INNERMOST loop only\nfor i = 1, 3 do\n  for j = 1, 3 do\n    if j == 2 then break end  -- exits inner loop, outer continues\n    print(i, j)\n  end\nend\n-- 1 1 \u002F 2 1 \u002F 3 1\n\n-- No continue in Lua. Options:\n\n-- 1. Wrap body in `if not skip then ... end`\nfor i = 1, 10 do\n  if i % 2 == 0 then  -- skip even\n    -- nothing\n  else\n    print(i)  -- only odd\n  end\nend\n\n-- 2. goto (Lua 5.2+) — clean continue replacement\nfor i = 1, 10 do\n  if i % 2 == 0 then goto continue end\n  print(i)\n  ::continue::\nend\n\n-- 3. Extract to function with early return (cleanest for complex logic)\nlocal function process(i)\n  if i % 2 == 0 then return end  -- skip\n  print(i)\nend\nfor i = 1, 10 do process(i) end\n",[19,2139,2140,2145,2161,2179,2198,2206,2210,2214,2219,2223,2228,2232,2237,2253,2274,2279,2284,2294,2298,2302,2306,2311,2327,2351,2357,2362,2366,2370,2375,2386,2409,2416,2421],{"__ignoreMap":103},[107,2141,2142],{"class":109,"line":110},[107,2143,2144],{"class":113},"-- break exits the INNERMOST loop only\n",[107,2146,2147,2149,2151,2153,2155,2157,2159],{"class":109,"line":117},[107,2148,42],{"class":120},[107,2150,523],{"class":124},[107,2152,128],{"class":120},[107,2154,528],{"class":131},[107,2156,29],{"class":124},[107,2158,751],{"class":131},[107,2160,685],{"class":120},[107,2162,2163,2166,2169,2171,2173,2175,2177],{"class":109,"line":135},[107,2164,2165],{"class":120},"  for",[107,2167,2168],{"class":124}," j ",[107,2170,128],{"class":120},[107,2172,528],{"class":131},[107,2174,29],{"class":124},[107,2176,751],{"class":131},[107,2178,685],{"class":120},[107,2180,2181,2183,2185,2187,2189,2191,2193,2195],{"class":109,"line":151},[107,2182,1017],{"class":120},[107,2184,2168],{"class":124},[107,2186,1023],{"class":120},[107,2188,1254],{"class":131},[107,2190,851],{"class":120},[107,2192,854],{"class":120},[107,2194,857],{"class":120},[107,2196,2197],{"class":113},"  -- exits inner loop, outer continues\n",[107,2199,2200,2203],{"class":109,"line":167},[107,2201,2202],{"class":131},"    print",[107,2204,2205],{"class":124},"(i, j)\n",[107,2207,2208],{"class":109,"line":181},[107,2209,1044],{"class":120},[107,2211,2212],{"class":109,"line":193},[107,2213,214],{"class":120},[107,2215,2216],{"class":109,"line":199},[107,2217,2218],{"class":113},"-- 1 1 \u002F 2 1 \u002F 3 1\n",[107,2220,2221],{"class":109,"line":211},[107,2222,221],{"emptyLinePlaceholder":220},[107,2224,2225],{"class":109,"line":217},[107,2226,2227],{"class":113},"-- No continue in Lua. Options:\n",[107,2229,2230],{"class":109,"line":224},[107,2231,221],{"emptyLinePlaceholder":220},[107,2233,2234],{"class":109,"line":230},[107,2235,2236],{"class":113},"-- 1. Wrap body in `if not skip then ... end`\n",[107,2238,2239,2241,2243,2245,2247,2249,2251],{"class":109,"line":242},[107,2240,42],{"class":120},[107,2242,523],{"class":124},[107,2244,128],{"class":120},[107,2246,528],{"class":131},[107,2248,29],{"class":124},[107,2250,595],{"class":131},[107,2252,685],{"class":120},[107,2254,2255,2257,2259,2262,2264,2267,2269,2271],{"class":109,"line":269},[107,2256,841],{"class":120},[107,2258,523],{"class":124},[107,2260,2261],{"class":120},"%",[107,2263,1254],{"class":131},[107,2265,2266],{"class":120}," ==",[107,2268,176],{"class":131},[107,2270,851],{"class":120},[107,2272,2273],{"class":113},"  -- skip even\n",[107,2275,2276],{"class":109,"line":274},[107,2277,2278],{"class":113},"    -- nothing\n",[107,2280,2281],{"class":109,"line":287},[107,2282,2283],{"class":120},"  else\n",[107,2285,2286,2288,2291],{"class":109,"line":309},[107,2287,2202],{"class":131},[107,2289,2290],{"class":124},"(i)  ",[107,2292,2293],{"class":113},"-- only odd\n",[107,2295,2296],{"class":109,"line":314},[107,2297,1044],{"class":120},[107,2299,2300],{"class":109,"line":320},[107,2301,214],{"class":120},[107,2303,2304],{"class":109,"line":333},[107,2305,221],{"emptyLinePlaceholder":220},[107,2307,2308],{"class":109,"line":359},[107,2309,2310],{"class":113},"-- 2. goto (Lua 5.2+) — clean continue replacement\n",[107,2312,2313,2315,2317,2319,2321,2323,2325],{"class":109,"line":365},[107,2314,42],{"class":120},[107,2316,523],{"class":124},[107,2318,128],{"class":120},[107,2320,528],{"class":131},[107,2322,29],{"class":124},[107,2324,595],{"class":131},[107,2326,685],{"class":120},[107,2328,2329,2331,2333,2335,2337,2339,2341,2343,2346,2349],{"class":109,"line":370},[107,2330,841],{"class":120},[107,2332,523],{"class":124},[107,2334,2261],{"class":120},[107,2336,1254],{"class":131},[107,2338,2266],{"class":120},[107,2340,176],{"class":131},[107,2342,851],{"class":120},[107,2344,2345],{"class":120}," goto",[107,2347,2348],{"class":160}," continue",[107,2350,1165],{"class":120},[107,2352,2353,2355],{"class":109,"line":376},[107,2354,154],{"class":131},[107,2356,2021],{"class":124},[107,2358,2359],{"class":109,"line":412},[107,2360,2361],{"class":160},"  ::continue::\n",[107,2363,2364],{"class":109,"line":434},[107,2365,214],{"class":120},[107,2367,2368],{"class":109,"line":439},[107,2369,221],{"emptyLinePlaceholder":220},[107,2371,2372],{"class":109,"line":445},[107,2373,2374],{"class":113},"-- 3. Extract to function with early return (cleanest for complex logic)\n",[107,2376,2377,2379,2381,2384],{"class":109,"line":453},[107,2378,121],{"class":120},[107,2380,763],{"class":120},[107,2382,2383],{"class":1074}," process",[107,2385,2021],{"class":124},[107,2387,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406],{"class":109,"line":1781},[107,2389,841],{"class":120},[107,2391,523],{"class":124},[107,2393,2261],{"class":120},[107,2395,1254],{"class":131},[107,2397,2266],{"class":120},[107,2399,176],{"class":131},[107,2401,851],{"class":120},[107,2403,1121],{"class":120},[107,2405,857],{"class":120},[107,2407,2408],{"class":113},"  -- skip\n",[107,2410,2412,2414],{"class":109,"line":2411},31,[107,2413,154],{"class":131},[107,2415,2021],{"class":124},[107,2417,2419],{"class":109,"line":2418},32,[107,2420,214],{"class":120},[107,2422,2424,2426,2428,2430,2432,2434,2436,2438,2440,2442],{"class":109,"line":2423},33,[107,2425,42],{"class":120},[107,2427,523],{"class":124},[107,2429,128],{"class":120},[107,2431,528],{"class":131},[107,2433,29],{"class":124},[107,2435,595],{"class":131},[107,2437,536],{"class":120},[107,2439,2383],{"class":131},[107,2441,542],{"class":124},[107,2443,214],{"class":120},[84,2445,2447,2449],{"id":2446},"goto-structured-escape-state-machines",[19,2448,52],{}," — Structured Escape & State Machines",[95,2451,2452,2725,2729,2801,2805],{"language":97},[99,2453,2455],{"className":101,"code":2454,"language":97,"meta":103,"style":103},"-- goto is available in Lua 5.2+. Cannot jump into a local variable's scope,\n-- cannot jump out of a function, cannot jump into a block's local scope.\n\n-- Pattern 1: multi-level break (break only exits one loop)\nfor i = 1, 10 do\n  for j = 1, 10 do\n    if found_at(i, j) then goto found end\n  end\nend\n::found::\nprint(\"exited both loops\")\n\n-- Pattern 2: continue (shown above)\n\n-- Pattern 3: state machine without function call overhead\nlocal function parse_header(text)\n  ::read_key::\n  local key = read_token(text)\n  if key == \"\" then goto done end\n  ::read_colon::\n  if peek_char() ~= \":\" then goto error end\n  consume_char()\n  ::read_value::\n  local value = read_token(text)\n  store(key, value)\n  goto read_key\n  ::error::\n  return nil, \"parse error at key: \" .. key\n  ::done::\n  return true\nend\n",[19,2456,2457,2462,2467,2471,2476,2492,2508,2527,2531,2535,2540,2551,2555,2560,2564,2569,2581,2586,2600,2620,2625,2648,2655,2660,2672,2680,2688,2693,2710,2715,2721],{"__ignoreMap":103},[107,2458,2459],{"class":109,"line":110},[107,2460,2461],{"class":113},"-- goto is available in Lua 5.2+. Cannot jump into a local variable's scope,\n",[107,2463,2464],{"class":109,"line":117},[107,2465,2466],{"class":113},"-- cannot jump out of a function, cannot jump into a block's local scope.\n",[107,2468,2469],{"class":109,"line":135},[107,2470,221],{"emptyLinePlaceholder":220},[107,2472,2473],{"class":109,"line":151},[107,2474,2475],{"class":113},"-- Pattern 1: multi-level break (break only exits one loop)\n",[107,2477,2478,2480,2482,2484,2486,2488,2490],{"class":109,"line":167},[107,2479,42],{"class":120},[107,2481,523],{"class":124},[107,2483,128],{"class":120},[107,2485,528],{"class":131},[107,2487,29],{"class":124},[107,2489,595],{"class":131},[107,2491,685],{"class":120},[107,2493,2494,2496,2498,2500,2502,2504,2506],{"class":109,"line":181},[107,2495,2165],{"class":120},[107,2497,2168],{"class":124},[107,2499,128],{"class":120},[107,2501,528],{"class":131},[107,2503,29],{"class":124},[107,2505,595],{"class":131},[107,2507,685],{"class":120},[107,2509,2510,2512,2515,2518,2520,2522,2525],{"class":109,"line":193},[107,2511,1017],{"class":120},[107,2513,2514],{"class":131}," found_at",[107,2516,2517],{"class":124},"(i, j) ",[107,2519,460],{"class":120},[107,2521,2345],{"class":120},[107,2523,2524],{"class":160}," found",[107,2526,1165],{"class":120},[107,2528,2529],{"class":109,"line":199},[107,2530,1044],{"class":120},[107,2532,2533],{"class":109,"line":211},[107,2534,214],{"class":120},[107,2536,2537],{"class":109,"line":217},[107,2538,2539],{"class":160},"::found::\n",[107,2541,2542,2544,2546,2549],{"class":109,"line":224},[107,2543,784],{"class":131},[107,2545,157],{"class":124},[107,2547,2548],{"class":160},"\"exited both loops\"",[107,2550,164],{"class":124},[107,2552,2553],{"class":109,"line":230},[107,2554,221],{"emptyLinePlaceholder":220},[107,2556,2557],{"class":109,"line":242},[107,2558,2559],{"class":113},"-- Pattern 2: continue (shown above)\n",[107,2561,2562],{"class":109,"line":269},[107,2563,221],{"emptyLinePlaceholder":220},[107,2565,2566],{"class":109,"line":274},[107,2567,2568],{"class":113},"-- Pattern 3: state machine without function call overhead\n",[107,2570,2571,2573,2575,2578],{"class":109,"line":287},[107,2572,121],{"class":120},[107,2574,763],{"class":120},[107,2576,2577],{"class":1074}," parse_header",[107,2579,2580],{"class":124},"(text)\n",[107,2582,2583],{"class":109,"line":309},[107,2584,2585],{"class":160},"  ::read_key::\n",[107,2587,2588,2590,2593,2595,2598],{"class":109,"line":314},[107,2589,690],{"class":120},[107,2591,2592],{"class":124}," key ",[107,2594,128],{"class":120},[107,2596,2597],{"class":131}," read_token",[107,2599,2580],{"class":124},[107,2601,2602,2604,2606,2608,2611,2613,2615,2618],{"class":109,"line":320},[107,2603,841],{"class":120},[107,2605,2592],{"class":124},[107,2607,1023],{"class":120},[107,2609,2610],{"class":160}," \"\" ",[107,2612,460],{"class":120},[107,2614,2345],{"class":120},[107,2616,2617],{"class":160}," done",[107,2619,1165],{"class":120},[107,2621,2622],{"class":109,"line":333},[107,2623,2624],{"class":160},"  ::read_colon::\n",[107,2626,2627,2629,2632,2634,2636,2639,2641,2643,2646],{"class":109,"line":359},[107,2628,841],{"class":120},[107,2630,2631],{"class":131}," peek_char",[107,2633,766],{"class":124},[107,2635,1114],{"class":120},[107,2637,2638],{"class":160}," \":\" ",[107,2640,460],{"class":120},[107,2642,2345],{"class":120},[107,2644,2645],{"class":160}," error",[107,2647,1165],{"class":120},[107,2649,2650,2653],{"class":109,"line":365},[107,2651,2652],{"class":131},"  consume_char",[107,2654,1496],{"class":124},[107,2656,2657],{"class":109,"line":370},[107,2658,2659],{"class":160},"  ::read_value::\n",[107,2661,2662,2664,2666,2668,2670],{"class":109,"line":376},[107,2663,690],{"class":120},[107,2665,417],{"class":124},[107,2667,128],{"class":120},[107,2669,2597],{"class":131},[107,2671,2580],{"class":124},[107,2673,2674,2677],{"class":109,"line":412},[107,2675,2676],{"class":131},"  store",[107,2678,2679],{"class":124},"(key, value)\n",[107,2681,2682,2685],{"class":109,"line":434},[107,2683,2684],{"class":120},"  goto",[107,2686,2687],{"class":160}," read_key\n",[107,2689,2690],{"class":109,"line":439},[107,2691,2692],{"class":160},"  ::error::\n",[107,2694,2695,2697,2699,2701,2704,2707],{"class":109,"line":445},[107,2696,1134],{"class":120},[107,2698,347],{"class":131},[107,2700,29],{"class":124},[107,2702,2703],{"class":160},"\"parse error at key: \" ",[107,2705,2706],{"class":120},"..",[107,2708,2709],{"class":124}," key\n",[107,2711,2712],{"class":109,"line":453},[107,2713,2714],{"class":160},"  ::done::\n",[107,2716,2717,2719],{"class":109,"line":1781},[107,2718,1134],{"class":120},[107,2720,330],{"class":131},[107,2722,2723],{"class":109,"line":2411},[107,2724,214],{"class":120},[806,2726,2728],{"id":2727},"anti-pattern-goto-for-general-control-flow","Anti-pattern: goto for general control flow",[95,2730,2731],{"language":97},[99,2732,2734],{"className":101,"code":2733,"language":97,"meta":103,"style":103},"-- BAD: goto used as a replacement for normal control flow — unreadable spaghetti\ngoto step3\n::step1::\ndo_something()\n::step2::\ndo_other()\n::step3::\ngoto step1  -- infinite goto loop — use `while true` instead\n\n-- GOOD: goto is ONLY for: (1) multi-level break, (2) continue, (3) state machines\n-- where the state transitions are the logic, not a sequence of steps.\n",[19,2735,2736,2741,2748,2753,2760,2765,2772,2777,2787,2791,2796],{"__ignoreMap":103},[107,2737,2738],{"class":109,"line":110},[107,2739,2740],{"class":113},"-- BAD: goto used as a replacement for normal control flow — unreadable spaghetti\n",[107,2742,2743,2745],{"class":109,"line":117},[107,2744,52],{"class":120},[107,2746,2747],{"class":160}," step3\n",[107,2749,2750],{"class":109,"line":135},[107,2751,2752],{"class":160},"::step1::\n",[107,2754,2755,2758],{"class":109,"line":151},[107,2756,2757],{"class":131},"do_something",[107,2759,1496],{"class":124},[107,2761,2762],{"class":109,"line":167},[107,2763,2764],{"class":160},"::step2::\n",[107,2766,2767,2770],{"class":109,"line":181},[107,2768,2769],{"class":131},"do_other",[107,2771,1496],{"class":124},[107,2773,2774],{"class":109,"line":193},[107,2775,2776],{"class":160},"::step3::\n",[107,2778,2779,2781,2784],{"class":109,"line":199},[107,2780,52],{"class":120},[107,2782,2783],{"class":160}," step1",[107,2785,2786],{"class":113},"  -- infinite goto loop — use `while true` instead\n",[107,2788,2789],{"class":109,"line":211},[107,2790,221],{"emptyLinePlaceholder":220},[107,2792,2793],{"class":109,"line":217},[107,2794,2795],{"class":113},"-- GOOD: goto is ONLY for: (1) multi-level break, (2) continue, (3) state machines\n",[107,2797,2798],{"class":109,"line":224},[107,2799,2800],{"class":113},"-- where the state transitions are the logic, not a sequence of steps.\n",[84,2802,2804],{"id":2803},"table-dispatch-o1-switch-replacement","Table Dispatch — O(1) Switch Replacement",[95,2806,2807,3340,3344],{"language":97},[99,2808,2810],{"className":101,"code":2809,"language":97,"meta":103,"style":103},"-- No switch in Lua. Table of functions is the idiomatic, performant replacement.\nlocal handlers = {\n  [\"GET\"]    = function(req) return fetch_resource(req.path) end,\n  [\"POST\"]   = function(req) return create_resource(req.body) end,\n  [\"PUT\"]    = function(req) return update_resource(req.path, req.body) end,\n  [\"DELETE\"] = function(req) return delete_resource(req.path) end,\n  [\"PATCH\"]  = function(req) return patch_resource(req.path, req.body) end,\n}\n\nlocal function route(req)\n  local handler = handlers[req.method]  -- O(1) hash lookup, not O(n) elseif chain\n  if not handler then\n    return 405, \"method not allowed\"\n  end\n  return handler(req)\nend\n\n-- Dispatch with default handler:\nlocal function dispatch(event, ...)\n  local handler = handlers[event] or default_handler  -- fallback\n  return handler(...)\nend\n\n-- Pattern: command registry with metadata\nlocal commands = {}\nlocal function register_cmd(name, fn, help)\n  commands[name] = {fn = fn, help = help or \"\"}\nend\n\nregister_cmd(\"help\", function()\n  for name, cmd in pairs(commands) do\n    print(name, cmd.help)\n  end\nend, \"show this help\")\nregister_cmd(\"quit\", function() os.exit(0) end, \"exit program\")\n\n-- Runtime extensible: add commands without touching the dispatch code\nregister_cmd(\"version\", function() print(\"v1.0\") end, \"show version\")\n",[19,2811,2812,2817,2829,2865,2897,2932,2963,2997,3002,3006,3018,3038,3048,3060,3064,3073,3077,3081,3086,3098,3117,3130,3134,3138,3143,3154,3166,3193,3197,3201,3217,3233,3245,3249,3261,3295,3300,3306],{"__ignoreMap":103},[107,2813,2814],{"class":109,"line":110},[107,2815,2816],{"class":113},"-- No switch in Lua. Table of functions is the idiomatic, performant replacement.\n",[107,2818,2819,2821,2824,2826],{"class":109,"line":117},[107,2820,121],{"class":120},[107,2822,2823],{"class":124}," handlers ",[107,2825,128],{"class":120},[107,2827,2828],{"class":124}," {\n",[107,2830,2831,2834,2837,2840,2842,2844,2847,2849,2852,2855,2858,2860,2862],{"class":109,"line":135},[107,2832,2833],{"class":124},"  [",[107,2835,2836],{"class":160},"\"GET\"",[107,2838,2839],{"class":124},"]    ",[107,2841,128],{"class":120},[107,2843,763],{"class":120},[107,2845,2846],{"class":124},"(req) ",[107,2848,56],{"class":120},[107,2850,2851],{"class":131}," fetch_resource",[107,2853,2854],{"class":124},"(req.",[107,2856,2857],{"class":1074},"path",[107,2859,904],{"class":124},[107,2861,545],{"class":120},[107,2863,2864],{"class":124},",\n",[107,2866,2867,2869,2872,2875,2877,2879,2881,2883,2886,2888,2891,2893,2895],{"class":109,"line":151},[107,2868,2833],{"class":124},[107,2870,2871],{"class":160},"\"POST\"",[107,2873,2874],{"class":124},"]   ",[107,2876,128],{"class":120},[107,2878,763],{"class":120},[107,2880,2846],{"class":124},[107,2882,56],{"class":120},[107,2884,2885],{"class":131}," create_resource",[107,2887,2854],{"class":124},[107,2889,2890],{"class":1074},"body",[107,2892,904],{"class":124},[107,2894,545],{"class":120},[107,2896,2864],{"class":124},[107,2898,2899,2901,2904,2906,2908,2910,2912,2914,2917,2919,2921,2924,2926,2928,2930],{"class":109,"line":167},[107,2900,2833],{"class":124},[107,2902,2903],{"class":160},"\"PUT\"",[107,2905,2839],{"class":124},[107,2907,128],{"class":120},[107,2909,763],{"class":120},[107,2911,2846],{"class":124},[107,2913,56],{"class":120},[107,2915,2916],{"class":131}," update_resource",[107,2918,2854],{"class":124},[107,2920,2857],{"class":1074},[107,2922,2923],{"class":124},", req.",[107,2925,2890],{"class":1074},[107,2927,904],{"class":124},[107,2929,545],{"class":120},[107,2931,2864],{"class":124},[107,2933,2934,2936,2939,2942,2944,2946,2948,2950,2953,2955,2957,2959,2961],{"class":109,"line":181},[107,2935,2833],{"class":124},[107,2937,2938],{"class":160},"\"DELETE\"",[107,2940,2941],{"class":124},"] ",[107,2943,128],{"class":120},[107,2945,763],{"class":120},[107,2947,2846],{"class":124},[107,2949,56],{"class":120},[107,2951,2952],{"class":131}," delete_resource",[107,2954,2854],{"class":124},[107,2956,2857],{"class":1074},[107,2958,904],{"class":124},[107,2960,545],{"class":120},[107,2962,2864],{"class":124},[107,2964,2965,2967,2970,2972,2974,2976,2978,2980,2983,2985,2987,2989,2991,2993,2995],{"class":109,"line":193},[107,2966,2833],{"class":124},[107,2968,2969],{"class":160},"\"PATCH\"",[107,2971,428],{"class":124},[107,2973,128],{"class":120},[107,2975,763],{"class":120},[107,2977,2846],{"class":124},[107,2979,56],{"class":120},[107,2981,2982],{"class":131}," patch_resource",[107,2984,2854],{"class":124},[107,2986,2857],{"class":1074},[107,2988,2923],{"class":124},[107,2990,2890],{"class":1074},[107,2992,904],{"class":124},[107,2994,545],{"class":120},[107,2996,2864],{"class":124},[107,2998,2999],{"class":109,"line":199},[107,3000,3001],{"class":124},"}\n",[107,3003,3004],{"class":109,"line":211},[107,3005,221],{"emptyLinePlaceholder":220},[107,3007,3008,3010,3012,3015],{"class":109,"line":217},[107,3009,121],{"class":120},[107,3011,763],{"class":120},[107,3013,3014],{"class":1074}," route",[107,3016,3017],{"class":124},"(req)\n",[107,3019,3020,3022,3025,3027,3030,3033,3035],{"class":109,"line":224},[107,3021,690],{"class":120},[107,3023,3024],{"class":124}," handler ",[107,3026,128],{"class":120},[107,3028,3029],{"class":124}," handlers[req.",[107,3031,3032],{"class":1074},"method",[107,3034,428],{"class":124},[107,3036,3037],{"class":113},"-- O(1) hash lookup, not O(n) elseif chain\n",[107,3039,3040,3042,3044,3046],{"class":109,"line":230},[107,3041,841],{"class":120},[107,3043,1846],{"class":120},[107,3045,3024],{"class":124},[107,3047,1551],{"class":120},[107,3049,3050,3052,3055,3057],{"class":109,"line":242},[107,3051,1712],{"class":120},[107,3053,3054],{"class":131}," 405",[107,3056,29],{"class":124},[107,3058,3059],{"class":160},"\"method not allowed\"\n",[107,3061,3062],{"class":109,"line":269},[107,3063,1044],{"class":120},[107,3065,3066,3068,3071],{"class":109,"line":274},[107,3067,1134],{"class":120},[107,3069,3070],{"class":131}," handler",[107,3072,3017],{"class":124},[107,3074,3075],{"class":109,"line":287},[107,3076,214],{"class":120},[107,3078,3079],{"class":109,"line":309},[107,3080,221],{"emptyLinePlaceholder":220},[107,3082,3083],{"class":109,"line":314},[107,3084,3085],{"class":113},"-- Dispatch with default handler:\n",[107,3087,3088,3090,3092,3095],{"class":109,"line":320},[107,3089,121],{"class":120},[107,3091,763],{"class":120},[107,3093,3094],{"class":1074}," dispatch",[107,3096,3097],{"class":124},"(event, ...)\n",[107,3099,3100,3102,3104,3106,3109,3111,3114],{"class":109,"line":333},[107,3101,690],{"class":120},[107,3103,3024],{"class":124},[107,3105,128],{"class":120},[107,3107,3108],{"class":124}," handlers[event] ",[107,3110,260],{"class":120},[107,3112,3113],{"class":124}," default_handler  ",[107,3115,3116],{"class":113},"-- fallback\n",[107,3118,3119,3121,3123,3125,3128],{"class":109,"line":359},[107,3120,1134],{"class":120},[107,3122,3070],{"class":131},[107,3124,157],{"class":124},[107,3126,3127],{"class":131},"...",[107,3129,164],{"class":124},[107,3131,3132],{"class":109,"line":365},[107,3133,214],{"class":120},[107,3135,3136],{"class":109,"line":370},[107,3137,221],{"emptyLinePlaceholder":220},[107,3139,3140],{"class":109,"line":376},[107,3141,3142],{"class":113},"-- Pattern: command registry with metadata\n",[107,3144,3145,3147,3150,3152],{"class":109,"line":412},[107,3146,121],{"class":120},[107,3148,3149],{"class":124}," commands ",[107,3151,128],{"class":120},[107,3153,736],{"class":124},[107,3155,3156,3158,3160,3163],{"class":109,"line":434},[107,3157,121],{"class":120},[107,3159,763],{"class":120},[107,3161,3162],{"class":1074}," register_cmd",[107,3164,3165],{"class":124},"(name, fn, help)\n",[107,3167,3168,3171,3173,3176,3178,3181,3183,3186,3188,3191],{"class":109,"line":439},[107,3169,3170],{"class":124},"  commands[name] ",[107,3172,128],{"class":120},[107,3174,3175],{"class":124}," {fn ",[107,3177,128],{"class":120},[107,3179,3180],{"class":124}," fn, help ",[107,3182,128],{"class":120},[107,3184,3185],{"class":124}," help ",[107,3187,260],{"class":120},[107,3189,3190],{"class":160}," \"\"",[107,3192,3001],{"class":124},[107,3194,3195],{"class":109,"line":445},[107,3196,214],{"class":120},[107,3198,3199],{"class":109,"line":453},[107,3200,221],{"emptyLinePlaceholder":220},[107,3202,3203,3206,3208,3211,3213,3215],{"class":109,"line":1781},[107,3204,3205],{"class":131},"register_cmd",[107,3207,157],{"class":124},[107,3209,3210],{"class":160},"\"help\"",[107,3212,29],{"class":124},[107,3214,1824],{"class":120},[107,3216,1496],{"class":124},[107,3218,3219,3221,3224,3226,3228,3231],{"class":109,"line":2411},[107,3220,2165],{"class":120},[107,3222,3223],{"class":124}," name, cmd ",[107,3225,1178],{"class":120},[107,3227,1239],{"class":131},[107,3229,3230],{"class":124},"(commands) ",[107,3232,950],{"class":120},[107,3234,3235,3237,3240,3243],{"class":109,"line":2418},[107,3236,2202],{"class":131},[107,3238,3239],{"class":124},"(name, cmd.",[107,3241,3242],{"class":1074},"help",[107,3244,164],{"class":124},[107,3246,3247],{"class":109,"line":2423},[107,3248,1044],{"class":120},[107,3250,3252,3254,3256,3259],{"class":109,"line":3251},34,[107,3253,545],{"class":120},[107,3255,29],{"class":124},[107,3257,3258],{"class":160},"\"show this help\"",[107,3260,164],{"class":124},[107,3262,3264,3266,3268,3271,3273,3275,3277,3280,3282,3284,3286,3288,3290,3293],{"class":109,"line":3263},35,[107,3265,3205],{"class":131},[107,3267,157],{"class":124},[107,3269,3270],{"class":160},"\"quit\"",[107,3272,29],{"class":124},[107,3274,1824],{"class":120},[107,3276,766],{"class":124},[107,3278,3279],{"class":131},"os.exit",[107,3281,157],{"class":124},[107,3283,888],{"class":131},[107,3285,904],{"class":124},[107,3287,545],{"class":120},[107,3289,29],{"class":124},[107,3291,3292],{"class":160},"\"exit program\"",[107,3294,164],{"class":124},[107,3296,3298],{"class":109,"line":3297},36,[107,3299,221],{"emptyLinePlaceholder":220},[107,3301,3303],{"class":109,"line":3302},37,[107,3304,3305],{"class":113},"-- Runtime extensible: add commands without touching the dispatch code\n",[107,3307,3309,3311,3313,3316,3318,3320,3322,3324,3326,3329,3331,3333,3335,3338],{"class":109,"line":3308},38,[107,3310,3205],{"class":131},[107,3312,157],{"class":124},[107,3314,3315],{"class":160},"\"version\"",[107,3317,29],{"class":124},[107,3319,1824],{"class":120},[107,3321,766],{"class":124},[107,3323,784],{"class":131},[107,3325,157],{"class":124},[107,3327,3328],{"class":160},"\"v1.0\"",[107,3330,904],{"class":124},[107,3332,545],{"class":120},[107,3334,29],{"class":124},[107,3336,3337],{"class":160},"\"show version\"",[107,3339,164],{"class":124},[806,3341,3343],{"id":3342},"edge-case-dispatch-table-with-integer-keys-vs-string-keys","Edge case: dispatch table with integer keys vs string keys",[95,3345,3346],{"language":97},[99,3347,3349],{"className":101,"code":3348,"language":97,"meta":103,"style":103},"-- Integer keys and string keys that look like integers are DIFFERENT keys\nlocal t = {}\nt[1] = \"array index 1\"\nt[\"1\"] = \"string key '1'\"\nprint(t[1])    -- \"array index 1\"\nprint(t[\"1\"]) -- \"string key '1'\"\nprint(t[1.0]) -- \"array index 1\" (1.0 == 1 in Lua; same key)\n\n-- HTTP status codes: use integer keys, not string\nlocal status_texts = {\n  [200] = \"OK\",\n  [404] = \"Not Found\",\n  [500] = \"Internal Server Error\",\n}\nprint(status_texts[404])  -- \"Not Found\" (integer key)\nprint(status_texts[\"404\"]) -- nil (string key — different!)\n",[19,3350,3351,3356,3367,3381,3395,3410,3424,3437,3441,3446,3457,3473,3489,3505,3509,3524],{"__ignoreMap":103},[107,3352,3353],{"class":109,"line":110},[107,3354,3355],{"class":113},"-- Integer keys and string keys that look like integers are DIFFERENT keys\n",[107,3357,3358,3360,3363,3365],{"class":109,"line":117},[107,3359,121],{"class":120},[107,3361,3362],{"class":124}," t ",[107,3364,128],{"class":120},[107,3366,736],{"class":124},[107,3368,3369,3372,3374,3376,3378],{"class":109,"line":135},[107,3370,3371],{"class":124},"t[",[107,3373,425],{"class":131},[107,3375,2941],{"class":124},[107,3377,128],{"class":120},[107,3379,3380],{"class":160}," \"array index 1\"\n",[107,3382,3383,3385,3388,3390,3392],{"class":109,"line":151},[107,3384,3371],{"class":124},[107,3386,3387],{"class":160},"\"1\"",[107,3389,2941],{"class":124},[107,3391,128],{"class":120},[107,3393,3394],{"class":160}," \"string key '1'\"\n",[107,3396,3397,3399,3402,3404,3407],{"class":109,"line":167},[107,3398,784],{"class":131},[107,3400,3401],{"class":124},"(t[",[107,3403,425],{"class":131},[107,3405,3406],{"class":124},"])    ",[107,3408,3409],{"class":113},"-- \"array index 1\"\n",[107,3411,3412,3414,3416,3418,3421],{"class":109,"line":181},[107,3413,784],{"class":131},[107,3415,3401],{"class":124},[107,3417,3387],{"class":160},[107,3419,3420],{"class":124},"]) ",[107,3422,3423],{"class":113},"-- \"string key '1'\"\n",[107,3425,3426,3428,3430,3432,3434],{"class":109,"line":193},[107,3427,784],{"class":131},[107,3429,3401],{"class":124},[107,3431,636],{"class":131},[107,3433,3420],{"class":124},[107,3435,3436],{"class":113},"-- \"array index 1\" (1.0 == 1 in Lua; same key)\n",[107,3438,3439],{"class":109,"line":199},[107,3440,221],{"emptyLinePlaceholder":220},[107,3442,3443],{"class":109,"line":211},[107,3444,3445],{"class":113},"-- HTTP status codes: use integer keys, not string\n",[107,3447,3448,3450,3453,3455],{"class":109,"line":217},[107,3449,121],{"class":120},[107,3451,3452],{"class":124}," status_texts ",[107,3454,128],{"class":120},[107,3456,2828],{"class":124},[107,3458,3459,3461,3464,3466,3468,3471],{"class":109,"line":224},[107,3460,2833],{"class":124},[107,3462,3463],{"class":131},"200",[107,3465,2941],{"class":124},[107,3467,128],{"class":120},[107,3469,3470],{"class":160}," \"OK\"",[107,3472,2864],{"class":124},[107,3474,3475,3477,3480,3482,3484,3487],{"class":109,"line":230},[107,3476,2833],{"class":124},[107,3478,3479],{"class":131},"404",[107,3481,2941],{"class":124},[107,3483,128],{"class":120},[107,3485,3486],{"class":160}," \"Not Found\"",[107,3488,2864],{"class":124},[107,3490,3491,3493,3496,3498,3500,3503],{"class":109,"line":242},[107,3492,2833],{"class":124},[107,3494,3495],{"class":131},"500",[107,3497,2941],{"class":124},[107,3499,128],{"class":120},[107,3501,3502],{"class":160}," \"Internal Server Error\"",[107,3504,2864],{"class":124},[107,3506,3507],{"class":109,"line":269},[107,3508,3001],{"class":124},[107,3510,3511,3513,3516,3518,3521],{"class":109,"line":274},[107,3512,784],{"class":131},[107,3514,3515],{"class":124},"(status_texts[",[107,3517,3479],{"class":131},[107,3519,3520],{"class":124},"])  ",[107,3522,3523],{"class":113},"-- \"Not Found\" (integer key)\n",[107,3525,3526,3528,3530,3533,3535],{"class":109,"line":287},[107,3527,784],{"class":131},[107,3529,3515],{"class":124},[107,3531,3532],{"class":160},"\"404\"",[107,3534,3420],{"class":124},[107,3536,3537],{"class":113},"-- nil (string key — different!)\n",[84,3539,3541],{"id":3540},"comparison-logical-operators","Comparison & Logical Operators",[95,3543,3544,3768,3776],{"language":97},[99,3545,3547],{"className":101,"code":3546,"language":97,"meta":103,"style":103},"-- Comparison: ==, ~= (NOT !=), \u003C, >, \u003C=, >=\n5 == 5.0   -- true (mathematically equal, int vs float)\n\"5\" == 5   -- false (different types — no coercion in ==)\nnil == nil -- true\n{} == {}   -- false (table identity comparison, not content)\nlocal t = {}\nt == t     -- true (same reference)\n\n-- Metamethod __eq: only called if both operands are tables (or userdata),\n-- AND they are NOT the same object, AND both have the same __eq metamethod.\n-- (Not called for different types, not called if either is nil\u002Fnumber\u002Fstring)\n\n-- Logical: and, or, not (lowercase, no && || !)\n-- Short-circuit: return the VALUE, not a boolean (like JS, unlike Python's True\u002FFalse)\ntrue and \"yes\"        -- \"yes\" (and returns 2nd operand if 1st is truthy)\nfalse and \"yes\"       -- false (and returns 1st if it's falsy)\nnil and \"yes\"         -- nil\ntrue or \"yes\"         -- true (or returns 1st if truthy)\nfalse or \"yes\"        -- \"yes\" (or returns 2nd if 1st is falsy)\nnil or \"yes\"          -- \"yes\"\nnot nil               -- true (not DOES return boolean)\nnot false             -- true\nnot 0                -- false (0 is truthy!)\nnot \"\"               -- false (\"\" is truthy!)\n",[19,3548,3549,3554,3566,3578,3589,3602,3612,3624,3628,3633,3638,3643,3647,3652,3657,3670,3683,3695,3706,3717,3729,3739,3749,3758],{"__ignoreMap":103},[107,3550,3551],{"class":109,"line":110},[107,3552,3553],{"class":113},"-- Comparison: ==, ~= (NOT !=), \u003C, >, \u003C=, >=\n",[107,3555,3556,3558,3560,3563],{"class":109,"line":117},[107,3557,533],{"class":131},[107,3559,2266],{"class":120},[107,3561,3562],{"class":131}," 5.0",[107,3564,3565],{"class":113},"   -- true (mathematically equal, int vs float)\n",[107,3567,3568,3571,3573,3575],{"class":109,"line":135},[107,3569,3570],{"class":160},"\"5\" ",[107,3572,1023],{"class":120},[107,3574,145],{"class":131},[107,3576,3577],{"class":113},"   -- false (different types — no coercion in ==)\n",[107,3579,3580,3582,3584,3586],{"class":109,"line":151},[107,3581,393],{"class":131},[107,3583,2266],{"class":120},[107,3585,347],{"class":131},[107,3587,3588],{"class":113}," -- true\n",[107,3590,3591,3594,3596,3599],{"class":109,"line":167},[107,3592,3593],{"class":124},"{} ",[107,3595,1023],{"class":120},[107,3597,3598],{"class":124}," {}   ",[107,3600,3601],{"class":113},"-- false (table identity comparison, not content)\n",[107,3603,3604,3606,3608,3610],{"class":109,"line":181},[107,3605,121],{"class":120},[107,3607,3362],{"class":124},[107,3609,128],{"class":120},[107,3611,736],{"class":124},[107,3613,3614,3616,3618,3621],{"class":109,"line":193},[107,3615,1369],{"class":124},[107,3617,1023],{"class":120},[107,3619,3620],{"class":124}," t     ",[107,3622,3623],{"class":113},"-- true (same reference)\n",[107,3625,3626],{"class":109,"line":199},[107,3627,221],{"emptyLinePlaceholder":220},[107,3629,3630],{"class":109,"line":211},[107,3631,3632],{"class":113},"-- Metamethod __eq: only called if both operands are tables (or userdata),\n",[107,3634,3635],{"class":109,"line":217},[107,3636,3637],{"class":113},"-- AND they are NOT the same object, AND both have the same __eq metamethod.\n",[107,3639,3640],{"class":109,"line":224},[107,3641,3642],{"class":113},"-- (Not called for different types, not called if either is nil\u002Fnumber\u002Fstring)\n",[107,3644,3645],{"class":109,"line":230},[107,3646,221],{"emptyLinePlaceholder":220},[107,3648,3649],{"class":109,"line":242},[107,3650,3651],{"class":113},"-- Logical: and, or, not (lowercase, no && || !)\n",[107,3653,3654],{"class":109,"line":269},[107,3655,3656],{"class":113},"-- Short-circuit: return the VALUE, not a boolean (like JS, unlike Python's True\u002FFalse)\n",[107,3658,3659,3662,3664,3667],{"class":109,"line":274},[107,3660,3661],{"class":131},"true",[107,3663,1523],{"class":120},[107,3665,3666],{"class":160}," \"yes\"        ",[107,3668,3669],{"class":113},"-- \"yes\" (and returns 2nd operand if 1st is truthy)\n",[107,3671,3672,3675,3677,3680],{"class":109,"line":287},[107,3673,3674],{"class":131},"false",[107,3676,1523],{"class":120},[107,3678,3679],{"class":160}," \"yes\"       ",[107,3681,3682],{"class":113},"-- false (and returns 1st if it's falsy)\n",[107,3684,3685,3687,3689,3692],{"class":109,"line":309},[107,3686,393],{"class":131},[107,3688,1523],{"class":120},[107,3690,3691],{"class":160}," \"yes\"         ",[107,3693,3694],{"class":113},"-- nil\n",[107,3696,3697,3699,3701,3703],{"class":109,"line":314},[107,3698,3661],{"class":131},[107,3700,350],{"class":120},[107,3702,3691],{"class":160},[107,3704,3705],{"class":113},"-- true (or returns 1st if truthy)\n",[107,3707,3708,3710,3712,3714],{"class":109,"line":320},[107,3709,3674],{"class":131},[107,3711,350],{"class":120},[107,3713,3666],{"class":160},[107,3715,3716],{"class":113},"-- \"yes\" (or returns 2nd if 1st is falsy)\n",[107,3718,3719,3721,3723,3726],{"class":109,"line":333},[107,3720,393],{"class":131},[107,3722,350],{"class":120},[107,3724,3725],{"class":160}," \"yes\"          ",[107,3727,3728],{"class":113},"-- \"yes\"\n",[107,3730,3731,3734,3736],{"class":109,"line":359},[107,3732,3733],{"class":120},"not",[107,3735,347],{"class":131},[107,3737,3738],{"class":113},"               -- true (not DOES return boolean)\n",[107,3740,3741,3743,3746],{"class":109,"line":365},[107,3742,3733],{"class":120},[107,3744,3745],{"class":131}," false",[107,3747,3748],{"class":113},"             -- true\n",[107,3750,3751,3753,3755],{"class":109,"line":370},[107,3752,3733],{"class":120},[107,3754,176],{"class":131},[107,3756,3757],{"class":113},"                -- false (0 is truthy!)\n",[107,3759,3760,3762,3765],{"class":109,"line":376},[107,3761,3733],{"class":120},[107,3763,3764],{"class":160}," \"\"               ",[107,3766,3767],{"class":113},"-- false (\"\" is truthy!)\n",[84,3769,3771,22,3773,3775],{"id":3770},"doend-explicit-scope-blocks",[19,3772,1201],{},[19,3774,545],{}," — Explicit Scope Blocks",[95,3777,3778,3923,3927,3940],{"language":97},[99,3779,3781],{"className":101,"code":3780,"language":97,"meta":103,"style":103},"-- do...end creates a lexical scope without a loop or condition\n-- Use for: limiting variable lifetime, cleanup, isolating locals\n\ndo\n  local large_buffer = allocate_megabyte()\n  process(large_buffer)\n  -- large_buffer goes out of scope here → eligible for GC immediately\nend\n-- large_buffer is nil here — not holding memory\n\n-- Pattern: resource lifecycle with do\u002Fend\ndo\n  local file \u003Cclose> = io.open(\"data.txt\", \"r\")  -- Lua 5.4: \u003Cclose> auto-closes\n  local data = file:read(\"*a\")\n  process(data)\n  -- file:close() called automatically at end of block (even on error)\nend\n",[19,3782,3783,3788,3793,3797,3801,3815,3823,3828,3832,3837,3841,3846,3850,3882,3907,3914,3919],{"__ignoreMap":103},[107,3784,3785],{"class":109,"line":110},[107,3786,3787],{"class":113},"-- do...end creates a lexical scope without a loop or condition\n",[107,3789,3790],{"class":109,"line":117},[107,3791,3792],{"class":113},"-- Use for: limiting variable lifetime, cleanup, isolating locals\n",[107,3794,3795],{"class":109,"line":135},[107,3796,221],{"emptyLinePlaceholder":220},[107,3798,3799],{"class":109,"line":151},[107,3800,950],{"class":120},[107,3802,3803,3805,3808,3810,3813],{"class":109,"line":167},[107,3804,690],{"class":120},[107,3806,3807],{"class":124}," large_buffer ",[107,3809,128],{"class":120},[107,3811,3812],{"class":131}," allocate_megabyte",[107,3814,1496],{"class":124},[107,3816,3817,3820],{"class":109,"line":181},[107,3818,3819],{"class":131},"  process",[107,3821,3822],{"class":124},"(large_buffer)\n",[107,3824,3825],{"class":109,"line":193},[107,3826,3827],{"class":113},"  -- large_buffer goes out of scope here → eligible for GC immediately\n",[107,3829,3830],{"class":109,"line":199},[107,3831,214],{"class":120},[107,3833,3834],{"class":109,"line":211},[107,3835,3836],{"class":113},"-- large_buffer is nil here — not holding memory\n",[107,3838,3839],{"class":109,"line":217},[107,3840,221],{"emptyLinePlaceholder":220},[107,3842,3843],{"class":109,"line":224},[107,3844,3845],{"class":113},"-- Pattern: resource lifecycle with do\u002Fend\n",[107,3847,3848],{"class":109,"line":230},[107,3849,950],{"class":120},[107,3851,3852,3854,3857,3860,3863,3866,3868,3871,3873,3876,3879],{"class":109,"line":242},[107,3853,690],{"class":120},[107,3855,3856],{"class":124}," file ",[107,3858,3859],{"class":120},"\u003Cclose>",[107,3861,3862],{"class":120}," =",[107,3864,3865],{"class":131}," io.open",[107,3867,157],{"class":124},[107,3869,3870],{"class":160},"\"data.txt\"",[107,3872,29],{"class":124},[107,3874,3875],{"class":160},"\"r\"",[107,3877,3878],{"class":124},")  ",[107,3880,3881],{"class":113},"-- Lua 5.4: \u003Cclose> auto-closes\n",[107,3883,3884,3886,3889,3891,3894,3897,3900,3902,3905],{"class":109,"line":269},[107,3885,690],{"class":120},[107,3887,3888],{"class":124}," data ",[107,3890,128],{"class":120},[107,3892,3893],{"class":1074}," file",[107,3895,3896],{"class":124},":",[107,3898,3899],{"class":131},"read",[107,3901,157],{"class":124},[107,3903,3904],{"class":160},"\"*a\"",[107,3906,164],{"class":124},[107,3908,3909,3911],{"class":109,"line":274},[107,3910,3819],{"class":131},[107,3912,3913],{"class":124},"(data)\n",[107,3915,3916],{"class":109,"line":287},[107,3917,3918],{"class":113},"  -- file:close() called automatically at end of block (even on error)\n",[107,3920,3921],{"class":109,"line":309},[107,3922,214],{"class":120},[84,3924,3926],{"id":3925},"tips-tricks","💡 Tips & Tricks",[15,3928,3929,3936,3937,3939],{},[67,3930,3931,3932,3935],{},"Use ",[19,3933,3934],{},"goto continue"," for clean skip logic",": Better than nested ",[19,3938,21],{}," or extracting functions when the skip condition is simple.",[95,3941,3942],{"language":97},[99,3943,3945],{"className":101,"code":3944,"language":97,"meta":103,"style":103},"for _, item in ipairs(items) do\n  if not validate(item) then goto continue end\n  if item.skip then goto continue end\n  process(item)\n  ::continue::\nend\n",[19,3946,3947,3963,3983,4001,4008,4012],{"__ignoreMap":103},[107,3948,3949,3951,3954,3956,3958,3961],{"class":109,"line":110},[107,3950,42],{"class":120},[107,3952,3953],{"class":124}," _, item ",[107,3955,1178],{"class":120},[107,3957,1885],{"class":131},[107,3959,3960],{"class":124},"(items) ",[107,3962,950],{"class":120},[107,3964,3965,3967,3969,3972,3975,3977,3979,3981],{"class":109,"line":117},[107,3966,841],{"class":120},[107,3968,1846],{"class":120},[107,3970,3971],{"class":131}," validate",[107,3973,3974],{"class":124},"(item) ",[107,3976,460],{"class":120},[107,3978,2345],{"class":120},[107,3980,2348],{"class":160},[107,3982,1165],{"class":120},[107,3984,3985,3987,3990,3993,3995,3997,3999],{"class":109,"line":135},[107,3986,841],{"class":120},[107,3988,3989],{"class":124}," item.",[107,3991,3992],{"class":1074},"skip",[107,3994,851],{"class":120},[107,3996,2345],{"class":120},[107,3998,2348],{"class":160},[107,4000,1165],{"class":120},[107,4002,4003,4005],{"class":109,"line":151},[107,4004,3819],{"class":131},[107,4006,4007],{"class":124},"(item)\n",[107,4009,4010],{"class":109,"line":167},[107,4011,2361],{"class":160},[107,4013,4014],{"class":109,"line":181},[107,4015,214],{"class":120},[15,4017,4018,4021,4022,4025,4026,82],{},[67,4019,4020],{},"Build custom iterators instead of manual indexing",": ",[19,4023,4024],{},"for x in my_iter() do"," is cleaner and less error-prone than ",[19,4027,4028],{},"for i = 1, #t do local x = t[i] end",[95,4030,4031],{"language":97},[99,4032,4034],{"className":101,"code":4033,"language":97,"meta":103,"style":103},"-- Stateless iterator for iterating two tables in parallel (zip)\nlocal function zip_iter(data, i)\n  i = i + 1\n  local a, b = data[1][i], data[2][i]\n  if a ~= nil or b ~= nil then return i, a, b end\nend\nlocal function zip(t1, t2)\n  return zip_iter, {t1, t2}, 0\nend\nfor i, a, b in zip({1, 2, 3}, {\"a\", \"b\", \"c\"}) do\n  print(i, a, b)  -- 1 1 a \u002F 2 2 b \u002F 3 3 c\nend\n",[19,4035,4036,4041,4053,4065,4086,4115,4119,4131,4141,4145,4184,4194],{"__ignoreMap":103},[107,4037,4038],{"class":109,"line":110},[107,4039,4040],{"class":113},"-- Stateless iterator for iterating two tables in parallel (zip)\n",[107,4042,4043,4045,4047,4050],{"class":109,"line":117},[107,4044,121],{"class":120},[107,4046,763],{"class":120},[107,4048,4049],{"class":1074}," zip_iter",[107,4051,4052],{"class":124},"(data, i)\n",[107,4054,4055,4057,4059,4061,4063],{"class":109,"line":135},[107,4056,1083],{"class":124},[107,4058,128],{"class":120},[107,4060,523],{"class":124},[107,4062,1090],{"class":120},[107,4064,1093],{"class":131},[107,4066,4067,4069,4071,4073,4076,4078,4081,4083],{"class":109,"line":151},[107,4068,690],{"class":120},[107,4070,1672],{"class":124},[107,4072,128],{"class":120},[107,4074,4075],{"class":124}," data[",[107,4077,425],{"class":131},[107,4079,4080],{"class":124},"][i], data[",[107,4082,600],{"class":131},[107,4084,4085],{"class":124},"][i]\n",[107,4087,4088,4090,4093,4095,4097,4099,4102,4104,4106,4108,4110,4113],{"class":109,"line":167},[107,4089,841],{"class":120},[107,4091,4092],{"class":124}," a ",[107,4094,1114],{"class":120},[107,4096,347],{"class":131},[107,4098,350],{"class":120},[107,4100,4101],{"class":124}," b ",[107,4103,1114],{"class":120},[107,4105,347],{"class":131},[107,4107,851],{"class":120},[107,4109,1121],{"class":120},[107,4111,4112],{"class":124}," i, a, b ",[107,4114,214],{"class":120},[107,4116,4117],{"class":109,"line":181},[107,4118,214],{"class":120},[107,4120,4121,4123,4125,4128],{"class":109,"line":193},[107,4122,121],{"class":120},[107,4124,763],{"class":120},[107,4126,4127],{"class":1074}," zip",[107,4129,4130],{"class":124},"(t1, t2)\n",[107,4132,4133,4135,4138],{"class":109,"line":199},[107,4134,1134],{"class":120},[107,4136,4137],{"class":124}," zip_iter, {t1, t2}, ",[107,4139,4140],{"class":131},"0\n",[107,4142,4143],{"class":109,"line":211},[107,4144,214],{"class":120},[107,4146,4147,4149,4151,4153,4155,4157,4159,4161,4163,4165,4167,4170,4172,4174,4176,4178,4180,4182],{"class":109,"line":217},[107,4148,42],{"class":120},[107,4150,4112],{"class":124},[107,4152,1178],{"class":120},[107,4154,4127],{"class":131},[107,4156,1183],{"class":124},[107,4158,425],{"class":131},[107,4160,29],{"class":124},[107,4162,600],{"class":131},[107,4164,29],{"class":124},[107,4166,751],{"class":131},[107,4168,4169],{"class":124},"}, {",[107,4171,1399],{"class":160},[107,4173,29],{"class":124},[107,4175,1404],{"class":160},[107,4177,29],{"class":124},[107,4179,1409],{"class":160},[107,4181,1198],{"class":124},[107,4183,950],{"class":120},[107,4185,4186,4188,4191],{"class":109,"line":224},[107,4187,154],{"class":131},[107,4189,4190],{"class":124},"(i, a, b)  ",[107,4192,4193],{"class":113},"-- 1 1 a \u002F 2 2 b \u002F 3 3 c\n",[107,4195,4196],{"class":109,"line":230},[107,4197,214],{"class":120},[15,4199,4200,4203],{},[67,4201,4202],{},"Table dispatch with fallback chain",": For layered handlers (e.g., event bubbling).",[95,4205,4206,4484,4486,4496,4545,4553,4608,4617,4746,4750],{"language":97},[99,4207,4209],{"className":101,"code":4208,"language":97,"meta":103,"style":103},"local function dispatch(event_name, ...)\n  local handler = specific_handlers[event_name]  -- try specific first\n  if handler then return handler(...) end\n  handler = general_handlers[event_name]  -- then general\n  if handler then return handler(...) end\n  return default_handler(...)  -- finally default\nend\n``\n::\n\n## ⚠️ Edge Cases & Gotchas\n\n**`for` loop with a function call as limit**: The function is called ONCE, not per iteration.\n\n::code-wrapper{language=\"lua\"}\n```lua\nlocal function count()\n  n = n + 1  -- side effect\n  return 5\nend\nfor i = 1, count() do print(i) end  -- count() called once; prints 1 2 3 4 5\n",[19,4210,4211,4222,4236,4256,4269,4289,4305,4309,4314,4319,4323,4331,4335,4387,4391,4413,4418,4429,4445,4452,4456],{"__ignoreMap":103},[107,4212,4213,4215,4217,4219],{"class":109,"line":110},[107,4214,121],{"class":120},[107,4216,763],{"class":120},[107,4218,3094],{"class":1074},[107,4220,4221],{"class":124},"(event_name, ...)\n",[107,4223,4224,4226,4228,4230,4233],{"class":109,"line":117},[107,4225,690],{"class":120},[107,4227,3024],{"class":124},[107,4229,128],{"class":120},[107,4231,4232],{"class":124}," specific_handlers[event_name]  ",[107,4234,4235],{"class":113},"-- try specific first\n",[107,4237,4238,4240,4242,4244,4246,4248,4250,4252,4254],{"class":109,"line":135},[107,4239,841],{"class":120},[107,4241,3024],{"class":124},[107,4243,460],{"class":120},[107,4245,1121],{"class":120},[107,4247,3070],{"class":131},[107,4249,157],{"class":124},[107,4251,3127],{"class":131},[107,4253,904],{"class":124},[107,4255,214],{"class":120},[107,4257,4258,4261,4263,4266],{"class":109,"line":151},[107,4259,4260],{"class":124},"  handler ",[107,4262,128],{"class":120},[107,4264,4265],{"class":124}," general_handlers[event_name]  ",[107,4267,4268],{"class":113},"-- then general\n",[107,4270,4271,4273,4275,4277,4279,4281,4283,4285,4287],{"class":109,"line":167},[107,4272,841],{"class":120},[107,4274,3024],{"class":124},[107,4276,460],{"class":120},[107,4278,1121],{"class":120},[107,4280,3070],{"class":131},[107,4282,157],{"class":124},[107,4284,3127],{"class":131},[107,4286,904],{"class":124},[107,4288,214],{"class":120},[107,4290,4291,4293,4296,4298,4300,4302],{"class":109,"line":181},[107,4292,1134],{"class":120},[107,4294,4295],{"class":131}," default_handler",[107,4297,157],{"class":124},[107,4299,3127],{"class":131},[107,4301,3878],{"class":124},[107,4303,4304],{"class":113},"-- finally default\n",[107,4306,4307],{"class":109,"line":193},[107,4308,214],{"class":120},[107,4310,4311],{"class":109,"line":199},[107,4312,4313],{"class":160},"``\n",[107,4315,4316],{"class":109,"line":211},[107,4317,4318],{"class":124},"::\n",[107,4320,4321],{"class":109,"line":217},[107,4322,221],{"emptyLinePlaceholder":220},[107,4324,4325,4328],{"class":109,"line":224},[107,4326,4327],{"class":120},"##",[107,4329,4330],{"class":124}," ⚠️ Edge Cases & Gotchas\n",[107,4332,4333],{"class":109,"line":230},[107,4334,221],{"emptyLinePlaceholder":220},[107,4336,4337,4340,4343,4346,4348,4351,4354,4357,4360,4363,4365,4368,4371,4374,4376,4378,4381,4384],{"class":109,"line":242},[107,4338,4339],{"class":120},"**",[107,4341,4342],{"class":160},"`for` ",[107,4344,4345],{"class":124},"loop with a ",[107,4347,1824],{"class":120},[107,4349,4350],{"class":1074}," call",[107,4352,4353],{"class":1074}," as",[107,4355,4356],{"class":1074}," limit",[107,4358,4359],{"class":124},"**: ",[107,4361,4362],{"class":1074},"The",[107,4364,763],{"class":1074},[107,4366,4367],{"class":1074}," is",[107,4369,4370],{"class":1074}," called",[107,4372,4373],{"class":1074}," ONCE",[107,4375,29],{"class":124},[107,4377,3733],{"class":1074},[107,4379,4380],{"class":1074}," per",[107,4382,4383],{"class":1074}," iteration",[107,4385,4386],{"class":124},".\n",[107,4388,4389],{"class":109,"line":269},[107,4390,221],{"emptyLinePlaceholder":220},[107,4392,4393,4396,4398,4400,4403,4406,4408,4411],{"class":109,"line":274},[107,4394,4395],{"class":124},"::",[107,4397,19],{"class":1074},[107,4399,567],{"class":124},[107,4401,4402],{"class":131},"wrapper",[107,4404,4405],{"class":124},"{language",[107,4407,128],{"class":120},[107,4409,4410],{"class":160},"\"lua\"",[107,4412,3001],{"class":124},[107,4414,4415],{"class":109,"line":287},[107,4416,4417],{"class":160},"```lua\n",[107,4419,4420,4422,4424,4427],{"class":109,"line":309},[107,4421,121],{"class":120},[107,4423,763],{"class":120},[107,4425,4426],{"class":1074}," count",[107,4428,1496],{"class":124},[107,4430,4431,4434,4436,4438,4440,4442],{"class":109,"line":314},[107,4432,4433],{"class":124},"  n ",[107,4435,128],{"class":120},[107,4437,1849],{"class":124},[107,4439,1090],{"class":120},[107,4441,528],{"class":131},[107,4443,4444],{"class":113},"  -- side effect\n",[107,4446,4447,4449],{"class":109,"line":320},[107,4448,1134],{"class":120},[107,4450,4451],{"class":131}," 5\n",[107,4453,4454],{"class":109,"line":333},[107,4455,214],{"class":120},[107,4457,4458,4460,4462,4464,4466,4468,4471,4473,4475,4477,4479,4481],{"class":109,"line":359},[107,4459,42],{"class":120},[107,4461,523],{"class":124},[107,4463,128],{"class":120},[107,4465,528],{"class":131},[107,4467,29],{"class":124},[107,4469,4470],{"class":131},"count",[107,4472,766],{"class":124},[107,4474,1201],{"class":120},[107,4476,539],{"class":131},[107,4478,542],{"class":124},[107,4480,545],{"class":120},[107,4482,4483],{"class":113},"  -- count() called once; prints 1 2 3 4 5\n",[15,4485,4395],{},[15,4487,4488,4021,4493,4495],{},[67,4489,4490,4492],{},[19,4491,49],{}," inside a function inside a loop does NOT break the loop",[19,4494,49],{}," only breaks the lexically enclosing loop, not dynamically.",[95,4497,4498],{"language":97},[99,4499,4501],{"className":101,"code":4500,"language":97,"meta":103,"style":103},"for i = 1, 10 do\n  local function f() break end  -- SYNTAX ERROR: break outside loop\n  -- Even if legal, calling f() wouldn't break the for — break is lexical, not dynamic\nend\n",[19,4502,4503,4519,4536,4541],{"__ignoreMap":103},[107,4504,4505,4507,4509,4511,4513,4515,4517],{"class":109,"line":110},[107,4506,42],{"class":120},[107,4508,523],{"class":124},[107,4510,128],{"class":120},[107,4512,528],{"class":131},[107,4514,29],{"class":124},[107,4516,595],{"class":131},[107,4518,685],{"class":120},[107,4520,4521,4523,4525,4527,4529,4531,4533],{"class":109,"line":117},[107,4522,690],{"class":120},[107,4524,763],{"class":120},[107,4526,988],{"class":1074},[107,4528,766],{"class":124},[107,4530,49],{"class":120},[107,4532,857],{"class":120},[107,4534,4535],{"class":113},"  -- SYNTAX ERROR: break outside loop\n",[107,4537,4538],{"class":109,"line":135},[107,4539,4540],{"class":113},"  -- Even if legal, calling f() wouldn't break the for — break is lexical, not dynamic\n",[107,4542,4543],{"class":109,"line":151},[107,4544,214],{"class":120},[15,4546,4547,4552],{},[67,4548,4549,4551],{},[19,4550,52],{}," cannot jump into the scope of a local",": This is a compile error, not runtime.",[95,4554,4555],{"language":97},[99,4556,4558],{"className":101,"code":4557,"language":97,"meta":103,"style":103},"do\n  goto skip\n  local x = 5    -- x's scope starts here\n  ::skip::\n  print(x)       -- x is in scope here, but we jumped past its declaration\nend\n-- ERROR: \u003Cgoto skip> jumps into the scope of local 'x'\n",[19,4559,4560,4564,4571,4584,4589,4599,4603],{"__ignoreMap":103},[107,4561,4562],{"class":109,"line":110},[107,4563,950],{"class":120},[107,4565,4566,4568],{"class":109,"line":117},[107,4567,2684],{"class":120},[107,4569,4570],{"class":160}," skip\n",[107,4572,4573,4575,4577,4579,4581],{"class":109,"line":135},[107,4574,690],{"class":120},[107,4576,125],{"class":124},[107,4578,128],{"class":120},[107,4580,145],{"class":131},[107,4582,4583],{"class":113},"    -- x's scope starts here\n",[107,4585,4586],{"class":109,"line":151},[107,4587,4588],{"class":160},"  ::skip::\n",[107,4590,4591,4593,4596],{"class":109,"line":167},[107,4592,154],{"class":131},[107,4594,4595],{"class":124},"(x)       ",[107,4597,4598],{"class":113},"-- x is in scope here, but we jumped past its declaration\n",[107,4600,4601],{"class":109,"line":181},[107,4602,214],{"class":120},[107,4604,4605],{"class":109,"line":193},[107,4606,4607],{"class":113},"-- ERROR: \u003Cgoto skip> jumps into the scope of local 'x'\n",[15,4609,4610,4616],{},[67,4611,4612,4615],{},[19,4613,4614],{},"pairs"," order is undefined — never rely on insertion order",": Use a separate ordered keys array if you need ordered iteration.",[95,4618,4619],{"language":97},[99,4620,4622],{"className":101,"code":4621,"language":97,"meta":103,"style":103},"local ordered = {}\nlocal dict = {}\nfor _, key in ipairs({\"name\", \"age\", \"email\"}) do\n  dict[key] = get_value(key)\n  ordered[#ordered + 1] = key  -- maintain order separately\nend\nfor _, key in ipairs(ordered) do  -- ordered iteration\n  print(key, dict[key])\nend\n",[19,4623,4624,4635,4646,4676,4689,4713,4717,4735,4742],{"__ignoreMap":103},[107,4625,4626,4628,4631,4633],{"class":109,"line":110},[107,4627,121],{"class":120},[107,4629,4630],{"class":124}," ordered ",[107,4632,128],{"class":120},[107,4634,736],{"class":124},[107,4636,4637,4639,4642,4644],{"class":109,"line":117},[107,4638,121],{"class":120},[107,4640,4641],{"class":124}," dict ",[107,4643,128],{"class":120},[107,4645,736],{"class":124},[107,4647,4648,4650,4653,4655,4657,4659,4662,4664,4667,4669,4672,4674],{"class":109,"line":135},[107,4649,42],{"class":120},[107,4651,4652],{"class":124}," _, key ",[107,4654,1178],{"class":120},[107,4656,1885],{"class":131},[107,4658,1183],{"class":124},[107,4660,4661],{"class":160},"\"name\"",[107,4663,29],{"class":124},[107,4665,4666],{"class":160},"\"age\"",[107,4668,29],{"class":124},[107,4670,4671],{"class":160},"\"email\"",[107,4673,1198],{"class":124},[107,4675,950],{"class":120},[107,4677,4678,4681,4683,4686],{"class":109,"line":151},[107,4679,4680],{"class":124},"  dict[key] ",[107,4682,128],{"class":120},[107,4684,4685],{"class":131}," get_value",[107,4687,4688],{"class":124},"(key)\n",[107,4690,4691,4694,4696,4699,4701,4703,4705,4707,4710],{"class":109,"line":167},[107,4692,4693],{"class":124},"  ordered[",[107,4695,1366],{"class":120},[107,4697,4698],{"class":124},"ordered ",[107,4700,1090],{"class":120},[107,4702,528],{"class":131},[107,4704,2941],{"class":124},[107,4706,128],{"class":120},[107,4708,4709],{"class":124}," key  ",[107,4711,4712],{"class":113},"-- maintain order separately\n",[107,4714,4715],{"class":109,"line":181},[107,4716,214],{"class":120},[107,4718,4719,4721,4723,4725,4727,4730,4732],{"class":109,"line":193},[107,4720,42],{"class":120},[107,4722,4652],{"class":124},[107,4724,1178],{"class":120},[107,4726,1885],{"class":131},[107,4728,4729],{"class":124},"(ordered) ",[107,4731,1201],{"class":120},[107,4733,4734],{"class":113},"  -- ordered iteration\n",[107,4736,4737,4739],{"class":109,"line":199},[107,4738,154],{"class":131},[107,4740,4741],{"class":124},"(key, dict[key])\n",[107,4743,4744],{"class":109,"line":211},[107,4745,214],{"class":120},[84,4747,4749],{"id":4748},"spot-the-bug","🧠 Spot the Bug",[95,4751,4752,4841],{"language":97},[99,4753,4755],{"className":101,"code":4754,"language":97,"meta":103,"style":103},"local fns = {}\nlocal i = 1\nwhile i \u003C= 3 do\n  fns[i] = function() return i end\n  i = i + 1\nend\nprint(fns[1](), fns[2](), fns[3]())\n",[19,4756,4757,4767,4777,4790,4806,4818,4822],{"__ignoreMap":103},[107,4758,4759,4761,4763,4765],{"class":109,"line":110},[107,4760,121],{"class":120},[107,4762,731],{"class":124},[107,4764,128],{"class":120},[107,4766,736],{"class":124},[107,4768,4769,4771,4773,4775],{"class":109,"line":117},[107,4770,121],{"class":120},[107,4772,523],{"class":124},[107,4774,128],{"class":120},[107,4776,1093],{"class":131},[107,4778,4779,4781,4783,4785,4788],{"class":109,"line":135},[107,4780,32],{"class":120},[107,4782,523],{"class":124},[107,4784,1528],{"class":120},[107,4786,4787],{"class":131}," 3",[107,4789,685],{"class":120},[107,4791,4792,4794,4796,4798,4800,4802,4804],{"class":109,"line":151},[107,4793,758],{"class":124},[107,4795,128],{"class":120},[107,4797,763],{"class":120},[107,4799,766],{"class":124},[107,4801,56],{"class":120},[107,4803,523],{"class":124},[107,4805,214],{"class":120},[107,4807,4808,4810,4812,4814,4816],{"class":109,"line":167},[107,4809,1083],{"class":124},[107,4811,128],{"class":120},[107,4813,523],{"class":124},[107,4815,1090],{"class":120},[107,4817,1093],{"class":131},[107,4819,4820],{"class":109,"line":181},[107,4821,214],{"class":120},[107,4823,4824,4826,4828,4830,4832,4834,4836,4838],{"class":109,"line":193},[107,4825,784],{"class":131},[107,4827,787],{"class":124},[107,4829,425],{"class":131},[107,4831,792],{"class":124},[107,4833,600],{"class":131},[107,4835,792],{"class":124},[107,4837,751],{"class":131},[107,4839,4840],{"class":124},"]())\n",[4842,4843,4844,4848,4854,4881,4887],"details",{},[4845,4846,4847],"summary",{},"Answer",[15,4849,4850,4851,82],{},"Prints ",[19,4852,4853],{},"4 4 4",[15,4855,4856,4857,4859,4860,4863,4864,4866,4867,4869,4870,4873,4874,4876,4877,4880],{},"Unlike the ",[19,4858,42],{}," loop (which creates a fresh ",[19,4861,4862],{},"i"," per iteration), the ",[19,4865,32],{}," loop uses a single ",[19,4868,4862],{}," variable. All three closures capture the ",[67,4871,4872],{},"same upvalue cell",". By the time the closures are called, ",[19,4875,4862],{}," has been incremented to 4 (the loop exits when ",[19,4878,4879],{},"i > 3","). So all three return 4.",[15,4882,4883,4884,4886],{},"Fix: introduce a new ",[19,4885,121],{}," inside the loop body to create a fresh cell per iteration:",[99,4888,4890],{"className":101,"code":4889,"language":97,"meta":103,"style":103},"local i = 1\nwhile i \u003C= 3 do\n  do\n    local captured = i\n    fns[i] = function() return captured end\n  end\n  i = i + 1\nend\n-- Now fns[1]() → 1, fns[2]() → 2, fns[3]() → 3\n",[19,4891,4892,4902,4914,4919,4930,4947,4951,4963,4967],{"__ignoreMap":103},[107,4893,4894,4896,4898,4900],{"class":109,"line":110},[107,4895,121],{"class":120},[107,4897,523],{"class":124},[107,4899,128],{"class":120},[107,4901,1093],{"class":131},[107,4903,4904,4906,4908,4910,4912],{"class":109,"line":117},[107,4905,32],{"class":120},[107,4907,523],{"class":124},[107,4909,1528],{"class":120},[107,4911,4787],{"class":131},[107,4913,685],{"class":120},[107,4915,4916],{"class":109,"line":135},[107,4917,4918],{"class":120},"  do\n",[107,4920,4921,4923,4926,4928],{"class":109,"line":151},[107,4922,980],{"class":120},[107,4924,4925],{"class":124}," captured ",[107,4927,128],{"class":120},[107,4929,1559],{"class":124},[107,4931,4932,4935,4937,4939,4941,4943,4945],{"class":109,"line":167},[107,4933,4934],{"class":124},"    fns[i] ",[107,4936,128],{"class":120},[107,4938,763],{"class":120},[107,4940,766],{"class":124},[107,4942,56],{"class":120},[107,4944,4925],{"class":124},[107,4946,214],{"class":120},[107,4948,4949],{"class":109,"line":181},[107,4950,1044],{"class":120},[107,4952,4953,4955,4957,4959,4961],{"class":109,"line":193},[107,4954,1083],{"class":124},[107,4956,128],{"class":120},[107,4958,523],{"class":124},[107,4960,1090],{"class":120},[107,4962,1093],{"class":131},[107,4964,4965],{"class":109,"line":199},[107,4966,214],{"class":120},[107,4968,4969],{"class":109,"line":211},[107,4970,4971],{"class":113},"-- Now fns[1]() → 1, fns[2]() → 2, fns[3]() → 3\n",[4973,4974,4975],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}",{"title":103,"searchDepth":117,"depth":117,"links":4977},[4978,4980,4985,4989,4991,4995,4996,4997,4999],{"id":86,"depth":117,"text":4979},"if\u002Felseif\u002Felse — Statement, Not Expression",{"id":481,"depth":117,"text":4981,"children":4982},"Numeric for — Precise Semantics",[4983],{"id":808,"depth":135,"text":4984},"Edge case: for with NaN or inf limits",{"id":926,"depth":117,"text":4986,"children":4987},"Generic for — The Iterator Protocol",[4988],{"id":1787,"depth":135,"text":1788},{"id":1973,"depth":117,"text":4990},"while and repeat\u002Funtil",{"id":2446,"depth":117,"text":4992,"children":4993},"goto — Structured Escape & State Machines",[4994],{"id":2727,"depth":135,"text":2728},{"id":2803,"depth":117,"text":2804},{"id":3540,"depth":117,"text":3541},{"id":3770,"depth":117,"text":4998},"do\u002Fend — Explicit Scope Blocks",{"id":4748,"depth":117,"text":4749},"[object Object]","md",{},"\u002Flua\u002F04-control-flow",{"title":5,"description":5005},{"Deep-dive into Lua's control flow":5006},"if\u002Felseif as statements (not expressions), numeric\u002Fgeneric for loops with custom iterators, goto for state machines, table dispatch as switch replacement, and the iterator protocol (stateless, stateful, and coroutine-based).","lua\u002F04-control-flow","O2aATU5PzC9hQ6jQCdP31t5jfPXrxnY1GzLLMdkcdyY",1789924650293]