Variadic function

From Rosetta Code
Revision as of 03:37, 14 March 2018 by rosettacode>Spruit11 (Added Egel Language example to Variadic Functions)
Task
Variadic function
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Create a function which takes in a variable number of arguments and prints each one on its own line.

Also show, if possible in your language, how to call the function on a list of arguments constructed at runtime.


Functions of this type are also known as Variadic Functions.


Related task



Ada

Ada doesn't have variadic functions. But you can mimic the behavior by defining a function with an unconstrained array as its parameter, i.e., an array whose length is determined at run time.

<lang Ada>with Ada.Strings.Unbounded, Ada.Text_IO;

procedure Variadic is

  subtype U_String is Ada.Strings.Unbounded.Unbounded_String;
  use type U_String;
  function "+"(S: String) return U_String
    renames Ada.Strings.Unbounded.To_Unbounded_String;
  function "-"(U: U_String) return String
    renames Ada.Strings.Unbounded.To_String;
  type Variadic_Array is array(Positive range <>) of U_String;
  procedure Print_Line(Params: Variadic_Array) is
  begin
     for I in Params'Range loop
        Ada.Text_IO.Put(-Params(I));
        if I < Params'Last then
           Ada.Text_IO.Put(" ");
        end if;
     end loop;
     Ada.Text_IO.New_Line;
  end Print_Line;

begin

  Print_Line((+"Mary", +"had", +"a", +"little", +"lamb.")); -- print five strings
  Print_Line((1 => +"Rosetta Code is cooool!")); -- print one string

end;</lang>

Output:

Mary had a little lamb.
Rosetta Code is cooool!

ACL2

<lang Lisp>(defun print-all-fn (xs)

  (if (endp xs)
      nil
      (prog2$ (cw "~x0~%" (first xs))
              (print-all-fn (rest xs)))))

(defmacro print-all (&rest args)

  `(print-all-fn (quote ,args)))</lang>

ActionScript

<lang actionscript>public function printArgs(... args):void {

   for (var i:int = 0; i < args.length; i++)
       trace(args[i]);

}</lang>

Aime

Printing strings: <lang aime>void f(...) {

   integer i;
   i = 0;
   while (i < count()) {

o_text($i); o_byte('\n'); i += 1;

   }

}

integer main(void) {

   f("Mary", "had", "a", "little", "lamb");
   return 0;

}</lang> Printing data of assorted types: <lang aime>void output_date(date d) {

   o_integer(d_year(d));
   o_byte('/');
   o_finteger(2, d_y_month(d));
   o_byte('/');
   o_finteger(2, d_m_day(d));

}

void output_real(real x) {

   o_real(8, x);

}

void g(...) {

   integer i;
   record r;
   r_put(r, "integer", o_integer);
   r_put(r, "real", output_real);
   r_put(r, "text", o_text);
   r_put(r, "date", output_date);
   i = 0;
   while (i < count()) {

call(r_query(r, __type($i)), $i); o_byte('\n'); i += 1;

   }

}

date now(void) {

   date d;
   d_now(d);
   return d;

}

integer main(void) {

   g("X.1", 707, .5, now());
   return 0;

}</lang>

ALGOL 68

Variable arguments of arbitrarily typed values are not permitted in ALGOL 68. However a flexible array of tagged types (union) is permitted. This effectively allows the passing of strongly typed variable arguments to procedures.

Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8-8d

<lang algol68>main:(

 MODE STRINT = UNION(STRING, INT, PROC(REF FILE)VOID, VOID);
 PROC print strint = (FLEX[]STRINT argv)VOID: (
   FOR i TO UPB argv DO
     CASE argv[i] IN
       (INT i):print(whole(i,-1)),
       (STRING s):print(s),
       (PROC(REF FILE)VOID f):f(stand out),
       (VOID):print(error char)
     ESAC;
     IF i NE UPB argv THEN print((" ")) FI
   OD
 );
print strint(("Mary","had",1,"little",EMPTY,new line))

)</lang> Output:

Mary had 1 little *

Also note that empty (of type void) can be used to indicate missing or optional arguments.

For another example see Average/Simple moving average. This example is closer to the keyword arguments found in python.


AppleScript

Works with: OS X Yosemite onwards version (10.10+) for the use of NSDictionary with record arguments

AppleScript handlers have no internal access to an argument vector, but we can use AppleScript's Patterned Parameters, in the form of lists of arbitrary length for variadic positional parameters, or records for variadic named parameters.

<lang AppleScript>use framework "Foundation"

-- positionalArgs :: [a] -> String on positionalArgs(xs)

   -- follow each argument with a line feed
   map(my putStrLn, xs) as string

end positionalArgs

-- namedArgs :: Record -> String on namedArgs(rec)

   script showKVpair
       on |λ|(k)
           my putStrLn(k & " -> " & keyValue(rec, k))
       end |λ|
   end script
   
   -- follow each argument name and value with line feed    
   map(showKVpair, allKeys(rec)) as string

end namedArgs

-- TEST on run

   intercalate(linefeed, ¬
       {positionalArgs(["alpha", "beta", "gamma", "delta"]), ¬
           namedArgs({epsilon:27, zeta:48, eta:81, theta:8, iota:1})})
   
   --> "alpha
   --   beta
   --   gamma
   --   delta
   -- 
   --   epsilon -> 27
   --   eta -> 81
   --   iota -> 1
   --   zeta -> 48
   --   theta -> 8
   --  "

end run


-- GENERIC FUNCTIONS

-- putStrLn :: a -> String on putStrLn(a)

   (a as string) & linefeed

end putStrLn

-- map :: (a -> b) -> [a] -> [b] on map(f, xs)

   tell mReturn(f)
       set lng to length of xs
       set lst to {}
       repeat with i from 1 to lng
           set end of lst to |λ|(item i of xs, i, xs)
       end repeat
       return lst
   end tell

end map

-- intercalate :: Text -> [Text] -> Text on intercalate(strText, lstText)

   set {dlm, my text item delimiters} to {my text item delimiters, strText}
   set strJoined to lstText as text
   set my text item delimiters to dlm
   return strJoined

end intercalate

-- allKeys :: Record -> [String] on allKeys(rec)

   (current application's NSDictionary's dictionaryWithDictionary:rec)'s allKeys() as list

end allKeys

-- keyValue :: Record -> String -> Maybe String on keyValue(rec, strKey)

   set ca to current application
   set v to (ca's NSDictionary's dictionaryWithDictionary:rec)'s objectForKey:strKey
   if v is not missing value then
       item 1 of ((ca's NSArray's arrayWithObject:v) as list)
   else
       missing value
   end if

end keyValue

-- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: Handler -> Script on mReturn(f)

   if class of f is script then
       f
   else
       script
           property |λ| : f
       end script
   end if

end mReturn</lang>

Output:
"alpha
beta
gamma
delta

epsilon -> 27
eta -> 81
iota -> 1
zeta -> 48
theta -> 8
"

Applesoft BASIC

An array of parameters with a count as parameter zero can be used in a subroutine to simulate a variadic function. The values in the array should probably be cleared when the subroutine returns because the array is a global variable. <lang ApplesoftBasic>10 P$(0) = STR$(5) 20 P$(1) = "MARY" 30 P$(2) = "HAD" 40 P$(3) = "A" 50 P$(4) = "LITTLE" 60 P$(5) = "LAMB" 70 GOSUB 90"VARIADIC FUNCTION 80 END 90 FOR I = 1 TO VAL(P$(0)) : ? P$(I) : P$(I) = "" : NEXT I : P$(0) = "" : RETURN</lang>

AutoHotkey

Works with: AutoHotkey_L

Writing an asterisk after the final parameter marks the function as variadic, allowing it to receive a variable number of parameters: <lang AutoHotkey>printAll(args*) {

 for k,v in args
   t .= v "`n"
 MsgBox, %t%

}</lang> This function can be called with any number of arguments:<lang AutoHotkey>printAll(4, 3, 5, 6, 4, 3) printAll(4, 3, 5) printAll("Rosetta", "Code", "Is", "Awesome!")</lang> An array of parameters can be passed to any function by applying the same syntax to a function-call:<lang AutoHotkey>args := ["Rosetta", "Code", "Is", "Awesome!"] printAll(args*)</lang>


