After missing a couple of sessions I was able to attend the reading group to go through There and back again, a functional pearl demonstrating techniques for recursing over a list or other data structure and processing it "at return time" to perform convolutions or other operations like palindrome checking.
The examples were all given in ML which gives me a bit of a headache, but the paper leads off with three exercises for the reader that were very helpful for focusing the attention and led to some interesting discussion.
The attached files demonstrate how to use the there-and-back-again approach in Haskell (taba.hs) and Prolog (taba.pl) to implement convolution, palindrome checking, and also general list reverse. It's basically just using the call stack to avoid needing to construct an auxiliary list, and whether that's beneficial or not depends on what you're doing (and how big is your stack) but it's a useful technique to know.
It inspired me to add a decidedly non-functional bonus: a C program (palindrome.c) that checks whether a list is a palindrome using no recursive calls and no allocation by reversing the second half of the list in place, doing the check, then reversing it back again! (It would have been nice to do this in Rust, but sneaking the mutation past the borrow checker appears to require unsafe code or additional overhead).
There and back again
https://dl.acm.org/doi/10.1145/581478.581500