[{"data":1,"prerenderedAt":3935},["ShallowReactive",2],{"page-\u002Fscala\u002F04-control-flow":3},{"id":4,"title":5,"body":6,"description":3928,"extension":3929,"meta":3930,"navigation":94,"path":3931,"seo":3932,"stem":3933,"__hash__":3934},"content\u002Fscala\u002F04-control-flow.md","Scala — Pattern Matching, Exhaustiveness & Branch Elimination",{"type":7,"value":8,"toc":3909},"minimark",[9,14,27,269,276,605,609,1214,1218,1520,1524,2065,2078,2528,2541,2726,2730,3065,3076,3486,3490,3507,3642,3661,3689,3693,3699,3809,3834,3854,3858,3865,3905],[10,11,13],"h1",{"id":12},"_04-pattern-matching-exhaustiveness-branch-elimination","04 — Pattern Matching, Exhaustiveness & Branch Elimination",[15,16,18,22,23,26],"h2",{"id":17},"if-else-expression-not-statement",[19,20,21],"code",{},"if"," \u002F ",[19,24,25],{},"else"," — Expression, Not Statement",[28,29,31],"code-wrapper",{"language":30},"scala",[32,33,37],"pre",{"className":34,"code":35,"language":30,"meta":36,"style":36},"language-scala shiki shiki-themes github-light github-dark","\u002F\u002F if\u002Felse evaluates to a value — the branch expression is the result\nval status = if httpCode \u003C 400 then \"ok\" else \"error\"\n\n\u002F\u002F All branches must have a common supertype (LUB — least upper bound)\nval result: Any = if cond then 42 else \"fail\"  \u002F\u002F LUB of Int and String = Any (AnyVal in Scala 3)\n\n\u002F\u002F if WITHOUT else returns Unit — the else branch implicitly is ()\nval sideEffect: Unit = if cond then println(\"yes\")  \u002F\u002F = if cond then println(\"yes\") else ()\n\n\u002F\u002F ❌ ANTI-PATTERN: using if for side effects when you need the value\nvar result = \"\"\nif cond then result = \"yes\" else result = \"no\"  \u002F\u002F mutation + if-as-statement\n\n\u002F\u002F ✅ CORRECT: expression form, no mutation\nval result = if cond then \"yes\" else \"no\"\n","",[19,38,39,48,89,96,102,138,143,149,182,187,193,206,236,241,247],{"__ignoreMap":36},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sdCPZ","\u002F\u002F if\u002Felse evaluates to a value — the branch expression is the result\n",[40,49,51,55,59,62,65,69,72,76,79,83,86],{"class":42,"line":50},2,[40,52,54],{"class":53},"svdQ7","val",[40,56,58],{"class":57},"sCrzJ"," status",[40,60,61],{"class":53}," =",[40,63,64],{"class":53}," if",[40,66,68],{"class":67},"ssxIu"," httpCode ",[40,70,71],{"class":53},"\u003C",[40,73,75],{"class":74},"snvgF"," 400",[40,77,78],{"class":53}," then",[40,80,82],{"class":81},"sJ6F3"," \"ok\"",[40,84,85],{"class":53}," else",[40,87,88],{"class":81}," \"error\"\n",[40,90,92],{"class":42,"line":91},3,[40,93,95],{"emptyLinePlaceholder":94},true,"\n",[40,97,99],{"class":42,"line":98},4,[40,100,101],{"class":46},"\u002F\u002F All branches must have a common supertype (LUB — least upper bound)\n",[40,103,105,107,110,113,117,119,121,124,127,130,132,135],{"class":42,"line":104},5,[40,106,54],{"class":53},[40,108,109],{"class":57}," result",[40,111,112],{"class":53},":",[40,114,116],{"class":115},"sIsaT"," Any",[40,118,61],{"class":53},[40,120,64],{"class":53},[40,122,123],{"class":67}," cond ",[40,125,126],{"class":53},"then",[40,128,129],{"class":74}," 42",[40,131,85],{"class":53},[40,133,134],{"class":81}," \"fail\"",[40,136,137],{"class":46},"  \u002F\u002F LUB of Int and String = Any (AnyVal in Scala 3)\n",[40,139,141],{"class":42,"line":140},6,[40,142,95],{"emptyLinePlaceholder":94},[40,144,146],{"class":42,"line":145},7,[40,147,148],{"class":46},"\u002F\u002F if WITHOUT else returns Unit — the else branch implicitly is ()\n",[40,150,152,154,157,159,162,164,166,168,170,173,176,179],{"class":42,"line":151},8,[40,153,54],{"class":53},[40,155,156],{"class":57}," sideEffect",[40,158,112],{"class":53},[40,160,161],{"class":115}," Unit",[40,163,61],{"class":53},[40,165,64],{"class":53},[40,167,123],{"class":67},[40,169,126],{"class":53},[40,171,172],{"class":67}," println(",[40,174,175],{"class":81},"\"yes\"",[40,177,178],{"class":67},")  ",[40,180,181],{"class":46},"\u002F\u002F = if cond then println(\"yes\") else ()\n",[40,183,185],{"class":42,"line":184},9,[40,186,95],{"emptyLinePlaceholder":94},[40,188,190],{"class":42,"line":189},10,[40,191,192],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: using if for side effects when you need the value\n",[40,194,196,199,201,203],{"class":42,"line":195},11,[40,197,198],{"class":53},"var",[40,200,109],{"class":57},[40,202,61],{"class":53},[40,204,205],{"class":81}," \"\"\n",[40,207,209,211,213,215,218,221,224,226,228,230,233],{"class":42,"line":208},12,[40,210,21],{"class":53},[40,212,123],{"class":67},[40,214,126],{"class":53},[40,216,217],{"class":67}," result ",[40,219,220],{"class":53},"=",[40,222,223],{"class":81}," \"yes\"",[40,225,85],{"class":53},[40,227,217],{"class":67},[40,229,220],{"class":53},[40,231,232],{"class":81}," \"no\"",[40,234,235],{"class":46},"  \u002F\u002F mutation + if-as-statement\n",[40,237,239],{"class":42,"line":238},13,[40,240,95],{"emptyLinePlaceholder":94},[40,242,244],{"class":42,"line":243},14,[40,245,246],{"class":46},"\u002F\u002F ✅ CORRECT: expression form, no mutation\n",[40,248,250,252,254,256,258,260,262,264,266],{"class":42,"line":249},15,[40,251,54],{"class":53},[40,253,109],{"class":57},[40,255,61],{"class":53},[40,257,64],{"class":53},[40,259,123],{"class":67},[40,261,126],{"class":53},[40,263,223],{"class":81},[40,265,85],{"class":53},[40,267,268],{"class":81}," \"no\"\n",[15,270,272,275],{"id":271},"match-exhaustiveness-sealed-hierarchies",[19,273,274],{},"match"," — Exhaustiveness & Sealed Hierarchies",[28,277,278],{"language":30},[32,279,281],{"className":34,"code":280,"language":30,"meta":36,"style":36},"\u002F\u002F Sealed hierarchy: compiler knows ALL subtypes → exhaustiveness check\nsealed trait HttpStatus\nobject HttpStatus:\n  case class Ok(body: String) extends HttpStatus\n  case class Error(code: Int, msg: String) extends HttpStatus\n  case object Pending extends HttpStatus\n\nimport HttpStatus.*\n\n\u002F\u002F Compiler verifies ALL cases are covered — missing case = compile ERROR (Scala 3)\ndef describe(s: HttpStatus): String = s match\n  case Ok(body)        => s\"OK: $body\"\n  case Error(code, _)  => s\"Error $code\"\n  case Pending         => \"Still processing\"\n\u002F\u002F If you add a new case (e.g., Redirect) → ALL match expressions break at compile time\n\u002F\u002F This is the #1 reason to use sealed: refactoring safety.\n\n\u002F\u002F ❌ ANTI-PATTERN: catch-all case hides missing branches\ndef describeBad(s: HttpStatus): String = s match\n  case Ok(_) => \"ok\"\n  case _ => \"other\"                        \u002F\u002F swallows Error AND Pending — silent bug on new cases\n\n\u002F\u002F ✅ CORRECT: explicit per-case, no catch-all for sealed types\n\u002F\u002F (unless genuinely handling unknown subtypes from unsealed hierarchies)\n",[19,282,283,288,299,310,341,375,390,394,407,411,416,450,474,495,507,512,518,523,529,557,572,588,593,599],{"__ignoreMap":36},[40,284,285],{"class":42,"line":43},[40,286,287],{"class":46},"\u002F\u002F Sealed hierarchy: compiler knows ALL subtypes → exhaustiveness check\n",[40,289,290,293,296],{"class":42,"line":50},[40,291,292],{"class":53},"sealed",[40,294,295],{"class":53}," trait",[40,297,298],{"class":115}," HttpStatus\n",[40,300,301,304,307],{"class":42,"line":91},[40,302,303],{"class":53},"object",[40,305,306],{"class":115}," HttpStatus",[40,308,309],{"class":53},":\n",[40,311,312,315,318,321,324,327,330,333,336,339],{"class":42,"line":98},[40,313,314],{"class":53},"  case",[40,316,317],{"class":53}," class",[40,319,320],{"class":115}," Ok",[40,322,323],{"class":67},"(",[40,325,326],{"class":57},"body",[40,328,329],{"class":67},": ",[40,331,332],{"class":115},"String",[40,334,335],{"class":67},") ",[40,337,338],{"class":53},"extends",[40,340,298],{"class":115},[40,342,343,345,347,350,352,354,356,359,362,365,367,369,371,373],{"class":42,"line":104},[40,344,314],{"class":53},[40,346,317],{"class":53},[40,348,349],{"class":115}," Error",[40,351,323],{"class":67},[40,353,19],{"class":57},[40,355,329],{"class":67},[40,357,358],{"class":115},"Int",[40,360,361],{"class":67},", ",[40,363,364],{"class":57},"msg",[40,366,329],{"class":67},[40,368,332],{"class":115},[40,370,335],{"class":67},[40,372,338],{"class":53},[40,374,298],{"class":115},[40,376,377,379,382,385,388],{"class":42,"line":140},[40,378,314],{"class":53},[40,380,381],{"class":53}," object",[40,383,384],{"class":115}," Pending",[40,386,387],{"class":53}," extends",[40,389,298],{"class":115},[40,391,392],{"class":42,"line":145},[40,393,95],{"emptyLinePlaceholder":94},[40,395,396,399,401,404],{"class":42,"line":151},[40,397,398],{"class":53},"import",[40,400,306],{"class":115},[40,402,403],{"class":67},".",[40,405,406],{"class":115},"*\n",[40,408,409],{"class":42,"line":184},[40,410,95],{"emptyLinePlaceholder":94},[40,412,413],{"class":42,"line":189},[40,414,415],{"class":46},"\u002F\u002F Compiler verifies ALL cases are covered — missing case = compile ERROR (Scala 3)\n",[40,417,418,421,424,426,429,431,434,437,439,442,444,447],{"class":42,"line":195},[40,419,420],{"class":53},"def",[40,422,423],{"class":115}," describe",[40,425,323],{"class":67},[40,427,428],{"class":57},"s",[40,430,329],{"class":67},[40,432,433],{"class":115},"HttpStatus",[40,435,436],{"class":67},")",[40,438,112],{"class":53},[40,440,441],{"class":115}," String",[40,443,61],{"class":53},[40,445,446],{"class":67}," s ",[40,448,449],{"class":53},"match\n",[40,451,452,454,456,459,462,465,468,471],{"class":42,"line":208},[40,453,314],{"class":53},[40,455,320],{"class":115},[40,457,458],{"class":67},"(body)        ",[40,460,461],{"class":53},"=>",[40,463,464],{"class":53}," s",[40,466,467],{"class":81},"\"OK: ",[40,469,470],{"class":67},"$body",[40,472,473],{"class":81},"\"\n",[40,475,476,478,480,483,485,487,490,493],{"class":42,"line":238},[40,477,314],{"class":53},[40,479,349],{"class":115},[40,481,482],{"class":67},"(code, _)  ",[40,484,461],{"class":53},[40,486,464],{"class":53},[40,488,489],{"class":81},"\"Error ",[40,491,492],{"class":67},"$code",[40,494,473],{"class":81},[40,496,497,499,501,504],{"class":42,"line":243},[40,498,314],{"class":53},[40,500,384],{"class":115},[40,502,503],{"class":53},"         =>",[40,505,506],{"class":81}," \"Still processing\"\n",[40,508,509],{"class":42,"line":249},[40,510,511],{"class":46},"\u002F\u002F If you add a new case (e.g., Redirect) → ALL match expressions break at compile time\n",[40,513,515],{"class":42,"line":514},16,[40,516,517],{"class":46},"\u002F\u002F This is the #1 reason to use sealed: refactoring safety.\n",[40,519,521],{"class":42,"line":520},17,[40,522,95],{"emptyLinePlaceholder":94},[40,524,526],{"class":42,"line":525},18,[40,527,528],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: catch-all case hides missing branches\n",[40,530,532,534,537,539,541,543,545,547,549,551,553,555],{"class":42,"line":531},19,[40,533,420],{"class":53},[40,535,536],{"class":115}," describeBad",[40,538,323],{"class":67},[40,540,428],{"class":57},[40,542,329],{"class":67},[40,544,433],{"class":115},[40,546,436],{"class":67},[40,548,112],{"class":53},[40,550,441],{"class":115},[40,552,61],{"class":53},[40,554,446],{"class":67},[40,556,449],{"class":53},[40,558,560,562,564,567,569],{"class":42,"line":559},20,[40,561,314],{"class":53},[40,563,320],{"class":115},[40,565,566],{"class":67},"(_) ",[40,568,461],{"class":53},[40,570,571],{"class":81}," \"ok\"\n",[40,573,575,577,580,582,585],{"class":42,"line":574},21,[40,576,314],{"class":53},[40,578,579],{"class":67}," _ ",[40,581,461],{"class":53},[40,583,584],{"class":81}," \"other\"",[40,586,587],{"class":46},"                        \u002F\u002F swallows Error AND Pending — silent bug on new cases\n",[40,589,591],{"class":42,"line":590},22,[40,592,95],{"emptyLinePlaceholder":94},[40,594,596],{"class":42,"line":595},23,[40,597,598],{"class":46},"\u002F\u002F ✅ CORRECT: explicit per-case, no catch-all for sealed types\n",[40,600,602],{"class":42,"line":601},24,[40,603,604],{"class":46},"\u002F\u002F (unless genuinely handling unknown subtypes from unsealed hierarchies)\n",[15,606,608],{"id":607},"pattern-types-literal-constructor-type-guard","Pattern Types — Literal, Constructor, Type, Guard",[28,610,611],{"language":30},[32,612,614],{"className":34,"code":613,"language":30,"meta":36,"style":36},"final case class HttpRequest(method: String, path: String, headers: Map[String, String])\nfinal case class HttpResponse(status: Int, body: Array[Byte])\n\n\u002F\u002F 1. Literal pattern — exact value match\ndef httpVerb(method: String): String = method match\n  case \"GET\"    => \"read\"\n  case \"POST\"   => \"create\"\n  case \"PUT\"    => \"update\"\n  case \"DELETE\" => \"remove\"\n  case other    => s\"unknown: $other\"      \u002F\u002F variable pattern — catches anything, binds it\n\n\u002F\u002F 2. Constructor pattern — destructure case class fields\ndef route(req: HttpRequest): HttpResponse = req match\n  case HttpRequest(\"GET\", path, _) if path.startsWith(\"\u002Fapi\u002F\") =>\n    HttpResponse(200, handleApi(path).getBytes)\n  case HttpRequest(\"GET\", \"\u002F\", headers) =>\n    HttpResponse(200, serveIndex(headers).getBytes)\n  case HttpRequest(\"POST\", \"\u002Fusers\", h) if h.get(\"Content-Type\").contains(\"application\u002Fjson\") =>\n    HttpResponse(201, createUser().getBytes)\n  case HttpRequest(method, path, _) =>\n    HttpResponse(405, s\"Method $method not allowed for $path\".getBytes)\n\n\u002F\u002F 3. Type pattern — runtime type test + safe cast (no ClassCastException)\ndef serialize(value: Any): String = value match\n  case s: String    => s\"\"\"\"$s\"\"\"\"          \u002F\u002F type test + binding in one\n  case i: Int       => i.toString\n  case a: Array[Byte] => java.util.Base64.getEncoder.encodeToString(a)\n  case m: Map[?, ?] => m.map { case (k, v) => s\"$k:$v\" }.mkString(\"{\", \",\", \"}\")\n  case null         => \"null\"              \u002F\u002F explicit null match (Scala 3 without -explicitNulls)\n",[19,615,616,669,705,709,714,742,755,768,780,793,816,820,825,855,882,895,915,926,963,975,986,1016,1020,1025,1055,1081,1099,1129,1198],{"__ignoreMap":36},[40,617,618,621,624,626,629,631,634,636,638,640,643,645,647,649,652,654,657,660,662,664,666],{"class":42,"line":43},[40,619,620],{"class":53},"final",[40,622,623],{"class":53}," case",[40,625,317],{"class":53},[40,627,628],{"class":115}," HttpRequest",[40,630,323],{"class":67},[40,632,633],{"class":57},"method",[40,635,329],{"class":67},[40,637,332],{"class":115},[40,639,361],{"class":67},[40,641,642],{"class":57},"path",[40,644,329],{"class":67},[40,646,332],{"class":115},[40,648,361],{"class":67},[40,650,651],{"class":57},"headers",[40,653,329],{"class":67},[40,655,656],{"class":115},"Map",[40,658,659],{"class":67},"[",[40,661,332],{"class":115},[40,663,361],{"class":67},[40,665,332],{"class":115},[40,667,668],{"class":67},"])\n",[40,670,671,673,675,677,680,682,685,687,689,691,693,695,698,700,703],{"class":42,"line":50},[40,672,620],{"class":53},[40,674,623],{"class":53},[40,676,317],{"class":53},[40,678,679],{"class":115}," HttpResponse",[40,681,323],{"class":67},[40,683,684],{"class":57},"status",[40,686,329],{"class":67},[40,688,358],{"class":115},[40,690,361],{"class":67},[40,692,326],{"class":57},[40,694,329],{"class":67},[40,696,697],{"class":115},"Array",[40,699,659],{"class":67},[40,701,702],{"class":115},"Byte",[40,704,668],{"class":67},[40,706,707],{"class":42,"line":91},[40,708,95],{"emptyLinePlaceholder":94},[40,710,711],{"class":42,"line":98},[40,712,713],{"class":46},"\u002F\u002F 1. Literal pattern — exact value match\n",[40,715,716,718,721,723,725,727,729,731,733,735,737,740],{"class":42,"line":104},[40,717,420],{"class":53},[40,719,720],{"class":115}," httpVerb",[40,722,323],{"class":67},[40,724,633],{"class":57},[40,726,329],{"class":67},[40,728,332],{"class":115},[40,730,436],{"class":67},[40,732,112],{"class":53},[40,734,441],{"class":115},[40,736,61],{"class":53},[40,738,739],{"class":67}," method ",[40,741,449],{"class":53},[40,743,744,746,749,752],{"class":42,"line":140},[40,745,314],{"class":53},[40,747,748],{"class":81}," \"GET\"",[40,750,751],{"class":53},"    =>",[40,753,754],{"class":81}," \"read\"\n",[40,756,757,759,762,765],{"class":42,"line":145},[40,758,314],{"class":53},[40,760,761],{"class":81}," \"POST\"",[40,763,764],{"class":53},"   =>",[40,766,767],{"class":81}," \"create\"\n",[40,769,770,772,775,777],{"class":42,"line":151},[40,771,314],{"class":53},[40,773,774],{"class":81}," \"PUT\"",[40,776,751],{"class":53},[40,778,779],{"class":81}," \"update\"\n",[40,781,782,784,787,790],{"class":42,"line":184},[40,783,314],{"class":53},[40,785,786],{"class":81}," \"DELETE\"",[40,788,789],{"class":53}," =>",[40,791,792],{"class":81}," \"remove\"\n",[40,794,795,797,800,802,804,807,810,813],{"class":42,"line":189},[40,796,314],{"class":53},[40,798,799],{"class":67}," other    ",[40,801,461],{"class":53},[40,803,464],{"class":53},[40,805,806],{"class":81},"\"unknown: ",[40,808,809],{"class":67},"$other",[40,811,812],{"class":81},"\"",[40,814,815],{"class":46},"      \u002F\u002F variable pattern — catches anything, binds it\n",[40,817,818],{"class":42,"line":195},[40,819,95],{"emptyLinePlaceholder":94},[40,821,822],{"class":42,"line":208},[40,823,824],{"class":46},"\u002F\u002F 2. Constructor pattern — destructure case class fields\n",[40,826,827,829,832,834,837,839,842,844,846,848,850,853],{"class":42,"line":238},[40,828,420],{"class":53},[40,830,831],{"class":115}," route",[40,833,323],{"class":67},[40,835,836],{"class":57},"req",[40,838,329],{"class":67},[40,840,841],{"class":115},"HttpRequest",[40,843,436],{"class":67},[40,845,112],{"class":53},[40,847,679],{"class":115},[40,849,61],{"class":53},[40,851,852],{"class":67}," req ",[40,854,449],{"class":53},[40,856,857,859,861,863,866,869,871,874,877,879],{"class":42,"line":243},[40,858,314],{"class":53},[40,860,628],{"class":115},[40,862,323],{"class":67},[40,864,865],{"class":81},"\"GET\"",[40,867,868],{"class":67},", path, _) ",[40,870,21],{"class":53},[40,872,873],{"class":67}," path.startsWith(",[40,875,876],{"class":81},"\"\u002Fapi\u002F\"",[40,878,335],{"class":67},[40,880,881],{"class":53},"=>\n",[40,883,884,887,889,892],{"class":42,"line":249},[40,885,886],{"class":115},"    HttpResponse",[40,888,323],{"class":67},[40,890,891],{"class":74},"200",[40,893,894],{"class":67},", handleApi(path).getBytes)\n",[40,896,897,899,901,903,905,907,910,913],{"class":42,"line":514},[40,898,314],{"class":53},[40,900,628],{"class":115},[40,902,323],{"class":67},[40,904,865],{"class":81},[40,906,361],{"class":67},[40,908,909],{"class":81},"\"\u002F\"",[40,911,912],{"class":67},", headers) ",[40,914,881],{"class":53},[40,916,917,919,921,923],{"class":42,"line":520},[40,918,886],{"class":115},[40,920,323],{"class":67},[40,922,891],{"class":74},[40,924,925],{"class":67},", serveIndex(headers).getBytes)\n",[40,927,928,930,932,934,937,939,942,945,947,950,953,956,959,961],{"class":42,"line":525},[40,929,314],{"class":53},[40,931,628],{"class":115},[40,933,323],{"class":67},[40,935,936],{"class":81},"\"POST\"",[40,938,361],{"class":67},[40,940,941],{"class":81},"\"\u002Fusers\"",[40,943,944],{"class":67},", h) ",[40,946,21],{"class":53},[40,948,949],{"class":67}," h.get(",[40,951,952],{"class":81},"\"Content-Type\"",[40,954,955],{"class":67},").contains(",[40,957,958],{"class":81},"\"application\u002Fjson\"",[40,960,335],{"class":67},[40,962,881],{"class":53},[40,964,965,967,969,972],{"class":42,"line":531},[40,966,886],{"class":115},[40,968,323],{"class":67},[40,970,971],{"class":74},"201",[40,973,974],{"class":67},", createUser().getBytes)\n",[40,976,977,979,981,984],{"class":42,"line":559},[40,978,314],{"class":53},[40,980,628],{"class":115},[40,982,983],{"class":67},"(method, path, _) ",[40,985,881],{"class":53},[40,987,988,990,992,995,997,999,1002,1005,1008,1011,1013],{"class":42,"line":574},[40,989,886],{"class":115},[40,991,323],{"class":67},[40,993,994],{"class":74},"405",[40,996,361],{"class":67},[40,998,428],{"class":53},[40,1000,1001],{"class":81},"\"Method ",[40,1003,1004],{"class":67},"$method",[40,1006,1007],{"class":81}," not allowed for ",[40,1009,1010],{"class":67},"$path",[40,1012,812],{"class":81},[40,1014,1015],{"class":67},".getBytes)\n",[40,1017,1018],{"class":42,"line":590},[40,1019,95],{"emptyLinePlaceholder":94},[40,1021,1022],{"class":42,"line":595},[40,1023,1024],{"class":46},"\u002F\u002F 3. Type pattern — runtime type test + safe cast (no ClassCastException)\n",[40,1026,1027,1029,1032,1034,1037,1039,1042,1044,1046,1048,1050,1053],{"class":42,"line":601},[40,1028,420],{"class":53},[40,1030,1031],{"class":115}," serialize",[40,1033,323],{"class":67},[40,1035,1036],{"class":57},"value",[40,1038,329],{"class":67},[40,1040,1041],{"class":115},"Any",[40,1043,436],{"class":67},[40,1045,112],{"class":53},[40,1047,441],{"class":115},[40,1049,61],{"class":53},[40,1051,1052],{"class":67}," value ",[40,1054,449],{"class":53},[40,1056,1058,1060,1062,1064,1066,1068,1070,1073,1076,1078],{"class":42,"line":1057},25,[40,1059,314],{"class":53},[40,1061,464],{"class":57},[40,1063,329],{"class":67},[40,1065,332],{"class":115},[40,1067,751],{"class":53},[40,1069,464],{"class":53},[40,1071,1072],{"class":81},"\"\"\"\"",[40,1074,1075],{"class":67},"$s",[40,1077,1072],{"class":81},[40,1079,1080],{"class":46},"          \u002F\u002F type test + binding in one\n",[40,1082,1084,1086,1089,1091,1093,1096],{"class":42,"line":1083},26,[40,1085,314],{"class":53},[40,1087,1088],{"class":57}," i",[40,1090,329],{"class":67},[40,1092,358],{"class":115},[40,1094,1095],{"class":53},"       =>",[40,1097,1098],{"class":67}," i.toString\n",[40,1100,1102,1104,1107,1109,1111,1113,1115,1118,1120,1123,1126],{"class":42,"line":1101},27,[40,1103,314],{"class":53},[40,1105,1106],{"class":57}," a",[40,1108,329],{"class":67},[40,1110,697],{"class":115},[40,1112,659],{"class":67},[40,1114,702],{"class":115},[40,1116,1117],{"class":67},"] ",[40,1119,461],{"class":53},[40,1121,1122],{"class":67}," java.util.",[40,1124,1125],{"class":115},"Base64",[40,1127,1128],{"class":67},".getEncoder.encodeToString(a)\n",[40,1130,1132,1134,1137,1139,1141,1143,1146,1148,1150,1152,1154,1157,1160,1163,1165,1167,1169,1172,1174,1177,1179,1182,1185,1187,1190,1192,1195],{"class":42,"line":1131},28,[40,1133,314],{"class":53},[40,1135,1136],{"class":57}," m",[40,1138,329],{"class":67},[40,1140,656],{"class":115},[40,1142,659],{"class":67},[40,1144,1145],{"class":53},"?",[40,1147,361],{"class":67},[40,1149,1145],{"class":53},[40,1151,1117],{"class":67},[40,1153,461],{"class":53},[40,1155,1156],{"class":67}," m.map { ",[40,1158,1159],{"class":53},"case",[40,1161,1162],{"class":67}," (k, v) ",[40,1164,461],{"class":53},[40,1166,464],{"class":53},[40,1168,812],{"class":81},[40,1170,1171],{"class":67},"$k",[40,1173,112],{"class":81},[40,1175,1176],{"class":67},"$v",[40,1178,812],{"class":81},[40,1180,1181],{"class":67}," }.mkString(",[40,1183,1184],{"class":81},"\"{\"",[40,1186,361],{"class":67},[40,1188,1189],{"class":81},"\",\"",[40,1191,361],{"class":67},[40,1193,1194],{"class":81},"\"}\"",[40,1196,1197],{"class":67},")\n",[40,1199,1201,1203,1206,1208,1211],{"class":42,"line":1200},29,[40,1202,314],{"class":53},[40,1204,1205],{"class":74}," null",[40,1207,503],{"class":53},[40,1209,1210],{"class":81}," \"null\"",[40,1212,1213],{"class":46},"              \u002F\u002F explicit null match (Scala 3 without -explicitNulls)\n",[15,1215,1217],{"id":1216},"type-erasure-the-generic-pattern-trap","Type Erasure — The Generic Pattern Trap",[28,1219,1220],{"language":30},[32,1221,1223],{"className":34,"code":1222,"language":30,"meta":36,"style":36},"\u002F\u002F ❌ DANGEROUS: type parameters are erased — runtime can't distinguish List[Int] from List[String]\ndef headAsInt(list: List[?]): Option[Int] = list match\n  case _: List[Int]    => Some(list.head.asInstanceOf[Int])  \u002F\u002F UNCHECKED — will match List[String]!\n  case _: List[String] => None                                \u002F\u002F UNREACHABLE — erasure makes both identical\n  case _               => None\n\nheadAsInt(List(\"a\", \"b\"))                  \u002F\u002F → Some(\"a\".asInstanceOf[Int]) — ClassCastException at use!\n\n\u002F\u002F Scala 3 gives a WARNING: \"pattern type List[Int] is unchecked since it is eliminated by erasure\"\n\n\u002F\u002F ✅ CORRECT: match on element types at runtime, not the container's type parameter\ndef headAsIntSafe(list: List[?]): Option[Int] = list.headOption match\n  case Some(i: Int) => Some(i)             \u002F\u002F element-level type test — safe\n  case _            => None\n\nheadAsIntSafe(List(1, 2, 3))               \u002F\u002F → Some(1)\nheadAsIntSafe(List(\"a\", \"b\"))             \u002F\u002F → None (String doesn't match Int)\n",[19,1224,1225,1230,1272,1311,1335,1347,1351,1374,1378,1383,1387,1392,1430,1457,1468,1472,1500],{"__ignoreMap":36},[40,1226,1227],{"class":42,"line":43},[40,1228,1229],{"class":46},"\u002F\u002F ❌ DANGEROUS: type parameters are erased — runtime can't distinguish List[Int] from List[String]\n",[40,1231,1232,1234,1237,1239,1242,1244,1247,1249,1251,1254,1256,1259,1261,1263,1265,1267,1270],{"class":42,"line":50},[40,1233,420],{"class":53},[40,1235,1236],{"class":115}," headAsInt",[40,1238,323],{"class":67},[40,1240,1241],{"class":57},"list",[40,1243,329],{"class":67},[40,1245,1246],{"class":115},"List",[40,1248,659],{"class":67},[40,1250,1145],{"class":53},[40,1252,1253],{"class":67},"])",[40,1255,112],{"class":53},[40,1257,1258],{"class":115}," Option",[40,1260,659],{"class":67},[40,1262,358],{"class":115},[40,1264,1117],{"class":67},[40,1266,220],{"class":53},[40,1268,1269],{"class":67}," list ",[40,1271,449],{"class":53},[40,1273,1274,1276,1279,1281,1283,1285,1287,1290,1292,1295,1298,1301,1303,1305,1308],{"class":42,"line":91},[40,1275,314],{"class":53},[40,1277,1278],{"class":57}," _",[40,1280,329],{"class":67},[40,1282,1246],{"class":115},[40,1284,659],{"class":67},[40,1286,358],{"class":115},[40,1288,1289],{"class":67},"]    ",[40,1291,461],{"class":53},[40,1293,1294],{"class":115}," Some",[40,1296,1297],{"class":67},"(list.head.",[40,1299,1300],{"class":74},"asInstanceOf",[40,1302,659],{"class":67},[40,1304,358],{"class":115},[40,1306,1307],{"class":67},"])  ",[40,1309,1310],{"class":46},"\u002F\u002F UNCHECKED — will match List[String]!\n",[40,1312,1313,1315,1317,1319,1321,1323,1325,1327,1329,1332],{"class":42,"line":98},[40,1314,314],{"class":53},[40,1316,1278],{"class":57},[40,1318,329],{"class":67},[40,1320,1246],{"class":115},[40,1322,659],{"class":67},[40,1324,332],{"class":115},[40,1326,1117],{"class":67},[40,1328,461],{"class":53},[40,1330,1331],{"class":115}," None",[40,1333,1334],{"class":46},"                                \u002F\u002F UNREACHABLE — erasure makes both identical\n",[40,1336,1337,1339,1342,1344],{"class":42,"line":104},[40,1338,314],{"class":53},[40,1340,1341],{"class":67}," _               ",[40,1343,461],{"class":53},[40,1345,1346],{"class":115}," None\n",[40,1348,1349],{"class":42,"line":140},[40,1350,95],{"emptyLinePlaceholder":94},[40,1352,1353,1356,1358,1360,1363,1365,1368,1371],{"class":42,"line":145},[40,1354,1355],{"class":67},"headAsInt(",[40,1357,1246],{"class":115},[40,1359,323],{"class":67},[40,1361,1362],{"class":81},"\"a\"",[40,1364,361],{"class":67},[40,1366,1367],{"class":81},"\"b\"",[40,1369,1370],{"class":67},"))                  ",[40,1372,1373],{"class":46},"\u002F\u002F → Some(\"a\".asInstanceOf[Int]) — ClassCastException at use!\n",[40,1375,1376],{"class":42,"line":151},[40,1377,95],{"emptyLinePlaceholder":94},[40,1379,1380],{"class":42,"line":184},[40,1381,1382],{"class":46},"\u002F\u002F Scala 3 gives a WARNING: \"pattern type List[Int] is unchecked since it is eliminated by erasure\"\n",[40,1384,1385],{"class":42,"line":189},[40,1386,95],{"emptyLinePlaceholder":94},[40,1388,1389],{"class":42,"line":195},[40,1390,1391],{"class":46},"\u002F\u002F ✅ CORRECT: match on element types at runtime, not the container's type parameter\n",[40,1393,1394,1396,1399,1401,1403,1405,1407,1409,1411,1413,1415,1417,1419,1421,1423,1425,1428],{"class":42,"line":208},[40,1395,420],{"class":53},[40,1397,1398],{"class":115}," headAsIntSafe",[40,1400,323],{"class":67},[40,1402,1241],{"class":57},[40,1404,329],{"class":67},[40,1406,1246],{"class":115},[40,1408,659],{"class":67},[40,1410,1145],{"class":53},[40,1412,1253],{"class":67},[40,1414,112],{"class":53},[40,1416,1258],{"class":115},[40,1418,659],{"class":67},[40,1420,358],{"class":115},[40,1422,1117],{"class":67},[40,1424,220],{"class":53},[40,1426,1427],{"class":67}," list.headOption ",[40,1429,449],{"class":53},[40,1431,1432,1434,1436,1438,1441,1443,1445,1447,1449,1451,1454],{"class":42,"line":238},[40,1433,314],{"class":53},[40,1435,1294],{"class":115},[40,1437,323],{"class":67},[40,1439,1440],{"class":57},"i",[40,1442,329],{"class":67},[40,1444,358],{"class":115},[40,1446,335],{"class":67},[40,1448,461],{"class":53},[40,1450,1294],{"class":115},[40,1452,1453],{"class":67},"(i)             ",[40,1455,1456],{"class":46},"\u002F\u002F element-level type test — safe\n",[40,1458,1459,1461,1464,1466],{"class":42,"line":243},[40,1460,314],{"class":53},[40,1462,1463],{"class":67}," _            ",[40,1465,461],{"class":53},[40,1467,1346],{"class":115},[40,1469,1470],{"class":42,"line":249},[40,1471,95],{"emptyLinePlaceholder":94},[40,1473,1474,1477,1479,1481,1484,1486,1489,1491,1494,1497],{"class":42,"line":514},[40,1475,1476],{"class":67},"headAsIntSafe(",[40,1478,1246],{"class":115},[40,1480,323],{"class":67},[40,1482,1483],{"class":74},"1",[40,1485,361],{"class":67},[40,1487,1488],{"class":74},"2",[40,1490,361],{"class":67},[40,1492,1493],{"class":74},"3",[40,1495,1496],{"class":67},"))               ",[40,1498,1499],{"class":46},"\u002F\u002F → Some(1)\n",[40,1501,1502,1504,1506,1508,1510,1512,1514,1517],{"class":42,"line":520},[40,1503,1476],{"class":67},[40,1505,1246],{"class":115},[40,1507,323],{"class":67},[40,1509,1362],{"class":81},[40,1511,361],{"class":67},[40,1513,1367],{"class":81},[40,1515,1516],{"class":67},"))             ",[40,1518,1519],{"class":46},"\u002F\u002F → None (String doesn't match Int)\n",[15,1521,1523],{"id":1522},"unapply-extractors-custom-pattern-matching","Unapply \u002F Extractors — Custom Pattern Matching",[28,1525,1526],{"language":30},[32,1527,1529],{"className":34,"code":1528,"language":30,"meta":36,"style":36},"\u002F\u002F Custom extractor via unapply — enables pattern matching on non-case-class types\nobject HttpStatusCode:\n  def unapply(code: Int): Option[(String, String)] =\n    val reason = code match\n      case 200 => \"OK\"\n      case 404 => \"Not Found\"\n      case 500 => \"Internal Server Error\"\n      case _   => return None               \u002F\u002F early return — no match\n    val category = code \u002F 100 match\n      case 2 => \"Success\"\n      case 4 => \"Client Error\"\n      case 5 => \"Server Error\"\n      case _ => \"Unknown\"\n    Some((category, reason))\n\n\u002F\u002F Now usable in match:\ndef describe(code: Int): String = code match\n  case HttpStatusCode(cat, reason) => s\"$cat: $reason\"\n  case _ => \"Unknown code\"\n\n\u002F\u002F Boolean extractor — unapply returning Boolean (no captured values)\nobject IsEven:\n  def unapply(n: Int): Boolean = n % 2 == 0\n\ndef classify(n: Int): String = n match\n  case IsEven() => \"even\"                   \u002F\u002F note: () not _ — boolean extractor\n  case _        => \"odd\"\n\n\u002F\u002F Product extractor — unapply returning Option[Tuple] for destructuring\nobject SplitPath:\n  def unapply(path: String): Option[(String, String)] =\n    val idx = path.indexOf('\u002F')\n    if idx \u003C 0 then None else Some((path.take(idx), path.drop(idx + 1)))\n\n\"\u002Fapi\u002Fusers\" match\n  case SplitPath(head, rest) => println(s\"head=$head, rest=$rest\")  \u002F\u002F head=\"\", rest=\"api\u002Fusers\"\n",[19,1530,1531,1536,1545,1582,1597,1610,1622,1634,1651,1671,1683,1695,1707,1718,1726,1730,1735,1761,1786,1797,1801,1806,1815,1853,1857,1884,1901,1913,1917,1922,1932,1965,1983,2017,2022,2030],{"__ignoreMap":36},[40,1532,1533],{"class":42,"line":43},[40,1534,1535],{"class":46},"\u002F\u002F Custom extractor via unapply — enables pattern matching on non-case-class types\n",[40,1537,1538,1540,1543],{"class":42,"line":50},[40,1539,303],{"class":53},[40,1541,1542],{"class":115}," HttpStatusCode",[40,1544,309],{"class":53},[40,1546,1547,1550,1553,1555,1557,1559,1561,1563,1565,1567,1570,1572,1574,1576,1579],{"class":42,"line":91},[40,1548,1549],{"class":53},"  def",[40,1551,1552],{"class":115}," unapply",[40,1554,323],{"class":67},[40,1556,19],{"class":57},[40,1558,329],{"class":67},[40,1560,358],{"class":115},[40,1562,436],{"class":67},[40,1564,112],{"class":53},[40,1566,1258],{"class":115},[40,1568,1569],{"class":67},"[(",[40,1571,332],{"class":115},[40,1573,361],{"class":67},[40,1575,332],{"class":115},[40,1577,1578],{"class":67},")] ",[40,1580,1581],{"class":53},"=\n",[40,1583,1584,1587,1590,1592,1595],{"class":42,"line":98},[40,1585,1586],{"class":53},"    val",[40,1588,1589],{"class":57}," reason",[40,1591,61],{"class":53},[40,1593,1594],{"class":67}," code ",[40,1596,449],{"class":53},[40,1598,1599,1602,1605,1607],{"class":42,"line":104},[40,1600,1601],{"class":53},"      case",[40,1603,1604],{"class":74}," 200",[40,1606,789],{"class":53},[40,1608,1609],{"class":81}," \"OK\"\n",[40,1611,1612,1614,1617,1619],{"class":42,"line":140},[40,1613,1601],{"class":53},[40,1615,1616],{"class":74}," 404",[40,1618,789],{"class":53},[40,1620,1621],{"class":81}," \"Not Found\"\n",[40,1623,1624,1626,1629,1631],{"class":42,"line":145},[40,1625,1601],{"class":53},[40,1627,1628],{"class":74}," 500",[40,1630,789],{"class":53},[40,1632,1633],{"class":81}," \"Internal Server Error\"\n",[40,1635,1636,1638,1641,1643,1646,1648],{"class":42,"line":151},[40,1637,1601],{"class":53},[40,1639,1640],{"class":67}," _   ",[40,1642,461],{"class":53},[40,1644,1645],{"class":53}," return",[40,1647,1331],{"class":115},[40,1649,1650],{"class":46},"               \u002F\u002F early return — no match\n",[40,1652,1653,1655,1658,1660,1662,1665,1668],{"class":42,"line":184},[40,1654,1586],{"class":53},[40,1656,1657],{"class":57}," category",[40,1659,61],{"class":53},[40,1661,1594],{"class":67},[40,1663,1664],{"class":53},"\u002F",[40,1666,1667],{"class":74}," 100",[40,1669,1670],{"class":53}," match\n",[40,1672,1673,1675,1678,1680],{"class":42,"line":189},[40,1674,1601],{"class":53},[40,1676,1677],{"class":74}," 2",[40,1679,789],{"class":53},[40,1681,1682],{"class":81}," \"Success\"\n",[40,1684,1685,1687,1690,1692],{"class":42,"line":195},[40,1686,1601],{"class":53},[40,1688,1689],{"class":74}," 4",[40,1691,789],{"class":53},[40,1693,1694],{"class":81}," \"Client Error\"\n",[40,1696,1697,1699,1702,1704],{"class":42,"line":208},[40,1698,1601],{"class":53},[40,1700,1701],{"class":74}," 5",[40,1703,789],{"class":53},[40,1705,1706],{"class":81}," \"Server Error\"\n",[40,1708,1709,1711,1713,1715],{"class":42,"line":238},[40,1710,1601],{"class":53},[40,1712,579],{"class":67},[40,1714,461],{"class":53},[40,1716,1717],{"class":81}," \"Unknown\"\n",[40,1719,1720,1723],{"class":42,"line":243},[40,1721,1722],{"class":115},"    Some",[40,1724,1725],{"class":67},"((category, reason))\n",[40,1727,1728],{"class":42,"line":249},[40,1729,95],{"emptyLinePlaceholder":94},[40,1731,1732],{"class":42,"line":514},[40,1733,1734],{"class":46},"\u002F\u002F Now usable in match:\n",[40,1736,1737,1739,1741,1743,1745,1747,1749,1751,1753,1755,1757,1759],{"class":42,"line":520},[40,1738,420],{"class":53},[40,1740,423],{"class":115},[40,1742,323],{"class":67},[40,1744,19],{"class":57},[40,1746,329],{"class":67},[40,1748,358],{"class":115},[40,1750,436],{"class":67},[40,1752,112],{"class":53},[40,1754,441],{"class":115},[40,1756,61],{"class":53},[40,1758,1594],{"class":67},[40,1760,449],{"class":53},[40,1762,1763,1765,1767,1770,1772,1774,1776,1779,1781,1784],{"class":42,"line":525},[40,1764,314],{"class":53},[40,1766,1542],{"class":115},[40,1768,1769],{"class":67},"(cat, reason) ",[40,1771,461],{"class":53},[40,1773,464],{"class":53},[40,1775,812],{"class":81},[40,1777,1778],{"class":67},"$cat",[40,1780,329],{"class":81},[40,1782,1783],{"class":67},"$reason",[40,1785,473],{"class":81},[40,1787,1788,1790,1792,1794],{"class":42,"line":531},[40,1789,314],{"class":53},[40,1791,579],{"class":67},[40,1793,461],{"class":53},[40,1795,1796],{"class":81}," \"Unknown code\"\n",[40,1798,1799],{"class":42,"line":559},[40,1800,95],{"emptyLinePlaceholder":94},[40,1802,1803],{"class":42,"line":574},[40,1804,1805],{"class":46},"\u002F\u002F Boolean extractor — unapply returning Boolean (no captured values)\n",[40,1807,1808,1810,1813],{"class":42,"line":590},[40,1809,303],{"class":53},[40,1811,1812],{"class":115}," IsEven",[40,1814,309],{"class":53},[40,1816,1817,1819,1821,1823,1826,1828,1830,1832,1834,1837,1839,1842,1845,1847,1850],{"class":42,"line":595},[40,1818,1549],{"class":53},[40,1820,1552],{"class":115},[40,1822,323],{"class":67},[40,1824,1825],{"class":57},"n",[40,1827,329],{"class":67},[40,1829,358],{"class":115},[40,1831,436],{"class":67},[40,1833,112],{"class":53},[40,1835,1836],{"class":115}," Boolean",[40,1838,61],{"class":53},[40,1840,1841],{"class":67}," n ",[40,1843,1844],{"class":53},"%",[40,1846,1677],{"class":74},[40,1848,1849],{"class":53}," ==",[40,1851,1852],{"class":74}," 0\n",[40,1854,1855],{"class":42,"line":601},[40,1856,95],{"emptyLinePlaceholder":94},[40,1858,1859,1861,1864,1866,1868,1870,1872,1874,1876,1878,1880,1882],{"class":42,"line":1057},[40,1860,420],{"class":53},[40,1862,1863],{"class":115}," classify",[40,1865,323],{"class":67},[40,1867,1825],{"class":57},[40,1869,329],{"class":67},[40,1871,358],{"class":115},[40,1873,436],{"class":67},[40,1875,112],{"class":53},[40,1877,441],{"class":115},[40,1879,61],{"class":53},[40,1881,1841],{"class":67},[40,1883,449],{"class":53},[40,1885,1886,1888,1890,1893,1895,1898],{"class":42,"line":1083},[40,1887,314],{"class":53},[40,1889,1812],{"class":115},[40,1891,1892],{"class":67},"() ",[40,1894,461],{"class":53},[40,1896,1897],{"class":81}," \"even\"",[40,1899,1900],{"class":46},"                   \u002F\u002F note: () not _ — boolean extractor\n",[40,1902,1903,1905,1908,1910],{"class":42,"line":1101},[40,1904,314],{"class":53},[40,1906,1907],{"class":67}," _        ",[40,1909,461],{"class":53},[40,1911,1912],{"class":81}," \"odd\"\n",[40,1914,1915],{"class":42,"line":1131},[40,1916,95],{"emptyLinePlaceholder":94},[40,1918,1919],{"class":42,"line":1200},[40,1920,1921],{"class":46},"\u002F\u002F Product extractor — unapply returning Option[Tuple] for destructuring\n",[40,1923,1925,1927,1930],{"class":42,"line":1924},30,[40,1926,303],{"class":53},[40,1928,1929],{"class":115}," SplitPath",[40,1931,309],{"class":53},[40,1933,1935,1937,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963],{"class":42,"line":1934},31,[40,1936,1549],{"class":53},[40,1938,1552],{"class":115},[40,1940,323],{"class":67},[40,1942,642],{"class":57},[40,1944,329],{"class":67},[40,1946,332],{"class":115},[40,1948,436],{"class":67},[40,1950,112],{"class":53},[40,1952,1258],{"class":115},[40,1954,1569],{"class":67},[40,1956,332],{"class":115},[40,1958,361],{"class":67},[40,1960,332],{"class":115},[40,1962,1578],{"class":67},[40,1964,1581],{"class":53},[40,1966,1968,1970,1973,1975,1978,1981],{"class":42,"line":1967},32,[40,1969,1586],{"class":53},[40,1971,1972],{"class":57}," idx",[40,1974,61],{"class":53},[40,1976,1977],{"class":67}," path.indexOf(",[40,1979,1980],{"class":74},"'\u002F'",[40,1982,1197],{"class":67},[40,1984,1986,1989,1992,1994,1997,1999,2001,2003,2005,2008,2011,2014],{"class":42,"line":1985},33,[40,1987,1988],{"class":53},"    if",[40,1990,1991],{"class":67}," idx ",[40,1993,71],{"class":53},[40,1995,1996],{"class":74}," 0",[40,1998,78],{"class":53},[40,2000,1331],{"class":115},[40,2002,85],{"class":53},[40,2004,1294],{"class":115},[40,2006,2007],{"class":67},"((path.take(idx), path.drop(idx ",[40,2009,2010],{"class":53},"+",[40,2012,2013],{"class":74}," 1",[40,2015,2016],{"class":67},")))\n",[40,2018,2020],{"class":42,"line":2019},34,[40,2021,95],{"emptyLinePlaceholder":94},[40,2023,2025,2028],{"class":42,"line":2024},35,[40,2026,2027],{"class":81},"\"\u002Fapi\u002Fusers\"",[40,2029,1670],{"class":53},[40,2031,2033,2035,2037,2040,2042,2044,2046,2049,2052,2055,2058,2060,2062],{"class":42,"line":2032},36,[40,2034,314],{"class":53},[40,2036,1929],{"class":115},[40,2038,2039],{"class":67},"(head, rest) ",[40,2041,461],{"class":53},[40,2043,172],{"class":67},[40,2045,428],{"class":53},[40,2047,2048],{"class":81},"\"head=",[40,2050,2051],{"class":67},"$head",[40,2053,2054],{"class":81},", rest=",[40,2056,2057],{"class":67},"$rest",[40,2059,812],{"class":81},[40,2061,178],{"class":67},[40,2063,2064],{"class":46},"\u002F\u002F head=\"\", rest=\"api\u002Fusers\"\n",[15,2066,2068,22,2071,22,2074,2077],{"id":2067},"either-try-option-error-as-values",[19,2069,2070],{},"Either",[19,2072,2073],{},"Try",[19,2075,2076],{},"Option"," — Error as Values",[28,2079,2080],{"language":30},[32,2081,2083],{"className":34,"code":2082,"language":30,"meta":36,"style":36},"import scala.util.{Try, Success, Failure}\n\n\u002F\u002F Either[L, R]: error on Left, success on Right. Right-biased in stdlib.\ndef parsePort(s: String): Either[String, Int] =\n  Try(s.toInt).toEither                    \u002F\u002F → Either[Throwable, Int]\n    .left.map(_.getMessage)                \u002F\u002F → Either[String, Int]\n    .filterOrElse(p => p > 0 && p \u003C= 65535, \"port out of range 1-65535\")\n\n\u002F\u002F Chaining with for-comprehension — short-circuits on first Left\ndef connect(host: String, portStr: String): Either[String, Connection] =\n  for\n    port \u003C- parsePort(portStr)             \u002F\u002F Left(\"...\") → short-circuits entire chain\n    conn \u003C- openConnection(host, port)     \u002F\u002F only runs if parsePort succeeded\n  yield conn\n\n\u002F\u002F recover \u002F recoverWith — transform failure into success\ndef fetchWithFallback(url: String): Future[String] =\n  httpClient.get(url)\n    .recoverWith:\n      case _: TimeoutException => httpClient.get(fallbackUrl(url))  \u002F\u002F try fallback\n      case _: ConnectionRefused => Future.successful(\"\")             \u002F\u002F degrade gracefully\n\n\u002F\u002F Try → Option (discard error info) or Either (preserve it)\ndef parseInt(s: String): Option[Int] = Try(s.toInt).toOption\ndef parseIntEither(s: String): Either[Throwable, Int] = Try(s.toInt).toEither\n\n\u002F\u002F ❌ ANTI-PATTERN: throw exceptions in library code — breaks for-comprehension chains\ndef badParse(s: String): Int = s.toInt     \u002F\u002F throws NumberFormatException → uncomposable\n\u002F\u002F ✅ CORRECT: return Either\u002FTry\u002FOption — callers can chain safely\n",[19,2084,2085,2115,2119,2124,2158,2169,2177,2210,2214,2219,2263,2268,2282,2295,2303,2307,2312,2343,2348,2355,2374,2401,2405,2410,2445,2484,2488,2493,2523],{"__ignoreMap":36},[40,2086,2087,2089,2092,2094,2097,2100,2102,2104,2107,2109,2112],{"class":42,"line":43},[40,2088,398],{"class":53},[40,2090,2091],{"class":115}," scala",[40,2093,403],{"class":67},[40,2095,2096],{"class":115},"util",[40,2098,2099],{"class":67},".{",[40,2101,2073],{"class":115},[40,2103,361],{"class":67},[40,2105,2106],{"class":115},"Success",[40,2108,361],{"class":67},[40,2110,2111],{"class":115},"Failure",[40,2113,2114],{"class":67},"}\n",[40,2116,2117],{"class":42,"line":50},[40,2118,95],{"emptyLinePlaceholder":94},[40,2120,2121],{"class":42,"line":91},[40,2122,2123],{"class":46},"\u002F\u002F Either[L, R]: error on Left, success on Right. Right-biased in stdlib.\n",[40,2125,2126,2128,2131,2133,2135,2137,2139,2141,2143,2146,2148,2150,2152,2154,2156],{"class":42,"line":98},[40,2127,420],{"class":53},[40,2129,2130],{"class":115}," parsePort",[40,2132,323],{"class":67},[40,2134,428],{"class":57},[40,2136,329],{"class":67},[40,2138,332],{"class":115},[40,2140,436],{"class":67},[40,2142,112],{"class":53},[40,2144,2145],{"class":115}," Either",[40,2147,659],{"class":67},[40,2149,332],{"class":115},[40,2151,361],{"class":67},[40,2153,358],{"class":115},[40,2155,1117],{"class":67},[40,2157,1581],{"class":53},[40,2159,2160,2163,2166],{"class":42,"line":104},[40,2161,2162],{"class":115},"  Try",[40,2164,2165],{"class":67},"(s.toInt).toEither                    ",[40,2167,2168],{"class":46},"\u002F\u002F → Either[Throwable, Int]\n",[40,2170,2171,2174],{"class":42,"line":140},[40,2172,2173],{"class":67},"    .left.map(_.getMessage)                ",[40,2175,2176],{"class":46},"\u002F\u002F → Either[String, Int]\n",[40,2178,2179,2182,2184,2187,2190,2192,2195,2197,2200,2203,2205,2208],{"class":42,"line":145},[40,2180,2181],{"class":67},"    .filterOrElse(p ",[40,2183,461],{"class":53},[40,2185,2186],{"class":67}," p ",[40,2188,2189],{"class":53},">",[40,2191,1996],{"class":74},[40,2193,2194],{"class":53}," &&",[40,2196,2186],{"class":67},[40,2198,2199],{"class":53},"\u003C=",[40,2201,2202],{"class":74}," 65535",[40,2204,361],{"class":67},[40,2206,2207],{"class":81},"\"port out of range 1-65535\"",[40,2209,1197],{"class":67},[40,2211,2212],{"class":42,"line":151},[40,2213,95],{"emptyLinePlaceholder":94},[40,2215,2216],{"class":42,"line":184},[40,2217,2218],{"class":46},"\u002F\u002F Chaining with for-comprehension — short-circuits on first Left\n",[40,2220,2221,2223,2226,2228,2231,2233,2235,2237,2240,2242,2244,2246,2248,2250,2252,2254,2256,2259,2261],{"class":42,"line":189},[40,2222,420],{"class":53},[40,2224,2225],{"class":115}," connect",[40,2227,323],{"class":67},[40,2229,2230],{"class":57},"host",[40,2232,329],{"class":67},[40,2234,332],{"class":115},[40,2236,361],{"class":67},[40,2238,2239],{"class":57},"portStr",[40,2241,329],{"class":67},[40,2243,332],{"class":115},[40,2245,436],{"class":67},[40,2247,112],{"class":53},[40,2249,2145],{"class":115},[40,2251,659],{"class":67},[40,2253,332],{"class":115},[40,2255,361],{"class":67},[40,2257,2258],{"class":115},"Connection",[40,2260,1117],{"class":67},[40,2262,1581],{"class":53},[40,2264,2265],{"class":42,"line":195},[40,2266,2267],{"class":53},"  for\n",[40,2269,2270,2273,2276,2279],{"class":42,"line":208},[40,2271,2272],{"class":67},"    port ",[40,2274,2275],{"class":53},"\u003C-",[40,2277,2278],{"class":67}," parsePort(portStr)             ",[40,2280,2281],{"class":46},"\u002F\u002F Left(\"...\") → short-circuits entire chain\n",[40,2283,2284,2287,2289,2292],{"class":42,"line":238},[40,2285,2286],{"class":67},"    conn ",[40,2288,2275],{"class":53},[40,2290,2291],{"class":67}," openConnection(host, port)     ",[40,2293,2294],{"class":46},"\u002F\u002F only runs if parsePort succeeded\n",[40,2296,2297,2300],{"class":42,"line":243},[40,2298,2299],{"class":53},"  yield",[40,2301,2302],{"class":67}," conn\n",[40,2304,2305],{"class":42,"line":249},[40,2306,95],{"emptyLinePlaceholder":94},[40,2308,2309],{"class":42,"line":514},[40,2310,2311],{"class":46},"\u002F\u002F recover \u002F recoverWith — transform failure into success\n",[40,2313,2314,2316,2319,2321,2324,2326,2328,2330,2332,2335,2337,2339,2341],{"class":42,"line":520},[40,2315,420],{"class":53},[40,2317,2318],{"class":115}," fetchWithFallback",[40,2320,323],{"class":67},[40,2322,2323],{"class":57},"url",[40,2325,329],{"class":67},[40,2327,332],{"class":115},[40,2329,436],{"class":67},[40,2331,112],{"class":53},[40,2333,2334],{"class":115}," Future",[40,2336,659],{"class":67},[40,2338,332],{"class":115},[40,2340,1117],{"class":67},[40,2342,1581],{"class":53},[40,2344,2345],{"class":42,"line":525},[40,2346,2347],{"class":67},"  httpClient.get(url)\n",[40,2349,2350,2353],{"class":42,"line":531},[40,2351,2352],{"class":67},"    .recoverWith",[40,2354,309],{"class":53},[40,2356,2357,2359,2361,2363,2366,2368,2371],{"class":42,"line":559},[40,2358,1601],{"class":53},[40,2360,1278],{"class":57},[40,2362,329],{"class":67},[40,2364,2365],{"class":115},"TimeoutException",[40,2367,789],{"class":53},[40,2369,2370],{"class":67}," httpClient.get(fallbackUrl(url))  ",[40,2372,2373],{"class":46},"\u002F\u002F try fallback\n",[40,2375,2376,2378,2380,2382,2385,2387,2389,2392,2395,2398],{"class":42,"line":574},[40,2377,1601],{"class":53},[40,2379,1278],{"class":57},[40,2381,329],{"class":67},[40,2383,2384],{"class":115},"ConnectionRefused",[40,2386,789],{"class":53},[40,2388,2334],{"class":115},[40,2390,2391],{"class":67},".successful(",[40,2393,2394],{"class":81},"\"\"",[40,2396,2397],{"class":67},")             ",[40,2399,2400],{"class":46},"\u002F\u002F degrade gracefully\n",[40,2402,2403],{"class":42,"line":590},[40,2404,95],{"emptyLinePlaceholder":94},[40,2406,2407],{"class":42,"line":595},[40,2408,2409],{"class":46},"\u002F\u002F Try → Option (discard error info) or Either (preserve it)\n",[40,2411,2412,2414,2417,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437,2439,2442],{"class":42,"line":601},[40,2413,420],{"class":53},[40,2415,2416],{"class":115}," parseInt",[40,2418,323],{"class":67},[40,2420,428],{"class":57},[40,2422,329],{"class":67},[40,2424,332],{"class":115},[40,2426,436],{"class":67},[40,2428,112],{"class":53},[40,2430,1258],{"class":115},[40,2432,659],{"class":67},[40,2434,358],{"class":115},[40,2436,1117],{"class":67},[40,2438,220],{"class":53},[40,2440,2441],{"class":115}," Try",[40,2443,2444],{"class":67},"(s.toInt).toOption\n",[40,2446,2447,2449,2452,2454,2456,2458,2460,2462,2464,2466,2468,2471,2473,2475,2477,2479,2481],{"class":42,"line":1057},[40,2448,420],{"class":53},[40,2450,2451],{"class":115}," parseIntEither",[40,2453,323],{"class":67},[40,2455,428],{"class":57},[40,2457,329],{"class":67},[40,2459,332],{"class":115},[40,2461,436],{"class":67},[40,2463,112],{"class":53},[40,2465,2145],{"class":115},[40,2467,659],{"class":67},[40,2469,2470],{"class":115},"Throwable",[40,2472,361],{"class":67},[40,2474,358],{"class":115},[40,2476,1117],{"class":67},[40,2478,220],{"class":53},[40,2480,2441],{"class":115},[40,2482,2483],{"class":67},"(s.toInt).toEither\n",[40,2485,2486],{"class":42,"line":1083},[40,2487,95],{"emptyLinePlaceholder":94},[40,2489,2490],{"class":42,"line":1101},[40,2491,2492],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: throw exceptions in library code — breaks for-comprehension chains\n",[40,2494,2495,2497,2500,2502,2504,2506,2508,2510,2512,2515,2517,2520],{"class":42,"line":1131},[40,2496,420],{"class":53},[40,2498,2499],{"class":115}," badParse",[40,2501,323],{"class":67},[40,2503,428],{"class":57},[40,2505,329],{"class":67},[40,2507,332],{"class":115},[40,2509,436],{"class":67},[40,2511,112],{"class":53},[40,2513,2514],{"class":115}," Int",[40,2516,61],{"class":53},[40,2518,2519],{"class":67}," s.toInt     ",[40,2521,2522],{"class":46},"\u002F\u002F throws NumberFormatException → uncomposable\n",[40,2524,2525],{"class":42,"line":1200},[40,2526,2527],{"class":46},"\u002F\u002F ✅ CORRECT: return Either\u002FTry\u002FOption — callers can chain safely\n",[15,2529,2531,22,2534,22,2537,2540],{"id":2530},"try-catch-finally-expression-semantics",[19,2532,2533],{},"try",[19,2535,2536],{},"catch",[19,2538,2539],{},"finally"," — Expression Semantics",[28,2542,2543],{"language":30},[32,2544,2546],{"className":34,"code":2545,"language":30,"meta":36,"style":36},"\u002F\u002F try is an expression — evaluates to the body or the catch handler result\nval result: Int = try\n  riskyComputation()\ncatch\n  case _: ArithmeticException => 0         \u002F\u002F catch by type, no variable needed if unused\n  case e: IllegalArgumentException => -1\nfinally\n  cleanup()                                \u002F\u002F finally returns Unit — doesn't affect the value\n\n\u002F\u002F ❌ ANTI-PATTERN: returning from finally — swallows exceptions\ndef bad(): Int =\n  try throw new RuntimeException(\"real error\")\n  finally return 42                         \u002F\u002F SILENTLY swallows the exception → returns 42\n\u002F\u002F This is a warning in Scala 3: \"return in finally is discouraged\"\n\n\u002F\u002F Non-local return inside try is deprecated in Scala 3:\n\u002F\u002F   def find(xs: List[Int]): Int = xs.foreach(x => if x > 0 then return x)\n\u002F\u002F → Use xs.find(_ > 0).get or a proper recursive function instead\n\n\u002F\u002F Try-catch is EXPENSIVE on JVM (exception construction captures stack trace)\n\u002F\u002F → Use Either\u002FTry for expected failures, reserve try\u002Fcatch for truly unexpected errors\n",[19,2547,2548,2553,2568,2573,2578,2596,2616,2621,2629,2633,2638,2655,2676,2688,2693,2697,2702,2707,2712,2716,2721],{"__ignoreMap":36},[40,2549,2550],{"class":42,"line":43},[40,2551,2552],{"class":46},"\u002F\u002F try is an expression — evaluates to the body or the catch handler result\n",[40,2554,2555,2557,2559,2561,2563,2565],{"class":42,"line":50},[40,2556,54],{"class":53},[40,2558,109],{"class":57},[40,2560,112],{"class":53},[40,2562,2514],{"class":115},[40,2564,61],{"class":53},[40,2566,2567],{"class":53}," try\n",[40,2569,2570],{"class":42,"line":91},[40,2571,2572],{"class":67},"  riskyComputation()\n",[40,2574,2575],{"class":42,"line":98},[40,2576,2577],{"class":53},"catch\n",[40,2579,2580,2582,2584,2586,2589,2591,2593],{"class":42,"line":104},[40,2581,314],{"class":53},[40,2583,1278],{"class":57},[40,2585,329],{"class":67},[40,2587,2588],{"class":115},"ArithmeticException",[40,2590,789],{"class":53},[40,2592,1996],{"class":74},[40,2594,2595],{"class":46},"         \u002F\u002F catch by type, no variable needed if unused\n",[40,2597,2598,2600,2603,2605,2608,2610,2613],{"class":42,"line":140},[40,2599,314],{"class":53},[40,2601,2602],{"class":57}," e",[40,2604,329],{"class":67},[40,2606,2607],{"class":115},"IllegalArgumentException",[40,2609,789],{"class":53},[40,2611,2612],{"class":53}," -",[40,2614,2615],{"class":74},"1\n",[40,2617,2618],{"class":42,"line":145},[40,2619,2620],{"class":53},"finally\n",[40,2622,2623,2626],{"class":42,"line":151},[40,2624,2625],{"class":67},"  cleanup()                                ",[40,2627,2628],{"class":46},"\u002F\u002F finally returns Unit — doesn't affect the value\n",[40,2630,2631],{"class":42,"line":184},[40,2632,95],{"emptyLinePlaceholder":94},[40,2634,2635],{"class":42,"line":189},[40,2636,2637],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: returning from finally — swallows exceptions\n",[40,2639,2640,2642,2645,2648,2650,2652],{"class":42,"line":195},[40,2641,420],{"class":53},[40,2643,2644],{"class":115}," bad",[40,2646,2647],{"class":67},"()",[40,2649,112],{"class":53},[40,2651,2514],{"class":115},[40,2653,2654],{"class":53}," =\n",[40,2656,2657,2660,2663,2666,2669,2671,2674],{"class":42,"line":208},[40,2658,2659],{"class":53},"  try",[40,2661,2662],{"class":53}," throw",[40,2664,2665],{"class":53}," new",[40,2667,2668],{"class":115}," RuntimeException",[40,2670,323],{"class":67},[40,2672,2673],{"class":81},"\"real error\"",[40,2675,1197],{"class":67},[40,2677,2678,2681,2683,2685],{"class":42,"line":238},[40,2679,2680],{"class":53},"  finally",[40,2682,1645],{"class":53},[40,2684,129],{"class":74},[40,2686,2687],{"class":46},"                         \u002F\u002F SILENTLY swallows the exception → returns 42\n",[40,2689,2690],{"class":42,"line":243},[40,2691,2692],{"class":46},"\u002F\u002F This is a warning in Scala 3: \"return in finally is discouraged\"\n",[40,2694,2695],{"class":42,"line":249},[40,2696,95],{"emptyLinePlaceholder":94},[40,2698,2699],{"class":42,"line":514},[40,2700,2701],{"class":46},"\u002F\u002F Non-local return inside try is deprecated in Scala 3:\n",[40,2703,2704],{"class":42,"line":520},[40,2705,2706],{"class":46},"\u002F\u002F   def find(xs: List[Int]): Int = xs.foreach(x => if x > 0 then return x)\n",[40,2708,2709],{"class":42,"line":525},[40,2710,2711],{"class":46},"\u002F\u002F → Use xs.find(_ > 0).get or a proper recursive function instead\n",[40,2713,2714],{"class":42,"line":531},[40,2715,95],{"emptyLinePlaceholder":94},[40,2717,2718],{"class":42,"line":559},[40,2719,2720],{"class":46},"\u002F\u002F Try-catch is EXPENSIVE on JVM (exception construction captures stack trace)\n",[40,2722,2723],{"class":42,"line":574},[40,2724,2725],{"class":46},"\u002F\u002F → Use Either\u002FTry for expected failures, reserve try\u002Fcatch for truly unexpected errors\n",[15,2727,2729],{"id":2728},"match-types-compile-time-pattern-matching-on-types","Match Types — Compile-Time Pattern Matching on Types",[28,2731,2732],{"language":30},[32,2733,2735],{"className":34,"code":2734,"language":30,"meta":36,"style":36},"\u002F\u002F Scala 3 match types — the return type is computed at compile time based on input type\ntype Json[T] = T match\n  case Int     => \"int\"\n  case String  => \"string\"\n  case Boolean => \"bool\"\n  case List[t] => s\"[${Json[t]}]\"          \u002F\u002F recursive match type\n  case Option[t] => s\"opt:${Json[t]}\"\n  case Map[k, v] => s\"map:${Json[k]}:${Json[v]}\"\n\ninline def toJsonType[T]: Json[T] = summon[Json[T] =:= String] match\n  case _ => ???\n\n\u002F\u002F Practical use: type-level serialization\ntype Repr[T] = T match\n  case Int    => Int\n  case String => String\n  case Double => Double\n  case Boolean => Boolean\n  case List[t] => Array[Repr[t]]           \u002F\u002F List[Int] → Array[Int], no boxing!\n\n\u002F\u002F The compiler reduces Repr[List[Int]] to Array[Int] at compile time\n\u002F\u002F No runtime pattern matching, no type erasure issues\n",[19,2736,2737,2742,2764,2776,2788,2799,2831,2854,2889,2893,2943,2954,2958,2963,2982,2993,3004,3016,3027,3051,3055,3060],{"__ignoreMap":36},[40,2738,2739],{"class":42,"line":43},[40,2740,2741],{"class":46},"\u002F\u002F Scala 3 match types — the return type is computed at compile time based on input type\n",[40,2743,2744,2747,2750,2752,2755,2757,2759,2762],{"class":42,"line":50},[40,2745,2746],{"class":53},"type",[40,2748,2749],{"class":115}," Json",[40,2751,659],{"class":67},[40,2753,2754],{"class":115},"T",[40,2756,1117],{"class":67},[40,2758,220],{"class":53},[40,2760,2761],{"class":115}," T",[40,2763,1670],{"class":53},[40,2765,2766,2768,2770,2773],{"class":42,"line":91},[40,2767,314],{"class":53},[40,2769,2514],{"class":115},[40,2771,2772],{"class":53},"     =>",[40,2774,2775],{"class":81}," \"int\"\n",[40,2777,2778,2780,2782,2785],{"class":42,"line":98},[40,2779,314],{"class":53},[40,2781,441],{"class":115},[40,2783,2784],{"class":53},"  =>",[40,2786,2787],{"class":81}," \"string\"\n",[40,2789,2790,2792,2794,2796],{"class":42,"line":104},[40,2791,314],{"class":53},[40,2793,1836],{"class":115},[40,2795,789],{"class":53},[40,2797,2798],{"class":81}," \"bool\"\n",[40,2800,2801,2803,2806,2809,2811,2813,2816,2819,2822,2825,2828],{"class":42,"line":140},[40,2802,314],{"class":53},[40,2804,2805],{"class":115}," List",[40,2807,2808],{"class":67},"[t] ",[40,2810,461],{"class":53},[40,2812,464],{"class":53},[40,2814,2815],{"class":81},"\"[",[40,2817,2818],{"class":67},"${",[40,2820,2821],{"class":115},"Json",[40,2823,2824],{"class":67},"[t]}",[40,2826,2827],{"class":81},"]\"",[40,2829,2830],{"class":46},"          \u002F\u002F recursive match type\n",[40,2832,2833,2835,2837,2839,2841,2843,2846,2848,2850,2852],{"class":42,"line":145},[40,2834,314],{"class":53},[40,2836,1258],{"class":115},[40,2838,2808],{"class":67},[40,2840,461],{"class":53},[40,2842,464],{"class":53},[40,2844,2845],{"class":81},"\"opt:",[40,2847,2818],{"class":67},[40,2849,2821],{"class":115},[40,2851,2824],{"class":67},[40,2853,473],{"class":81},[40,2855,2856,2858,2861,2864,2866,2868,2871,2873,2875,2878,2880,2882,2884,2887],{"class":42,"line":151},[40,2857,314],{"class":53},[40,2859,2860],{"class":115}," Map",[40,2862,2863],{"class":67},"[k, v] ",[40,2865,461],{"class":53},[40,2867,464],{"class":53},[40,2869,2870],{"class":81},"\"map:",[40,2872,2818],{"class":67},[40,2874,2821],{"class":115},[40,2876,2877],{"class":67},"[k]}",[40,2879,112],{"class":81},[40,2881,2818],{"class":67},[40,2883,2821],{"class":115},[40,2885,2886],{"class":67},"[v]}",[40,2888,473],{"class":81},[40,2890,2891],{"class":42,"line":184},[40,2892,95],{"emptyLinePlaceholder":94},[40,2894,2895,2898,2901,2904,2906,2908,2911,2913,2915,2917,2919,2921,2923,2926,2928,2930,2932,2934,2937,2939,2941],{"class":42,"line":189},[40,2896,2897],{"class":53},"inline",[40,2899,2900],{"class":53}," def",[40,2902,2903],{"class":115}," toJsonType",[40,2905,659],{"class":67},[40,2907,2754],{"class":115},[40,2909,2910],{"class":67},"]",[40,2912,112],{"class":53},[40,2914,2749],{"class":115},[40,2916,659],{"class":67},[40,2918,2754],{"class":115},[40,2920,1117],{"class":67},[40,2922,220],{"class":53},[40,2924,2925],{"class":67}," summon[",[40,2927,2821],{"class":115},[40,2929,659],{"class":67},[40,2931,2754],{"class":115},[40,2933,1117],{"class":67},[40,2935,2936],{"class":53},"=:=",[40,2938,441],{"class":115},[40,2940,1117],{"class":67},[40,2942,449],{"class":53},[40,2944,2945,2947,2949,2951],{"class":42,"line":195},[40,2946,314],{"class":53},[40,2948,579],{"class":67},[40,2950,461],{"class":53},[40,2952,2953],{"class":53}," ???\n",[40,2955,2956],{"class":42,"line":208},[40,2957,95],{"emptyLinePlaceholder":94},[40,2959,2960],{"class":42,"line":238},[40,2961,2962],{"class":46},"\u002F\u002F Practical use: type-level serialization\n",[40,2964,2965,2967,2970,2972,2974,2976,2978,2980],{"class":42,"line":243},[40,2966,2746],{"class":53},[40,2968,2969],{"class":115}," Repr",[40,2971,659],{"class":67},[40,2973,2754],{"class":115},[40,2975,1117],{"class":67},[40,2977,220],{"class":53},[40,2979,2761],{"class":115},[40,2981,1670],{"class":53},[40,2983,2984,2986,2988,2990],{"class":42,"line":249},[40,2985,314],{"class":53},[40,2987,2514],{"class":115},[40,2989,751],{"class":53},[40,2991,2992],{"class":115}," Int\n",[40,2994,2995,2997,2999,3001],{"class":42,"line":514},[40,2996,314],{"class":53},[40,2998,441],{"class":115},[40,3000,789],{"class":53},[40,3002,3003],{"class":115}," String\n",[40,3005,3006,3008,3011,3013],{"class":42,"line":520},[40,3007,314],{"class":53},[40,3009,3010],{"class":115}," Double",[40,3012,789],{"class":53},[40,3014,3015],{"class":115}," Double\n",[40,3017,3018,3020,3022,3024],{"class":42,"line":525},[40,3019,314],{"class":53},[40,3021,1836],{"class":115},[40,3023,789],{"class":53},[40,3025,3026],{"class":115}," Boolean\n",[40,3028,3029,3031,3033,3035,3037,3040,3042,3045,3048],{"class":42,"line":531},[40,3030,314],{"class":53},[40,3032,2805],{"class":115},[40,3034,2808],{"class":67},[40,3036,461],{"class":53},[40,3038,3039],{"class":115}," Array",[40,3041,659],{"class":67},[40,3043,3044],{"class":115},"Repr",[40,3046,3047],{"class":67},"[t]]           ",[40,3049,3050],{"class":46},"\u002F\u002F List[Int] → Array[Int], no boxing!\n",[40,3052,3053],{"class":42,"line":559},[40,3054,95],{"emptyLinePlaceholder":94},[40,3056,3057],{"class":42,"line":574},[40,3058,3059],{"class":46},"\u002F\u002F The compiler reduces Repr[List[Int]] to Array[Int] at compile time\n",[40,3061,3062],{"class":42,"line":590},[40,3063,3064],{"class":46},"\u002F\u002F No runtime pattern matching, no type erasure issues\n",[15,3066,3068,3069,22,3072,3075],{"id":3067},"loops-while-for-and-their-desugaring","Loops — ",[19,3070,3071],{},"while",[19,3073,3074],{},"for"," and Their Desugaring",[28,3077,3078],{"language":30},[32,3079,3081],{"className":34,"code":3080,"language":30,"meta":36,"style":36},"\u002F\u002F while: raw loop, returns Unit, no functional sugar\nvar i = 0\nwhile i \u003C items.length do\n  process(items(i))\n  i += 1\n\n\u002F\u002F for (no yield): desugars to foreach — side-effect loop, returns Unit\nfor item \u003C- items do process(item)         \u002F\u002F → items.foreach(item => process(item))\n\n\u002F\u002F for with yield: desugars to flatMap\u002Fmap chain (see 03-functions)\nval results = for\n  a \u003C- OptionA\n  b \u003C- OptionB\n  if a > b                                 \u002F\u002F guard → withFilter\nyield a + b\n\n\u002F\u002F ❌ ANTI-PATTERN: building collections with for-loop + mutable accumulator\nval buf = scala.collection.mutable.ArrayBuffer.empty[Int]\nfor x \u003C- 1 to 1000 do buf += x * 2         \u002F\u002F O(1) per append, but imperative + mutable\n\n\u002F\u002F ✅ CORRECT: for-yield or direct functional call — immutable, fused\nval doubled = for x \u003C- 1 to 1000 yield x * 2  \u002F\u002F → Vector(2, 4, ..., 2000)\nval direct = (1 to 1000).map(_ * 2)           \u002F\u002F same result, single pass\n\n\u002F\u002F No break\u002Fcontinue — use takeWhile\u002FdropWhile or tail recursion\n@tailrec\ndef findFirstPositive(xs: List[Int]): Option[Int] = xs match\n  case Nil              => None\n  case head :: _ if head > 0 => Some(head)  \u002F\u002F early exit via pattern match\n  case _ :: tail        => findFirstPositive(tail)  \u002F\u002F tail call → loop\n",[19,3082,3083,3088,3098,3113,3118,3129,3133,3138,3159,3163,3168,3180,3190,3200,3216,3228,3232,3237,3260,3295,3299,3304,3338,3369,3373,3378,3386,3425,3437,3467],{"__ignoreMap":36},[40,3084,3085],{"class":42,"line":43},[40,3086,3087],{"class":46},"\u002F\u002F while: raw loop, returns Unit, no functional sugar\n",[40,3089,3090,3092,3094,3096],{"class":42,"line":50},[40,3091,198],{"class":53},[40,3093,1088],{"class":57},[40,3095,61],{"class":53},[40,3097,1852],{"class":74},[40,3099,3100,3102,3105,3107,3110],{"class":42,"line":91},[40,3101,3071],{"class":53},[40,3103,3104],{"class":67}," i ",[40,3106,71],{"class":53},[40,3108,3109],{"class":67}," items.length ",[40,3111,3112],{"class":53},"do\n",[40,3114,3115],{"class":42,"line":98},[40,3116,3117],{"class":67},"  process(items(i))\n",[40,3119,3120,3123,3126],{"class":42,"line":104},[40,3121,3122],{"class":67},"  i ",[40,3124,3125],{"class":53},"+=",[40,3127,3128],{"class":74}," 1\n",[40,3130,3131],{"class":42,"line":140},[40,3132,95],{"emptyLinePlaceholder":94},[40,3134,3135],{"class":42,"line":145},[40,3136,3137],{"class":46},"\u002F\u002F for (no yield): desugars to foreach — side-effect loop, returns Unit\n",[40,3139,3140,3142,3145,3147,3150,3153,3156],{"class":42,"line":151},[40,3141,3074],{"class":53},[40,3143,3144],{"class":67}," item ",[40,3146,2275],{"class":53},[40,3148,3149],{"class":67}," items ",[40,3151,3152],{"class":53},"do",[40,3154,3155],{"class":67}," process(item)         ",[40,3157,3158],{"class":46},"\u002F\u002F → items.foreach(item => process(item))\n",[40,3160,3161],{"class":42,"line":184},[40,3162,95],{"emptyLinePlaceholder":94},[40,3164,3165],{"class":42,"line":189},[40,3166,3167],{"class":46},"\u002F\u002F for with yield: desugars to flatMap\u002Fmap chain (see 03-functions)\n",[40,3169,3170,3172,3175,3177],{"class":42,"line":195},[40,3171,54],{"class":53},[40,3173,3174],{"class":57}," results",[40,3176,61],{"class":53},[40,3178,3179],{"class":53}," for\n",[40,3181,3182,3185,3187],{"class":42,"line":208},[40,3183,3184],{"class":67},"  a ",[40,3186,2275],{"class":53},[40,3188,3189],{"class":115}," OptionA\n",[40,3191,3192,3195,3197],{"class":42,"line":238},[40,3193,3194],{"class":67},"  b ",[40,3196,2275],{"class":53},[40,3198,3199],{"class":115}," OptionB\n",[40,3201,3202,3205,3208,3210,3213],{"class":42,"line":243},[40,3203,3204],{"class":53},"  if",[40,3206,3207],{"class":67}," a ",[40,3209,2189],{"class":53},[40,3211,3212],{"class":67}," b                                 ",[40,3214,3215],{"class":46},"\u002F\u002F guard → withFilter\n",[40,3217,3218,3221,3223,3225],{"class":42,"line":249},[40,3219,3220],{"class":53},"yield",[40,3222,3207],{"class":67},[40,3224,2010],{"class":53},[40,3226,3227],{"class":67}," b\n",[40,3229,3230],{"class":42,"line":514},[40,3231,95],{"emptyLinePlaceholder":94},[40,3233,3234],{"class":42,"line":520},[40,3235,3236],{"class":46},"\u002F\u002F ❌ ANTI-PATTERN: building collections with for-loop + mutable accumulator\n",[40,3238,3239,3241,3244,3246,3249,3252,3255,3257],{"class":42,"line":525},[40,3240,54],{"class":53},[40,3242,3243],{"class":57}," buf",[40,3245,61],{"class":53},[40,3247,3248],{"class":67}," scala.collection.mutable.",[40,3250,3251],{"class":115},"ArrayBuffer",[40,3253,3254],{"class":67},".empty[",[40,3256,358],{"class":115},[40,3258,3259],{"class":67},"]\n",[40,3261,3262,3264,3267,3269,3271,3274,3277,3280,3283,3285,3287,3290,3292],{"class":42,"line":531},[40,3263,3074],{"class":53},[40,3265,3266],{"class":67}," x ",[40,3268,2275],{"class":53},[40,3270,2013],{"class":74},[40,3272,3273],{"class":67}," to ",[40,3275,3276],{"class":74},"1000",[40,3278,3279],{"class":53}," do",[40,3281,3282],{"class":67}," buf ",[40,3284,3125],{"class":53},[40,3286,3266],{"class":67},[40,3288,3289],{"class":53},"*",[40,3291,1677],{"class":74},[40,3293,3294],{"class":46},"         \u002F\u002F O(1) per append, but imperative + mutable\n",[40,3296,3297],{"class":42,"line":559},[40,3298,95],{"emptyLinePlaceholder":94},[40,3300,3301],{"class":42,"line":574},[40,3302,3303],{"class":46},"\u002F\u002F ✅ CORRECT: for-yield or direct functional call — immutable, fused\n",[40,3305,3306,3308,3311,3313,3316,3318,3320,3322,3324,3326,3329,3331,3333,3335],{"class":42,"line":590},[40,3307,54],{"class":53},[40,3309,3310],{"class":57}," doubled",[40,3312,61],{"class":53},[40,3314,3315],{"class":53}," for",[40,3317,3266],{"class":67},[40,3319,2275],{"class":53},[40,3321,2013],{"class":74},[40,3323,3273],{"class":67},[40,3325,3276],{"class":74},[40,3327,3328],{"class":53}," yield",[40,3330,3266],{"class":67},[40,3332,3289],{"class":53},[40,3334,1677],{"class":74},[40,3336,3337],{"class":46},"  \u002F\u002F → Vector(2, 4, ..., 2000)\n",[40,3339,3340,3342,3345,3347,3350,3352,3354,3356,3359,3361,3363,3366],{"class":42,"line":595},[40,3341,54],{"class":53},[40,3343,3344],{"class":57}," direct",[40,3346,61],{"class":53},[40,3348,3349],{"class":67}," (",[40,3351,1483],{"class":74},[40,3353,3273],{"class":67},[40,3355,3276],{"class":74},[40,3357,3358],{"class":67},").map(_ ",[40,3360,3289],{"class":53},[40,3362,1677],{"class":74},[40,3364,3365],{"class":67},")           ",[40,3367,3368],{"class":46},"\u002F\u002F same result, single pass\n",[40,3370,3371],{"class":42,"line":601},[40,3372,95],{"emptyLinePlaceholder":94},[40,3374,3375],{"class":42,"line":1057},[40,3376,3377],{"class":46},"\u002F\u002F No break\u002Fcontinue — use takeWhile\u002FdropWhile or tail recursion\n",[40,3379,3380,3383],{"class":42,"line":1083},[40,3381,3382],{"class":53},"@",[40,3384,3385],{"class":67},"tailrec\n",[40,3387,3388,3390,3393,3395,3398,3400,3402,3404,3406,3408,3410,3412,3414,3416,3418,3420,3423],{"class":42,"line":1101},[40,3389,420],{"class":53},[40,3391,3392],{"class":115}," findFirstPositive",[40,3394,323],{"class":67},[40,3396,3397],{"class":57},"xs",[40,3399,329],{"class":67},[40,3401,1246],{"class":115},[40,3403,659],{"class":67},[40,3405,358],{"class":115},[40,3407,1253],{"class":67},[40,3409,112],{"class":53},[40,3411,1258],{"class":115},[40,3413,659],{"class":67},[40,3415,358],{"class":115},[40,3417,1117],{"class":67},[40,3419,220],{"class":53},[40,3421,3422],{"class":67}," xs ",[40,3424,449],{"class":53},[40,3426,3427,3429,3432,3435],{"class":42,"line":1131},[40,3428,314],{"class":53},[40,3430,3431],{"class":115}," Nil",[40,3433,3434],{"class":53},"              =>",[40,3436,1346],{"class":115},[40,3438,3439,3441,3444,3447,3449,3451,3453,3455,3457,3459,3461,3464],{"class":42,"line":1200},[40,3440,314],{"class":53},[40,3442,3443],{"class":67}," head ",[40,3445,3446],{"class":53},"::",[40,3448,579],{"class":67},[40,3450,21],{"class":53},[40,3452,3443],{"class":67},[40,3454,2189],{"class":53},[40,3456,1996],{"class":74},[40,3458,789],{"class":53},[40,3460,1294],{"class":115},[40,3462,3463],{"class":67},"(head)  ",[40,3465,3466],{"class":46},"\u002F\u002F early exit via pattern match\n",[40,3468,3469,3471,3473,3475,3478,3480,3483],{"class":42,"line":1924},[40,3470,314],{"class":53},[40,3472,579],{"class":67},[40,3474,3446],{"class":53},[40,3476,3477],{"class":67}," tail        ",[40,3479,461],{"class":53},[40,3481,3482],{"class":67}," findFirstPositive(tail)  ",[40,3484,3485],{"class":46},"\u002F\u002F tail call → loop\n",[15,3487,3489],{"id":3488},"tips-tricks","💡 Tips & Tricks",[3491,3492,3493,3503,3504,3506],"p",{},[3494,3495,3496,3498,3499,3502],"strong",{},[19,3497,292],{}," + ",[19,3500,3501],{},"enum"," for exhaustive state machines",": Scala 3 ",[19,3505,3501],{}," is automatically sealed — all variants known at compile time.",[28,3508,3509],{"language":30},[32,3510,3512],{"className":34,"code":3511,"language":30,"meta":36,"style":36},"enum ConnectionState:\n  case Disconnected, Connecting, Connected, Error(msg: String)\n\ndef handle(s: ConnectionState): Unit = s match\n  case Disconnected   => reconnect()\n  case Connecting     => waitForTimeout()\n  case Connected      => ()\n  case Error(msg)     => log.error(msg)\n\u002F\u002F Add a new state → compile error on ALL match expressions → forced handling\n",[19,3513,3514,3523,3555,3559,3587,3598,3610,3623,3637],{"__ignoreMap":36},[40,3515,3516,3518,3521],{"class":42,"line":43},[40,3517,3501],{"class":53},[40,3519,3520],{"class":115}," ConnectionState",[40,3522,309],{"class":53},[40,3524,3525,3527,3530,3532,3535,3537,3540,3542,3545,3547,3549,3551,3553],{"class":42,"line":50},[40,3526,314],{"class":53},[40,3528,3529],{"class":115}," Disconnected",[40,3531,361],{"class":67},[40,3533,3534],{"class":115},"Connecting",[40,3536,361],{"class":67},[40,3538,3539],{"class":115},"Connected",[40,3541,361],{"class":67},[40,3543,3544],{"class":115},"Error",[40,3546,323],{"class":67},[40,3548,364],{"class":57},[40,3550,329],{"class":67},[40,3552,332],{"class":115},[40,3554,1197],{"class":67},[40,3556,3557],{"class":42,"line":91},[40,3558,95],{"emptyLinePlaceholder":94},[40,3560,3561,3563,3566,3568,3570,3572,3575,3577,3579,3581,3583,3585],{"class":42,"line":98},[40,3562,420],{"class":53},[40,3564,3565],{"class":115}," handle",[40,3567,323],{"class":67},[40,3569,428],{"class":57},[40,3571,329],{"class":67},[40,3573,3574],{"class":115},"ConnectionState",[40,3576,436],{"class":67},[40,3578,112],{"class":53},[40,3580,161],{"class":115},[40,3582,61],{"class":53},[40,3584,446],{"class":67},[40,3586,449],{"class":53},[40,3588,3589,3591,3593,3595],{"class":42,"line":104},[40,3590,314],{"class":53},[40,3592,3529],{"class":115},[40,3594,764],{"class":53},[40,3596,3597],{"class":67}," reconnect()\n",[40,3599,3600,3602,3605,3607],{"class":42,"line":140},[40,3601,314],{"class":53},[40,3603,3604],{"class":115}," Connecting",[40,3606,2772],{"class":53},[40,3608,3609],{"class":67}," waitForTimeout()\n",[40,3611,3612,3614,3617,3620],{"class":42,"line":145},[40,3613,314],{"class":53},[40,3615,3616],{"class":115}," Connected",[40,3618,3619],{"class":53},"      =>",[40,3621,3622],{"class":67}," ()\n",[40,3624,3625,3627,3629,3632,3634],{"class":42,"line":151},[40,3626,314],{"class":53},[40,3628,349],{"class":115},[40,3630,3631],{"class":67},"(msg)     ",[40,3633,461],{"class":53},[40,3635,3636],{"class":67}," log.error(msg)\n",[40,3638,3639],{"class":42,"line":184},[40,3640,3641],{"class":46},"\u002F\u002F Add a new state → compile error on ALL match expressions → forced handling\n",[3491,3643,3644,329,3650,3653,3654,3657,3658,3660],{},[3494,3645,3646,3647,3649],{},"Pattern match with ",[19,3648,3382],{}," to bind the whole value while destructuring",[19,3651,3652],{},"case ev @ Error(code, _) =>"," gives you both ",[19,3655,3656],{},"ev"," (the full object) and ",[19,3659,19],{}," (the field).",[3491,3662,3663,329,3673,3676,3677,3680,3681,3684,3685,3688],{},[3494,3664,3665,3668,3669,3672],{},[19,3666,3667],{},"orElse"," on ",[19,3670,3671],{},"PartialFunction"," for composition",[19,3674,3675],{},"pf1.orElse(pf2)"," tries ",[19,3678,3679],{},"pf1"," first, falls back to ",[19,3682,3683],{},"pf2"," if ",[19,3686,3687],{},"pf1.isDefinedAt"," is false.",[15,3690,3692],{"id":3691},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[3491,3694,3695,3698],{},[3494,3696,3697],{},"Variable pattern vs constant pattern",": A lowercase name is a variable (binds anything). An uppercase name or backtick-quoted name is a constant (matches by value).",[28,3700,3701],{"language":30},[32,3702,3704],{"className":34,"code":3703,"language":30,"meta":36,"style":36},"val MAX = 100\ndef classify(n: Int): String = n match\n  case MAX => \"max\"                        \u002F\u002F ✅ uppercase = constant pattern, matches 100\n  case `max` => \"also max\"                 \u002F\u002F ✅ backtick = constant\n  case max => s\"got $max\"                  \u002F\u002F ❌ lowercase = variable, binds n, always matches!\n\n\u002F\u002F The `case max =>` line is a catch-all that shadows MAX — no warning in Scala 2,\n\u002F\u002F Scala 3 warns: \"pattern var max shadows the same-named val\"\n",[19,3705,3706,3718,3744,3758,3773,3795,3799,3804],{"__ignoreMap":36},[40,3707,3708,3710,3713,3715],{"class":42,"line":43},[40,3709,54],{"class":53},[40,3711,3712],{"class":57}," MAX",[40,3714,61],{"class":53},[40,3716,3717],{"class":74}," 100\n",[40,3719,3720,3722,3724,3726,3728,3730,3732,3734,3736,3738,3740,3742],{"class":42,"line":50},[40,3721,420],{"class":53},[40,3723,1863],{"class":115},[40,3725,323],{"class":67},[40,3727,1825],{"class":57},[40,3729,329],{"class":67},[40,3731,358],{"class":115},[40,3733,436],{"class":67},[40,3735,112],{"class":53},[40,3737,441],{"class":115},[40,3739,61],{"class":53},[40,3741,1841],{"class":67},[40,3743,449],{"class":53},[40,3745,3746,3748,3750,3752,3755],{"class":42,"line":91},[40,3747,314],{"class":53},[40,3749,3712],{"class":115},[40,3751,789],{"class":53},[40,3753,3754],{"class":81}," \"max\"",[40,3756,3757],{"class":46},"                        \u002F\u002F ✅ uppercase = constant pattern, matches 100\n",[40,3759,3760,3762,3765,3767,3770],{"class":42,"line":98},[40,3761,314],{"class":53},[40,3763,3764],{"class":67}," `max` ",[40,3766,461],{"class":53},[40,3768,3769],{"class":81}," \"also max\"",[40,3771,3772],{"class":46},"                 \u002F\u002F ✅ backtick = constant\n",[40,3774,3775,3777,3780,3782,3784,3787,3790,3792],{"class":42,"line":104},[40,3776,314],{"class":53},[40,3778,3779],{"class":67}," max ",[40,3781,461],{"class":53},[40,3783,464],{"class":53},[40,3785,3786],{"class":81},"\"got ",[40,3788,3789],{"class":67},"$max",[40,3791,812],{"class":81},[40,3793,3794],{"class":46},"                  \u002F\u002F ❌ lowercase = variable, binds n, always matches!\n",[40,3796,3797],{"class":42,"line":140},[40,3798,95],{"emptyLinePlaceholder":94},[40,3800,3801],{"class":42,"line":145},[40,3802,3803],{"class":46},"\u002F\u002F The `case max =>` line is a catch-all that shadows MAX — no warning in Scala 2,\n",[40,3805,3806],{"class":42,"line":151},[40,3807,3808],{"class":46},"\u002F\u002F Scala 3 warns: \"pattern var max shadows the same-named val\"\n",[3491,3810,3811,3821,3822,3824,3825,3827,3828,3830,3831,3833],{},[3494,3812,3813,3816,3817,3820],{},[19,3814,3815],{},"withFilter"," vs ",[19,3818,3819],{},"filter"," in for-comprehensions",": The compiler uses ",[19,3823,3815],{}," (lazy) for guards. If ",[19,3826,3815],{}," doesn't exist, it falls back to ",[19,3829,3819],{}," (strict, allocates intermediate collection). Custom monads must implement ",[19,3832,3815],{}," for efficiency.",[3491,3835,3836,3843,3844,361,3847,3849,3850,3853],{},[3494,3837,3838,3839,3842],{},"Match on ",[19,3840,3841],{},"null"," explicitly",": In Scala 3 without ",[19,3845,3846],{},"-explicitNulls",[19,3848,3841],{}," can appear anywhere. A ",[19,3851,3852],{},"case null =>"," guard is the only way to handle it in pattern matching.",[15,3855,3857],{"id":3856},"quick-quiz","🧠 Quick Quiz",[3491,3859,3860,3861,3864],{},"What happens if you add ",[19,3862,3863],{},"case object Redirect extends HttpStatus"," to the sealed trait but don't update a match expression?",[3866,3867,3868,3872,3898],"details",{},[3869,3870,3871],"summary",{},"Answer",[3491,3873,3874,3877,3878,3881,3882,3885,3886,3888,3889,3892,3893,3668,3895,3897],{},[3494,3875,3876],{},"Compile error"," (Scala 3) or ",[3494,3879,3880],{},"compile warning"," (Scala 2 with ",[19,3883,3884],{},"-Werror","). The compiler tracks all subtypes of a sealed trait and verifies that every ",[19,3887,274],{}," expression handles all of them. Adding ",[19,3890,3891],{},"Redirect"," makes every existing ",[19,3894,274],{},[19,3896,433],{}," non-exhaustive.",[3491,3899,3900,3901,3904],{},"This is the primary benefit of sealed hierarchies: ",[3494,3902,3903],{},"refactoring safety",". You cannot add a case without updating all consumers — the compiler forces you.",[3906,3907,3908],"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 .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}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 pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}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);}",{"title":36,"searchDepth":50,"depth":50,"links":3910},[3911,3913,3915,3916,3917,3918,3920,3922,3923,3925,3926,3927],{"id":17,"depth":50,"text":3912},"if \u002F else — Expression, Not Statement",{"id":271,"depth":50,"text":3914},"match — Exhaustiveness & Sealed Hierarchies",{"id":607,"depth":50,"text":608},{"id":1216,"depth":50,"text":1217},{"id":1522,"depth":50,"text":1523},{"id":2067,"depth":50,"text":3919},"Either \u002F Try \u002F Option — Error as Values",{"id":2530,"depth":50,"text":3921},"try \u002F catch \u002F finally — Expression Semantics",{"id":2728,"depth":50,"text":2729},{"id":3067,"depth":50,"text":3924},"Loops — while \u002F for and Their Desugaring",{"id":3488,"depth":50,"text":3489},{"id":3691,"depth":50,"text":3692},{"id":3856,"depth":50,"text":3857},"Production-grade pattern matching, sealed exhaustiveness, refutable vs irrefutable patterns, match type desugaring, and control-flow-as-expression semantics in Scala 3.","md",{},"\u002Fscala\u002F04-control-flow",{"title":5,"description":3928},"scala\u002F04-control-flow","Qnt5kTO9WOT2cvO-0Y_z8NqMoe3AMA4KQAqFd8qP-SM",1789924653961]