[{"data":1,"prerenderedAt":2876},["ShallowReactive",2],{"page-\u002Fscala\u002F02-variables-and-data-types":3},{"id":4,"title":5,"body":6,"description":2869,"extension":2870,"meta":2871,"navigation":108,"path":2872,"seo":2873,"stem":2874,"__hash__":2875},"content\u002Fscala\u002F02-variables-and-data-types.md","Scala — Value Semantics, Type Hierarchy & Memory Model",{"type":7,"value":8,"toc":2850},"minimark",[9,14,30,211,219,381,385,750,754,1096,1100,1387,1401,2846],[10,11,13],"h1",{"id":12},"_02-value-semantics-type-hierarchy-memory-model","02 — Value Semantics, Type Hierarchy & Memory Model",[15,16,18,22,23,22,26,29],"h2",{"id":17},"val-var-lazy-val-initialization-semantics",[19,20,21],"code",{},"val"," \u002F ",[19,24,25],{},"var",[19,27,28],{},"lazy val"," — Initialization Semantics",[31,32,34],"code-wrapper",{"language":33},"scala",[35,36,40],"pre",{"className":37,"code":38,"language":33,"meta":39,"style":39},"language-scala shiki shiki-themes github-light github-dark","\u002F\u002F val: final field, initialized at construction, stored on heap as object field\n\u002F\u002F      For local vals: stored on stack (no heap allocation if not captured)\nfinal val MAX_CONNECTIONS = 100           \u002F\u002F → inlined as literal 100 at use sites\n                                         \u002F\u002F   (final val of literal type = compile-time constant)\nval connectionTimeout = 5000              \u002F\u002F → field + getter; not inlined\n\n\u002F\u002F var: volatile? no. Just a mutable field with getter+setter.\n\u002F\u002F      NOT thread-safe — no happens-before guarantee, no atomicity.\n@volatile var running = true              \u002F\u002F @volatile adds JMM visibility (no reorder across)\n                                         \u002F\u002F   but NOT atomicity for compound ops (x += 1 is racy)\n\n\u002F\u002F lazy val: double-checked locking under the hood\n\u002F\u002F   → private volatile bitmap field; first access computes & caches\n\u002F\u002F   → Thread-safe but first-access contended; allocation on every lazy val\n\u002F\u002F   → SCALA 2: synchronization on the enclosing object (coarse lock — contention!)\n\u002F\u002F   → SCALA 3: fine-grained per-field DCL pattern (less contention)\nlazy val heavyConfig = parseConfig()     \u002F\u002F first access: parseConfig() runs, cached\n                                         \u002F\u002F subsequent: direct field read (volatile read only)\n","",[19,41,42,51,57,81,87,103,110,116,122,145,151,156,162,168,174,180,186,205],{"__ignoreMap":39},[43,44,47],"span",{"class":45,"line":46},"line",1,[43,48,50],{"class":49},"sdCPZ","\u002F\u002F val: final field, initialized at construction, stored on heap as object field\n",[43,52,54],{"class":45,"line":53},2,[43,55,56],{"class":49},"\u002F\u002F      For local vals: stored on stack (no heap allocation if not captured)\n",[43,58,60,64,67,71,74,78],{"class":45,"line":59},3,[43,61,63],{"class":62},"svdQ7","final",[43,65,66],{"class":62}," val",[43,68,70],{"class":69},"sCrzJ"," MAX_CONNECTIONS",[43,72,73],{"class":62}," =",[43,75,77],{"class":76},"snvgF"," 100",[43,79,80],{"class":49},"           \u002F\u002F → inlined as literal 100 at use sites\n",[43,82,84],{"class":45,"line":83},4,[43,85,86],{"class":49},"                                         \u002F\u002F   (final val of literal type = compile-time constant)\n",[43,88,90,92,95,97,100],{"class":45,"line":89},5,[43,91,21],{"class":62},[43,93,94],{"class":69}," connectionTimeout",[43,96,73],{"class":62},[43,98,99],{"class":76}," 5000",[43,101,102],{"class":49},"              \u002F\u002F → field + getter; not inlined\n",[43,104,106],{"class":45,"line":105},6,[43,107,109],{"emptyLinePlaceholder":108},true,"\n",[43,111,113],{"class":45,"line":112},7,[43,114,115],{"class":49},"\u002F\u002F var: volatile? no. Just a mutable field with getter+setter.\n",[43,117,119],{"class":45,"line":118},8,[43,120,121],{"class":49},"\u002F\u002F      NOT thread-safe — no happens-before guarantee, no atomicity.\n",[43,123,125,128,132,134,137,139,142],{"class":45,"line":124},9,[43,126,127],{"class":62},"@",[43,129,131],{"class":130},"ssxIu","volatile ",[43,133,25],{"class":62},[43,135,136],{"class":69}," running",[43,138,73],{"class":62},[43,140,141],{"class":76}," true",[43,143,144],{"class":49},"              \u002F\u002F @volatile adds JMM visibility (no reorder across)\n",[43,146,148],{"class":45,"line":147},10,[43,149,150],{"class":49},"                                         \u002F\u002F   but NOT atomicity for compound ops (x += 1 is racy)\n",[43,152,154],{"class":45,"line":153},11,[43,155,109],{"emptyLinePlaceholder":108},[43,157,159],{"class":45,"line":158},12,[43,160,161],{"class":49},"\u002F\u002F lazy val: double-checked locking under the hood\n",[43,163,165],{"class":45,"line":164},13,[43,166,167],{"class":49},"\u002F\u002F   → private volatile bitmap field; first access computes & caches\n",[43,169,171],{"class":45,"line":170},14,[43,172,173],{"class":49},"\u002F\u002F   → Thread-safe but first-access contended; allocation on every lazy val\n",[43,175,177],{"class":45,"line":176},15,[43,178,179],{"class":49},"\u002F\u002F   → SCALA 2: synchronization on the enclosing object (coarse lock — contention!)\n",[43,181,183],{"class":45,"line":182},16,[43,184,185],{"class":49},"\u002F\u002F   → SCALA 3: fine-grained per-field DCL pattern (less contention)\n",[43,187,189,192,194,197,199,202],{"class":45,"line":188},17,[43,190,191],{"class":62},"lazy",[43,193,66],{"class":62},[43,195,196],{"class":69}," heavyConfig",[43,198,73],{"class":62},[43,200,201],{"class":130}," parseConfig()     ",[43,203,204],{"class":49},"\u002F\u002F first access: parseConfig() runs, cached\n",[43,206,208],{"class":45,"line":207},18,[43,209,210],{"class":49},"                                         \u002F\u002F subsequent: direct field read (volatile read only)\n",[212,213,215,216,218],"h3",{"id":214},"anti-pattern-lazy-val-inside-hot-path","Anti-Pattern: ",[19,217,28],{}," Inside Hot Path",[31,220,221],{"language":33},[35,222,224],{"className":37,"code":223,"language":33,"meta":39,"style":39},"\u002F\u002F ❌ WRONG — lazy val allocates a bitmap slot + volatile read on EVERY call\ndef process(items: List[Int]): Int =\n  lazy val hasher = new XXHash64()        \u002F\u002F bitmap check on every invocation\n  items.foldLeft(0)((acc, n) => hasher.update(n))  \u002F\u002F hasher init: DCL overhead\n\n\u002F\u002F ✅ CORRECT — pre-allocate, reuse, no per-call lazy machinery\ndef process(items: List[Int]): Int =\n  val hasher = new XXHash64()             \u002F\u002F stack-allocated reference (JIT scalar-replacement)\n  items.foldLeft(0)((acc, n) => hasher.update(n))\n",[19,225,226,231,270,294,314,318,323,349,368],{"__ignoreMap":39},[43,227,228],{"class":45,"line":46},[43,229,230],{"class":49},"\u002F\u002F ❌ WRONG — lazy val allocates a bitmap slot + volatile read on EVERY call\n",[43,232,233,236,240,243,246,249,252,255,258,261,264,267],{"class":45,"line":53},[43,234,235],{"class":62},"def",[43,237,239],{"class":238},"sIsaT"," process",[43,241,242],{"class":130},"(",[43,244,245],{"class":69},"items",[43,247,248],{"class":130},": ",[43,250,251],{"class":238},"List",[43,253,254],{"class":130},"[",[43,256,257],{"class":238},"Int",[43,259,260],{"class":130},"])",[43,262,263],{"class":62},":",[43,265,266],{"class":238}," Int",[43,268,269],{"class":62}," =\n",[43,271,272,275,277,280,282,285,288,291],{"class":45,"line":59},[43,273,274],{"class":62},"  lazy",[43,276,66],{"class":62},[43,278,279],{"class":69}," hasher",[43,281,73],{"class":62},[43,283,284],{"class":62}," new",[43,286,287],{"class":238}," XXHash64",[43,289,290],{"class":130},"()        ",[43,292,293],{"class":49},"\u002F\u002F bitmap check on every invocation\n",[43,295,296,299,302,305,308,311],{"class":45,"line":83},[43,297,298],{"class":130},"  items.foldLeft(",[43,300,301],{"class":76},"0",[43,303,304],{"class":130},")((acc, n) ",[43,306,307],{"class":62},"=>",[43,309,310],{"class":130}," hasher.update(n))  ",[43,312,313],{"class":49},"\u002F\u002F hasher init: DCL overhead\n",[43,315,316],{"class":45,"line":89},[43,317,109],{"emptyLinePlaceholder":108},[43,319,320],{"class":45,"line":105},[43,321,322],{"class":49},"\u002F\u002F ✅ CORRECT — pre-allocate, reuse, no per-call lazy machinery\n",[43,324,325,327,329,331,333,335,337,339,341,343,345,347],{"class":45,"line":112},[43,326,235],{"class":62},[43,328,239],{"class":238},[43,330,242],{"class":130},[43,332,245],{"class":69},[43,334,248],{"class":130},[43,336,251],{"class":238},[43,338,254],{"class":130},[43,340,257],{"class":238},[43,342,260],{"class":130},[43,344,263],{"class":62},[43,346,266],{"class":238},[43,348,269],{"class":62},[43,350,351,354,356,358,360,362,365],{"class":45,"line":118},[43,352,353],{"class":62},"  val",[43,355,279],{"class":69},[43,357,73],{"class":62},[43,359,284],{"class":62},[43,361,287],{"class":238},[43,363,364],{"class":130},"()             ",[43,366,367],{"class":49},"\u002F\u002F stack-allocated reference (JIT scalar-replacement)\n",[43,369,370,372,374,376,378],{"class":45,"line":124},[43,371,298],{"class":130},[43,373,301],{"class":76},[43,375,304],{"class":130},[43,377,307],{"class":62},[43,379,380],{"class":130}," hasher.update(n))\n",[15,382,384],{"id":383},"primitive-boxing-specialization","Primitive Boxing & Specialization",[31,386,387],{"language":33},[35,388,390],{"className":37,"code":389,"language":33,"meta":39,"style":39},"\u002F\u002F Scala primitives (Int, Long, Double, etc.) compile to JVM primitives in most contexts:\nval x: Int = 42                           \u002F\u002F → ILOAD\u002FISTORE (no boxing)\nval arr = new Array[Int](1000)            \u002F\u002F → int[] (primitive array, contiguous memory)\n\n\u002F\u002F BUT: generics box. List[Int] → List[java.lang.Integer] at runtime (type erasure).\nval nums: List[Int] = List(1, 2, 3)       \u002F\u002F each Int boxed to Integer → 3 heap allocations\n\n\u002F\u002F @specialized — generate monomorphic versions for primitive types to avoid boxing\n\u002F\u002F Scala 2 only (Scala 3 uses transparent inline match \u002F opaque types instead)\ntrait Min[@specialized(Int, Long, Double) T]:\n  def min(a: T, b: T): T\n\u002F\u002F Compiler generates Min$mc$I$sp, Min$mc$J$sp, Min$mc$D$sp — no boxing for Int\u002FLong\u002FDouble\n\n\u002F\u002F Scala 3 approach — opaque types for zero-cost newtype wrappers:\nobject Meter:\n  opaque type Meter = Double              \u002F\u002F compile-time: Meter; runtime: just double\n  def apply(d: Double): Meter = d         \u002F\u002F zero allocation, zero boxing\n  extension (m: Meter) def toFeet: Double = m * 3.28084\n\nval depth: Meter = Meter(10.0)            \u002F\u002F runtime: just a double on the stack\n\u002F\u002F depth * 2  ← compile error: Meter has no * operator — type-safe!\nMeter(10.0).toFeet                        \u002F\u002F → 32.8084 (no runtime Meter object)\n",[19,391,392,397,416,446,450,455,501,505,510,515,554,588,593,597,602,612,630,660,698,703,729,735],{"__ignoreMap":39},[43,393,394],{"class":45,"line":46},[43,395,396],{"class":49},"\u002F\u002F Scala primitives (Int, Long, Double, etc.) compile to JVM primitives in most contexts:\n",[43,398,399,401,404,406,408,410,413],{"class":45,"line":53},[43,400,21],{"class":62},[43,402,403],{"class":69}," x",[43,405,263],{"class":62},[43,407,266],{"class":238},[43,409,73],{"class":62},[43,411,412],{"class":76}," 42",[43,414,415],{"class":49},"                           \u002F\u002F → ILOAD\u002FISTORE (no boxing)\n",[43,417,418,420,423,425,427,430,432,434,437,440,443],{"class":45,"line":59},[43,419,21],{"class":62},[43,421,422],{"class":69}," arr",[43,424,73],{"class":62},[43,426,284],{"class":62},[43,428,429],{"class":238}," Array",[43,431,254],{"class":130},[43,433,257],{"class":238},[43,435,436],{"class":130},"](",[43,438,439],{"class":76},"1000",[43,441,442],{"class":130},")            ",[43,444,445],{"class":49},"\u002F\u002F → int[] (primitive array, contiguous memory)\n",[43,447,448],{"class":45,"line":83},[43,449,109],{"emptyLinePlaceholder":108},[43,451,452],{"class":45,"line":89},[43,453,454],{"class":49},"\u002F\u002F BUT: generics box. List[Int] → List[java.lang.Integer] at runtime (type erasure).\n",[43,456,457,459,462,464,467,469,471,474,477,479,481,484,487,490,492,495,498],{"class":45,"line":105},[43,458,21],{"class":62},[43,460,461],{"class":69}," nums",[43,463,263],{"class":62},[43,465,466],{"class":238}," List",[43,468,254],{"class":130},[43,470,257],{"class":238},[43,472,473],{"class":130},"] ",[43,475,476],{"class":62},"=",[43,478,466],{"class":238},[43,480,242],{"class":130},[43,482,483],{"class":76},"1",[43,485,486],{"class":130},", ",[43,488,489],{"class":76},"2",[43,491,486],{"class":130},[43,493,494],{"class":76},"3",[43,496,497],{"class":130},")       ",[43,499,500],{"class":49},"\u002F\u002F each Int boxed to Integer → 3 heap allocations\n",[43,502,503],{"class":45,"line":112},[43,504,109],{"emptyLinePlaceholder":108},[43,506,507],{"class":45,"line":118},[43,508,509],{"class":49},"\u002F\u002F @specialized — generate monomorphic versions for primitive types to avoid boxing\n",[43,511,512],{"class":45,"line":124},[43,513,514],{"class":49},"\u002F\u002F Scala 2 only (Scala 3 uses transparent inline match \u002F opaque types instead)\n",[43,516,517,520,523,525,527,530,532,534,537,539,542,545,548,551],{"class":45,"line":147},[43,518,519],{"class":62},"trait",[43,521,522],{"class":238}," Min",[43,524,254],{"class":130},[43,526,127],{"class":62},[43,528,529],{"class":130},"specialized(",[43,531,257],{"class":238},[43,533,486],{"class":130},[43,535,536],{"class":238},"Long",[43,538,486],{"class":130},[43,540,541],{"class":238},"Double",[43,543,544],{"class":130},") ",[43,546,547],{"class":238},"T",[43,549,550],{"class":130},"]",[43,552,553],{"class":62},":\n",[43,555,556,559,562,564,567,569,571,573,576,578,580,583,585],{"class":45,"line":153},[43,557,558],{"class":62},"  def",[43,560,561],{"class":238}," min",[43,563,242],{"class":130},[43,565,566],{"class":69},"a",[43,568,248],{"class":130},[43,570,547],{"class":238},[43,572,486],{"class":130},[43,574,575],{"class":69},"b",[43,577,248],{"class":130},[43,579,547],{"class":238},[43,581,582],{"class":130},")",[43,584,263],{"class":62},[43,586,587],{"class":238}," T\n",[43,589,590],{"class":45,"line":158},[43,591,592],{"class":49},"\u002F\u002F Compiler generates Min$mc$I$sp, Min$mc$J$sp, Min$mc$D$sp — no boxing for Int\u002FLong\u002FDouble\n",[43,594,595],{"class":45,"line":164},[43,596,109],{"emptyLinePlaceholder":108},[43,598,599],{"class":45,"line":170},[43,600,601],{"class":49},"\u002F\u002F Scala 3 approach — opaque types for zero-cost newtype wrappers:\n",[43,603,604,607,610],{"class":45,"line":176},[43,605,606],{"class":62},"object",[43,608,609],{"class":238}," Meter",[43,611,553],{"class":62},[43,613,614,617,620,622,624,627],{"class":45,"line":182},[43,615,616],{"class":62},"  opaque",[43,618,619],{"class":62}," type",[43,621,609],{"class":238},[43,623,73],{"class":62},[43,625,626],{"class":238}," Double",[43,628,629],{"class":49},"              \u002F\u002F compile-time: Meter; runtime: just double\n",[43,631,632,634,637,639,642,644,646,648,650,652,654,657],{"class":45,"line":188},[43,633,558],{"class":62},[43,635,636],{"class":238}," apply",[43,638,242],{"class":130},[43,640,641],{"class":69},"d",[43,643,248],{"class":130},[43,645,541],{"class":238},[43,647,582],{"class":130},[43,649,263],{"class":62},[43,651,609],{"class":238},[43,653,73],{"class":62},[43,655,656],{"class":130}," d         ",[43,658,659],{"class":49},"\u002F\u002F zero allocation, zero boxing\n",[43,661,662,665,668,671,673,676,678,680,683,685,687,689,692,695],{"class":45,"line":207},[43,663,664],{"class":62},"  extension",[43,666,667],{"class":130}," (",[43,669,670],{"class":69},"m",[43,672,248],{"class":130},[43,674,675],{"class":238},"Meter",[43,677,544],{"class":130},[43,679,235],{"class":62},[43,681,682],{"class":238}," toFeet",[43,684,263],{"class":62},[43,686,626],{"class":238},[43,688,73],{"class":62},[43,690,691],{"class":130}," m ",[43,693,694],{"class":62},"*",[43,696,697],{"class":76}," 3.28084\n",[43,699,701],{"class":45,"line":700},19,[43,702,109],{"emptyLinePlaceholder":108},[43,704,706,708,711,713,715,717,719,721,724,726],{"class":45,"line":705},20,[43,707,21],{"class":62},[43,709,710],{"class":69}," depth",[43,712,263],{"class":62},[43,714,609],{"class":238},[43,716,73],{"class":62},[43,718,609],{"class":238},[43,720,242],{"class":130},[43,722,723],{"class":76},"10.0",[43,725,442],{"class":130},[43,727,728],{"class":49},"\u002F\u002F runtime: just a double on the stack\n",[43,730,732],{"class":45,"line":731},21,[43,733,734],{"class":49},"\u002F\u002F depth * 2  ← compile error: Meter has no * operator — type-safe!\n",[43,736,738,740,742,744,747],{"class":45,"line":737},22,[43,739,675],{"class":238},[43,741,242],{"class":130},[43,743,723],{"class":76},[43,745,746],{"class":130},").toFeet                        ",[43,748,749],{"class":49},"\u002F\u002F → 32.8084 (no runtime Meter object)\n",[15,751,753],{"id":752},"numeric-types-precision-overflow","Numeric Types — Precision & Overflow",[31,755,756],{"language":33},[35,757,759],{"className":37,"code":758,"language":33,"meta":39,"style":39},"\u002F\u002F JVM primitive sizes — same as Java, no surprises\nval b: Byte = 127                         \u002F\u002F 8-bit signed: -128..127\nval s: Short = 32767                      \u002F\u002F 16-bit signed\nval i: Int = 2147483647                   \u002F\u002F 32-bit signed\nval l: Long = 9223372036854775807L        \u002F\u002F 64-bit signed\nval f: Float = 3.14f                      \u002F\u002F 32-bit IEEE 754\nval d: Double = 3.14                      \u002F\u002F 64-bit IEEE 754\n\n\u002F\u002F Silent overflow — no exception, wraps around (JVM semantics)\nval overflowed: Int = 2147483647 + 1      \u002F\u002F → -2147483648 (two's complement wrap)\n\n\u002F\u002F BigInt \u002F BigDecimal — arbitrary precision, heap-allocated, immutable\nval huge = BigInt(\"999999999999999999999\")\nval precise = BigDecimal(\"0.1\") + BigDecimal(\"0.2\")  \u002F\u002F → 0.3 (exact, not 0.30000000000000004)\n\u002F\u002F Internally wraps java.math.BigInteger \u002F java.math.BigDecimal\n\u002F\u002F Every arithmetic op allocates a new BigInt — avoid in hot loops\n\n\u002F\u002F Safe arithmetic with overflow detection (Scala doesn't have built-in;\n\u002F\u002F use Math.addExact etc. from Java):\nimport scala.util.Try\ndef safeAdd(a: Int, b: Int): Try[Int] = Try(java.lang.Math.addExact(a, b))\nsafeAdd(Int.MaxValue, 1)                  \u002F\u002F Failure(ArithmeticException: integer overflow)\n",[19,760,761,766,786,806,825,845,865,884,888,893,917,921,926,947,982,987,992,996,1001,1006,1025,1074],{"__ignoreMap":39},[43,762,763],{"class":45,"line":46},[43,764,765],{"class":49},"\u002F\u002F JVM primitive sizes — same as Java, no surprises\n",[43,767,768,770,773,775,778,780,783],{"class":45,"line":53},[43,769,21],{"class":62},[43,771,772],{"class":69}," b",[43,774,263],{"class":62},[43,776,777],{"class":238}," Byte",[43,779,73],{"class":62},[43,781,782],{"class":76}," 127",[43,784,785],{"class":49},"                         \u002F\u002F 8-bit signed: -128..127\n",[43,787,788,790,793,795,798,800,803],{"class":45,"line":59},[43,789,21],{"class":62},[43,791,792],{"class":69}," s",[43,794,263],{"class":62},[43,796,797],{"class":238}," Short",[43,799,73],{"class":62},[43,801,802],{"class":76}," 32767",[43,804,805],{"class":49},"                      \u002F\u002F 16-bit signed\n",[43,807,808,810,813,815,817,819,822],{"class":45,"line":83},[43,809,21],{"class":62},[43,811,812],{"class":69}," i",[43,814,263],{"class":62},[43,816,266],{"class":238},[43,818,73],{"class":62},[43,820,821],{"class":76}," 2147483647",[43,823,824],{"class":49},"                   \u002F\u002F 32-bit signed\n",[43,826,827,829,832,834,837,839,842],{"class":45,"line":89},[43,828,21],{"class":62},[43,830,831],{"class":69}," l",[43,833,263],{"class":62},[43,835,836],{"class":238}," Long",[43,838,73],{"class":62},[43,840,841],{"class":76}," 9223372036854775807L",[43,843,844],{"class":49},"        \u002F\u002F 64-bit signed\n",[43,846,847,849,852,854,857,859,862],{"class":45,"line":105},[43,848,21],{"class":62},[43,850,851],{"class":69}," f",[43,853,263],{"class":62},[43,855,856],{"class":238}," Float",[43,858,73],{"class":62},[43,860,861],{"class":76}," 3.14f",[43,863,864],{"class":49},"                      \u002F\u002F 32-bit IEEE 754\n",[43,866,867,869,872,874,876,878,881],{"class":45,"line":112},[43,868,21],{"class":62},[43,870,871],{"class":69}," d",[43,873,263],{"class":62},[43,875,626],{"class":238},[43,877,73],{"class":62},[43,879,880],{"class":76}," 3.14",[43,882,883],{"class":49},"                      \u002F\u002F 64-bit IEEE 754\n",[43,885,886],{"class":45,"line":118},[43,887,109],{"emptyLinePlaceholder":108},[43,889,890],{"class":45,"line":124},[43,891,892],{"class":49},"\u002F\u002F Silent overflow — no exception, wraps around (JVM semantics)\n",[43,894,895,897,900,902,904,906,908,911,914],{"class":45,"line":147},[43,896,21],{"class":62},[43,898,899],{"class":69}," overflowed",[43,901,263],{"class":62},[43,903,266],{"class":238},[43,905,73],{"class":62},[43,907,821],{"class":76},[43,909,910],{"class":62}," +",[43,912,913],{"class":76}," 1",[43,915,916],{"class":49},"      \u002F\u002F → -2147483648 (two's complement wrap)\n",[43,918,919],{"class":45,"line":153},[43,920,109],{"emptyLinePlaceholder":108},[43,922,923],{"class":45,"line":158},[43,924,925],{"class":49},"\u002F\u002F BigInt \u002F BigDecimal — arbitrary precision, heap-allocated, immutable\n",[43,927,928,930,933,935,938,940,944],{"class":45,"line":164},[43,929,21],{"class":62},[43,931,932],{"class":69}," huge",[43,934,73],{"class":62},[43,936,937],{"class":238}," BigInt",[43,939,242],{"class":130},[43,941,943],{"class":942},"sJ6F3","\"999999999999999999999\"",[43,945,946],{"class":130},")\n",[43,948,949,951,954,956,959,961,964,966,969,971,973,976,979],{"class":45,"line":170},[43,950,21],{"class":62},[43,952,953],{"class":69}," precise",[43,955,73],{"class":62},[43,957,958],{"class":238}," BigDecimal",[43,960,242],{"class":130},[43,962,963],{"class":942},"\"0.1\"",[43,965,544],{"class":130},[43,967,968],{"class":62},"+",[43,970,958],{"class":238},[43,972,242],{"class":130},[43,974,975],{"class":942},"\"0.2\"",[43,977,978],{"class":130},")  ",[43,980,981],{"class":49},"\u002F\u002F → 0.3 (exact, not 0.30000000000000004)\n",[43,983,984],{"class":45,"line":176},[43,985,986],{"class":49},"\u002F\u002F Internally wraps java.math.BigInteger \u002F java.math.BigDecimal\n",[43,988,989],{"class":45,"line":182},[43,990,991],{"class":49},"\u002F\u002F Every arithmetic op allocates a new BigInt — avoid in hot loops\n",[43,993,994],{"class":45,"line":188},[43,995,109],{"emptyLinePlaceholder":108},[43,997,998],{"class":45,"line":207},[43,999,1000],{"class":49},"\u002F\u002F Safe arithmetic with overflow detection (Scala doesn't have built-in;\n",[43,1002,1003],{"class":45,"line":700},[43,1004,1005],{"class":49},"\u002F\u002F use Math.addExact etc. from Java):\n",[43,1007,1008,1011,1014,1017,1020,1022],{"class":45,"line":705},[43,1009,1010],{"class":62},"import",[43,1012,1013],{"class":238}," scala",[43,1015,1016],{"class":130},".",[43,1018,1019],{"class":238},"util",[43,1021,1016],{"class":130},[43,1023,1024],{"class":238},"Try\n",[43,1026,1027,1029,1032,1034,1036,1038,1040,1042,1044,1046,1048,1050,1052,1055,1057,1059,1061,1063,1065,1068,1071],{"class":45,"line":731},[43,1028,235],{"class":62},[43,1030,1031],{"class":238}," safeAdd",[43,1033,242],{"class":130},[43,1035,566],{"class":69},[43,1037,248],{"class":130},[43,1039,257],{"class":238},[43,1041,486],{"class":130},[43,1043,575],{"class":69},[43,1045,248],{"class":130},[43,1047,257],{"class":238},[43,1049,582],{"class":130},[43,1051,263],{"class":62},[43,1053,1054],{"class":238}," Try",[43,1056,254],{"class":130},[43,1058,257],{"class":238},[43,1060,473],{"class":130},[43,1062,476],{"class":62},[43,1064,1054],{"class":238},[43,1066,1067],{"class":130},"(java.lang.",[43,1069,1070],{"class":238},"Math",[43,1072,1073],{"class":130},".addExact(a, b))\n",[43,1075,1076,1079,1081,1083,1086,1088,1090,1093],{"class":45,"line":737},[43,1077,1078],{"class":130},"safeAdd(",[43,1080,257],{"class":238},[43,1082,1016],{"class":130},[43,1084,1085],{"class":238},"MaxValue",[43,1087,486],{"class":130},[43,1089,483],{"class":76},[43,1091,1092],{"class":130},")                  ",[43,1094,1095],{"class":49},"\u002F\u002F Failure(ArithmeticException: integer overflow)\n",[15,1097,1099],{"id":1098},"floating-point-ieee-754-gotchas","Floating-Point — IEEE 754 Gotchas",[31,1101,1102],{"language":33},[35,1103,1105],{"className":37,"code":1104,"language":33,"meta":39,"style":39},"\u002F\u002F NaN is NOT equal to itself — the #1 floating-point trap\nval nan = 0.0 \u002F 0.0                       \u002F\u002F → NaN\nnan == nan                                \u002F\u002F → false (!!)\nnan.isNaN                                 \u002F\u002F → true (always use isNaN for NaN checks)\n\n\u002F\u002F -0.0 vs 0.0\n(-0.0) == 0.0                             \u002F\u002F → true (IEEE says they're equal)\n1.0 \u002F (-0.0)                              \u002F\u002F → -Infinity (sign matters for division)\njava.lang.Double.compare(-0.0, 0.0) != 0  \u002F\u002F → true (compare distinguishes them)\n\n\u002F\u002F 0.1 + 0.2 ≠ 0.3 — binary representation of 0.1 is inexact\n0.1 + 0.2 == 0.3                          \u002F\u002F → false\nBigDecimal(\"0.1\") + BigDecimal(\"0.2\") == BigDecimal(\"0.3\")  \u002F\u002F → true\n\n\u002F\u002F Epsilon comparison for float equality:\ndef approxEq(a: Double, b: Double, eps: Double = 1e-9): Boolean =\n  math.abs(a - b) \u003C eps                   \u002F\u002F works for normal values, NOT for NaN\u002FInf\napproxEq(0.1 + 0.2, 0.3)                  \u002F\u002F → true\n",[19,1106,1107,1112,1132,1146,1154,1158,1163,1182,1201,1230,1234,1239,1258,1293,1297,1302,1348,1367],{"__ignoreMap":39},[43,1108,1109],{"class":45,"line":46},[43,1110,1111],{"class":49},"\u002F\u002F NaN is NOT equal to itself — the #1 floating-point trap\n",[43,1113,1114,1116,1119,1121,1124,1127,1129],{"class":45,"line":53},[43,1115,21],{"class":62},[43,1117,1118],{"class":69}," nan",[43,1120,73],{"class":62},[43,1122,1123],{"class":76}," 0.0",[43,1125,1126],{"class":62}," \u002F",[43,1128,1123],{"class":76},[43,1130,1131],{"class":49},"                       \u002F\u002F → NaN\n",[43,1133,1134,1137,1140,1143],{"class":45,"line":59},[43,1135,1136],{"class":130},"nan ",[43,1138,1139],{"class":62},"==",[43,1141,1142],{"class":130}," nan                                ",[43,1144,1145],{"class":49},"\u002F\u002F → false (!!)\n",[43,1147,1148,1151],{"class":45,"line":83},[43,1149,1150],{"class":130},"nan.isNaN                                 ",[43,1152,1153],{"class":49},"\u002F\u002F → true (always use isNaN for NaN checks)\n",[43,1155,1156],{"class":45,"line":89},[43,1157,109],{"emptyLinePlaceholder":108},[43,1159,1160],{"class":45,"line":105},[43,1161,1162],{"class":49},"\u002F\u002F -0.0 vs 0.0\n",[43,1164,1165,1167,1170,1173,1175,1177,1179],{"class":45,"line":112},[43,1166,242],{"class":130},[43,1168,1169],{"class":62},"-",[43,1171,1172],{"class":76},"0.0",[43,1174,544],{"class":130},[43,1176,1139],{"class":62},[43,1178,1123],{"class":76},[43,1180,1181],{"class":49},"                             \u002F\u002F → true (IEEE says they're equal)\n",[43,1183,1184,1187,1189,1191,1193,1195,1198],{"class":45,"line":118},[43,1185,1186],{"class":76},"1.0",[43,1188,1126],{"class":62},[43,1190,667],{"class":130},[43,1192,1169],{"class":62},[43,1194,1172],{"class":76},[43,1196,1197],{"class":130},")                              ",[43,1199,1200],{"class":49},"\u002F\u002F → -Infinity (sign matters for division)\n",[43,1202,1203,1206,1208,1211,1213,1215,1217,1219,1221,1224,1227],{"class":45,"line":124},[43,1204,1205],{"class":130},"java.lang.",[43,1207,541],{"class":238},[43,1209,1210],{"class":130},".compare(",[43,1212,1169],{"class":62},[43,1214,1172],{"class":76},[43,1216,486],{"class":130},[43,1218,1172],{"class":76},[43,1220,544],{"class":130},[43,1222,1223],{"class":62},"!=",[43,1225,1226],{"class":76}," 0",[43,1228,1229],{"class":49},"  \u002F\u002F → true (compare distinguishes them)\n",[43,1231,1232],{"class":45,"line":147},[43,1233,109],{"emptyLinePlaceholder":108},[43,1235,1236],{"class":45,"line":153},[43,1237,1238],{"class":49},"\u002F\u002F 0.1 + 0.2 ≠ 0.3 — binary representation of 0.1 is inexact\n",[43,1240,1241,1244,1246,1249,1252,1255],{"class":45,"line":158},[43,1242,1243],{"class":76},"0.1",[43,1245,910],{"class":62},[43,1247,1248],{"class":76}," 0.2",[43,1250,1251],{"class":62}," ==",[43,1253,1254],{"class":76}," 0.3",[43,1256,1257],{"class":49},"                          \u002F\u002F → false\n",[43,1259,1260,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1288,1290],{"class":45,"line":164},[43,1261,1262],{"class":238},"BigDecimal",[43,1264,242],{"class":130},[43,1266,963],{"class":942},[43,1268,544],{"class":130},[43,1270,968],{"class":62},[43,1272,958],{"class":238},[43,1274,242],{"class":130},[43,1276,975],{"class":942},[43,1278,544],{"class":130},[43,1280,1139],{"class":62},[43,1282,958],{"class":238},[43,1284,242],{"class":130},[43,1286,1287],{"class":942},"\"0.3\"",[43,1289,978],{"class":130},[43,1291,1292],{"class":49},"\u002F\u002F → true\n",[43,1294,1295],{"class":45,"line":170},[43,1296,109],{"emptyLinePlaceholder":108},[43,1298,1299],{"class":45,"line":176},[43,1300,1301],{"class":49},"\u002F\u002F Epsilon comparison for float equality:\n",[43,1303,1304,1306,1309,1311,1313,1315,1317,1319,1321,1323,1325,1327,1330,1332,1334,1336,1339,1341,1343,1346],{"class":45,"line":182},[43,1305,235],{"class":62},[43,1307,1308],{"class":238}," approxEq",[43,1310,242],{"class":130},[43,1312,566],{"class":69},[43,1314,248],{"class":130},[43,1316,541],{"class":238},[43,1318,486],{"class":130},[43,1320,575],{"class":69},[43,1322,248],{"class":130},[43,1324,541],{"class":238},[43,1326,486],{"class":130},[43,1328,1329],{"class":69},"eps",[43,1331,248],{"class":130},[43,1333,541],{"class":238},[43,1335,73],{"class":62},[43,1337,1338],{"class":76}," 1e-9",[43,1340,582],{"class":130},[43,1342,263],{"class":62},[43,1344,1345],{"class":238}," Boolean",[43,1347,269],{"class":62},[43,1349,1350,1353,1355,1358,1361,1364],{"class":45,"line":188},[43,1351,1352],{"class":130},"  math.abs(a ",[43,1354,1169],{"class":62},[43,1356,1357],{"class":130}," b) ",[43,1359,1360],{"class":62},"\u003C",[43,1362,1363],{"class":130}," eps                   ",[43,1365,1366],{"class":49},"\u002F\u002F works for normal values, NOT for NaN\u002FInf\n",[43,1368,1369,1372,1374,1376,1378,1380,1383,1385],{"class":45,"line":207},[43,1370,1371],{"class":130},"approxEq(",[43,1373,1243],{"class":76},[43,1375,910],{"class":62},[43,1377,1248],{"class":76},[43,1379,486],{"class":130},[43,1381,1382],{"class":76},"0.3",[43,1384,1092],{"class":130},[43,1386,1292],{"class":49},[15,1388,1390,1391,1394,1395,22,1398],{"id":1389},"type-hierarchy-any-anyval-anyref","Type Hierarchy — ",[19,1392,1393],{},"Any"," → ",[19,1396,1397],{},"AnyVal",[19,1399,1400],{},"AnyRef",[31,1402,1404,1411,1597,1601,1848,1852,2090,2097,2289,2293,2304,2342,2351,2520,2529,2533,2549,2563,2684,2702,2744,2748,2759],{"language":1403},"text",[35,1405,1409],{"className":1406,"code":1408,"language":1403,"meta":39},[1407],"language-text","                              Any\n                 ┌─────────────┴──────────────┐\n               AnyVal                       AnyRef\n          (value types)               (reference types = java.lang.Object)\n    ┌───┬───┬───┬───┬───┬───┐           ┌─────┴─────┐\n   Int Long Double Float Char Byte    String   user classes\n    Boolean Unit                                 (all extend AnyRef)\n    \n    Null  ←─ extends all AnyRef types (can be assigned to any reference)\n    Nothing ←─ extends ALL types (bottom type — function never returns)\n",[19,1410,1408],{"__ignoreMap":39},[31,1412,1413],{"language":33},[35,1414,1416],{"className":37,"code":1415,"language":33,"meta":39,"style":39},"\u002F\u002F Unit = \"no meaningful value\" — corresponds to Java's void but IS a type\ndef log(msg: String): Unit = println(msg)  \u002F\u002F → returns scala.runtime.BoxedUnit, a singleton\nval u: Unit = ()                           \u002F\u002F () is the sole Unit value (BoxedUnit.INSTANCE)\n\n\u002F\u002F Nothing — the bottom type. A function returning Nothing never returns normally.\ndef fail(msg: String): Nothing = throw new Exception(msg)  \u002F\u002F Nothing is subtype of EVERY type\ndef uncheckedDefault[T]: T = ???           \u002F\u002F ??? = Predef.??? → throws NotImplementedError\n\n\u002F\u002F Null — the type of null. Subtype of all AnyRef types (NOT AnyVal in Scala 3!)\nval x: String = null                       \u002F\u002F OK: Null \u003C: String\n\u002F\u002F val y: Int = null                        \u002F\u002F ERROR in Scala 3: Null is not a subtype of Int\n\n\u002F\u002F Scala 3 explicit null: with -explicitNulls flag, T no longer includes null\n\u002F\u002F   → must write T | Null for nullable references. Forces null-safety at type level.\n",[19,1417,1418,1423,1455,1474,1478,1483,1521,1547,1551,1556,1575,1583,1587,1592],{"__ignoreMap":39},[43,1419,1420],{"class":45,"line":46},[43,1421,1422],{"class":49},"\u002F\u002F Unit = \"no meaningful value\" — corresponds to Java's void but IS a type\n",[43,1424,1425,1427,1430,1432,1435,1437,1440,1442,1444,1447,1449,1452],{"class":45,"line":53},[43,1426,235],{"class":62},[43,1428,1429],{"class":238}," log",[43,1431,242],{"class":130},[43,1433,1434],{"class":69},"msg",[43,1436,248],{"class":130},[43,1438,1439],{"class":238},"String",[43,1441,582],{"class":130},[43,1443,263],{"class":62},[43,1445,1446],{"class":238}," Unit",[43,1448,73],{"class":62},[43,1450,1451],{"class":130}," println(msg)  ",[43,1453,1454],{"class":49},"\u002F\u002F → returns scala.runtime.BoxedUnit, a singleton\n",[43,1456,1457,1459,1462,1464,1466,1468,1471],{"class":45,"line":59},[43,1458,21],{"class":62},[43,1460,1461],{"class":69}," u",[43,1463,263],{"class":62},[43,1465,1446],{"class":238},[43,1467,73],{"class":62},[43,1469,1470],{"class":130}," ()                           ",[43,1472,1473],{"class":49},"\u002F\u002F () is the sole Unit value (BoxedUnit.INSTANCE)\n",[43,1475,1476],{"class":45,"line":83},[43,1477,109],{"emptyLinePlaceholder":108},[43,1479,1480],{"class":45,"line":89},[43,1481,1482],{"class":49},"\u002F\u002F Nothing — the bottom type. A function returning Nothing never returns normally.\n",[43,1484,1485,1487,1490,1492,1494,1496,1498,1500,1502,1505,1507,1510,1512,1515,1518],{"class":45,"line":105},[43,1486,235],{"class":62},[43,1488,1489],{"class":238}," fail",[43,1491,242],{"class":130},[43,1493,1434],{"class":69},[43,1495,248],{"class":130},[43,1497,1439],{"class":238},[43,1499,582],{"class":130},[43,1501,263],{"class":62},[43,1503,1504],{"class":238}," Nothing",[43,1506,73],{"class":62},[43,1508,1509],{"class":62}," throw",[43,1511,284],{"class":62},[43,1513,1514],{"class":238}," Exception",[43,1516,1517],{"class":130},"(msg)  ",[43,1519,1520],{"class":49},"\u002F\u002F Nothing is subtype of EVERY type\n",[43,1522,1523,1525,1528,1530,1532,1534,1536,1539,1541,1544],{"class":45,"line":112},[43,1524,235],{"class":62},[43,1526,1527],{"class":238}," uncheckedDefault",[43,1529,254],{"class":130},[43,1531,547],{"class":238},[43,1533,550],{"class":130},[43,1535,263],{"class":62},[43,1537,1538],{"class":238}," T",[43,1540,73],{"class":62},[43,1542,1543],{"class":62}," ???",[43,1545,1546],{"class":49},"           \u002F\u002F ??? = Predef.??? → throws NotImplementedError\n",[43,1548,1549],{"class":45,"line":118},[43,1550,109],{"emptyLinePlaceholder":108},[43,1552,1553],{"class":45,"line":124},[43,1554,1555],{"class":49},"\u002F\u002F Null — the type of null. Subtype of all AnyRef types (NOT AnyVal in Scala 3!)\n",[43,1557,1558,1560,1562,1564,1567,1569,1572],{"class":45,"line":147},[43,1559,21],{"class":62},[43,1561,403],{"class":69},[43,1563,263],{"class":62},[43,1565,1566],{"class":238}," String",[43,1568,73],{"class":62},[43,1570,1571],{"class":76}," null",[43,1573,1574],{"class":49},"                       \u002F\u002F OK: Null \u003C: String\n",[43,1576,1577,1580],{"class":45,"line":153},[43,1578,1579],{"class":49},"\u002F\u002F val y: Int = null",[43,1581,1582],{"class":49},"                        \u002F\u002F ERROR in Scala 3: Null is not a subtype of Int\n",[43,1584,1585],{"class":45,"line":158},[43,1586,109],{"emptyLinePlaceholder":108},[43,1588,1589],{"class":45,"line":164},[43,1590,1591],{"class":49},"\u002F\u002F Scala 3 explicit null: with -explicitNulls flag, T no longer includes null\n",[43,1593,1594],{"class":45,"line":170},[43,1595,1596],{"class":49},"\u002F\u002F   → must write T | Null for nullable references. Forces null-safety at type level.\n",[15,1598,1600],{"id":1599},"value-classes-zero-cost-wrappers","Value Classes — Zero-Cost Wrappers",[31,1602,1603],{"language":33},[35,1604,1606],{"className":37,"code":1605,"language":33,"meta":39,"style":39},"\u002F\u002F `AnyVal` subclass with single val field → inlined at use sites, zero runtime allocation\nfinal class UserId(val value: Long) extends AnyVal:\n  override def toString = s\"UserId($value)\"\n\nfinal class EmailAddress private (val value: String) extends AnyVal:\n  def domain: String = value.dropWhile(_ != '@').tail\n\nobject EmailAddress:\n  def from(s: String): Option[EmailAddress] =\n    if s.matches(\"^[^@]+@[^@]+\\\\.[^@]+$\") then Some(new EmailAddress(s))\n    else None\n\n\u002F\u002F At runtime: UserId is just a long — no wrapper object on heap\n\u002F\u002F BUT: value classes box when used in:\n\u002F\u002F   - generic collections (List[UserId] → List[Object])\n\u002F\u002F   - stored in Option (Some(userId) → boxes)\n\u002F\u002F   - passed to generic methods\n\u002F\u002F   - used as array element (Array[UserId] → Object[])\n",[19,1607,1608,1613,1644,1668,1672,1702,1726,1730,1738,1771,1806,1814,1818,1823,1828,1833,1838,1843],{"__ignoreMap":39},[43,1609,1610],{"class":45,"line":46},[43,1611,1612],{"class":49},"\u002F\u002F `AnyVal` subclass with single val field → inlined at use sites, zero runtime allocation\n",[43,1614,1615,1617,1620,1623,1625,1627,1630,1632,1634,1636,1639,1642],{"class":45,"line":53},[43,1616,63],{"class":62},[43,1618,1619],{"class":62}," class",[43,1621,1622],{"class":238}," UserId",[43,1624,242],{"class":130},[43,1626,21],{"class":62},[43,1628,1629],{"class":69}," value",[43,1631,263],{"class":62},[43,1633,836],{"class":238},[43,1635,544],{"class":130},[43,1637,1638],{"class":62},"extends",[43,1640,1641],{"class":238}," AnyVal",[43,1643,553],{"class":62},[43,1645,1646,1649,1652,1655,1657,1659,1662,1665],{"class":45,"line":59},[43,1647,1648],{"class":62},"  override",[43,1650,1651],{"class":62}," def",[43,1653,1654],{"class":238}," toString",[43,1656,73],{"class":62},[43,1658,792],{"class":62},[43,1660,1661],{"class":942},"\"UserId(",[43,1663,1664],{"class":130},"$value",[43,1666,1667],{"class":942},")\"\n",[43,1669,1670],{"class":45,"line":83},[43,1671,109],{"emptyLinePlaceholder":108},[43,1673,1674,1676,1678,1681,1684,1686,1688,1690,1692,1694,1696,1698,1700],{"class":45,"line":89},[43,1675,63],{"class":62},[43,1677,1619],{"class":62},[43,1679,1680],{"class":238}," EmailAddress",[43,1682,1683],{"class":62}," private",[43,1685,667],{"class":130},[43,1687,21],{"class":62},[43,1689,1629],{"class":69},[43,1691,263],{"class":62},[43,1693,1566],{"class":238},[43,1695,544],{"class":130},[43,1697,1638],{"class":62},[43,1699,1641],{"class":238},[43,1701,553],{"class":62},[43,1703,1704,1706,1709,1711,1713,1715,1718,1720,1723],{"class":45,"line":105},[43,1705,558],{"class":62},[43,1707,1708],{"class":238}," domain",[43,1710,263],{"class":62},[43,1712,1566],{"class":238},[43,1714,73],{"class":62},[43,1716,1717],{"class":130}," value.dropWhile(_ ",[43,1719,1223],{"class":62},[43,1721,1722],{"class":76}," '@'",[43,1724,1725],{"class":130},").tail\n",[43,1727,1728],{"class":45,"line":112},[43,1729,109],{"emptyLinePlaceholder":108},[43,1731,1732,1734,1736],{"class":45,"line":118},[43,1733,606],{"class":62},[43,1735,1680],{"class":238},[43,1737,553],{"class":62},[43,1739,1740,1742,1745,1747,1750,1752,1754,1756,1758,1761,1763,1766,1768],{"class":45,"line":124},[43,1741,558],{"class":62},[43,1743,1744],{"class":238}," from",[43,1746,242],{"class":130},[43,1748,1749],{"class":69},"s",[43,1751,248],{"class":130},[43,1753,1439],{"class":238},[43,1755,582],{"class":130},[43,1757,263],{"class":62},[43,1759,1760],{"class":238}," Option",[43,1762,254],{"class":130},[43,1764,1765],{"class":238},"EmailAddress",[43,1767,473],{"class":130},[43,1769,1770],{"class":62},"=\n",[43,1772,1773,1776,1779,1782,1785,1788,1790,1793,1796,1798,1801,1803],{"class":45,"line":147},[43,1774,1775],{"class":62},"    if",[43,1777,1778],{"class":130}," s.matches(",[43,1780,1781],{"class":942},"\"^[^@]+@[^@]+",[43,1783,1784],{"class":76},"\\\\",[43,1786,1787],{"class":942},".[^@]+$\"",[43,1789,544],{"class":130},[43,1791,1792],{"class":62},"then",[43,1794,1795],{"class":238}," Some",[43,1797,242],{"class":130},[43,1799,1800],{"class":62},"new",[43,1802,1680],{"class":238},[43,1804,1805],{"class":130},"(s))\n",[43,1807,1808,1811],{"class":45,"line":153},[43,1809,1810],{"class":62},"    else",[43,1812,1813],{"class":238}," None\n",[43,1815,1816],{"class":45,"line":158},[43,1817,109],{"emptyLinePlaceholder":108},[43,1819,1820],{"class":45,"line":164},[43,1821,1822],{"class":49},"\u002F\u002F At runtime: UserId is just a long — no wrapper object on heap\n",[43,1824,1825],{"class":45,"line":170},[43,1826,1827],{"class":49},"\u002F\u002F BUT: value classes box when used in:\n",[43,1829,1830],{"class":45,"line":176},[43,1831,1832],{"class":49},"\u002F\u002F   - generic collections (List[UserId] → List[Object])\n",[43,1834,1835],{"class":45,"line":182},[43,1836,1837],{"class":49},"\u002F\u002F   - stored in Option (Some(userId) → boxes)\n",[43,1839,1840],{"class":45,"line":188},[43,1841,1842],{"class":49},"\u002F\u002F   - passed to generic methods\n",[43,1844,1845],{"class":45,"line":207},[43,1846,1847],{"class":49},"\u002F\u002F   - used as array element (Array[UserId] → Object[])\n",[15,1849,1851],{"id":1850},"tuples-product-types-allocation","Tuples — Product Types & Allocation",[31,1853,1854],{"language":33},[35,1855,1857],{"className":37,"code":1856,"language":33,"meta":39,"style":39},"\u002F\u002F Tuples are Product1..Product22 — each is a case class with _1, _2, ... fields\nval pair = (1, \"hello\")                   \u002F\u002F → scala.Tuple2[Int, String] = new Tuple2(1, \"hello\")\npair._1                                   \u002F\u002F → 1 (field access, no allocation)\npair(0)                                   \u002F\u002F → 1 (Scala 3: index access, still field access)\n\n\u002F\u002F Scala 3 tuple type arithmetic at compile time:\ntype T1 = (Int, String, Boolean)\ntype Head = T1.Head                       \u002F\u002F → Int (computed by the compiler, not runtime)\ntype Tail = T1.Tail                       \u002F\u002F → (String, Boolean)\ntype Concat = T1 *: (Double, Long)        \u002F\u002F → (Int, String, Boolean, Double, Long)\n\n\u002F\u002F Destructuring compiles to field access, not pattern matching:\nval (id, name) = (42, \"Alice\")            \u002F\u002F → val id = pair._1; val name = pair._2\n\n\u002F\u002F ❌ AVOID: creating tuples in hot loops — each tuple is a heap allocation\n\u002F\u002F ✅ PREFER: case classes (also allocate, but clearer) or opaque types for primitives\ncase class Hit(id: Long, score: Double)   \u002F\u002F 1 allocation, but readable + pattern-matchable\n",[19,1858,1859,1864,1888,1896,1909,1913,1918,1943,1962,1981,2009,2013,2018,2042,2046,2051,2056],{"__ignoreMap":39},[43,1860,1861],{"class":45,"line":46},[43,1862,1863],{"class":49},"\u002F\u002F Tuples are Product1..Product22 — each is a case class with _1, _2, ... fields\n",[43,1865,1866,1868,1871,1873,1875,1877,1879,1882,1885],{"class":45,"line":53},[43,1867,21],{"class":62},[43,1869,1870],{"class":69}," pair",[43,1872,73],{"class":62},[43,1874,667],{"class":130},[43,1876,483],{"class":76},[43,1878,486],{"class":130},[43,1880,1881],{"class":942},"\"hello\"",[43,1883,1884],{"class":130},")                   ",[43,1886,1887],{"class":49},"\u002F\u002F → scala.Tuple2[Int, String] = new Tuple2(1, \"hello\")\n",[43,1889,1890,1893],{"class":45,"line":59},[43,1891,1892],{"class":130},"pair._1                                   ",[43,1894,1895],{"class":49},"\u002F\u002F → 1 (field access, no allocation)\n",[43,1897,1898,1901,1903,1906],{"class":45,"line":83},[43,1899,1900],{"class":130},"pair(",[43,1902,301],{"class":76},[43,1904,1905],{"class":130},")                                   ",[43,1907,1908],{"class":49},"\u002F\u002F → 1 (Scala 3: index access, still field access)\n",[43,1910,1911],{"class":45,"line":89},[43,1912,109],{"emptyLinePlaceholder":108},[43,1914,1915],{"class":45,"line":105},[43,1916,1917],{"class":49},"\u002F\u002F Scala 3 tuple type arithmetic at compile time:\n",[43,1919,1920,1923,1926,1928,1930,1932,1934,1936,1938,1941],{"class":45,"line":112},[43,1921,1922],{"class":62},"type",[43,1924,1925],{"class":238}," T1",[43,1927,73],{"class":62},[43,1929,667],{"class":130},[43,1931,257],{"class":238},[43,1933,486],{"class":130},[43,1935,1439],{"class":238},[43,1937,486],{"class":130},[43,1939,1940],{"class":238},"Boolean",[43,1942,946],{"class":130},[43,1944,1945,1947,1950,1952,1954,1956,1959],{"class":45,"line":118},[43,1946,1922],{"class":62},[43,1948,1949],{"class":238}," Head",[43,1951,73],{"class":62},[43,1953,1925],{"class":238},[43,1955,1016],{"class":130},[43,1957,1958],{"class":238},"Head",[43,1960,1961],{"class":49},"                       \u002F\u002F → Int (computed by the compiler, not runtime)\n",[43,1963,1964,1966,1969,1971,1973,1975,1978],{"class":45,"line":124},[43,1965,1922],{"class":62},[43,1967,1968],{"class":238}," Tail",[43,1970,73],{"class":62},[43,1972,1925],{"class":238},[43,1974,1016],{"class":130},[43,1976,1977],{"class":238},"Tail",[43,1979,1980],{"class":49},"                       \u002F\u002F → (String, Boolean)\n",[43,1982,1983,1985,1988,1990,1992,1995,1997,1999,2001,2003,2006],{"class":45,"line":147},[43,1984,1922],{"class":62},[43,1986,1987],{"class":238}," Concat",[43,1989,73],{"class":62},[43,1991,1925],{"class":238},[43,1993,1994],{"class":62}," *:",[43,1996,667],{"class":130},[43,1998,541],{"class":238},[43,2000,486],{"class":130},[43,2002,536],{"class":238},[43,2004,2005],{"class":130},")        ",[43,2007,2008],{"class":49},"\u002F\u002F → (Int, String, Boolean, Double, Long)\n",[43,2010,2011],{"class":45,"line":153},[43,2012,109],{"emptyLinePlaceholder":108},[43,2014,2015],{"class":45,"line":158},[43,2016,2017],{"class":49},"\u002F\u002F Destructuring compiles to field access, not pattern matching:\n",[43,2019,2020,2022,2025,2027,2029,2032,2034,2037,2039],{"class":45,"line":164},[43,2021,21],{"class":62},[43,2023,2024],{"class":130}," (id, name) ",[43,2026,476],{"class":62},[43,2028,667],{"class":130},[43,2030,2031],{"class":76},"42",[43,2033,486],{"class":130},[43,2035,2036],{"class":942},"\"Alice\"",[43,2038,442],{"class":130},[43,2040,2041],{"class":49},"\u002F\u002F → val id = pair._1; val name = pair._2\n",[43,2043,2044],{"class":45,"line":170},[43,2045,109],{"emptyLinePlaceholder":108},[43,2047,2048],{"class":45,"line":176},[43,2049,2050],{"class":49},"\u002F\u002F ❌ AVOID: creating tuples in hot loops — each tuple is a heap allocation\n",[43,2052,2053],{"class":45,"line":182},[43,2054,2055],{"class":49},"\u002F\u002F ✅ PREFER: case classes (also allocate, but clearer) or opaque types for primitives\n",[43,2057,2058,2061,2063,2066,2068,2071,2073,2075,2077,2080,2082,2084,2087],{"class":45,"line":188},[43,2059,2060],{"class":62},"case",[43,2062,1619],{"class":62},[43,2064,2065],{"class":238}," Hit",[43,2067,242],{"class":130},[43,2069,2070],{"class":69},"id",[43,2072,248],{"class":130},[43,2074,536],{"class":238},[43,2076,486],{"class":130},[43,2078,2079],{"class":69},"score",[43,2081,248],{"class":130},[43,2083,541],{"class":238},[43,2085,2086],{"class":130},")   ",[43,2088,2089],{"class":49},"\u002F\u002F 1 allocation, but readable + pattern-matchable\n",[15,2091,2093,2096],{"id":2092},"optiont-null-safety-without-null",[19,2094,2095],{},"Option[T]"," — Null Safety Without Null",[31,2098,2099],{"language":33},[35,2100,2102],{"className":37,"code":2101,"language":33,"meta":39,"style":39},"\u002F\u002F Option is a sealed abstract type:\n\u002F\u002F   sealed abstract class Option[+T]\n\u002F\u002F   final case class Some[+T](value: T) extends Option[T]\n\u002F\u002F   case object None extends Option[Nothing]\n\u002F\u002F\n\u002F\u002F Some(value) → 1 allocation (Some is a case class)\n\u002F\u002F None        → singleton, zero allocation (just a reference)\n\n\u002F\u002F Option.apply — converts nullable Java return to Option (null-safe)\ndef findUser(id: Long): Option[User] = Option(userDao.findById(id))\n\u002F\u002F   userDao returns null → Option(null) = None (no NPE)\n\u002F\u002F   userDao returns User → Option(user) = Some(user)\n\n\u002F\u002F Chaining with for-comprehension desugars to flatMap\u002Fmap:\nfor\n  user \u003C- findUser(42)\n  email \u003C- user.email           \u002F\u002F email is Option[String]\nyield email\n\u002F\u002F Desugars to:\n\u002F\u002F   findUser(42).flatMap(user => user.email.map(email => email))\n\n\u002F\u002F Anti-pattern: using .get on Option\n\u002F\u002F   someValue.get     \u002F\u002F throws NoSuchElementException if None\n\u002F\u002F   someValue.getOrElse(default)   \u002F\u002F ✅ safe\n\u002F\u002F   someValue.orElse(computeOther) \u002F\u002F ✅ fallback to another Option\n",[19,2103,2104,2109,2114,2119,2124,2129,2134,2139,2143,2148,2183,2188,2193,2197,2202,2207,2222,2235,2243,2248,2253,2257,2262,2271,2280],{"__ignoreMap":39},[43,2105,2106],{"class":45,"line":46},[43,2107,2108],{"class":49},"\u002F\u002F Option is a sealed abstract type:\n",[43,2110,2111],{"class":45,"line":53},[43,2112,2113],{"class":49},"\u002F\u002F   sealed abstract class Option[+T]\n",[43,2115,2116],{"class":45,"line":59},[43,2117,2118],{"class":49},"\u002F\u002F   final case class Some[+T](value: T) extends Option[T]\n",[43,2120,2121],{"class":45,"line":83},[43,2122,2123],{"class":49},"\u002F\u002F   case object None extends Option[Nothing]\n",[43,2125,2126],{"class":45,"line":89},[43,2127,2128],{"class":49},"\u002F\u002F\n",[43,2130,2131],{"class":45,"line":105},[43,2132,2133],{"class":49},"\u002F\u002F Some(value) → 1 allocation (Some is a case class)\n",[43,2135,2136],{"class":45,"line":112},[43,2137,2138],{"class":49},"\u002F\u002F None        → singleton, zero allocation (just a reference)\n",[43,2140,2141],{"class":45,"line":118},[43,2142,109],{"emptyLinePlaceholder":108},[43,2144,2145],{"class":45,"line":124},[43,2146,2147],{"class":49},"\u002F\u002F Option.apply — converts nullable Java return to Option (null-safe)\n",[43,2149,2150,2152,2155,2157,2159,2161,2163,2165,2167,2169,2171,2174,2176,2178,2180],{"class":45,"line":147},[43,2151,235],{"class":62},[43,2153,2154],{"class":238}," findUser",[43,2156,242],{"class":130},[43,2158,2070],{"class":69},[43,2160,248],{"class":130},[43,2162,536],{"class":238},[43,2164,582],{"class":130},[43,2166,263],{"class":62},[43,2168,1760],{"class":238},[43,2170,254],{"class":130},[43,2172,2173],{"class":238},"User",[43,2175,473],{"class":130},[43,2177,476],{"class":62},[43,2179,1760],{"class":238},[43,2181,2182],{"class":130},"(userDao.findById(id))\n",[43,2184,2185],{"class":45,"line":153},[43,2186,2187],{"class":49},"\u002F\u002F   userDao returns null → Option(null) = None (no NPE)\n",[43,2189,2190],{"class":45,"line":158},[43,2191,2192],{"class":49},"\u002F\u002F   userDao returns User → Option(user) = Some(user)\n",[43,2194,2195],{"class":45,"line":164},[43,2196,109],{"emptyLinePlaceholder":108},[43,2198,2199],{"class":45,"line":170},[43,2200,2201],{"class":49},"\u002F\u002F Chaining with for-comprehension desugars to flatMap\u002Fmap:\n",[43,2203,2204],{"class":45,"line":176},[43,2205,2206],{"class":62},"for\n",[43,2208,2209,2212,2215,2218,2220],{"class":45,"line":182},[43,2210,2211],{"class":130},"  user ",[43,2213,2214],{"class":62},"\u003C-",[43,2216,2217],{"class":130}," findUser(",[43,2219,2031],{"class":76},[43,2221,946],{"class":130},[43,2223,2224,2227,2229,2232],{"class":45,"line":188},[43,2225,2226],{"class":130},"  email ",[43,2228,2214],{"class":62},[43,2230,2231],{"class":130}," user.email           ",[43,2233,2234],{"class":49},"\u002F\u002F email is Option[String]\n",[43,2236,2237,2240],{"class":45,"line":207},[43,2238,2239],{"class":62},"yield",[43,2241,2242],{"class":130}," email\n",[43,2244,2245],{"class":45,"line":700},[43,2246,2247],{"class":49},"\u002F\u002F Desugars to:\n",[43,2249,2250],{"class":45,"line":705},[43,2251,2252],{"class":49},"\u002F\u002F   findUser(42).flatMap(user => user.email.map(email => email))\n",[43,2254,2255],{"class":45,"line":731},[43,2256,109],{"emptyLinePlaceholder":108},[43,2258,2259],{"class":45,"line":737},[43,2260,2261],{"class":49},"\u002F\u002F Anti-pattern: using .get on Option\n",[43,2263,2265,2268],{"class":45,"line":2264},23,[43,2266,2267],{"class":49},"\u002F\u002F   someValue.get",[43,2269,2270],{"class":49},"     \u002F\u002F throws NoSuchElementException if None\n",[43,2272,2274,2277],{"class":45,"line":2273},24,[43,2275,2276],{"class":49},"\u002F\u002F   someValue.getOrElse(default)",[43,2278,2279],{"class":49},"   \u002F\u002F ✅ safe\n",[43,2281,2283,2286],{"class":45,"line":2282},25,[43,2284,2285],{"class":49},"\u002F\u002F   someValue.orElse(computeOther)",[43,2287,2288],{"class":49}," \u002F\u002F ✅ fallback to another Option\n",[15,2290,2292],{"id":2291},"tips-tricks","💡 Tips & Tricks",[2294,2295,2296,2303],"p",{},[2297,2298,2299,2302],"strong",{},[19,2300,2301],{},"final val"," for compile-time constants",": When the RHS is a literal, the compiler inlines it at every use site — no field read, no bytecode for the val.",[31,2305,2306],{"language":33},[35,2307,2309],{"className":37,"code":2308,"language":33,"meta":39,"style":39},"final val BUFFER_SIZE = 4096              \u002F\u002F inlined as 4096 literal at every use\nval bufferSize = 4096                     \u002F\u002F NOT inlined — field read at each use\n",[19,2310,2311,2328],{"__ignoreMap":39},[43,2312,2313,2315,2317,2320,2322,2325],{"class":45,"line":46},[43,2314,63],{"class":62},[43,2316,66],{"class":62},[43,2318,2319],{"class":69}," BUFFER_SIZE",[43,2321,73],{"class":62},[43,2323,2324],{"class":76}," 4096",[43,2326,2327],{"class":49},"              \u002F\u002F inlined as 4096 literal at every use\n",[43,2329,2330,2332,2335,2337,2339],{"class":45,"line":53},[43,2331,21],{"class":62},[43,2333,2334],{"class":69}," bufferSize",[43,2336,73],{"class":62},[43,2338,2324],{"class":76},[43,2340,2341],{"class":49},"                     \u002F\u002F NOT inlined — field read at each use\n",[2294,2343,2344,2350],{},[2297,2345,2346,2349],{},[19,2347,2348],{},"opaque type"," for zero-cost domain types",": Replace value classes with opaque types in Scala 3 — no wrapper, no boxing, full type safety.",[31,2352,2353],{"language":33},[35,2354,2356],{"className":37,"code":2355,"language":33,"meta":39,"style":39},"object Quantities:\n  opaque type Kelvin = Double\n  opaque type Celsius = Double\n  def kelvin(d: Double): Kelvin = d\n  def celsius(d: Double): Celsius = d\n  extension (k: Kelvin) def toCelsius: Celsius = celsius(k - 273.15)\n\nval temp: Kelvin = Quantities.kelvin(300.0)  \u002F\u002F runtime: just 300.0 (double on stack)\n\u002F\u002F val wrong: Celsius = temp                 \u002F\u002F compile error — type-safe!\n",[19,2357,2358,2367,2381,2394,2420,2445,2482,2486,2512],{"__ignoreMap":39},[43,2359,2360,2362,2365],{"class":45,"line":46},[43,2361,606],{"class":62},[43,2363,2364],{"class":238}," Quantities",[43,2366,553],{"class":62},[43,2368,2369,2371,2373,2376,2378],{"class":45,"line":53},[43,2370,616],{"class":62},[43,2372,619],{"class":62},[43,2374,2375],{"class":238}," Kelvin",[43,2377,73],{"class":62},[43,2379,2380],{"class":238}," Double\n",[43,2382,2383,2385,2387,2390,2392],{"class":45,"line":59},[43,2384,616],{"class":62},[43,2386,619],{"class":62},[43,2388,2389],{"class":238}," Celsius",[43,2391,73],{"class":62},[43,2393,2380],{"class":238},[43,2395,2396,2398,2401,2403,2405,2407,2409,2411,2413,2415,2417],{"class":45,"line":83},[43,2397,558],{"class":62},[43,2399,2400],{"class":238}," kelvin",[43,2402,242],{"class":130},[43,2404,641],{"class":69},[43,2406,248],{"class":130},[43,2408,541],{"class":238},[43,2410,582],{"class":130},[43,2412,263],{"class":62},[43,2414,2375],{"class":238},[43,2416,73],{"class":62},[43,2418,2419],{"class":130}," d\n",[43,2421,2422,2424,2427,2429,2431,2433,2435,2437,2439,2441,2443],{"class":45,"line":89},[43,2423,558],{"class":62},[43,2425,2426],{"class":238}," celsius",[43,2428,242],{"class":130},[43,2430,641],{"class":69},[43,2432,248],{"class":130},[43,2434,541],{"class":238},[43,2436,582],{"class":130},[43,2438,263],{"class":62},[43,2440,2389],{"class":238},[43,2442,73],{"class":62},[43,2444,2419],{"class":130},[43,2446,2447,2449,2451,2454,2456,2459,2461,2463,2466,2468,2470,2472,2475,2477,2480],{"class":45,"line":105},[43,2448,664],{"class":62},[43,2450,667],{"class":130},[43,2452,2453],{"class":69},"k",[43,2455,248],{"class":130},[43,2457,2458],{"class":238},"Kelvin",[43,2460,544],{"class":130},[43,2462,235],{"class":62},[43,2464,2465],{"class":238}," toCelsius",[43,2467,263],{"class":62},[43,2469,2389],{"class":238},[43,2471,73],{"class":62},[43,2473,2474],{"class":130}," celsius(k ",[43,2476,1169],{"class":62},[43,2478,2479],{"class":76}," 273.15",[43,2481,946],{"class":130},[43,2483,2484],{"class":45,"line":112},[43,2485,109],{"emptyLinePlaceholder":108},[43,2487,2488,2490,2493,2495,2497,2499,2501,2504,2507,2509],{"class":45,"line":118},[43,2489,21],{"class":62},[43,2491,2492],{"class":69}," temp",[43,2494,263],{"class":62},[43,2496,2375],{"class":238},[43,2498,73],{"class":62},[43,2500,2364],{"class":238},[43,2502,2503],{"class":130},".kelvin(",[43,2505,2506],{"class":76},"300.0",[43,2508,978],{"class":130},[43,2510,2511],{"class":49},"\u002F\u002F runtime: just 300.0 (double on stack)\n",[43,2513,2514,2517],{"class":45,"line":124},[43,2515,2516],{"class":49},"\u002F\u002F val wrong: Celsius = temp",[43,2518,2519],{"class":49},"                 \u002F\u002F compile error — type-safe!\n",[2294,2521,2522,2528],{},[2297,2523,2524,2527],{},[19,2525,2526],{},"@targetName"," for interop",": Control the JVM-level method name to avoid collisions or to match Java conventions.",[15,2530,2532],{"id":2531},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[2294,2534,2535,2540,2541,2544,2545,2548],{},[2297,2536,2537,2539],{},[19,2538,28],{}," + circular dependency = deadlock",": If ",[19,2542,2543],{},"lazy val a"," depends on ",[19,2546,2547],{},"lazy val b"," and vice versa, the first access deadlocks (Scala 2: synchronized on object; Scala 3: per-field lock but still deadlockable).",[2294,2550,2551,2559,2560,2562],{},[2297,2552,2553,2555,2556,2558],{},[19,2554,21],{}," in ",[19,2557,519],{}," = abstract override complexity",": A ",[19,2561,21],{}," in a trait is an abstract field. If a class initializes it, trait linearization determines initialization order — subtle NPEs if order is wrong.",[31,2564,2565],{"language":33},[35,2566,2568],{"className":37,"code":2567,"language":33,"meta":39,"style":39},"trait Base:\n  val name: String                         \u002F\u002F abstract — no value yet\n  val greeting = s\"Hello, $name\"           \u002F\u002F NPE risk! name may be null during init\n\nclass Impl extends Base:\n  override val name = \"Alice\"              \u002F\u002F order: Base.greeting init BEFORE name set → NPE\n\u002F\u002F Fix: use 'lazy val greeting' or 'def greeting' or early-init:\nclass ImplSafe extends Base:\n  override val name = \"Alice\"              \u002F\u002F field init order: name first if declared before super\n",[19,2569,2570,2579,2593,2616,2620,2635,2651,2656,2669],{"__ignoreMap":39},[43,2571,2572,2574,2577],{"class":45,"line":46},[43,2573,519],{"class":62},[43,2575,2576],{"class":238}," Base",[43,2578,553],{"class":62},[43,2580,2581,2583,2586,2588,2590],{"class":45,"line":53},[43,2582,353],{"class":62},[43,2584,2585],{"class":69}," name",[43,2587,263],{"class":62},[43,2589,1566],{"class":238},[43,2591,2592],{"class":49},"                         \u002F\u002F abstract — no value yet\n",[43,2594,2595,2597,2600,2602,2604,2607,2610,2613],{"class":45,"line":59},[43,2596,353],{"class":62},[43,2598,2599],{"class":69}," greeting",[43,2601,73],{"class":62},[43,2603,792],{"class":62},[43,2605,2606],{"class":942},"\"Hello, ",[43,2608,2609],{"class":130},"$name",[43,2611,2612],{"class":942},"\"",[43,2614,2615],{"class":49},"           \u002F\u002F NPE risk! name may be null during init\n",[43,2617,2618],{"class":45,"line":83},[43,2619,109],{"emptyLinePlaceholder":108},[43,2621,2622,2625,2628,2631,2633],{"class":45,"line":89},[43,2623,2624],{"class":62},"class",[43,2626,2627],{"class":238}," Impl",[43,2629,2630],{"class":62}," extends",[43,2632,2576],{"class":238},[43,2634,553],{"class":62},[43,2636,2637,2639,2641,2643,2645,2648],{"class":45,"line":105},[43,2638,1648],{"class":62},[43,2640,66],{"class":62},[43,2642,2585],{"class":69},[43,2644,73],{"class":62},[43,2646,2647],{"class":942}," \"Alice\"",[43,2649,2650],{"class":49},"              \u002F\u002F order: Base.greeting init BEFORE name set → NPE\n",[43,2652,2653],{"class":45,"line":112},[43,2654,2655],{"class":49},"\u002F\u002F Fix: use 'lazy val greeting' or 'def greeting' or early-init:\n",[43,2657,2658,2660,2663,2665,2667],{"class":45,"line":118},[43,2659,2624],{"class":62},[43,2661,2662],{"class":238}," ImplSafe",[43,2664,2630],{"class":62},[43,2666,2576],{"class":238},[43,2668,553],{"class":62},[43,2670,2671,2673,2675,2677,2679,2681],{"class":45,"line":124},[43,2672,1648],{"class":62},[43,2674,66],{"class":62},[43,2676,2585],{"class":69},[43,2678,73],{"class":62},[43,2680,2647],{"class":942},[43,2682,2683],{"class":49},"              \u002F\u002F field init order: name first if declared before super\n",[2294,2685,2686,248,2694,2697,2698,2701],{},[2297,2687,2688,2690,2691],{},[19,2689,257],{}," overflow in ",[19,2692,2693],{},"Range",[19,2695,2696],{},"(1 to Int.MaxValue)"," can overflow internally. Use ",[19,2699,2700],{},"BigInt"," ranges for extreme values.",[2294,2703,2704,248,2712,2715,2716,2718,2719,2715,2722,2724,2725,2728,2729,2732,2733,2736,2737,2740,2741,1016],{},[2297,2705,2706,2709,2710],{},[19,2707,2708],{},"Char"," is NOT a ",[19,2711,1439],{},[19,2713,2714],{},"'a'"," is ",[19,2717,2708],{}," (16-bit UTF-16), ",[19,2720,2721],{},"\"a\"",[19,2723,1439],{},". ",[19,2726,2727],{},"s\"$c\""," boxes ",[19,2730,2731],{},"c"," to ",[19,2734,2735],{},"Character"," then calls ",[19,2738,2739],{},"toString"," — avoid in hot paths; use ",[19,2742,2743],{},"String.valueOf(c)",[15,2745,2747],{"id":2746},"quick-quiz","🧠 Quick Quiz",[2294,2749,2750,2751,2754,2755,2758],{},"What's the runtime difference between ",[19,2752,2753],{},"List[Int](1,2,3).map(_ * 2)"," and ",[19,2756,2757],{},"Array[Int](1,2,3).map(_ * 2)","?",[2760,2761,2762,2766,2831],"details",{},[2763,2764,2765],"summary",{},"Answer",[2767,2768,2769,2801],"ul",{},[2770,2771,2772,2775,2776,2778,2779,2782,2783,2785,2786,2789,2790,2793,2794,2796,2797,2800],"li",{},[19,2773,2774],{},"List[Int].map(_ * 2)",": Each ",[19,2777,257],{}," is boxed to ",[19,2780,2781],{},"Integer"," (generic ",[19,2784,251],{}," erases to ",[19,2787,2788],{},"List[Object]","). The lambda allocates a ",[19,2791,2792],{},"Function1"," object. Result: 3 ",[19,2795,2781],{}," boxes + 1 lambda + 3 new ",[19,2798,2799],{},"::"," cons cells.",[2770,2802,2803,248,2806,2809,2810,2813,2814,2817,2818,2820,2821,2824,2825,2827,2828,2830],{},[19,2804,2805],{},"Array[Int].map(_ * 2)",[19,2807,2808],{},"Array[Int]"," is a primitive ",[19,2811,2812],{},"int[]"," at runtime. The ",[19,2815,2816],{},"map"," specialization on ",[19,2819,2808],{}," uses ",[19,2822,2823],{},"while"," loops with ",[19,2826,257],{}," primitives — zero boxing. Result: 1 new ",[19,2829,2812],{}," + 1 lambda allocation.",[2294,2832,2833,2834,22,2836,2839,2840,22,2843,1016],{},"For hot-path numeric code, always prefer ",[19,2835,2808],{},[19,2837,2838],{},"Array[Double]"," over ",[19,2841,2842],{},"List[Int]",[19,2844,2845],{},"Vector[Int]",[2847,2848,2849],"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 .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}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}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}",{"title":39,"searchDepth":53,"depth":53,"links":2851},[2852,2857,2858,2859,2860,2862,2863,2864,2866,2867,2868],{"id":17,"depth":53,"text":2853,"children":2854},"val \u002F var \u002F lazy val — Initialization Semantics",[2855],{"id":214,"depth":59,"text":2856},"Anti-Pattern: lazy val Inside Hot Path",{"id":383,"depth":53,"text":384},{"id":752,"depth":53,"text":753},{"id":1098,"depth":53,"text":1099},{"id":1389,"depth":53,"text":2861},"Type Hierarchy — Any → AnyVal \u002F AnyRef",{"id":1599,"depth":53,"text":1600},{"id":1850,"depth":53,"text":1851},{"id":2092,"depth":53,"text":2865},"Option[T] — Null Safety Without Null",{"id":2291,"depth":53,"text":2292},{"id":2531,"depth":53,"text":2532},{"id":2746,"depth":53,"text":2747},"Deep-dive into val\u002Fvar\u002Flazy val initialization, primitive boxing, AnyVal\u002FAnyRef hierarchy, specialization, and zero-cost value classes in Scala 3.","md",{},"\u002Fscala\u002F02-variables-and-data-types",{"title":5,"description":2869},"scala\u002F02-variables-and-data-types","3dKdVqcYeb_UxFSLGj-aPXAC547G6EJD0ZfzcqTJQvc",1789924653881]