Variadic function: Difference between revisions

From Rosetta Code
Content added Content deleted
No edit summary
No edit summary
Line 2: Line 2:
Functions of this type are also known as [http://en.wikipedia.org/wiki/Variadic_function Variadic Functions].
Functions of this type are also known as [http://en.wikipedia.org/wiki/Variadic_function Variadic Functions].


=={{header|Groovy}}==
=={{header|Actionscript}}==
<lang actionscript>public function printArgs(... args):void
<lang actionscript>public function printArgs(... args):void
{
{
Line 318: Line 318:
end program varargs</lang>
end program varargs</lang>


=={{header|ActionScript}}==
=={{header|Groovy}}==
<lang groovy>def printAll( Object[] args) { args.each{ arg -> println arg } }
<lang groovy>def printAll( Object[] args) { args.each{ arg -> println arg } }



Revision as of 21:11, 6 September 2009

Task
Variadic function
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.

Actionscript

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

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

}</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 Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
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))
)

Output:

Mary had 1 little *

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

ALGOL 68 does not have anything similar the keyword argument found in python.

AutoHotkey

AutoHotkey allows function arguments to be given default values. Comparison with "" can indicate that an argument was present (and not of value ""). Calling a function with more than the defined arguments produces a warning. <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 functions to be called with less than the defined arguments - the missing one(s) default to "". Comparison with "" can indicate that an argument was present (and not of value ""). Calling a function with more than the defined arguments produces a warning. <lang awk>$ awk 'func f(a,b,c){if(a!="")print a;if(b!="")print b;if(c!="")print c}BEGIN{print f(1)}' 1 $ awk 'func f(a,b,c){if(a!="")print a;if(b!="")print b;if(c!="")print c}BEGIN{print f(1,2)}' 1 2 $ awk 'func f(a,b,c){if(a!="")print a;if(b!="")print b;if(c!="")print c}BEGIN{print f(1,2,3)}' 1 2 3</lang>

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.

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().

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>

  1. 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 as int in va_arg.

The next version of C++ will in addition allow typesafe variadic arguments through variadic templates. Some compilers, such as gcc, already provide this functionality. The following implements the task with variadic templates:

Works with: g++ version 4.3.0

using option -std=c++0x

<lang cpp>

  1. 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

Common Lisp

The &rest lambda list keyword causes all remaining arguments to be bound to the following variable.

(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))

D

<lang d>import std.stdio: writefln;

void printAll(TyArgs...)(TyArgs args) {

   foreach (el; args)
       writefln(el);

}

void main() {

   printAll(4, 5.6, "Rosetta", "Code", "Is", "Awseome!");

}</lang> Output:

4
5.6
Rosetta
Code
Is
Awseome!

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:

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"])


For comparison, a plain method doing the same thing for exactly two arguments would be like this:

def non_example {
    to run(x, y) {
        println(x)
        println(y)
    }
}

or, written using the function syntax,

def non_example(x, y) {
    println(x)
    println(y)
}

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.

: sum ( x_1 ... x_n n -- sum ) 1 ?do + loop ;
4 3 2 1  4 sum .   \ 10

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.

: .stack ( -- ) depth 0 ?do i pick . loop ;

Fortran

Works with: Fortran version 95 and later

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>

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.

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" "Awseome!"

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

varargs.icn

procedure main ()
  varargs("some", "extra", "args")
end

procedure varargs(args[])
  every write( args[1 to *args])
end

Using it

|icon varargs.icn
some
extra
args

Io

printAll := method(call message arguments foreach(println))

J

J's data is arbitrary length lists. So all functions implicitly support variable length argument lists unless their definitions specifically reject them.

Java

Works with: Java version 1.5+

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){

  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", "Awseome!");</lang>

Or with an array directly: <lang java5>Object[] args = {"Rosetta", "Code", "Is", "Awseome!"}; printAll(args);</lang>

But not with both: <lang java5>Object[] args = {"Rosetta", "Code", "Is", "Awseome,"}; printAll(args, "Dude!");//does not print "Rosetta Code Is Awesome, Dude!" //instead prints the type and hashcode for args followed by "Dude!"</lang>

JavaScript

<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", "Awseome!");</lang>

You can use the apply method of a function to apply it to a list of arguments: <lang javascript>args = ["Rosetta", "Code", "Is", "Awseome!"] printAll.apply(null, args)</lang>

Works with: UCB Logo

UCB Logo allows four classes of arguments (in order):

  1. 0 or more required inputs (colon prefixed words)
  2. 0 or more optional inputs (two member lists: colon prefixed word with default value)
  3. an optional "rest" input (a list containing a colon prefixed word, set to the list of remaining arguments)
  4. ...with an optional default arity (a number)
to varargs [:args]
 foreach :args [print ?]
end
(varargs "Mary "had "a "little "lamb)
apply "varargs [Mary had a little lamb]

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.

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>

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", @"Awseome!", nil); logObjects([NSNumber numberWithInt:4],

          [NSNumber numberWithInt:3],
          @"foo", nil);</lang>

OCaml

This is typically the kind of things that are impossible in OCaml, because it is a strongly statically typed language.

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", "Awseome!");</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", "Awseome!"); print_all(@args);</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", "Awseome!");</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", "Awseome!"); call_user_func_array('printAll', $args);</lang>

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", "Awseome!")</lang>

You can use the same "*" syntax to apply the function to an existing list of arguments: <lang python>args = ["Rosetta", "Code", "Is", "Awseome!"] 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.

R

This first function, almost completes the task, but the formatting isn't quite as specified. <lang R>

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 R>

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 R>

arglist <- list(x=runif(10), trim=0.1, na.rm=TRUE)
do.call(mean, arglist)

</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$.

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", "Awseome!"

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", "Awseome!")</lang>

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

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" "Awseome!")</lang>

The apply function will apply the function to a list of arguments: <lang scheme>(define args '("Rosetta" "Code" "Is" "Awseome!")) (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>

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>

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,

[myfn
   [zero? not] [swap puts pred]
   while
].
100 200 300 400 500 3 myfn

results in:

500
400
300