But having invariant is not enough to find (-1)!. So, extension to real numbers (or even to complex numbers) is a good approach to find limits lim(e-> -1+) e! and lim(e-> -1-) e!.
And trying to find a way how extend to unexited cases. For example, for f(x) = x / x function we could extend function to f(0) = 1 and for f(x) = x / x.abs() extends f(0) = 0
What you're missing is that the gamma-function is continous/smooth. That's what makes it a pleasing generalization of factorials. By including floor and ceil in your generalization, you're basically throwing away the benefits of real numbers, by going back to integers.
I regret adding the chunks section. I intended to make that less serious than the windows proposal. Didn't expect this to lead to some weird math discussion around how we extended factorial and how it is similar to this.
Here is one: given a sequence of numbers, find a subslice with the largest sum. This (granted: suboptimal) algorithm requires windows to work for 0 length:
You already mentioned "granted, suboptimal", but I'm not sure that this example fits under "reasonable, practical algorithms".
Or, to look at it slightly differently, we can ask how difficult it is to adapt something to deal with panicking for zero-length, and whether that makes the code better.
A simple tweak to make that function work without .windows(0) looks like this:
which fully maintains the structure and approach while being only marginally longer (_or&[] longer), but plausibly being faster by not having to look at all the zero-length slices.
Sure, you can always special case 0, but still, it's surprising to the user the code doesn't just work as is and they need to deal with the case separately. You can also imagine cases where you don't hit the panic in a unit test because you only get to 0 length windows sometimes, for example you start some search from longer length windows and usually you find what you're looking for before you get to 0, but sometimes you don't.
This tweak is incorrect. For instance, for input [-1, -2] the correct output is [] but your code gives [-1]. Which demonstrates the risk associated with having to deal with edge cases separately -- it increases the risk of bugs!