trying to make a simple procedure to modify a variable number of arguments in nim (for example to initialize a number of a variables from input).
proc Read(outputVars: var varargs[int]) =
for v in outputVars.mitems:
v = 3
var
a, b, c : int
Read(a, b, c)
However the compiler doesn’t like this and outputs:
Error: type mismatch: got <int, int, int>
but expected one of:
proc Read(outputVars: var varargs[int])
first type mismatch at position: 1
required type for outputVars: var varargs[int]
but expression 'a' is of type: int
expression: Read(a, b, c)
How can I make a procedure that accepts a variable number of mutable arguments?
>Solution :
The reason doesn’t work is because varargs is an array under the hood. Even if it could be mutable, the values would still have to be copied into the array, so updating them wouldn’t update the original variables.
IMO the correct "safe" way to express your example would be varargs[var int], i.e. an array of mutable views to integers. But this also doesn’t work because Nim’s views feature is still experimental.
A less safe solution which does work, is using a coercing varargs of pointers to integers. For example:
proc varIntAddr(n: var int): ptr int =
addr n
proc read(outputVars: varargs[ptr int, varIntAddr]) =
for v in outputVars:
v[] = 3
var a, b, c: int
read(a, b, c)
echo (a, b, c)
Here if you pass in mutable integers, varIntAddr will be implicitly applied to them to take their addresses which get added to the array.
You can also generalise the proc like so:
proc varAddr[T](n: var T): ptr T =
addr n