AutoHotkey Basic (deprecated):

Function arguments can be given default values. Comparison with "" can indicate that an argument was present (and not of value ""). As of version 1.0.48, you can pass more parameters than defined by a function, in which case the parameters are evaluated but discarded. Versions earlier than that produce warnings. <lang autohotkey>string = Mary had a little lamb StringSplit, arg, string, %A_Space%

Function(arg1,arg2,arg3,arg4,arg5) ;Calls the function with 5 arguments. Function() ;Calls the function with no arguments. return

Function(arg1="",arg2="",arg3="",arg4="",arg5="") {

 Loop,5
   If arg%A_Index% !=
     out .= arg%A_Index% "`n"
 MsgBox,% out ? out:"No non-blank arguments were passed."

}</lang>

AWK

AWK allows to call functions with fewer than the defined arguments; the missing one(s) default to "". Comparison with "" can check if the argument was present (and not of value ""). To call a function with more than the defined arguments, this produces a warning.

This f() can accept 0 to 3 arguments.

<lang awk>function f(a, b, c){ if (a != "") print a if (b != "") print b if (c != "") print c }

BEGIN { print "[1 arg]"; f(1) print "[2 args]"; f(1, 2) print "[3 args]"; f(1, 2, 3) }</lang>

[1 arg]
1
[2 args]
1
2
[3 args]
1
2
3

This f() can also accept array elements. This works because any missing array elements default to "", so f() ignores them.

<lang awk>function f(a, b, c) { if (a != "") print a if (b != "") print b if (c != "") print c }

