Skip to content

Commit

Permalink
sugar: add var x syntax to => (#1492)
Browse files Browse the repository at this point in the history
## Summary

Allow prefixing parameter names with `var`, to designate the parameter
as being a `var` parameter.

## Details

Type parameters cannot be inferred as `var`, and therefore it's
effectively not possible to use the `=>` macro for creating anonymous
procedures where the procedures needs `var` parameters. The `x: T`
syntax does exist, but it applies to all preceding parameter, limiting
its usefulness.

To address the aforementioned shortcoming, the `var x` syntax is now
supported (example: `(x, var y) => x`), assigning `var auto` as the
respective parameter's type. Due a NimSkull syntax/parser limitation,
`var x` cannot be used as the first parameter.
  • Loading branch information
zerbina authored Feb 18, 2025
1 parent f313cfc commit 59a0b26
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
7 changes: 6 additions & 1 deletion lib/pure/sugar.nim
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ proc createProcType(p, b: NimNode): NimNode =
result.add prag

macro `=>`*(p, b: untyped): untyped =
## Syntax sugar for anonymous procedures. It also supports pragmas.
## Syntax sugar for anonymous procedures. It also supports pragmas. Prefixing
## a parameter name with ``var`` makes the parameter a var parameter.
##
## .. warning:: Semicolons can not be used to separate procedure arguments.
runnableExamples:
Expand Down Expand Up @@ -109,6 +110,10 @@ macro `=>`*(p, b: untyped): untyped =
identDefs.add(newIdentNode("auto"))
identDefs.add(newEmptyNode())
inc untypedBeforeColon
of nnkVarTy:
identDefs.add(c[0])
identDefs.add(newTree(nnkVarTy, newIdentNode("auto")))
identDefs.add(newEmptyNode())
of nnkInfix:
if c[0].kind == nnkIdent and c[0].eqIdent"->":
var procTy = createProcType(c[1], c[2])
Expand Down
21 changes: 21 additions & 0 deletions tests/lang_callable/macros/tsugar_closuremacro.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,24 @@ type
var myBot = Bot()
myBot.call = () {.noSideEffect.} => "I'm a bot."
doAssert myBot.call() == "I'm a bot."

proc singleVar(p: (var int) -> int): int =
var x = 0
discard p(x)
x

doAssert singleVar((x: var auto) => (inc x; x)) == 1

proc trailingVar(p: (int, var int) -> int): int =
var x = 0
discard p(1, x)
x

doAssert trailingVar((x, var y) => (y += x; 0)) == 1

proc multiVar(p: (int, var int, var int) -> int): int =
var x, y = 0
discard p(1, x, y)
x

doAssert multiVar((x, var y, var z) => x) == 0

0 comments on commit 59a0b26

Please sign in to comment.