{"name":"test_05_closures_and_capture.nu","source":"// ============================================================\n// test_05_closures_and_capture.nu\n// Tarkoitus: testaa että\n//  (1) parametri-vapaa closure (\\ → T { ... }) toimii\n//  (2) closure kaappaa paikallisen muuttujan ARVON oikein\n//  (3) closure-funktiosta palautettu closure (factory pattern)\n//      kantaa kaapatun arvon mukanaan\n//  (4) sama tehdas kutsuttuna kahdesti tuottaa kaksi\n//      RIIPPUMATONTA closurea, joilla ei ole jaettua tilaa\n//  (5) closure voidaan tallentaa muuttujaan ja kutsua myöhemmin\n//  (6) closure voidaan ottaa parametrina (higher-order funktio)\n//      ja kutsua silmukassa — eli map_i-pattern grammatiikasta\n//  (7) globaali mutable-muuttuja closuren sisällä toimii oikein\n//      (eri polku kuin paikallisen kaappaus)\n//\n// Odotettu tuloste:\n//   greet=hello\n//   captured x=10\n//   add5(3)=8\n//   add5(7)=12\n//   add10(3)=13\n//   add10(7)=17\n//   add5 still works: add5(100)=105\n//   stored closure: 49\n//   mapped: 11 12 13 14 15\n//   global counter after: 3\n// ============================================================\n\n: ~ i call_count 0\n\n// ── (1) Parametri-vapaa closure tallennettu muuttujaan ───────\n@ make_greeting → ( @ s ) {\n    : s msg `hello`\n    : ( @ s ) g \\ → s { ^ msg }\n    ^ g\n}\n\n// ── (2) Closure-tehdas: palauttaa add-N -funktion ────────────\n@ make_adder i n → ( @ i i ) {\n    : ( @ i i ) f \\ i x → i { + x n }\n    ^ f\n}\n\n// ── (3) Higher-order: ota closure ja sovella se sliceen ──────\n@ map_i [i src ( @ i i ) f → [i {\n    : i n . src length\n    : *i buf # *i ( malloc * n 8 )\n    : ~ i i 0\n    ~ < i n {\n        : i v . src i\n        = . buf i ( f v )\n        = i + i 1\n    }\n    ^ @ [i { buf n }\n}\n\n// ── (4) Closure joka mutatoi globaalia ───────────────────────\n@ make_counter → ( @ i i ) {\n    : ( @ i i ) f \\ i x → i {\n        = call_count + call_count 1\n        ^ * x x\n    }\n    ^ f\n}\n\n@ main → i {\n    // (1) Parametri-vapaa closure\n    : ( @ s ) greet ( make_greeting )\n    ( puts `greet=` )\n    ( puts ( greet ) )\n    ( puts `\\n` )\n\n    // (2) Closure kaappaa paikallisen ARVON\n    : ~ i x 10\n    : ( @ s ) show_x \\ → s {\n        ( puts `captured x=` )\n        ( puts ( nurl_str_int x ) )\n        ( puts `\\n` )\n        ^ ``\n    }\n    ( show_x )\n    // Mitätöi: muuta x main-scopessa. Closure on jo kaapannut arvon 10.\n    // Jos kääntäjäsi toteuttaa \"capture by reference\", tämä antaisi 99:n.\n    // Jos \"capture by value\" (kuten grammar vihjaa), se antaa 10:n.\n    // En testaa tätä eksplisiittisesti — kerro outputista mitä tuli.\n    = x 99\n\n    // (3) Tehdas tuottaa kaksi riippumatonta closurea\n    : ( @ i i ) add5 ( make_adder 5 )\n    : ( @ i i ) add10 ( make_adder 10 )\n\n    ( puts `add5(3)=` )\n    ( puts ( nurl_str_int ( add5 3 ) ) )\n    ( puts `\\n` )\n    ( puts `add5(7)=` )\n    ( puts ( nurl_str_int ( add5 7 ) ) )\n    ( puts `\\n` )\n    ( puts `add10(3)=` )\n    ( puts ( nurl_str_int ( add10 3 ) ) )\n    ( puts `\\n` )\n    ( puts `add10(7)=` )\n    ( puts ( nurl_str_int ( add10 7 ) ) )\n    ( puts `\\n` )\n\n    // (4) add5 toimii edelleen add10:n luonnin jälkeen — ei ristikontaminaatiota\n    ( puts `add5 still works: add5(100)=` )\n    ( puts ( nurl_str_int ( add5 100 ) ) )\n    ( puts `\\n` )\n\n    // (5) Closure tallennettuna ja kutsuttuna myöhemmin\n    : ( @ i i ) sq \\ i v → i { * v v }\n    : i r ( sq 7 )\n    ( puts `stored closure: ` )\n    ( puts ( nurl_str_int r ) )\n    ( puts `\\n` )\n\n    // (6) Higher-order: map_i closurella\n    : [i nums [i | 1 2 3 4 5]\n    : ( @ i i ) bump \\ i n → i { + n 10 }\n    : [i mapped ( map_i nums bump )\n    ( puts `mapped: ` )\n    : i mn . mapped length\n    : ~ i mi 0\n    ~ < mi mn {\n        ( puts ( nurl_str_int . mapped mi ) )\n        ( puts ` ` )\n        = mi + mi 1\n    }\n    ( puts `\\n` )\n\n    // (7) Closure mutatoi globaalia → 3 kutsua → call_count=3\n    : ( @ i i ) cntr ( make_counter )\n    ( cntr 2 )\n    ( cntr 3 )\n    ( cntr 4 )\n    ( puts `global counter after: ` )\n    ( puts ( nurl_str_int call_count ) )\n    ( puts `\\n` )\n\n    ^ 0\n}\n","bytes":4143}