BEGIN { # Set ary[1] and ary[2] at runtime. split("Line 1:Line 2", ary, ":")

# Pass to f(). f(ary[1], ary[2], ary[3]) }</lang>

Line 1
Line 2

Functions like f() can take only a few arguments. To accept more arguments, or to accept "" as an argument, the function must take an array, and the caller must bundle its arguments into an array. This g() accepts 0 or more arguments in an array.

<lang awk>function g(len, ary, i) { for (i = 1; i <= len; i++) print ary[i]; }

BEGIN { c = split("Line 1:Line 2:Next line is empty::Last line", a, ":") g(c, a) # Pass a[1] = "Line 1", a[4] = "", ...

}</lang>

Line 1
Line 2
Next line is empty

Last line

BaCon

Variable argument lists are defined with the keyword VAR, and are passed as an indexed array of strings. The number of elements is specified by a SIZE parameter. Arguments to functions could also simply be indexed or associative arrays or multiple element delimited strings.

<lang freebasic>' Variadic functions OPTION BASE 1 SUB demo (VAR arg$ SIZE argc)

   LOCAL x
   PRINT "Amount of incoming arguments: ", argc
   FOR x = 1 TO argc
       PRINT arg$[x]
   NEXT

END SUB

' No argument demo(0) ' One argument demo("abc") ' Three arguments demo("123", "456", "789")</lang>

Output:
prompt$ bacon variadic.bac
Converting 'variadic.bac'... done, 16 lines were processed in 0.003 seconds.
Compiling 'variadic.bac'... cc  -c variadic.bac.c
cc -o variadic variadic.bac.o -lbacon -lm
Done, program 'variadic' ready.

prompt$ ./variadic
Amount of incoming arguments: 0
Amount of incoming arguments: 1
abc
Amount of incoming arguments: 3
123
456
789

BASIC

Using variable arguments has not been standardised in BASIC. Therefore there are several different implementations, and many BASIC versions do not have this feature at all.

Works with: FreeBASIC

Variadic functions on FreeBASIC are somewhat similar to those in C. The parameter list does not pass information about parameter type. If necessary, the type information has to be passed for example in the first parameter. C calling convention has to be used (with keyword cdecl). <lang freebasic>SUB printAll cdecl (count As Integer, ... )

   DIM arg AS Any Ptr 
   DIM i   AS Integer
   arg = va_first()
   FOR i = 1 To count
       PRINT va_arg(arg, Double)
       arg = va_next(arg, Double)
   NEXT i

END SUB

printAll 3, 3.1415, 1.4142, 2.71828</lang> For some reason, I was not able to get a Strings version of the above to work.

FreeBASIC

String version <lang freebasic>' version 15-09-2015 ' compile with: fbc -s console

Sub printAll_string Cdecl (count As Integer, ... )

   Dim arg As Any Ptr
   Dim i   As Integer
   arg = va_first()
   For i = 1 To count
       Print *Va_Arg(arg, ZString Ptr)
       arg = va_next(arg, ZString Ptr)
   Next i

End Sub

' ------=< MAIN >=------ ' direct printAll_string (5, "Foxtrot", "Romeo", "Echo", "Echo", "BASIC")

' strings Print : Print Dim As String a = "one", b = "two", c = "three" printAll_string (3, a, b, c)

' count is smaller then the number of arguments, no problem Print : Print printAll_string (1, a, b, c)

' count is greater then the number of arguments ' after the last valid argument garbage is displayed ' should be avoided, could lead to disaster Print : Print printAll_string (4, a, b, c) Print

' empty keyboard buffer While InKey <> "" : Wend Print : Print "hit any key to end program" Sleep End</lang>

Output:
only the last example shown
one
two
three
…À�”ÀƒÄ��¶À÷ØА¡<"A
Works with: Beta BASIC version 3.0
Works with: SAM BASIC

Beta BASIC uses keyword DATA to specify variable parameter list. The parameters are read with READ command just like when reading conventional DATA statements. The existence of more parameters as well as the type of each parameter can be checked with function ITEM().

<lang zxbasic>100 DEF PROC printAll DATA 110 DO UNTIL ITEM()=0 120 IF ITEM()=1 THEN

         READ a$
         PRINT a$

130 ELSE

         READ num
         PRINT num

140 LOOP 150 END PROC

200 printAll 3.1415, 1.4142, 2.71828 210 printAll "Mary", "had", "a", "little", "lamb",</lang>

The code above is for Beta BASIC. There is a small difference between Beta BASIC and SAM BASIC. On Beta BASIC, the function ITEM has empty parenthesis, on SAM BASIC the parenthesis are not used.

See also: RapidQ

==[[:Category: X -> "one" | X -> "one" ]] [[Category: X -> "one" ]] Property "Implemented in language" (as page type) with input value "X -> "one"" contains invalid characters or is incomplete and therefore can cause unexpected results during a query or annotation process.]</lang> Example: <lang Mathematica>ShowMultiArg[] ShowMultiArg[a, b, c] ShowMultiArg[5, 3, 1]</lang> gives back: <lang Mathematica>[nothing]

a b c

5 3 1</lang> In general Mathematica supports patterns in functions, mostly represented by the blanks and sequences: _, __ and ___ . With those you can create functions with variable type and number of arguments.

MATLAB

In MATLAB, the keyword "varargin" in the argument list of a function denotes that function as a variadic function. This keyword must come last in the list of arguments. "varargin" is actually a cell-array that assigns a comma separated list of input arguments as elements in the list. You can access each of these elements like you would any normal cell array.

<lang MATLAB>function variadicFunction(varargin)

   for i = (1:numel(varargin))
       disp(varargin{i});
   end
   

end</lang>

Sample Usage: <lang MATLAB>>> variadicFunction(1,2,3,4,'cat')

    1
    2
    3
    4

cat</lang>

Maxima

<lang maxima>show([L]) := block([n], n: length(L), for i from 1 thru n do disp(L[i]))$

show(1, 2, 3, 4);

apply(show, [1, 2, 3, 4]);

/* Actually, the built-in function "disp" is already what we want */ disp(1, 2, 3, 4);

apply(disp, [1, 2, 3, 4]);</lang>

Metafont

Variable number of arguments to a macro can be done using the text keyword identifying the kind of argument to the macro. In this way, each argument can be of any kind (here, as example, I show all the primitive types that Metafont knows)

<lang metafont>ddef print_arg(text t) = for x = t:

 if unknown x: message "unknown value"
 elseif numeric x: message decimal x
 elseif string x: message x
 elseif path x: message "a path"
 elseif pair x: message decimal (xpart(x)) & ", " & decimal (ypart(x))
 elseif boolean x: if x: message "true!" else: message "false!" fi
 elseif pen x: message "a pen"
 elseif picture x: message "a picture"
 elseif transform x: message "a transform" fi; endfor enddef;

