discard """ target: "c" output: ''' 1 3 6 11 20 foo foo88 23 24foo 88 18 18 99 99 99 99 99 99 99 12 99 99 12 99 99 success @[1, 2, 5] click at 10,20 lost focus 1 lost focus 2 registered handler for UserEvent 1 registered handler for UserEvent 2 registered handler for UserEvent 3 registered handler for UserEvent 4 asdas processClient end false baro0 foo88 23 24foo 88 foo88 23 24foo 88 11 @[1, 10, 45, 120, 210, 252, 210, 120, 45, 10, 1] ''' joinable: false """ block tclosure: proc map(n: var openarray[int], fn: proc (x: int): int {.closure}) = for i in 0..n.len-1: n[i] = fn(n[i]) proc each(n: openarray[int], fn: proc(x: int) {.closure.}) = for i in 0..n.len-1: fn(n[i]) var myData: array[0..4, int] = [0, 1, 2, 3, 4] proc testA() = var p = 0 map(myData, proc (x: int): int = result = x + 1 shl (proc (y: int): int = return y + p )(0) inc(p)) testA() myData.each do (x: int): write(stdout, x) write(stdout, " ") #OUT 2 4 6 8 10 # bug #5015 type Mutator = proc(matched: string): string {.noSideEffect, gcsafe, locks: 0.} proc putMutated( MutatorCount: static[int], mTable: static[array[MutatorCount, Mutator]], input: string) = for i in 0.. 5000_000: quit("still a leak!") echo "success" main() import json, tables, sequtils block tclosure4: proc run(json_params: OrderedTable) = let json_elems = json_params["files"].elems # These fail compilation. var files = map(json_elems, proc (x: JsonNode): string = x.str) let text = """{"files": ["a", "b", "c"]}""" run((text.parseJson).fields) import sugar block inference3304: type List[T] = ref object val: T proc foo[T](l: List[T]): seq[int] = @[1,2,3,5].filter(x => x != l.val) echo(foo(List[int](val: 3))) block tcodegenerr1923: type Foo[M] = proc() : M proc bar[M](f : Foo[M]) = discard f() proc baz() : int = 42 bar(baz) block doNotation: type Button = object Event = object x, y: int proc onClick(x: Button, handler: proc(x: Event)) = handler(Event(x: 10, y: 20)) proc onFocusLost(x: Button, handler: proc()) = handler() proc onUserEvent(x: Button, eventName: string, handler: proc) = echo "registered handler for ", eventName var b = Button() b.onClick do (e: Event): echo "click at ", e.x, ",", e.y b.onFocusLost: echo "lost focus 1" b.onFocusLost do: echo "lost focus 2" b.onUserEvent("UserEvent 1") do: discard b.onUserEvent "UserEvent 2": discard b.onUserEvent("UserEvent 3"): discard b.onUserEvent("UserEvent 4", () => echo "event 4") import tables block fib50: proc memoize(f: proc (a: int64): int64): proc (a: int64): int64 = var previous = initTable[int64, int64]() return proc(i: int64): int64 = if not previous.hasKey i: previous[i] = f(i) return previous[i] var fib: proc(a: int64): int64 fib = memoize(proc (i: int64): int64 = if i == 0 or i == 1: return 1 return fib(i-1) + fib(i-2) ) doAssert fib(50) == 20365011074 block tflatmap: # bug #3995 type RNG = tuple[] Rand[A] = (RNG) -> (A, RNG) proc nextInt(r: RNG): (int, RNG) = (1, ()) proc flatMap[A,B](f: Rand[A], g: A -> Rand[B]): Rand[B] = (rng: RNG) => ( let (a, rng2) = f(rng); let g1 = g(a); g1(rng2) ) proc map[A,B](s: Rand[A], f: A -> B): Rand[B] = let g: A -> Rand[B] = (a: A) => ((rng: RNG) => (f(a), rng)) flatMap(s, g) discard nextInt.map(i => i - i mod 2) block tforum: type PAsyncHttpServer = ref object value: string PFutureBase = ref object callback: proc () {.closure.} value: string failed: bool proc accept(server: PAsyncHttpServer): PFutureBase = new(result) result.callback = proc () = discard server.value = "hahaha" proc processClient(): PFutureBase = new(result) proc serve(server: PAsyncHttpServer): PFutureBase = iterator serveIter(): PFutureBase {.closure.} = echo server.value while true: var acceptAddrFut = server.accept() yield acceptAddrFut var fut = acceptAddrFut.value var f = processClient() f.callback = proc () = echo("processClient end") echo(f.failed) yield f var x = serveIter for i in 0 .. 1: result = x() result.callback() discard serve(PAsyncHttpServer(value: "asdas")) block futclosure2138: proc any[T](list: varargs[T], pred: (T) -> bool): bool = for item in list: if pred(item): result = true break proc contains(s: string, words: varargs[string]): bool = any(words, (word) => s.contains(word)) block tinterf: type ITest = tuple[ setter: proc(v: int) {.closure.}, getter1: proc(): int {.closure.}, getter2: proc(): int {.closure.}] proc getInterf(): ITest = var shared1, shared2: int return (setter: proc (x: int) = shared1 = x shared2 = x + 10, getter1: proc (): int = result = shared1, getter2: proc (): int = return shared2) var i = getInterf() i.setter(56) doAssert i.getter1() == 56 doAssert i.getter2() == 66 block tjester: type Future[T] = ref object data: T callback: proc () {.closure.} proc cbOuter(response: string) {.discardable.} = iterator cbIter(): Future[int] {.closure.} = for i in 0..7: proc foo(): int = iterator fooIter(): Future[int] {.closure.} = echo response, i yield Future[int](data: 17) var iterVar = fooIter iterVar().data yield Future[int](data: foo()) var iterVar2 = cbIter proc cb2() {.closure.} = try: if not finished(iterVar2): let next = iterVar2() if next != nil: next.callback = cb2 except: echo "WTF" cb2() cbOuter "baro" block tnamedparamanonproc: type PButton = ref object TButtonClicked = proc(button: PButton) {.nimcall.} proc newButton(onClick: TButtonClicked) = discard proc main() = newButton(onClick = proc(b: PButton) = var requestomat = 12 ) main() block tnestedclosure: proc main(param: int) = var foo = 23 proc outer(outerParam: string) = var outerVar = 88 echo outerParam, outerVar proc inner() = block Test: echo foo, " ", param, outerParam, " ", outerVar inner() outer("foo") # test simple closure within dummy 'main': proc dummy = proc main2(param: int) = var fooB = 23 proc outer(outerParam: string) = var outerVar = 88 echo outerParam, outerVar proc inner() = block Test: echo fooB, " ", param, outerParam, " ", outerVar inner() outer("foo") main2(24) dummy() main(24) # Jester + async triggered this bug: proc cbOuter() = var response = "hohoho" block: proc cbIter() = block: proc fooIter() = doAssert response == "hohoho" fooIter() cbIter() cbOuter() block tnestedproc: proc p(x, y: int): int = result = x + y echo p((proc (): int = var x = 7 return x)(), (proc (): int = return 4)()) block tnoclosure: proc pascal(n: int) = var row = @[1] for r in 1..n: row = zip(row & @[0], @[0] & row).mapIt(it[0] + it[1]) echo row pascal(10)