I quite like Jeremy's approach: https://nbviewer.org/github/fastai/fastbook/blob/master/17_f...
It shows a very simple "Pythonic" approach to assemble gradient of a composition of functions from the gradients of the components.