print_arg("hello", x, 12, fullcircle, currentpicture, down, identity, false, pencircle); end</lang>

Modula-3

Modula-3 provides the built ins FIRST and LAST, which can be used with FOR loops to cycle over all elements of an array. This, combined with open arrays allows Modula-3 to simulate variadic functions. <lang modula3>MODULE Varargs EXPORTS Main;

IMPORT IO;

VAR strings := ARRAY [1..5] OF TEXT {"foo", "bar", "baz", "quux", "zeepf"};

PROCEDURE Variable(VAR arr: ARRAY OF TEXT) =

 BEGIN
   FOR i := FIRST(arr) TO LAST(arr) DO
     IO.Put(arr[i] & "\n");
   END;
 END Variable;
 

BEGIN

 Variable(strings);

END Varargs.</lang> Output:

foo
bar
baz
quux
zeepf

Things get more complicated if you want to mix types: <lang modula3>MODULE Varargs EXPORTS Main;

IMPORT IO, Fmt;

VAR

 strings := NEW(REF TEXT);
 ints := NEW(REF INTEGER);
 reals := NEW(REF REAL);
 refarr := ARRAY [1..3] OF REFANY {strings, ints, reals};

PROCEDURE Variable(VAR arr: ARRAY OF REFANY) =

 BEGIN
   FOR i := FIRST(arr) TO LAST(arr) DO
     TYPECASE arr[i] OF
     | REF TEXT(n) => IO.Put(n^ & "\n");
     | REF INTEGER(n) => IO.Put(Fmt.Int(n^) & "\n");
     | REF REAL(n) => IO.Put(Fmt.Real(n^) & "\n");
     ELSE (* skip *)
     END;
   END;
 END Variable;
 

BEGIN

 strings^ := "Rosetta"; ints^ := 1; reals^ := 3.1415;
 Variable(refarr);

END Varargs.</lang> Output:

Rosetta
1
3.1415

Nemerle

Translation of: C#

Like C#, Nemerle uses the params keyword to specify that arguments are collected into an array. <lang Nemerle>using System; using System.Console;

module Variadic {

   PrintAll (params args : array[object]) : void
   {
       foreach (arg in args) WriteLine(arg);
   }
   
   Main() : void
   {
       PrintAll("test", "rosetta code", 123, 5.6, DateTime.Now);
   }

}</lang>

Nim

<lang nim>proc print(xs: varargs[string, `$`]) =

 for x in xs:
   echo x</lang>

The function can be called with any number of arguments and the argument list can be constructed at runtime: <lang nim>print(12, "Rosetta", "Code", 15.54321)

print 12, "Rosetta", "Code", 15.54321, "is", "awesome!"

let args = @["12", "Rosetta", "Code", "15.54321"] print(args)</lang>

Objective-C

Objective-C uses the same varargs functionality as C. Like C, it has no way of knowing the number or types of the arguments. When the arguments are all objects, the convention is that, if the number of arguments is undetermined, then the list must be "terminated" with nil. Functions that follow this convention include the constructors of data structures that take an undetermined number of elements, like [NSArray arrayWithObjects:...].

<lang objc>#include <stdarg.h>

void logObjects(id firstObject, ...) // <-- there is always at least one arg, "nil", so this is valid, even for "empty" list {

 va_list args;
 va_start(args, firstObject);
 id obj;
 for (obj = firstObject; obj != nil; obj = va_arg(args, id))
   NSLog(@"%@", obj);
 va_end(args);

}

// This function can be called with any number or type of objects, as long as you terminate it with "nil": logObjects(@"Rosetta", @"Code", @"Is", @"Awesome!", nil); logObjects(@4, @3, @"foo", nil);</lang>

Oforth

As Oforth uses a data stack, the only way to have a function using a variable number of parameters is to define one of its parameters as the number of parameters to use on the stack.

For instance : <lang Oforth>: sumNum(n) | i | 0 n loop: i [ + ] ;</lang>

Output:
sumNum(3, 1, 2, 3) println
6
sumNum(2, 1, 4) println
5
sumNum(5, 3, 4, 5, 6, 7) println
25

Oz

This is only possible for methods, not for functions/procedures. <lang oz>declare

 class Demo from BaseObject
    meth test(...)=Msg
       {Record.forAll Msg Show}
    end
 end
 D = {New Demo noop}
 Constructed = {List.toTuple test {List.number 1 10 1}}

in

 {D test(1 2 3 4)}
 {D Constructed}</lang>

PARI/GP

A variadic function can be coded directly in PARI using the parser code s*.

Works with: PARI/GP version 2.8+

