I have written a bit of a hack of a library for evolutionary computation, where I continually evolve a system of "cells" that have different reaction networks governed by ordinary differential equations. Basically, when I need to solve the ODE for a cell, I have it generate a string that after parse/eval'ing is a function to be passed onto ode23s in ODE.jl for solving.
In 0.4 everything works, however, I cannot run too many iterations due to #14113, so I was looking forward to 0.5 where this is resolved, but then I found out that the strategy of overwriting the same function over and over is not recommended due to #265 and my code crashes in 0.5 as a result. I also see #16593 is saying that parsing/evaling on a string is bad form (although TBH I don't understand why this is so). So I am looking for thoughts/advice on the "correct" way to perform evolutionary computations in julia. I do not mind writing my library from scratch to do it properly. My initial thought to avoid constantly overwriting the function that I generate was to install a counter to always give a unique name to the generated function. But this seems like poor form since I don't see how garbage collection would know to remove old and unused functions from previous generations, so it seems like the explosion of functions defined in global scope would cause an unnecessary amount of memory usage for a long running evolution simulation. Is there a way to mark a function as available to be garbage collected, or am I wrong that this will cause memory issues? Julia's speed and metaprogramming facilities seem ripe for evolutionary computation, but I'm just not clear on what the julianic approach should look like, since my attempted efforts seem to be considered poor form or even incorrect. Thanks in advance for any thoughts.
