check_repl ["id": "ANONYMOUS_FUNCTIONS", "name": "Live closures and recovery across submissions", "steps": [
["let \$x: Integer = 1; let \$f = fn (): Integer { \$x = \$x + 1; \$x }", "quiet", ""],
["echo (\$f) \$x", "output", "2 2"],
["\$x = 7", "quiet", ""],
["echo (\$f) \$x", "output", "8 8"],
["let \$copy = \$f; let \$x: Integer = 99", "quiet", ""],
["echo (\$copy) \$x", "output", "9 99"],
["fn factory(\$n: Integer): fn(): Integer { fn (): Integer { \$n = \$n + 1; \$n } }; let \$counter = factory 0", "quiet", ""],
["echo (\$counter) (\$counter)", "output", "1 2"],
["let \$bad = fn (): Integer { \"bad\" }", "error", "Expected Integer"],
["echo (\$counter)", "output", "3"],
["\$counter 7", "error", "Expected 0 arguments"],
["echo (\$counter)", "output", "4"],
["let \$explode: fn(): Integer = fn (): any { \$x = \$x + 1; \"bad\" }", "quiet", ""],
["\$explode", "error", "Return value: Expected Integer"],
["echo \$x (\$counter)", "output", "100 5"],
["let \$read = fn () { \$missing }", "quiet", ""],
["\$read", "error", "not found"],
["echo \$x (\$counter)", "output", "100 6"],
["let \$recover = fn (): any { let \$x = 1; \$missing }", "quiet", ""],
["\$recover", "error", "not found"],
["echo \$x (\$counter)", "output", "100 7"],
["let \$stop = fn () { break }", "quiet", ""],
["\$stop", "error", "outside a loop"],
["echo \$x (\$counter)", "output", "100 8"],
["let \$typed: fn(): Integer = \$f", "quiet", ""],
["\$typed = fn (\$x: String): String { \$x }", "error", "Expected fn"],
["echo (\$typed) \$x", "output", "10 100"],
["fn describe(): String { \"old\" }; let \$version = fn (): String { describe }", "quiet", ""],
["fn describe(): String { \"new\" }", "quiet", ""],
["echo (\$version) (describe)", "output", "old new"],
["struct Counter { n: Integer }; fn Counter::callback(): fn(): Integer { fn (): Integer { \$self.n = \$self.n + 1; \$self.n } }; let \$c = Counter(n: 1); let \$method = \$c.callback", "quiet", ""],
["echo (\$method) \$c.n", "output", "2 2"],
["\$c = Counter(n: 10)", "quiet", ""],
["echo (\$method) \$c.n", "output", "11 11"],
["fn siblings(\$n) { [fn () { \$n = \$n + 1; \$n }, fn () { \$n }] }; let \$siblings = siblings 0", "quiet", ""],
["echo (\$siblings[0]) (\$siblings[1])", "output", "1 1"],
["let \$array: [fn(Integer): Integer] = [fn (\$n: Integer): Integer { \$n + 1 }]", "quiet", ""],
["\$array[0] = fn (\$n: String): String { \$n }", "error", "incompatible"],
["echo (\$array[0] 4)", "output", "5"],
["type F = fn(): Integer; let \$named: F = fn (): Integer { 42 }", "quiet", ""],
["type F = fn(): String; let \$new: F = fn (): String { \"new\" }", "quiet", ""],
["echo (\$named) (\$new)", "output", "42 new"],
["\$named = \$new", "error", "Expected F, got F"],
["echo (\$named)", "output", "42"],
["let \$closure = fn () { echo hidden }", "quiet", ""],
["echo done", "output", "done"],
["let \$invalid = fn (\$n, \$n) { \$n }", "error", "Duplicate function parameter"],
["echo (\$counter)", "output", "9"],
["let \$returner = fn () { return 42; echo hidden }", "quiet", ""],
["echo (\$returner)", "output", "42"],
["let \$live = 1; let \$late = fn () { \$live }; \$live = \"changed\"", "quiet", ""],
["echo (\$late)", "output", "changed"],
["let \$u = fn (\$n) { \$n }; let \$a = fn (\$n) { \$n }; let \$identity = [\$u: \"saved\"]", "quiet", ""],
["echo (\$u == \$a) \$identity[\$u]", "output", "false saved"],
], "exit": 0]