Declaring arguments to a function
Jeremy Dunn
jeremydunn@ibm.net
Tue, 15 Jun 1999 10:12:10 -0700
The standard way of declaring a function and its arguments in C (or in
a
lot of languages) is a form like
return-type FUNCTION NAME (arg1,arg2,...,argN){
<program statements>
}
We wish to do the following in defining arguments:
1. We want to define the number of arguments.
2. We want to define the type of the arguments.
3. We want to define default values if the argument position is present
but empty.
4. We want to define default values if the argument position is not
present.
I propose a form something like
return-type FUNCTION NAME
(<# of arguments>,
<argument names>,
<argument types>,
<default values> (if any)
)
{
<program statements>
}
Let us discuss each part of the declaration one step at a time. I
envision the number of arguments as being declared as an integer as
one
would declare a string array in C where you must decide on a value. But
what if I define 20 arguments and I need to put in 30? I will get to
that later.
Declaring argument names is done by giving the name of the argument you
are going to use in your program and then following it by the index of
the argument position that is going to use that name. For instance, in
a
function of two arguments we could write either (Base,Power) without
indexes if we have a name for every argument or we could write it as
(Base(0),Power(1)) where we declare the indice. Suppose the 1st
argument
is named Base but we have several related arguments following it of the
same type in our program? We could write (Base(0),Power(1-)) where the
hyphen means that all arguments following index 0 are related somehow.
The compiler would automatically number these extra argument names as
Power1, Power2 and so on, and that is how we would call them in our
program.
Defining the argument types is done in a list like (int, float, string)
and so on for each argument. If all the arguments are of the same type
then you could write (int) to have the type default to int for all of
them. Suppose the first three arguments are type int and everything
following those are type string? You would write that as
(int(-2),string(3-)) where the statement means that arguments at list
indexes from 0 to 2 are ints and the indexes from 3 onwards are of type
string. Nonconsecutive indexes of the same type could be stated like
(int(0,2,4),string(1,3)). (Simple eh?
Default values are equivalent to what one does with the "optional"
statement in VB. In this case one declares the optional value and
follows it with a bracketed list of the index values of the arguments
it
applies to. The index values for the arguments are numbered starting at
0. So if I wanted to declare that argument 3 defaults to 24 then I
would
write the statement (24(23)). If I wanted arguments 1 thru 4 to default
to "A" and argument 5 onward to default to 2 then I would write
("A"(-3),2(5-)). I could also have written the start and end indexes
explcitly as in ("A"(0-3),2(5-)). If the start index is missing it
assumes that it is 0 and if the finish index is missing then it
continues for all arguments after the first one. Naturally, one can
choose nonconsecutive indexes as in a statement like ("A"(0,2,7)). One
may not declare more than one optional value for a given index.
Now we have three special commands in our language that are very useful
in regards to all of this. These three functions have no arguments but
return information that is very useful. The 1st function
NumberOfArguments() basically counts the number of commas in the
argument part of the function and adds one to give the total number of
argument spaces that are defined by your statement. So if you wrote
FUNCTION(,,,,)
with nothing actually input into the statement then NumberOfArguments()
would say there are 5 argument slots.
The 2nd function is called EmptyArguments(). This function looks at the
previous function statement and gives a list of the argument indices
that have nothing in them. In our example the list (0,1,2,3,4) would be
returned.
The 3rd function is the complement to the previous and is called
FullArguments(). This function returns a list of all indices that
actually had some characters typed into them.
This way of doing things gives us full argument control and enables us
to do some things programatically that cannot be done in other
languages.
How about an example? Let us write a function called Pwr() that returns
the power of a number. Let the statement Pwr(s,t) be equivalent to the
statement s^t. Let the function allow us to input up to 5 extra powers
so that the statement Pwr(s,t,u,v,w,x) would be equivalent to
(((((s^t)^u)^v)^w)^x). If the 1st argument "s" is empty then we wish
the
base to default to 2.718... the base of logarithms thus Pwr(,t) is
equivalent to exp(t). If there is only argument then the function takes
the square of whatever you put into it i.e. Pwr(x) is the same as x^2.
If there are two arguments and the 2nd argument is empty then the power
is assumed to be 3 i.e. Pwr(x,) is the same as x^3. If there is three
or
more arguments and any of the power arguments are empty then they are
assumed to be 2. So the statement Pwr(s,,,) would be the same as
(((s^2)^2)^2). We would write our function declaration like this:
double Pwr(<7,
(Base(0),Power(1-)),
(double),
(2.718(0),2(1-)),
)
{
<program statements>
}
Now using our special three functions we can access all the argument
information we need to write a program that does all of the above.
There
is no way to write a function with ALL the features described without
something like what I have described. I think my way is more intuitive,
we do not have to deal with Paramarrays and such.
What about if I write an addition function that has 20 arguments
defined
and I supply 30? We must come back to stating the number of arguments.
If I write <7 as in the example then the compiler assumes that I mean
that the function must have less than 7 arguments. If I wrote =6 or
just
6 instead then the compiler would assumed that I meant that the
function
must have 6 exactly 6 arguments present. In fact, we could even write
((>0,<7)) to declare that the function must have at least one argument
present but no more than 6. If the argument number statement is empty
then it assumes that the function requires NO arguments. I cannot
declare simply >0 to imply a function that holds any number of
arguments
but must declare some limit. If I say <7 and input 8 arguments then I
may input extra arguments but in the program I must use
NumberOfArguments() to test the number and if it is more than 6 I must
issue the equivalent of a VB Redim statement. Let us say I actually
input 10 arguments, I would have a statement like
N = NumberOfArguments()
If N > 6 {
ReDim Pwr(N)
}
In this case the name of the array is the name of the function. All
extra arguments will take on the name and qualities of the last
argument
defined in the original function. If we define the number of arguments
as =6 or just 6.
So, does anyone like any of this? Detest it? I await your insightful
comments.