Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using mutable varargs doesnt work as expected in Nim

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading