Variadic function: Difference between revisions
Prolog |
|||
Line 1,173:
<lang powershell>print_all @array</lang>
=={{header|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:
<pre>
?- write( (1) ), nl.
1
?- write( (1,2,3) ), nl.
1,2,3
</pre>
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>
<pre>
?- execute( write(1,2,3) ).
1
2
3
</pre>
=={{header|Python}}==
Putting <tt>*</tt> before an argument will take in any number of arguments and put them all in a tuple with the given name.
|
Revision as of 20:13, 26 March 2014
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
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: Call a function
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.
<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.
AutoHotkey
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
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.
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.
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().
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"
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
C
The ANSI C standard header stdarg.h defines macros for low-level access to the parameter stack. It does not know the number or types of these parameters; this is specified by the required initial parameter(s). For example, it could be a simple count, a terminating NULL, or a more complicated parameter specification like a printf() format string. <lang c>#include <stdio.h>
- include <stdarg.h>
void varstrings(int count, ...) /* the ellipsis indicates variable arguments */ {
va_list args; va_start(args, count); while (count--) puts(va_arg(args, const char *)); va_end(args);
}
varstrings(5, "Mary", "had", "a", "little", "lamb");</lang>
In C, there is no way to call a variadic function on a list of arguments constructed at runtime.
However, all standard library functions which are variadic have a corresponding version, usually named by prepending the letter "v", that is non-variadic and takes a va_list as argument in place of the variadic arguments. For example, printf has a corresponding vprintf which takes a format string and a va_list value as arguments.
Nevertheless, the only way of obtaining a va_list is from a variadic function itself. So the "v" functions are only useful for writing a variadic function "wrapper" that performs some processing and then calls on one of the "v" functions with its va_list. C still provides no standard way to construct a va_list manually at runtime.
The actual implementation of va_list is implementation-dependent. If you are developing on a specific platform, you may use platform-specific knowledge to create a va_list by hand in a non-portable way. For example, on many platforms, a va_list is simply a pointer to a buffer where the arguments are arranged contiguously in memory.
C++
The C++ varargs are basically the same as in C (therefore you can just take the code from C), but there are some limitations:
- Only PODs (basically, every type you could also write in C) can be passed to varargs
- An important difference is that enums are distinct types with possibly different representation than int in C++, but enumeration values are still converted to
int
when passed to varargs. Therefore they have to be accessed asint
inva_arg
.
C++11 in addition allows typesafe variadic arguments through variadic templates. Some compilers, such as gcc, already provide this functionality. The following implements the task with variadic templates:
using option -std=c++0x
<lang cpp>#include <iostream>
template<typename T>
void print(T const& t)
{
std::cout << t;
}
template<typename First, typename ... Rest>
void print(First const& first, Rest const& ... rest)
{
std::cout << first; print(rest ...);
}
int main() {
int i = 10; std::string s = "Hello world"; print("i = ", i, " and s = \"", s, "\"\n");
}</lang> As the example shows, variadic templates allow any type to be passed.
C#
<lang csharp>using System;
class Program {
static void Main(string[] args) { PrintAll("test", "rosetta code", 123, 5.6); }
static void PrintAll(params object[] varargs) { foreach (object i in varargs) { Console.WriteLine(i); } }
}</lang>
Output:
test rosetta code 123 5.6
Clojure
<lang lisp>(defn foo [& args]
(doseq [a args] (println a)))
(foo :bar :baz :quux) (apply foo [:bar :baz :quux])</lang>
Common Lisp
The &rest lambda list keyword causes all remaining arguments to be bound to the following variable.
<lang lisp>(defun example (&rest args)
(dolist (arg args) (print arg)))
(example "Mary" "had" "a" "little" "lamb")
(let ((args '("Mary" "had" "a" "little" "lamb")))
(apply #'example args))</lang>
D
<lang d>import std.stdio, std.algorithm;
void printAll(TyArgs...)(TyArgs args) {
foreach (el; args) el.writeln;
}
// Typesafe variadic function for dynamic array void showSum1(int[] items...) {
items.sum.writeln;
}
// Typesafe variadic function for fixed size array void showSum2(int[4] items...) {
items[].sum.writeln;
}
void main() {
printAll(4, 5.6, "Rosetta", "Code", "is", "awseome"); writeln; showSum1(1, 3, 50); showSum2(1, 3, 50, 10);
}</lang>
- Output:
4 5.6 Rosetta Code is awesome 54 64
Being a system language, in D there are also:
- C-style variadic functions
- D-style variadic functions with type info
- Typesafe variadic function for class objects
See for more info: http://dlang.org/function.html
Déjà Vu
Variadic functions in the Déjà Vu standard library generally end with (
, [
or {
. For this purpose, )
, ]
and }
are autonyms (that is, they have a global bindings to themselves, so that )
is the same as :)
).
<lang dejavu>show-all(:
while /= ) dup: !. drop
show-all( :foo "Hello" 42 [ true ] )</lang>
- Output:
:foo "Hello" 42 [ true ]
E
Varargs is mildly unidiomatic in E, as the argument count is dispatched on, and often considered part of the method name.
However, accepting any number of arguments can easily be done, as it is just a particular case of the basic mechanism for dynamic message handling:
<lang e>def example {
match [`run`, args] { for x in args { println(x) } }
}
example("Mary", "had", "a", "little", "lamb")
E.call(example, "run", ["Mary", "had", "a", "little", "lamb"])</lang>
For comparison, a plain method doing the same thing for exactly two arguments would be like this:
<lang e>def non_example {
to run(x, y) { println(x) println(y) }
}</lang>
or, written using the function syntax,
<lang e>def non_example(x, y) {
println(x) println(y)
}</lang>
Emacs Lisp
An &rest
in the formal parameters gives all further arguments in a list, which the code can then act on in usual list ways. Fixed arguments can precede the &rest
if desired.
<lang Lisp>(defun my-print-args (&rest arg-list)
(message "there are %d argument(s)" (length arg-list)) (dolist (arg arg-list) (message "arg is %S" arg)))
(my-print-args 1 2 3)</lang>
A function can be called with a list of arguments (and optionally fixed arguments too) with apply
, similar to most Lisp variants.
<lang Lisp>(let ((arg-list '("some thing %d %d %d" 1 2 3)))
(apply 'message arg-list))</lang>
Erlang
Variable amount of anything (like arguments): use a list. <lang Erlang> print_each( Arguments ) -> [io:fwrite( "~p~n", [X]) || X <- Arguments]. </lang>
Euphoria
<lang euphoria>procedure print_args(sequence args)
for i = 1 to length(args) do puts(1,args[i]) puts(1,' ') end for
end procedure
print_args({"Mary", "had", "a", "little", "lamb"})</lang>
Euler Math Toolbox
<lang Euler Math Toolbox> >function allargs () ... $ loop 1 to argn(); $ args(#), $ end $endfunction >allargs(1,3,"Test",1:2)
1 3 Test [ 1 2 ]
>function args test (x) := {x,x^2,x^3} >allargs(test(4))
4 16 64
</lang>
Forth
Words taking variable numbers of arguments may be written by specifying the number of parameters to operate upon as the top parameter. There are two standard words which operate this way: PICK and ROLL.
<lang forth>: sum ( x_1 ... x_n n -- sum ) 1 ?do + loop ; 4 3 2 1 4 sum . \ 10</lang>
Alternatively, you can operate upon the entire parameter stack for debugging by using the word DEPTH, which returns the number of items currently on the stack.
<lang forth>: .stack ( -- ) depth 0 ?do i pick . loop ;</lang>
Fortran
Fortran has no varargs for subroutines and functions, but has optional
arguments and varargs functions can be programmed passing an array as argument. Moreover you can program elemental functions or subroutines, i.e. function acting on a single element but which can be used automatically over a vector (but there are limits to respect in order to make it possible, e.g. it is not possible to use print
)
The following code shows how an optional vector argument can be used to pass a variable number of argument to a subroutine.
<lang fortran>program varargs
integer, dimension(:), allocatable :: va integer :: i
! using an array (vector) static call v_func() call v_func( (/ 100 /) ) call v_func( (/ 90, 20, 30 /) )
! dynamically creating an array of 5 elements allocate(va(5)) va = (/ (i,i=1,5) /) call v_func(va) deallocate(va)
contains
subroutine v_func(arglist) integer, dimension(:), intent(in), optional :: arglist
integer :: i
if ( present(arglist) ) then do i = lbound(arglist, 1), ubound(arglist, 1) print *, arglist(i) end do else print *, "no argument at all" end if end subroutine v_func
end program varargs</lang>
Go
There are two types of variadic mechanisms supported in Go, both specified by using a ...
before the name of the last argument in the function parameter list. [1]
If you know that all the variadic arguments are going to be of a certain type, then you can declare that type after the ...
, and all the variadic arguments will be collected in a slice variable, for example:
<lang go>func printAll(things ... string) {
// it's as if you declared "things" as a []string, containing all the arguments for _, x := range things { fmt.Println(x) }
}</lang>
On the other hand, if you want to be able to take different types of variadic arguments (like Printf
does), you can omit the type. What happens is that the compile-time type of the variable that collects it is "interface{}" (the universal interface, i.e. it gives you no information); but the runtime type of the variable will be a struct whose fields contain the arguments and their proper types. You must use reflection (via the reflect
module) to obtain these types and values. Because this is ugly, it is not shown here.
If you wish to supply an argument list to a variadic function at runtime, you can do this by adding a ...
after a slice argument:
<lang go>args := []string{"foo", "bar"}
printAll(args...)</lang>
Groovy
<lang groovy>def printAll( Object[] args) { args.each{ arg -> println arg } }
printAll(1, 2, "three", ["3", "4"])</lang>
Sample output:
1 2 three [3, 4]
Haskell
You can use some fancy recursive type-class instancing to make a function that takes an unlimited number of arguments. This is how, for example, printf works in Haskell. <lang haskell>class PrintAllType t where
process :: [String] -> t
instance PrintAllType (IO a) where
process args = do mapM_ putStrLn args return undefined
instance (Show a, PrintAllType r) => PrintAllType (a -> r) where
process args = \a -> process (args ++ [show a])
printAll :: (PrintAllType t) => t printAll = process []
main :: IO () main = do printAll 5 "Mary" "had" "a" "little" "lamb"
printAll 4 3 5 printAll "Rosetta" "Code" "Is" "Awesome!"</lang>
So here we created a type class specially for the use of this variable-argument function. The type class specifies a function, which takes as an argument some kind of accumulated state of the arguments so far, and returns the type of the type class. Here I chose to accumulate a list of the string representations of each of the arguments; this is not the only way to do it; for example, you could choose to print them directly and just accumulate the IO monad.
We need two kinds of instances of this type class. There is the "base case" instance, which has the type that can be thought of as the "return type" of the vararg function. It describes what to do when we are "done" with our arguments. Here we just take the accumulated list of strings and print them, one per line. (We actually wanted to use "IO ()" instead of "IO a"; but since you can't instance just a specialization like "IO ()", we used "IO a" but return "undefined" to make sure nobody uses it.) You can have multiple base case instances; for example, you might want an instances that returns the result as a string instead of printing it. This is how "printf" in Haskell can either print to stdout or print to string (like sprintf in other languages), depending on the type of its context.
The other kind of instance is the "recursive case". It describes what happens when you come across an argument. Here we simply append its string representation to the end of our previous "accumulated state", and then pass that state onto the next iteration. Make sure to specify the requirements of the types of the arguments; here I just required that each argument be an instance of Show (so you can use "show" to get the string representation), but it might be different for you.
Icon and Unicon
varargs.icn
<lang icon>procedure main ()
varargs("some", "extra", "args") write() varargs ! ["a","b","c","d"]
end
procedure varargs(args[])
every write(!args)
end</lang>
Using it
|icon varargs.icn some extra args a b c d
Io
<lang io>printAll := method(call message arguments foreach(println))</lang>
J
J's data is arbitrary length lists. So all functions implicitly support variable length argument lists unless their definitions specifically reject them.
For example:
<lang J> A=:2
B=:3 C=:5 sum=:+/ sum 1,A,B,4,C
15</lang>
That said, J expects that members of lists all use the same kind of machine representation. If you want both character literals and numbers for arguments, or if you want arrays with different dimensions, each argument must be put into a box, and the function is responsible for dealing with the packing material.
<lang J> commaAnd=: [: ; (<' and ') _2} ::] 1 }.&, (<', ') ,. ":each
commaAnd 'dog';A;B;'cat';C
dog, 2, 3, cat and 5</lang>
Java
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 java5>public static void printAll(Object... things){
// "things" is an Object[] for(Object i:things){ System.out.println(i); }
}</lang> This function can be called with any number of arguments: <lang java5>printAll(4, 3, 5, 6, 4, 3); printAll(4, 3, 5); printAll("Rosetta", "Code", "Is", "Awesome!");</lang>
Or with an array directly (the array must have the appropriate array type; i.e. if it is String..., then you need to pass a String[]): <lang java5>Object[] args = {"Rosetta", "Code", "Is", "Awesome!"}; printAll(args);</lang>
But not with both (in this case the array is considered as just one of two arguments, and not expanded): <lang java5>Object[] args = {"Rosetta", "Code", "Is", "Awesome,"}; printAll(args, "Dude!");//does not print "Rosetta Code Is Awesome, Dude!" //instead prints the type and hashcode for args followed by "Dude!"</lang>
In some rare cases, you may want to pass an array as just a single argument, but doing it directly would expand it to be the entire argument. In this case, you need to cast the array to Object (all arrays are objects) so the compiler doesn't know it's an array anymore. <lang java5>printAll((Object)args);</lang>
JavaScript
The arguments
special variable, when used inside a function, contains an array of all the arguments passed to that function.
<lang javascript>function printAll() {
for (var i=0; i<arguments.length; i++) print(arguments[i])
}
printAll(4, 3, 5, 6, 4, 3);
printAll(4, 3, 5);
printAll("Rosetta", "Code", "Is", "Awesome!");</lang>
The function.arguments
property is equivalent to the arguments
variable above, but is deprecated.
You can use the apply method of a function to apply it to a list of arguments: <lang javascript>args = ["Rosetta", "Code", "Is", "Awesome!"] printAll.apply(null, args)</lang>
TIScript
In TIScript last parameter of function may have '..' added to its name. On call that parameter will contain an array of rest of arguments passed to that function.
<lang javascript> function printAll(separator,argv..) {
if(argv.length) stdout.print(argv[0]); for (var i=1; i < argv.length; i++) stdout.print(separator, argv[i]);
} printAll(" ", 4, 3, 5, 6, 4, 3); printAll(",", 4, 3, 5); printAll("! ","Rosetta", "Code", "Is", "Awesome");</lang>
Julia
Putting ...
after the last argument in a function definition makes it variadic (any number of arguments are passed as a tuple):
<lang julia>
julia> print_each(X...) = for x in X; println(x); end
julia> print_each(1, "hello", 23.4)
1
hello
23.4
</lang>
Conversely, when ...
is appended to an array (or other iterable object) passed to the function, the array is converted to a sequence of arguments:
<lang julia>
julia> args = [ "first", (1,2,17), "last" ]
3-element Array{Any,1}:
"first" (1,2,17) "last
julia> print_each(args...) first (1,2,17) last </lang>
Lasso
A Lasso method parameter name can prefixed by "..." to specify a variable number of parameters, which are made available as a staticarray. If no name is specified, the staticarray will be named "rest". <lang lasso>define printArgs(...items) => stdoutnl(#items) define printEachArg(...) => with i in #rest do stdoutnl(#i)
printArgs('a', 2, (:3)) printEachArg('a', 2, (:3))</lang> To expand an existing list, pass it to the method using invocation syntax. <lang lasso>local(args = (:"Rosetta", "Code", "Is", "Awesome!")) printEachArg(:#args)</lang> Output: <lang lasso>staticarray(a, 2, staticarray(3)) a 2 staticarray(3) Rosetta Code Is Awesome!</lang>
Logo
UCB Logo allows four classes of arguments (in order):
- 0 or more required inputs (colon prefixed words)
- 0 or more optional inputs (two member lists: colon prefixed word with default value)
- an optional "rest" input (a list containing a colon prefixed word, set to the list of remaining arguments)
- ...with an optional default arity (a number)
<lang logo>to varargs [:args]
foreach :args [print ?]
end
(varargs "Mary "had "a "little "lamb) apply "varargs [Mary had a little lamb]</lang>
Lua
<lang lua>function varar(...)
for i, v in ipairs{...} do print(v) end
end</lang>
M4
<lang M4>define(`showN',
`ifelse($1,0,`',`$2
$0(decr($1),shift(shift($@)))')')dnl define(`showargs',`showN($#,$@)')dnl dnl showargs(a,b,c) dnl define(`x',`1,2') define(`y',`,3,4,5') showargs(x`'y)</lang>
Output (with tracing):
m4trace: -1- showargs(a, b, c) a b c m4trace: -1- showargs(1, 2, 3, 4, 5) 1 2 3 4 5
Mathematica
Function that takes 0 to infinite arguments and prints the arguments: <lang Mathematica>ShowMultiArg[x___] := Do[Print[i], {i, {x}}]</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
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>
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>
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*
.
<lang parigp>f(a[..])=for(i=1,#a,print(a[i]))</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>
Perl 6
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>
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>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>$args = array("Rosetta", "Code", "Is", "Awesome!"); call_user_func_array('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:
<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)
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 2 3 4 5
- [1] "abc"
- [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>
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 none),
although some REXX implementations impose a limit.
<lang rexx>call print_all .1,5,2,4,-3, 4.7e1, 013.000 ,, 8**2 -3, sign(-66), abs(-71.00), 8 || 6, '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>
Ruby
The * is sometimes referred to as the "splat" in Ruby. <lang ruby>def print_all(*things)
things.each { |x| puts x }
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>
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>
Tcl
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>
Ursala
<lang Ursala>f = %gP*=
- 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>
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.
- Programming Tasks
- Basic language learning
- Ada
- ACL2
- ActionScript
- Aime
- ALGOL 68
- AutoHotkey
- AWK
- BASIC
- C
- C++
- C sharp
- Clojure
- COBOL/Omit
- Common Lisp
- D
- Déjà Vu
- E
- Emacs Lisp
- Erlang
- Euphoria
- Euler Math Toolbox
- Forth
- Fortran
- Go
- Groovy
- Haskell
- Icon
- Unicon
- Io
- J
- Java
- JavaScript
- TIScript
- Julia
- Lasso
- Logo
- Lua
- M4
- Mathematica
- MATLAB
- Maxima
- Metafont
- Modula-3
- Nemerle
- Objective-C
- Oz
- PARI/GP
- Perl
- Perl 6
- PHP
- PL/I
- PicoLisp
- PowerShell
- Prolog
- Python
- Qi
- R
- Racket
- REBOL
- RapidQ
- REXX
- Ruby
- Scala
- Scheme
- Slate
- Tcl
- Ursala
- V
- Visual Basic
- Vorpal
- XPL0
- Zkl
- GUISS/Omit
- TI-89 BASIC/Omit
- ZX Spectrum Basic/Omit
- OCaml/Omit