introduce capture macro (#12712)
capture works for more cases than `closureScope`.
This commit is contained in:
parent
65fd95bf85
commit
56cf3403b4
3 changed files with 41 additions and 0 deletions
|
|
@ -42,6 +42,9 @@
|
||||||
`sorted` does.
|
`sorted` does.
|
||||||
- Added `sugar.collect` that does comprehension for seq/set/table collections.
|
- Added `sugar.collect` that does comprehension for seq/set/table collections.
|
||||||
|
|
||||||
|
- Added `sugar.capture` for capturing some local loop variables when creating a closure.
|
||||||
|
This is an enhanced version of `closureScope`.
|
||||||
|
|
||||||
## Library changes
|
## Library changes
|
||||||
|
|
||||||
- `asyncdispatch.drain` now properly takes into account `selector.hasPendingOperations`
|
- `asyncdispatch.drain` now properly takes into account `selector.hasPendingOperations`
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@
|
||||||
## This module implements nice syntactic sugar based on Nim's
|
## This module implements nice syntactic sugar based on Nim's
|
||||||
## macro system.
|
## macro system.
|
||||||
|
|
||||||
|
include system/inclrtl
|
||||||
|
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
proc createProcType(p, b: NimNode): NimNode {.compileTime.} =
|
||||||
|
|
@ -180,6 +182,30 @@ macro distinctBase*(T: typedesc): untyped =
|
||||||
typeSym = getTypeImpl(typeSym)[0]
|
typeSym = getTypeImpl(typeSym)[0]
|
||||||
typeSym.freshIdentNodes
|
typeSym.freshIdentNodes
|
||||||
|
|
||||||
|
macro capture*(locals: openArray[typed], body: untyped): untyped {.since: (1, 1).} =
|
||||||
|
## Useful when creating a closure in a loop to capture some local loop variables
|
||||||
|
## by their current iteration values. Example:
|
||||||
|
##
|
||||||
|
## .. code-block:: Nim
|
||||||
|
## import strformat, sequtils, sugar
|
||||||
|
## var myClosure : proc()
|
||||||
|
## for i in 5..7:
|
||||||
|
## for j in 7..9:
|
||||||
|
## if i * j == 42:
|
||||||
|
## capture [i, j]:
|
||||||
|
## myClosure = proc () = echo fmt"{i} * {j} = 42"
|
||||||
|
## myClosure() # output: 6 * 7 == 42
|
||||||
|
## let m = @[proc (s: string): string = "to " & s, proc (s: string): string = "not to " & s]
|
||||||
|
## var l = m.mapIt(capture([it], proc (s: string): string = it(s)))
|
||||||
|
## let r = l.mapIt(it("be"))
|
||||||
|
## echo r[0] & ", or " & r[1] # output: to be, or not to be
|
||||||
|
var params = @[newIdentNode("auto")]
|
||||||
|
for arg in locals:
|
||||||
|
params.add(newIdentDefs(ident(arg.strVal), freshIdentNodes getTypeImpl arg))
|
||||||
|
result = newNimNode(nnkCall)
|
||||||
|
result.add(newProc(newEmptyNode(), params, body, nnkProcDef))
|
||||||
|
for arg in locals: result.add(arg)
|
||||||
|
|
||||||
when (NimMajor, NimMinor) >= (1, 1):
|
when (NimMajor, NimMinor) >= (1, 1):
|
||||||
macro outplace*[T](arg: T, call: untyped; inplaceArgPosition: static[int] = 1): T =
|
macro outplace*[T](arg: T, call: untyped; inplaceArgPosition: static[int] = 1): T =
|
||||||
## Turns an `in-place`:idx: algorithm into one that works on
|
## Turns an `in-place`:idx: algorithm into one that works on
|
||||||
|
|
|
||||||
12
tests/closure/tcapture.nim
Normal file
12
tests/closure/tcapture.nim
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
discard """
|
||||||
|
output: '''
|
||||||
|
to be, or not to be'''
|
||||||
|
joinable: false
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sequtils, sugar
|
||||||
|
|
||||||
|
let m = @[proc (s: string): string = "to " & s, proc (s: string): string = "not to " & s]
|
||||||
|
var l = m.mapIt(capture([it], proc (s: string): string = it(s)))
|
||||||
|
let r = l.mapIt(it("be"))
|
||||||
|
echo r[0] & ", or " & r[1]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue