I’ve hit something of a roadblock in my Lox implementation when it comes to closures. Every implementation I’ve glanced at uses some kind of mutable object for the closure environment (which is stored alongside the Function declaration) that can be shared and gets cleaned up by the GC when all references to it are out of scope in the host language. (NOTE: the way environments are implemented so far is kind of in a linked list manner, whenever we enter a new block/function/etc a new environment is created and the current one is set as the 'enclosing' environment)
I had a solution in mind but it feels kind of bad:
Have some sort of map in the root (global) environment (or in some actor) that maps References to Environments, and give the Function declaration a Reference to some closure. When evaluating a call you just get the closure from the root. Then, whenever we're done evaluating the call, check the entire Enviroment (including all enclosing envs until the root) if there are any References in any Function somewhere on there and delete the closure entry if not.
To be fair I'm not even sure if the above works, I haven't really tried it, but I was wondering how you guys would tackle / have tackled something like this. Sorry if it's unclear, I can make my repo public if need be.
(For reference: https://craftinginterpreters.com/functions.html#local-functions-and-closures)