I considered the following piece of code. The Forward package is impressive in its flexibility! Nevertheless, I wonder if I am not missing some obvious optimization? Any suggestion are welcome.
using ForwardDiff n = 10_000 uv = [[randn(), randn()] for k = 1:n] function recfl(uv, fl, ∇fl) if length(fl) == 1 return fl(uv) + ∇fl(uv) else flv = @view fl[2:end] ∇flv = @view ∇fl[2:end] return fl(uv) + ∇fl(uv) * recfl(uv, flv, ∇flv) end end fl = [y -> cos(y * y), y -> sin(y + y), y -> atan(y - 3)] ∇fl = [y -> ForwardDiff.gradient(f, y) for f ∈ fl] recfls = uv -> recfl(uv, fl ,∇fl) @time ∇ffD = ForwardDiff.gradient.(recfls, uv);