Is there a way to make a variable number of args?

Monkey Forums/Monkey Programming/Is there a way to make a variable number of args?

ondesic(Posted 2013) [#1]
Is there a way in Monkey to create a function(0...n) where you can pass as many arguments as you want? I know you can pass an array, but I mean actual function(1,4,6,7,3,2) and then access them through an array inside the function?


Nobuyuki(Posted 2013) [#2]
Variadic functions are not directly supported in Monkey. I imagine to do so would be problematic. Instead, consider passing the last argument as an optional array of T, and call it by using an inline array, like so:

    Variadic([1,4,6,7,3,2])

Function Variatic:T[](args:T[])
    For Local i:Int = 0 Until args.Length
        args[i] = Something
    Next
    Return args
End Function


I forget whether arrays are passed by value or by reference, so directly manipulating those values (or not) depends on this. Assuming it's byVal and changes to args happen to a copy of what's passed in, simply pass args back out again and it will be an array of T.

If you only want variable args for part of the function, consider adding the array as an optional argument at the end, using the convention args:T[]=Null, where T is the type you want, depending if you want a specific type or if you want to use Generics. This way, you can specify some arguments as required, and leave the rest as variable number.


Samah(Posted 2013) [#3]
What I did in Diddy for the Format method (similar to printf) is to make 10 optional parameters and build them into an array internally. That way you can use a static array to reduce overhead.


Gerry Quinn(Posted 2013) [#4]
The way I understand it, a reference to the original array will be passed, so you can change values in the array if you want to return stuff that way. But if you resize the array or otherwise alter the value of the reference parameter, you just lose access to the passed array, and the calling function will see no further changes.




Output is 1 5 1


Samah(Posted 2013) [#5]
@Gerry Quinn:
ondesic is asking how to define varargs functions, not pass-by-reference/pointers. Your suggestion is a good solution to the latter, though.

As for varargs...
[monkeycode]Global foo_array:String[] = New String[5]
Function Foo(arg1$="",arg2$="",arg3$="",arg4$="",arg5$="")
Local argcount:Int = 0
If arg1 Then
foo_array[argcount] = arg1
argcount = argcount + 1
End
If arg2 Then
foo_array[argcount] = arg2
argcount = argcount + 1
End
If arg3 Then
foo_array[argcount] = arg3
argcount = argcount + 1
End
If arg4 Then
foo_array[argcount] = arg4
argcount = argcount + 1
End
If arg5 Then
foo_array[argcount] = arg5
argcount = argcount + 1
End

' ... stuff
End[/monkeycode]
Messy, I know. Now you can access your arguments with foo_array[0..argcount-1]. Since the array is global, there's no overhead on each call. The only catch is that if the function calls itself somewhere in the stack, you're likely to overwrite them.


Gerry Quinn(Posted 2013) [#6]
Yes, I was responding to Nobuyuki's mention of arrays.