My mistake. I meant to write "can SOMETIMES be entirely on the stack" -- fixed that just now.
Functions indeed cannot return closures without heap-allocating them. (It might be possible in specific obscure cases, but definitely not in general.) However, if you wish to curry a function foo(a,b), you can do that in the caller (instead of at the function definition itself) by writing:
let curried_foo = |b| foo(a,b);
That is then stack-allocated and can refer to 'a' in the same frame, and can be passed to other functions you might call from there (but not returned upwards, indeed).
Functions indeed cannot return closures without heap-allocating them. (It might be possible in specific obscure cases, but definitely not in general.) However, if you wish to curry a function foo(a,b), you can do that in the caller (instead of at the function definition itself) by writing:
let curried_foo = |b| foo(a,b);
That is then stack-allocated and can refer to 'a' in the same frame, and can be passed to other functions you might call from there (but not returned upwards, indeed).