I've been searching through the documentation and through various questions, but I have not seen a plain answer to this question. What types of values can be passed to Lua functions as arguments?
I believe the answer is:
Plain old data such as Integer or Boolean
Lua Tables
other Lua functions
What I am looking for is a comprehensive list of what all can be passed into a function.
From the Lua reference manual:
All values in Lua are first-class values. This means that all values can be stored in variables, passed as arguments to other functions, and returned as results.
vararg expression as an argument
In addition to passing any value as an argument, there is also an argument that is not a value: ..., the "vararg expression."
It can only be used in the body of a function where it is a formal parameter. When used at the end of a list, it expands the list with all of the actual arguments it represents. When used before the end of a list, it expands the list only with the first actual argument it represents.
local function f(a, b, ...)
print("f", a, b, ..., "end")
end
local function g(x, y, ...)
print( "g", x, y, ...)
end
f()
f(1)
f(1,2)
f(1,2,3)
f(1,2,3,4)
f(1,2,3,4,5)
g()
g(1)
g(1,2)
g(1,2,3)
g(1,2,3,4)
g(1,2,3,4,5)
Related
I am learning lambda expressions. I came across a scenario that can be understood by the below code:
Function<Integer,String> fn = (String s)->s;
In the above statement of lambda expression, I know that a function accepts an argument and returns the mentioned type. But why do we mention the argument type ,(here, it is Integer) on the part "Function" whereas the arguments are to be passed inside the "()". I know it is part of the syntax, but I just want to understand the point where it may be useful. It runs even if we pass an different argument type(String)?
First of all the Function you have written is wrong. It should be corrected as below.
Function<Integer, String> fn = s -> String.valueOf(s);
You can't state a different data type as above, only thing you can state is an integer. Any other data type as the input parameter would result in a compilation failure. The data type of the lambda function parameter is optional and is inferred by the compiler.
Consider the following function
ELEMENTAL FUNCTION int2str(i) RESULT(s)
INTEGER, INTENT(IN) :: i
CHARACTER(LEN = 50) :: appo
CHARACTER(LEN = :), ALLOCATABLE :: s
WRITE(appo, '(I0)') i
ALLOCATE(s, source = TRIM(appo))
END FUNCTION int2str
The function, being elemental, is a scalar function (in my case it takes one scalar integer and gives back one scalar character, even though allocatable in length) that applies elementwise to arrays.
Why the output of
print *, '>>>'//int2str([1, 3, 5, 7])//'<<<'
is (unexpectedly to me)
>>>1<<<>>>3<<<>>>5<<<>>>7<<<
whereas the output of
print *, '>>>', int2str([1, 3, 5, 7]), '<<<'
is (expectedly)
>>>1357<<<
?
What I mean is that the function should apply to every one of the four scalar integers composing the array, thus returning a length-4 array each element of which being a string, but it seems to me that its elementwise-ness applies to the whole concatenation of three strings, as though the // operator has precedence over the function's result.
For character concatenation, the expression
'>>>'//['1','3','5','7']
depends on the scalar '>>>' and the array ['1','3','5','7']. As with other intrinsic binary operations where the operands are a scalar and a rank-1 array, the expression is a rank-1 array.
In determining the value of the expression, the scalar operand is treated as an array like
['>>>','>>>','>>>','>>>']
and the expression is equivalent to
['>>>','>>>','>>>','>>>'] // ['1','3','5','7']
Finally, the expression has value where the elements are operands pairwise:
['>>>1','>>>3','>>>5','>>>7']
You can see the parallels with the expression
9+[1,3,5,7] ! [9,9,9,9]+[1,3,5,7] --> [10,12,14,16]
When there are two concentation operations going on, the obvious value is the result.
Note that I didn't express this in terms of an elemental function's result. This is partly because the fact the array comes from a function isn't significant. Also, your elemental function is not actually allowed: an elemental function result may not be allocatable.
On the invalid function, Vladimir F has submitted a bug report covering gfortran not detecting violation of the numbered constraint C1290 of Fortran 2008. In that report you can see that if you remove the result(s) and declare int2str as having the allocatable attribute the function is rejected. Some other compilers do already detect violation.
I've surprisingly experienced that result which I didn't expect (>>>1<<<>>>3<<<>>>5<<<>>>7<<<) is indeed the same even if I manually implement the ELEMENTALity of the function, namely
print *, '>>>'//[num2str(1), num2str(3), num2str(5), num2str(7)]//'<<<'
so I was possibly misunderstanding my own words thus RETURNing a length-4 array each element of which being a string. The function is indeed returning an array of strings, and the concatenation applies to every element of the array (the element of the array being stick together without space in between just because they're strings of characters).
Below is a sample code that addresses the problem I am having. The error message I am getting is
Function result 'sample' at (1) has no IMPLICIT type.
I label where line (1) is below.
I tried to follow this other question, however I wasn't able to figure it out. This function is within a module in my program and I made sure that the module has contains and I end the module after this function.
I also use implicit none in this function so I'm not sure why I get this message. How can I fix this error message?
Adding Real or Complex in front of function works, but I don't really get why. Shouldn't I only be able to use complex since the arrays are complex inside the function? Which is more suitable for my actual function? Both yield no compilation errors.
real function Sample(func) !this is line (1)
!complex function Sample(func)
implicit none
integer :: n,m
real :: x,y
complex, dimension(-9:9,-9:9), intent(in) :: func
complex, dimension(-9:9,-9:9) :: LocalF
LocalF = func
do n=-9,9
do m=-9,9
x = real(n)*0.2
y = real(m)*0.2
LocalF(n,m)= cmplx(z1(x,y),z2(x,y)) !assume z1,z2 are well defined
end do
end do
end function Sample
In Fortran every function has a result. If you like you can think of the result as a value returned by the function. Like every other value in a Fortran program a function result has a type, and a kind and a rank too.
By default the function result has the same name as the function itself, and its declaration is prepended to the function declaration. For example, here
integer function add(m,n)
integer, intent(in) :: a,b
add = a+b
end function
the function is called add and you can see (a) that the result is of type integer (and of default kind and scalar) and (b) that the result is formed by adding the two arguments together.
For functions returning arrays this syntax is not available, so you couldn't write something like
integer(1:4) add_vec(m1,m2)
In such cases you have to explicitly define the name (and later type and kind) of the result variable. Sticking with the simple example, something like
function add(m,n) result(addvec)
integer, intent(in) :: a(4),b(4)
integer, dimension(4) :: addvec
....
end function
Notice that you don't define the intent of the result.
In OP's case sample is, I think, intended to return a rank-2 array of complex values. I think OP needs to replace
function Sample(func) !this is line (1)
with
function Sample(func) result(LocalF)
and see how that goes. Here, if it is not evident already, you learn that the result name doesn't have to be the same as the name of the function.
Furthermore ... Adding Real or Complex in front of function works, but I don't really get why.
It might work in the sense of compiling, but executing it will lead to tears. By telling the compiler that the function result is either a real or complex value you satisfy the syntactical requirements for a function definition. But without assigning a (real or complex as declared) value to the result variable (called Sample in OP's code) the function will, at best, return junk.
To be as clear as I can ... in OP's original code there were two serious mistakes:
The function (result) was not given an explicit type, which lead to the compiler message shown.
The function did not include setting the value of the result variable, i.e. the variable with the same name as the function (in the absence of the result clause).
Procedures in Fortran come in two types: functions and subroutines. This question is about functions, so I'll consider just those.
What was missing in the first revision, giving the error about the implicit type of the function result1, was the result type.
Adding real function ... or complex function ..., etc., resolves that problem by explicitly giving the type of the function result. The linked documentation gives other ways of doing that.
The function's result is used when the function is referenced. When we have a reference like
func0 = Sample(func)
in the main program, the function Sample is invoked and the function result is defined in its execution. At the end of the function's execution its result is placed in the expression of the reference.
So, if you declare
real function Sample(func)
or
complex function Sample(func)
what you are saying is that the function result is either a real or complex entity. And when the function is evaluated, whatever value Sample had at the end is used in the expression (here assignment).
As a consequence of the function result being returned through Sample (in this case) we need to define its value. The important thing to note for the question, then, is that LocalF is a variable local to the function. If you mean it to be the result of the function you need to use the function result.
You have a number of options:
function Sample(func)
<type>, <attributes> :: sample ! Instead of LocalF
... :: func
end function
or
function Sample(func) result(LocalF)
<type>, <attributes> :: LocalF
... :: func
end function
You can even have
<type> function Sample(func)
<attribute statements for Sample>
... func
end function
but I really suggest you avoid that last one.
1 Note the error here is about type for the function result; in the linked question simply about the function when referenced.
Is there a way to pass a tuple as the parameters of a Lua function?
For example, I have a function that returns multiple values
function f(a,b) return b,a end
and I want this function f to be repeatedly applied, so I can write:
f (f ... f(1,2))
But what if I need to store this initial tuple (1,2) as a variable init?
f (f ... f(init))
Is there support for this?
According to this answer, it seems python has it with the splat operator *.
Lua does not have "tuples".
When a function returns multiple values, it returns multiple values. They aren't put together into some data structure; they're separate values. If you want to store multiple return values in a single data structure, you have to actually do that.
Lua 5.2 has the table.pack function, which you can use to store multiple return values in a table. But it does so in such a way that you can decompose them later:
local values = table.pack(f(1, 2))
f(table.unpack(values, values.n))
unpack exists in Lua 5.1, but pack does not. You can emulate it easily enough:
function pack(...)
return {n = select("#", ...), ...}
end
This question already has answers here:
What's the difference between an argument and a parameter?
(38 answers)
Closed 10 years ago.
I often find myself confused with how the terms 'arguments' and 'parameters' are used. They seem to be used interchangeably in the programming world.
What's the correct convention for their use?
Parameters are the things defined by functions as input, arguments are the things passed as parameters.
void foo(int bar) { ... }
foo(baz);
In this example, bar is a parameter for foo. baz is an argument passed to foo.
A Parameter is a variable in the declaration of a function:
functionName(parameter) {
// do something
}
An Argument is the actual value of this variable that gets passed to the function:
functionName(argument);
For user1515422, a very concrete example showing the difference between parameters and arguments:
Consider this function:
int divide(int numerator, int denominator) {
return numerator/denominator;
}
It has two parameters: numerator and denominator, set when it's defined. Once defined, the parameters of a function are fixed and won't change.
Now consider an invocation of that function:
int result = divide(8, 4);
In this case, 8 and 4 are the arguments passed to the function. The numerator parameter is set to the value of the argument 8, and denominator is set to 4. Then the function is evaluated with the parameters set to the value of the arguments. You can think of the process as equivalent to:
int divide() {
int numerator = 8;
int denominator = 4;
return numerator/denominator;
}
The difference between a parameter and an argument is akin to the difference between a variable and its value. If I write int x = 5;, the variable is x and the value is 5. Confusion can arise because it's natural to say things like "x is five," as shorthand for "The variable x has the value 5," but hopefully the distinction is clear.
Does that clarify things?
Arguments are what you have when you're invoking a subroutine. Parameters are what you are accessing inside the subroutine.
argle(foo, bar);
foo and bar are arguments.
public static void main(final String[] args) {
args.length;
}
args is a parameter.
There is nice section in parameter Wikipedia article about this subject.
In short -- parameter is the formal name defined by function and argument is actual value (like 5) or thing (like variable) passed into function.
Although Wikipedia is hardly an authoritative source, it does a decent job of explaining the terms.
I guess you could say that parameters are to arguments what classes are to instances of objects...
When you define a function like:
MyFunction(param1,param2) {
print parameter1, parameter
}
You set the parameters when you define the function.
When you call the function like this:
MyFunction('argument1', 'argument2');
You set the values of the parameters to the arguments you passed. The arguments are what you put in the question when you call it. Hope that helped.
Simply there is no major differences. If we go deeply inside this we can identify the diff.Mainly we know that Argument/Parameter/signature all are same.
Basically Parameter defines the type of Data we are passing.Where as the Argument defines the actual data/variable we are passing.
Parameter Example :-
int add(int a,int b){ //Here a and be both can treated as Parameter
return a+b;
}
Argument Example :-
int return_result=add(3,4); // Here 3 and 4 both can treated as Argument
or
int x=3,y=4;
int return_result=add(x,y);// Here x and y both can treated as Argument
In most cases, a procedure needs some information about the circumstances in which it has been called. A procedure that performs repeated or shared tasks uses different information for each call. This information consists of variables, constants, and expressions that you pass to the procedure when you call it.
To communicate this information to the procedure, the procedure defines a parameter, and the calling code passes an argument to that parameter. You can think of the parameter as a parking place and the argument as an automobile. Just as different automobiles can park in the parking place at different times, the calling code can pass a different argument to the same parameter each time it calls the procedure.
Parameters
A parameter represents a value that the procedure expects you to pass when you call it. The procedure's declaration defines its parameters.
When you define a Function or Sub procedure, you specify a parameter list in parentheses immediately following the procedure name. For each parameter, you specify a name, a data type, and a passing mechanism (ByVal or ByRef). You can also indicate that a parameter is optional, meaning the calling code does not have to pass a value for it.
The name of each parameter serves as a local variable within the procedure. You use the parameter name the same way you use any other variable.
Arguments
An argument represents the value you pass to a procedure parameter when you call the procedure. The calling code supplies the arguments when it calls the procedure.
When you call a Function or Sub procedure, you include an argument list in parentheses immediately following the procedure name. Each argument corresponds to the parameter in the same position in the list.
In contrast to parameter definition, arguments do not have names. Each argument is an expression, which can contain zero or more variables, constants, and literals. The data type of the evaluated expression should normally match the data type defined for the corresponding parameter, and in any case it must be convertible to the parameter type.
In fact both parameter and argument are different types of parameters. Those are
1)Formal Parameters - variables appear in function/subroutine definitions
for eg. (in Java)
public void foo(Integer integer, String... s2)
Here both integer and s2 are formal parameters or loosely speaking parameters.
2)Actual parameters or arguments - variables appear in subroutines while calling the
already defined subroutine
for eg. (in Java)
suppose If the function "foo" resides in object "testObject" ,
testObject.foo(new Integer(1), "test")
So variables in the function definition are called formal parameters or simply parameters and variables while calling methods are called as actual parameters or arguments. I hope it helps.
Think of it like basic algebra. X is the parameter that you have to fill in, and the number you place inside of it is the argument. So if you have an equation like X+2, X is your parameter, and any numbers you change for X become known as the arguments. So if using that equation you supplement 1 for x, you get 1+2. That means that 1 is an argument, supplied to the parameter of X.
Equally, if you have a function like dosomething("This"), it's definition would be dosomething(string parametername), but "This" would be the actual argument that is being supplied to the parameter, here named parametername.
In the simplest way to look at it, the parameter is the thing that the argument fills in, and the argument can be any number of things allowed by that parameter.
So it's a many-to-one relationship between Parameters and arguments, as you can have one parameter that can have many valid arguments, like our X+1 equation above. X can be any number known, and they are all valid.
A variable is a storage location and an associated symbolic name (an identifier) which contains data, a value.
A parameter is a variable passed to a function.
An argument is data (a value) passed to a function.
$variable = 'data/value';
function first($variable){ ... }
function second('data/value'){ ... }
function third(16){ ... }
In function first we are passing a parameter.
In function second and third we are passing arguments.