Reputation: 229361
Python, C++, Scheme, and others all let you define functions that take a variable number of arguments at the end of the argument list...
def function(a, b, *args):
#etc...
...that can be called as followed:
function(1, 2)
function(1, 2, 5, 6, 7, 8)
etc... Are there any languages that allow you to do variadic functions with the argument list somewhere else? Something like this:
def function(int a, string... args, int theend) {...}
With all of these valid:
function(1, 2)
function(1, "a", 3)
function(1, "b", "c", 4)
Also, what about optional arguments anywhere in the argument list?
def function(int a, int? b, int c, int... d) {}
function(1, 2) //a=1, c=2, b=undefined/null/something, d=[]
function(1,2,3) //a=1, b=2, c=3,d=[]
function(1,2,3,4,5) //a=1, b=2, c=3, d=[4,5]
Upvotes: 2
Views: 1016
Reputation: 45122
Several languages (perl, python, many others) can do named arguments, which are akin to doing optional arguments anywhere in the parameter list... (The named parameters can appear in any order, and any of them can be made optional...) They're not strictly the same, but they're close...
Not sure about varargs, though they can usually be replaced with an array/hash/list object...
Upvotes: 1
Reputation:
It is called Rest Arguments and it can be done at least in C++ and Java. Google "Rest Arguments" and you will find a lot of data on the subject with some examples like functions that will pass numbers and return an average of the numbers input, maybe the minimum or maximum of all numbers passed. As you can see, there are a lot of uses for such features, I used it in code for inputing data in MYSQL so when I want to add a row, I just add the Table name as the first string and the rest are all column names and then their data without having to sit there and manually do it over and over again. Good Luck!
Upvotes: 0
Reputation: 21218
R (the statistical language) has it as well, and it can be in the middle of the list, but there are subtle semantics.
http://cran.r-project.org/doc/manuals/R-intro.html#The-three-dots-argument
> f1 <- function(x,...,y) { return(x+y) }
> f1(1,2)
Error in f1(1, 2) : argument "y" is missing, with no default
> f1(1,y=2)
[1] 3
> f1 <- function(x,...,y) { return(x+y) }
> f1(1,2)
Error in f1(1, 2) : argument "y" is missing, with no default
> f1(1,y=2)
[1] 3
>
Upvotes: 0
Reputation: 49089
BASIC has had this for ages.
For instance:
LOCATE [row%] [,[column%] [,[cursor%] [,start% [,stop%]]]]
This command sets the position (row%, column%) of the cursor, as well as specifying the cursor size (start%, stop%) and whether it is actually visible (cursor%). Here, everything in square brackets can be omitted, and if it is, that property is not changed.
A usage example:
LOCATE , 5
to change to column 5, or
LOCATE 1, , 0
to move to the first line and make the cursor invisible.
Another command where this is seen is the PUT command for writing to files. If the middle argument (the file seek position) is omitted then writing occurs just after the previous write.
Importantly, argument omission is only seen in built-in statements, and not user-defined procedures and functions.
In terms of implementation, this is what the Microsoft Basic Compiler (BC) seems to do for a call to LOCATE:
Upvotes: 2
Reputation: 369458
Future versions of Ruby (1.9 and up, Ruby 1.9 is scheduled to released at the end of January, 2009) can do this.
It is however not always obvious which value gets bound to which parameter.
This is what Ruby 1.9 accepts:
0 or more mandatory arguments followed by 0 or more optional arguments followed by 0 or more mandatory arguments followed by rest arguments followed by 0 or more mandatory arguments.
Example:
def meth mand1, opt1 = :def1, o2 = :d2, *args, m2, m3
puts %w[mand1 opt1 o2 m2 args m3].inject('') { |s, arg|
s << "#{arg} = #{(eval arg).inspect}, "
}.gsub /, $/, ''
end
meth :arg1, :a2, :a3
# => mand1 = :arg1, opt1 = :def1, o2 = :d2, m2 = :a2, args = [], m3 = :a3
meth :arg1, :a2, :a3, :a4
# => mand1 = :arg1, opt1 = :a2, o2 = :d2, m2 = :a3, args = [], m3 = :a4
meth :arg1, :a2, :a3, :a4, :a5
# => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a4, args = [], m3 = :a5
meth :arg1, :a2, :a3, :a4, :a5, :a6
# => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a5, args = [:a4], m3 = :a6
meth :arg1, :a2, :a3, :a4, :a5, :a6, :a7
# => mand1 = :arg1, opt1 = :a2, o2 = :a3, m2 = :a6, args = [:a4, :a5], m3 = :a7
As you can see, mandatory arguments are bound first, from both the left and the right. Then optional arguments get bound and if any arguments are left over, they get bundled up in an array and bound to the rest argument.
Upvotes: 1
Reputation: 506955
The next C++ can do that with this syntax:
void f(int a, std::initializer_list<int> b, int c) {
// b.begin(), b.end(), b.size() allow to access them
}
void g() {
f(1, { 2, 3, 4, 5 }, 2);
}
Upvotes: 2
Reputation: 18984
I suppose PHP counts. You can do this to simulate what you are looking for. Personally, I think that would be confusing though.
function foo() {
$args = func_get_args(); // returns an array of args
}
Upvotes: 0
Reputation: 20621
Lisp's keyword parameters may be what you are looking for. I think there is a similar arrangement in Ruby. See also Lisp's function parameters overview.
Upvotes: 0