The behaviour you are seeing is basically how stacks work. You are appending stuff to the top of the stack by calling the function (as each call adds a new frame on top of the stack) and then removing from it when you print and return (you print the top, return removes the top frame). You also return a value which cascades down based on when it reaches the far top of the stack of calls.
Only if you inverted the order of printing and calls. If you printed first and then called second then yes, the first will be 5. Eg...
Code:
function f(n)
if n == 0 then return 0
else
print(n)
return f(n - 1)
end
end
print (f(5))
No, it is a value returned by the function. You need to use a function pointer to represent a function. I am unfamiliar with LUA (usually do C/C++ or JAVA) but I am guessing it would look something like this...
Again, I am not sure if that is valid LUA but the idea for the variable to represent a function is that you give it the function as an argument (its name) and not try and evaluate the function. In C/C++ you need to reference the function with & operator which will convert it into a function pointer.
The function calls itself until the condition "n == 0" is reached. This means the function is recursive as it will keep calling itself until a solution or crash occurs. I mention the crash as this is a big problem with recursive functions since if they go too deep they will overflow the stack which will either cause a process crash (modern OS) or BSoD (integrated systems or old OS). Generally you want to avoid recursive function calls where possible as their maximum depth is based on how deep they were called from and the thread stack size. This also makes them not very argument safe (large arguments can cause a crash, if you were to call your function with value 2147483647 your program will probably crash). They are useful as each stack frame can allocate new variables, as such you can take advantage of a stack based allocation system without the need for dynamic memory allocation on the heap however problems that need this seldom occur outside of tree like structures (which never go too deep anyway).
The most famous example of this gone wrong was the WC3 crash hack. If you were to queue over 30k invalid orders onto a unit and have them validate them all at once WC3 used to crash as it would cause a stack overflow due to nested function calls resolving each order. Hackers made a tool to queue up the orders (since that is not humanly possible, it even made a huge amount of lag from network traffic) and then all the user had to do was collapse the order (eg cancel a building) and then boom, everyone crashed. Obviously they used a hacked version of WC3 with larger stack size so they did not crash and they were counted as the winner. Luckily most of these people were banned when they patched the bug.