While I broadly agree with Mego's answer, I find that it leaves a few important cases as implications, and I think it would be clearer to spell them out explicitly.
I admit that the answer you linked isn't very explicit about how stack-based I/O works for functions, but there is a sort of unwritten but accepted set of rules that such functions adhere to (at least the ones I've written or reviewed), so this answer tries to collect these:
- When the function is called, input is given as a number of values on top of the stack. The function must not assume that the input is the only content of the stack. In particular, the function should work regardless of the stack contents beneath the input.
- If the input is a list of variable length, the individual values may appear as separate values on the stack, but then there either needs to be an appropriate terminating value (e.g. a
-1
if all elements are guaranteed to be non-negative numbers) or the number of elements should be on top of the stack.
- At the end of the function, all input values should be replaced with the output values. Any part of the stack that wasn't part of the input has to remain unchanged.
- As for input, variable-sized output is possible either by terminating it with an appropriate value or by storing the number of values on top.
- Finally, if the solution is entirely indistinguishable (by the means of the language) from a solution that follows the above rules, it's valid.
The last point is where infinite stacks come into play. In general, a function can't work with the infinite well at the bottom of the stack, because you're not allowed to make any assumptions about what lies between the input and the infinite well. However, if your function detects that there is nothing between the input and the infinite well, and the output is identical to the default value of the infinite well and it's impossible to distinguish implicit values from explicit ones, then the function can return on an "empty" stack.
The key here is "it's impossible to distinguish implicit values from explicit ones". As an example, my language Labyrinth (which doesn't have functions, but it will act as an example) has infinite stacks with an implicit well of zeros at the bottom. However, it does make a difference whether you leave off with an "empty" stack or a stack with a single explicit zero on top, because there's a stack-depth command, which would count the explicit zero. Other languages, like my language Stack Cats (still no functions, but you get the point) will automatically discard any zeros at the bottom of the stack, because they're indistinguishable from the infinite well anyway.
Further, consider a hypothetical language that doesn't have an infinite well of zeros, but where the stack starts out with 1 on top, 2 below that, then 3 and so on (still an infinite well, but it contains the natural numbers instead of copies of a fixed value). In this case, it's unlikely you'll be able to make use of the infinite well at all, because the function can't assume that all of the implicit values are still there, and even if they are, putting another 1
on top is clearly different from not doing so.
So while in principle it's possible to make use of the infinite well at the bottom, this only works in the very narrow case, that there is absolutely no way to tell the difference, which is probably not worth the bytes in most cases.