append to function lua - function

I have a function I want to add to dynamically as the program runs.
Let's say I have function Foo:
function foo()
Function1()
Function2()
Function3()
end
and I want to change Foo() to:
function foo()
Function1()
Function2()
Function3()
Function4()
end
later in the program. Is there any way to do this?

Just do it. The code that you wrote works fine. Functions in Lua can be redefined as desired.
If you don't know what foo does, you can do this:
do
local old = foo
foo = function () old() Function4() end
end
Or perhaps it is clearer to use a table of functions:
local F={ Function1, Function2, Function3 }
function foo()
for i=1,#F do F[i]() end
end
Latter, do
F[#F+1]=Function4
and you don't need to redefine foo.

This is a supplementary answer with background information.
Lua identifiers are used for global variables, local variables, parameters and table fields. They hold any type of value.
Lua functions are values. Lua functions are all anonymous, regardless of the syntax used to define them.
function f()
--...
end
is a Lua statement that compiles to a function definition and an assignment to a variable. It's an alternate to
f = function()
--...
end
Each time a function definition is executed, it produces a new function value, which is then used in any associated expression or assignment.
It should be clear that neither statement necessarily creates a new variable nor requires it to always have the same value, nor requires it to always hold a function value. Also, the function value created need not always be held only by the one variable.
It can be copied just like any other value.
Also, just like other values, function values are garbage collected. So, if f had a function value and is assigned a different value or goes out of scope (say, if it wasn't a global variable), the previous value will be garbage collected when nothing else refers to it.
Without any other context for function f() end, we would assume that f is a global variable. But that's not necessarily the case. If f was an in-scope local or parameter, that is the f that would be assigned to.

Related

Why a local variable is not accessible in a function that is declared after the function definition and before it's call?

I'm new to Lua. I noticed the following pattern in Lua. But I'm not understanding why it's happening.
Here, a is a global variable and it's accessible inside the foo function:
function foo()
print(a)
end
a = 10
foo() -- 10
But if we declare a as local it's not any more accessible inside the function foo:
function foo()
print(a)
end
local a = 10
foo() -- nil
Why the global variable is accessible inside the function while the local is not?
That's because global variables work differently: Local variables abide by lexical scoping. This means that variable visibility is intuitive: The variable is visible only after it has been declared; it is also visible in nested blocks (such as the function block) or other control flow statements (ifs or loops).
In
function foo()
print(a)
end
local a = 10
foo() prints nil because the local variable a isn't visible yet; the function accesses the global variable _G.a at run time instead, which evaluates to nil. Setting the the global variable a = 10 is equivalent to _G.a = 10 or _G["a"] = 10. When foo is run, it indexes the global table using _G["a"] to find the value for the variable a which yields 10 as expected.
TL;DR: Visibility of global variables depends on order of execution since global variables are just syntactic sugar for accessing a table under the hood; visiblity of local variables abides by lexical scoping - variables must be declared before use
(actually foo indexes the upvalue _ENV which is _G by default if it was not assigned to, but for the sake of simplicity I'm using _G above)
To use a local variable, which is often recommended both for performance & readability reasons, simply declare it before the function:
local a
function foo() print(a) end
a = 10
foo()
local variables inherited by functions are called upvalues in Lua.

Creating an ODE function Fortran [duplicate]

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.

Function result has no implicit type

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.

Functions and procedures in QTP/VBA/VB6

What is the difference between function and procedure ?Aprart from returning value
Because function can also be used as a procedure if you dont return any value then what is the difference...then what is the use of functions ?
Please specify a scenario where we can use functions and procedures ??
Since your title specifies VBA and VB6, I'll reference the type of subroutines used by those languages. VBA and VB6 use "Function" for subroutines that return a value and "Sub" for those that do not. It's certainly possible to use a Function for all of your subroutines and just ignore the return value. Unlike C++ and many other languages, you're not required to return a value from a VB function. Because VB automatically initializes all variables to default values (zero for number types, False for Boolean, the empty string for String, etc), any functions that don't explicitly return a value will simply return their default value, which you can ignore. For example:
Function MyFunc() As Long
' Nothing here
End Function
This function will return the value zero.
So while you can use Function in place of Sub and just ignore the return values, it's not a good programming practice. Other users of your code will assume you chose Function instead of Sub because you intended to return something meaningful and will likely be surprised to discover that you're not returning anything at all!
There MAY also be a slight performance hit when using Function vs Sub, due to the extra parameter value that is passed on the calling stack (the return value).

Where is the return value of a function stored?

I assume this question is language agnostic, and apologies if it's quite rudimentary, but say we have (PHP in this example)
function myFunc() {
return 4;
}
Now when this function is called, usually the result will be used in an expression or be assigned to a variable. But if it's not assigned to a variable, where does the return value "live" when it's been called? Is there an internal structure that keeps it in memory for the purpose of the current statement, and when that statement is executed, it removes it again?
If you just do something like:
var foo = bar();
myFunc();
var wibble = baz();
Then a Number 4 will be created for the return statement, then immediately will be discarded as there aren't any references to it.
(Note: C++ specific) In most cases compiler will user Return Value Optimisation and store value in the variable that gets the result of the function assigned to.
For example:
int myInt = myFunc();
will cause the pointer to myInt varaible to by passed to myFunc on the stack so myFunc will work directly with myInt without creating a new variable.
Otherwise the function returns by placing the return value on the stack.
I think in .NET it's called Name Return Value Optimization.
Other compilers probably have similar features in place.
so say we had a more complex statement like myFunc() + ComplexFunction()
I think this one depends on the compiler and it's register allocation scheme.
The compiler could store the result for myFunc() in a register, then jump to execute ComplexFunction(). On entering ComplexFunction(), the registers would be saved on the stack and the restored when returning.