<lang parigp>f(a[..])=for(i=1,#a,print(a[i]))</lang>

Works with: PARI/GP version 2.8.1+

<lang parigp>call(f, v)</lang>

Perl

Functions in Perl 5 don't have argument lists. All arguments are stored in the array @_ anyway, so there is variable arguments by default.

<lang perl>sub print_all {

 foreach (@_) {
   print "$_\n";
 }

}</lang>

This function can be called with any number of arguments: <lang perl>print_all(4, 3, 5, 6, 4, 3); print_all(4, 3, 5); print_all("Rosetta", "Code", "Is", "Awesome!");</lang>

Since lists are flattened when placed in a list context, you can just pass an array in as an argument and all its elements will become separate arguments: <lang perl>@args = ("Rosetta", "Code", "Is", "Awesome!"); print_all(@args);</lang>

Introduced experimentally in 5.20.0, subroutines can have signatures when the feature is turned on: <lang perl>use 5.020; use experimental 'signatures';</lang> Perl policy states that all bets are off with experimental features—their behavior is subject to change at any time, and they may even be removed completely (this feature will most likely stay in, but expect changes in the future that will break any scripts written using it as it stands in 5.20.1).

Functions can be declared with fixed arity: <lang perl>sub print ($x, $y) {

   say $x, "\n", $y;

}</lang>

But this can easily be converted to a variadic function with a slurpy parameter: <lang perl>sub print_many ($first, $second, @rest) {

   say "First: $first\n"
      ."Second: $second\n"
      ."And the rest: "
      . join("\n", @rest);

}</lang> It is valid for the @rest array to be empty, so this is also an optional parameter (see Optional parameters).

Perl 6

Works with: Rakudo version #25 "Minneapolis"

If a subroutine has no formal parameters but mentions the variables @_ or %_ in its body, it will accept arbitrary positional or keyword arguments, respectively. You can even use both in the same function.

<lang perl6>sub foo {

  .say for @_;
  say .key, ': ', .value for %_;

}

foo 1, 2, command => 'buckle my shoe',

   3, 4, order => 'knock at the door';</lang>

This prints:

1
2
3
4
command: buckle my shoe
order: knock at the door

Perl 6 also supports slurpy arrays and hashes, which are formal parameters that consume extra positional and keyword arguments like @_ and %_. You can make a parameter slurpy with the * twigil. This implementation of &foo works just like the last:

<lang perl6>sub foo (*@positional, *%named) {

  .say for @positional;
  say .key, ': ', .value for %named;

}</lang>

Unlike in Perl 5, arrays and hashes aren't flattened automatically. Use the | operator to flatten:

<lang perl6>foo |@ary, |%hsh;</lang>

Phix

Copy of Euphoria. The argument to print_args could be anything constructed at runtime. You can also specify optional parameters, simply by specifying a default value. Any non-optional arguments must be grouped together at the start. <lang Phix>procedure print_args(sequence args)

   for i=1 to length(args) do
       ?args[i]
   end for

end procedure print_args({"Mary", "had", "a", "little", "lamb"})</lang>

PHP

PHP 4 and above supports varargs. You can deal with the argument list using the func_num_args(), func_get_arg(), and func_get_args() functions. <lang php><?php function printAll() {

 foreach (func_get_args() as $x) // first way
   echo "$x\n";
 $numargs = func_num_args(); // second way
 for ($i = 0; $i < $numargs; $i++)
   echo func_get_arg($i), "\n";

} printAll(4, 3, 5, 6, 4, 3); printAll(4, 3, 5); printAll("Rosetta", "Code", "Is", "Awesome!"); ?></lang>

You can use the call_user_func_array function to apply it to a list of arguments: <lang php><?php $args = array("Rosetta", "Code", "Is", "Awesome!"); call_user_func_array('printAll', $args); ?></lang>

Works with: PHP version 5.6+

You can receive variable arguments in a list by having a parameter preceded by ...: <lang php><?php function printAll(...$things) {

 foreach ($things as $x)
   echo "$x\n";

} printAll(4, 3, 5, 6, 4, 3); printAll(4, 3, 5); printAll("Rosetta", "Code", "Is", "Awesome!"); ?></lang>

You can use the same ... syntax to supply a list of arguments to a function: <lang php><?php $args = ["Rosetta", "Code", "Is", "Awesome!"]; printAll(...$args); ?></lang>

PL/I

<lang pli>/* PL/I permits optional arguments, but not an infinitely varying */ /* argument list: */ s: procedure (a, b, c, d);

  declare (a, b, c, d) float optional;
  if ^omitted(a) then put skip list (a);
  if ^omitted(b) then put skip list (b);
  if ^omitted(c) then put skip list (c);
  if ^omitted(d) then put skip list (d);

end s;</lang>

PicoLisp

The '@' operator causes a function to accept a variable number of arguments. These can be accesed with the 'args', 'next', 'arg' and 'rest' functions. <lang PicoLisp>(de varargs @

  (while (args)
     (println (next)) ) )</lang>

The '@' operator may be used in combination with normal parameters: <lang PicoLisp>(de varargs (Arg1 Arg2 . @)

  (println Arg1)
  (println Arg2)
  (while (args)
     (println (next)) ) )</lang>

It is called like any other function <lang PicoLisp>(varargs 'a 123 '(d e f) "hello")</lang> also by possibly applying it to a ready-made list <lang PicoLisp>(apply varargs '(a 123 (d e f) "hello"))</lang> Output in all cases:

a
123
(d e f)
"hello"

PowerShell

<lang powershell>function print_all {

   foreach ($x in $args) {
       Write-Host $x
   }

}</lang> Normal usage of the function just uses all arguments one after another: <lang powershell>print_all 1 2 'foo'</lang> In PowerShell v1 there was no elegant way of using an array of objects as arguments to a function which leads to the following idiom: <lang powershell>$array = 1,2,'foo' Invoke-Expression "& print_all $array"</lang> PowerShell v2 introduced the splat operator which makes this easier:

Works with: PowerShell version 2

<lang powershell>print_all @array</lang>

Prolog

The Prolog standard does not require support for variadic functions, but there is no need for them in Prolog, because Prolog has first-class support for terms, including lists and terms such as (1,2,3), which are also known as comma-lists.

For example, the standard predicate write/1 has just one formal argument, but it will accept any term. Thus, except for the additional parentheses, write/1 is like a variadic function that requires at least one argument:

?- write( (1) ), nl.
1

?- write( (1,2,3) ), nl.
1,2,3

In practice, since the minimum length of a comma-list is 2, Prolog lists are often used instead of comma-lists to handle situations where vararg-behavior is wanted. For example: <lang prolog>printAll( List ) :- forall( member(X,List), (write(X), nl)). </lang> To handle more esoteric situations, we could define a higher-order predicate to handle terms of arbitrary arity, e.g. <lang prolog> execute( Term ) :-

 Term =.. [F | Args],
 forall( member(X,Args), (G =.. [F,X], G, nl) ).

</lang>

?- execute( write(1,2,3) ).
1
2
3

Python

Putting * before an argument will take in any number of arguments and put them all in a tuple with the given name.

<lang python>def print_all(*things):

   for x in things:
       print x</lang>

This function can be called with any number of arguments: <lang python>print_all(4, 3, 5, 6, 4, 3) print_all(4, 3, 5) print_all("Rosetta", "Code", "Is", "Awesome!")</lang>

You can use the same "*" syntax to apply the function to an existing list of arguments: <lang python>args = ["Rosetta", "Code", "Is", "Awesome!"] print_all(*args)</lang>

Keyword arguments

Python also has keyword arguments were you can add arbitrary func(keyword1=value1, keyword2=value2 ...) keyword-value pairs when calling a function. This example shows both keyword arguments and positional arguments. The two calls to the function are equivalent. *alist spreads the members of the list to create positional arguments, and **adict does similar for the keyword/value pairs from the dictionary. <lang python>>>> def printargs(*positionalargs, **keywordargs): print "POSITIONAL ARGS:\n " + "\n ".join(repr(x) for x in positionalargs) print "KEYWORD ARGS:\n " + '\n '.join( "%r = %r" % (k,v) for k,v in keywordargs.iteritems())


>>> printargs(1,'a',1+0j, fee='fi', fo='fum') POSITIONAL ARGS:

 1
 'a'
 (1+0j)

KEYWORD ARGS:

 'fee' = 'fi'
 'fo' = 'fum'

>>> alist = [1,'a',1+0j] >>> adict = {'fee':'fi', 'fo':'fum'} >>> printargs(*alist, **adict) POSITIONAL ARGS:

 1
 'a'
 (1+0j)

KEYWORD ARGS:

 'fee' = 'fi'
 'fo' = 'fum'

>>></lang>

See the Python entry in Named Arguments for a more comprehensive description of Python function parameters and call arguments.

Qi

Qi doesn't have support for variable argument functions, but we can fake it by using a macro that puts all arguments into a list.

<lang qi> (define varargs-func

 A -> (print A))

(define varargs

 [varargs | Args] -> [varargs-func [list | Args]]
 A -> A)

(sugar in varargs 1) </lang>

R

This first function, almost completes the task, but the formatting isn't quite as specified. <lang rsplus> printallargs1 <- function(...) list(...)

printallargs1(1:5, "abc", TRUE)
  1. 1
  2. [1] 1 2 3 4 5
  3. 2
  4. [1] "abc"
  5. 3
  6. [1] TRUE</lang>

This function is corrrect, though a little longer. <lang rsplus> printallargs2 <- function(...)

{  
  args <- list(...)
  lapply(args, print)
  invisible()
}
printallargs2(1:5, "abc", TRUE)
  1. [1] 1 2 3 4 5
  2. [1] "abc"
  3. [1] TRUE</lang>

Use do.call to call a function with a list of arguments. <lang rsplus>arglist <- list(x=runif(10), trim=0.1, na.rm=TRUE) do.call(mean, arglist)</lang>

Racket

The following defines and uses an any-number-of-arguments variadic function called "vfun".

<lang Racket> -> (define (vfun . xs) (for-each displayln xs)) -> (vfun) -> (vfun 1) 1 -> (vfun 1 2 3 4) 1 2 3 4 -> (apply vfun (range 10 15)) 10 11 12 13 14 </lang>

REALbasic

This subroutine prints it arguments. ParamArrays must be the last argument but may be preceded by any number of normal arguments.

<lang vb> Sub PrintArgs(ParamArray Args() As String)

 For i As Integer = 0 To Ubound(Args)
   Print(Args(i))
 Next

End Sub </lang>

Calling the subroutine. <lang vb> PrintArgs("Hello", "World!", "Googbye", "World!") </lang>

REBOL

REBOL does not have variadic functions, nevertheless, it is easy to define a function taking just one argument, an ARGS block. The ARGS block contents can then be processed one by one: <lang REBOL>REBOL [ Title: "Variadic Arguments" ]

print-all: func [

   args [block!] {the arguments to print}

] [

   foreach arg args [print arg]

]

print-all [rebol works this way]</lang>

RapidQ

RapidQ uses special keywords SUBI and FUNCTIONI for procedures and functions with variable number of parameters. Numeric parameters are accessed from array ParamVal and string parameters from array ParamStr$. <lang rapidq>SUBI printAll (...)

   FOR i = 1 TO ParamValCount

PRINT ParamVal(i)

   NEXT i
   FOR i = 1 TO ParamStrCount

PRINT ParamStr$(i)

   NEXT i

END SUBI

printAll 4, 3, 5, 6, 4, 3 printAll 4, 3, 5 printAll "Rosetta", "Code", "Is", "Awesome!"</lang>

REXX

simplistic

<lang rexx>print_all: procedure /* [↓] is the # of args passed.*/

                          do j=1  for arg()
                          say  arg(j)
                          end   /*j*/

return</lang>

annotated

<lang rexx>print_all: procedure /* [↓] is the # of args passed.*/

                          do j=1  for arg()
                          say  '[argument'   j"]: "   arg(j)
                          end   /*j*/

return</lang>

invocations

The function can be called with any number of arguments (including no arguments and/or omitted arguments),
although some REXX implementations impose a limit and the number of arguments. <lang rexx>call print_all .1,5,2,4,-3, 4.7e1, 013.000 ,, 8**2 -3, sign(-66), abs(-71.00), 8 || 9, 'seven numbers are prime, 8th is null'

call print_all "One ringy-dingy,",

               "two ringy-dingy,",
               "three ringy-dingy...",
               "Hello?  This is Ma Bell.",
               "Have you been misusing your instrument?",
               "(Lily Tomlin routine)"
                        /*  [↑]   example showing multi-line arguments.*/</lang>

Ring

<lang ring>

  1. Project : Variadic function
  2. Date  : 2017/11/13
  3. Author : Gal Zsolt (~ CalmoSoft ~)
  4. Email  : <calmosoft@gmail.com>

sum([1,2]) sum([1,2,3]) nums = [1,2,3,4] sum(nums)

func sum(nums)

      total = 0
      for num = 1 to len(nums)
          total = total + num
      next
      showarray(nums)
      see " " + total + nl
       

func showarray(vect)

      see "["
      svect = ""
      for n = 1 to len(vect)
          svect = svect + vect[n] + " "
      next
      svect = left(svect, len(svect) - 1)
      see "" + svect + "]"

</lang> Output:

[1 2] 3
[1 2 3] 6
[1 2 3 4] 10

Ruby

The * is sometimes referred to as the "splat" in Ruby. <lang ruby>def print_all(*things)

 puts things

end</lang>

This function can be called with any number of arguments: <lang ruby>print_all(4, 3, 5, 6, 4, 3) print_all(4, 3, 5) print_all("Rosetta", "Code", "Is", "Awesome!")</lang>

You can use the same "*" syntax to apply the function to an existing list of arguments: <lang ruby>args = ["Rosetta", "Code", "Is", "Awesome!"] print_all(*args)</lang>

Scala

<lang scala>def printAll(args: Any*) = args foreach println</lang>

Example:

scala> printAll(1,2,3, "Rosetta", "is cool")
1
2
3
Rosetta
is cool

scala> val list = List(1,2,3, "Rosetta", "is cool")
list: List[Any] = List(1, 2, 3, Rosetta, is cool)

scala> printAll(list: _*)
1
2
3
Rosetta
is cool

Scheme

Putting a dot before the last argument will take in any number of arguments and put them all in a list with the given name.

<lang scheme>(define (print-all . things)

   (for-each
       (lambda (x) (display x) (newline))
       things))</lang>

Note that if you define the function anonymously using lambda, and you want all the args to be collected in one list (i.e. you have no parameters before the parameter that collects everything), then you can just replace the parentheses altogether with that parameter, as if to say, let this be the argument list:

<lang scheme>(define print-all

 (lambda things
   (for-each
       (lambda (x) (display x) (newline))
       things)))</lang>

This function can be called with any number of arguments: <lang scheme>(print-all 4 3 5 6 4 3) (print-all 4 3 5) (print-all "Rosetta" "Code" "Is" "Awesome!")</lang>

The apply function will apply the function to a list of arguments: <lang scheme>(define args '("Rosetta" "Code" "Is" "Awesome!")) (apply print-all args)</lang>

Sidef

A parameter declared with "*", can take any number of arguments of any type. <lang ruby>func print_all(*things) {

   things.each { |x| say x };

}</lang> This function can be called with any number of arguments: <lang ruby>print_all(4, 3, 5, 6, 4, 3); print_all(4, 3, 5); print_all("Rosetta", "Code", "Is", "Awesome!");</lang> Also, there is "..." which transforms an array into a list of arguments. <lang ruby>var args = ["Rosetta", "Code", "Is", "Awesome!"]; print_all(args...);</lang>

Slate

Putting an asterisk before a method's input variable header name means it will contain all non-core input variables (those are prefixed with a colon) in an Array.

<lang slate>define: #printAll -> [| *rest | rest do: [| :arg | inform: arg printString]].

printAll applyTo: #(4 3 5 6 4 3). printAll applyTo: #('Rosetta' 'Code' 'Is' 'Awesome!').</lang>

For method definitions and message sends, the same mechanism is employed, but the syntax for passing arguments after the message phrase is special (using commas to append arguments which fill *rest): <lang slate>_@lobby printAll [| *rest | rest do: [| :arg | inform: arg printString]]. lobby printAll, 4, 3, 5, 6, 4, 3. lobby printAll, 'Rosetta', 'Code', 'Is', 'Awesome!'. </lang>

Swift

Using ... after the type of argument will take in any number of arguments and put them all in one array of the given type with the given name. <lang swift>func printAll<T>(things: T...) {

 // "things" is a [T]
 for i in things {
   print(i)
 }

}</lang> This function can be called with any number of arguments: <lang swift>printAll(4, 3, 5, 6, 4, 3) printAll(4, 3, 5) printAll("Rosetta", "Code", "Is", "Awesome!")</lang>

Tcl

Works with: Tcl version 8.5

If the last argument is named "args", it collects all the remaining arguments <lang tcl>proc print_all {args} {puts [join $args \n]}

print_all 4 3 5 6 4 3 print_all 4 3 5 print_all Rosetta Code Is Awesome!

set things {Rosetta Code Is Awesome!}

print_all $things ;# ==> incorrect: passes a single argument (a list) to print_all print_all {*}$things ;# ==> correct: passes each element of the list to the procedure</lang> The above code will work in all versions of Tcl except for the last line. A version-independent transcription of that (one of many possible) would be: <lang Tcl>eval [list print_all] [lrange $things 0 end]</lang>

uBasic/4tH

It's not easy to make a variadic function or procedure in uBasic/4tH, but it is possible with a little effort, provided the stack is used. However, sometimes it is required to reverse the order of the values by loading them into the array, from high memory to low memory. Strings may require even more effort, but the built-in hashing helps. <lang>Push _Mary, _had, _a, _little, _lamb ' Push the hashes Proc _PrintStrings (5) ' Print the string

Push 1, 4, 5, 19, 12, 3 ' Push the numbers Print "Maximum is: ";FUNC(_Max(6)) ' Call the function

End


_PrintStrings Param(1) ' Print a variadic number of strings

 Local(1)
 For b@ = a@-1 To 0 Step -1           ' Reverse the hashes, load in array
   @(b@) = Pop()
 Next
 For b@ = 0 To a@-1                   ' Now call the appropriate subroutines
   Proc @(b@)
 Until b@ = a@-1
   Print " ";                         ' Print a space
 Next                                 ' unless it is the last word
 Print                                ' Terminate the string

Return


_Max Param(1) ' Calculate the maximum value

 Local(3)
 d@ = -(2^31)                         ' Set maximum to a tiny value
 For b@ = 1 To a@                     ' Get all values from the stack
   c@ = Pop()
   If c@ > d@ THEN d@ = c@            ' Change maximum if required
 Next

Return (d@) ' Return the maximum

                                      ' Hashed labels

_Mary Print "Mary"; : Return _had Print "had"; : Return _a Print "a"; : Return _little Print "little"; : Return _lamb Print "lamb"; : Return</lang>

Output:
Mary had a little lamb
Maximum is: 19

0 OK, 0:236

Ursala

<lang Ursala>f = %gP*=

  1. show+

main = f <'foo',12.5,('x','y'),100></lang> f is defined as a function that takes a list of any length of items of any type, and uses a built-in heuristic to decide how to print them. All functions in the language are polymorphic and variadic unless specifically restricted to the contrary.

output:

'foo'
1.250000e+01
('x','y')
100

Unicon

See Icon.

V

In V, all the arguments are passed in stack, and the stack is freely accessible so var args is the default to any level of functions

Using a count as the indication of number of arguments to extract,

<lang v>[myfn

  [zero? not] [swap puts pred]
  while

].

100 200 300 400 500 3 myfn</lang> results in: <lang v>500 400 300</lang>

Visual Basic

<lang vb>Sub varargs(ParamArray a())

   For n = 0 To UBound(a)
       Debug.Print a(n&)
   Next

End Sub</lang>

Vorpal

Each method can have a variable-length parameter (VPL), indicated by empty brackets after the parameter name. The VLP (if present) will be replaced with an array containing all the extra arguments passed to the method. Effectively, extra arguments are absorbed into the array. Calling the function with fewer parameters than needed is still a runtime error. The VPL may be omitted, which will result in an empty array as the value of that parameter. <lang vorpal>self.f = method(x, y[ ], z){

  x.print()
  for(i = 0, i < y.size(), i = i + 1){
     ('[' + y[i] + ']').print()
  }
  z.print()

}

self.f(1, 2, 3) '---'.print() self.f(1, 2, 3, 4) '---'.print() self.f(1, 2)</lang>

XLISP

<lang lisp>(defun print-on-separate-lines (&rest xs)

   (for-each print xs))
test the function

(print-on-separate-lines 'i 'am 'doing 'a 'great 'work 'so 'that 'i 'cannot 'come 'down)

to use it on a list of arguments assembled at run time, first create your list

(define test '(why should the work cease whilst i leave it and come down to you))

and then call APPLY

(apply print-on-separate-lines test)</lang>

Output:
I 
AM 
DOING 
A 
GREAT 
WORK 
SO 
THAT 
I 
CANNOT 
COME 
DOWN 
WHY 
SHOULD 
THE 
WORK 
CEASE 
WHILST 
I 
LEAVE 
IT 
AND 
COME 
DOWN 
TO 
YOU

XPL0

Passing an array is probably a better way to accomplish this task. <lang XPL0>include c:\cxpl\codes; \intrinsic 'code' declarations def IntSize=4; \number of bytes in an integer

proc Var(N...); \Display N strings passed as arguments int N; [N:= Reserve(N*IntSize); \reserve space for N string pointers repeat Text(0,N(0)); CrLf(0); \display strings pointed to by N(0)

       N:= N+IntSize;          \point to next string

until N=GetHp; \pointing beyond reserved space? ];

Var(4, "Mary", "had", "a", "little")</lang>

Output:

Mary
had
a
little

zkl

In zkl, all functions and methods are variadic (they are just passed a list). <lang zkl>fcn f{vm.arglist.apply2("println")} f("Mary","had","a","little");</lang>

Output:
Mary
had
a
little

<lang zkl>a:="This is a test".split(); //-->L("This","is","a","test") f(a.xplode()); // xplode takes a list and blows it apart into call args</lang>

Output:
This
is
a
test

<lang zkl>fcn g{f(vm.pasteArgs(2)} g(a.xplode());</lang> pasteArgs takes the passed in function args and stuffs them back into the arglist of the function call

Output:
a
test

Of course, parameter lists can be named, have defaults, etc. Using the arglist, as a list, isn't the usual case.