DEV Community

Manav
Manav

Posted on • Edited on

Learning Nim: OpenArrays vs Varargs

At first, openArray and varargs seemed too similar to me, to the point that I felt openArray to be redundant. Then I tried to test my assumptions, and found out what I was missing.

OpenArrays

openArray is the answer to the question, what if you want to send a whole array or sequence as an argument in a procedure?

proc displayOpenArray(oa: openArray[string]) =
    echo oa.len

var fruits: seq[string] = @["apple", "banana", "orange"]

displayOpenArray(fruits)
displayOpenArray(fruits, "something else") #ERROR

openArray is designed to take only a single argument.

Can we pass multidimensional array as an argument?

#Yes
type
    oneDArray = array[0..1, int]
    twoDArray = array[0..1, oneDArray]

var complexArray: twoDArray = [[1, 2], [3, 5]]

proc displayOpenArray(oa: openArray[oneDArray]) = 
    for rows in oa:
        for col in rows:
            write(stdout, col, " ")
        write(stdout, "\n")

displayOpenArray(complexArray)

Varargs

With varargs you can pass any number of arguments to your procedure.

proc displayVarargs1(va: varargs[int]) =
    echo va.len #prints the number of arguments

displayVarargs1(1, 2, 3, 4, 5, 7) #6

proc displayVarargs2(va: varargs[array[0..1, int]]) =
    echo va.len #prints the number of arguments

displayVarargs2([1, 2], [3, 5]) #2

#Somehow this works too
displayVarargs1([1, 2, 3, 4]) #4

#But this doesn't
displayVarargs1([1, 2, 3, 4], 5) #ERROR

How can we send a mixture of array/seq and other types?

proc displayBoth1(oa: openArray[int], va: varargs[int]) =
    echo "Array lenth:", oa.len
    echo "varargs length:", va.len

displayBoth1([1, 2], 3, 5, 7)
displayBoth1([], 1, 2, 3, 5, 7)
displayBoth1([])

Note: The should only be one varargs parameter in your procedure.

Can we hack it to accept various arrays of multiple lengths?

proc displayBoth1(va: varargs[openArray[int]]) =
    echo "Number of arguments:", va.len
    echo "length of each argument:"
    for arg in va:
        echo arg.len

displayBoth1([1, 2], [2], [3, 6, 8])
# May be not, openArray cannot be used in the above context. 

Sum up: openArray is used for accepting one argument of array/seq type while varargs is used to accept multiple arguments of same type.

But can varargs replace openArray and make it redundant?

Well, I've just started learning the language, but I'd go for yes. As far as passing arrays and sequences are concerned.

If you learnt something, hit ❤️ and share. Others deserve to know about it 🙂

Top comments (0)