Adding a tail-call optimisation macro (for self-calls) is a really fun lispy project: https://github.com/Wilfred/tco.el/blob/179b82cacbd59692e3c187b98f87a1f453923878/tco.el#L51-L63
Ironically, I've implemented TCO using a recursive function that can blow the stack.