Description
I thought about way to get out of the current "dependency hell" (#378, #506, ...) - my apologies if this approach has been considered (and found wanting) already:
-
We move the DifferentiationInterface API definitions into a package DifferentiationInterfaceAPI (or similar name).
-
We create one package per AD backend, e.g. DIForwardDiff and so on. These packages are basically empty, they only depend on DifferentiationInterfaceAPI, and they implement the DifferentiationInterface API for "their" backend via a single extension (in each backend-implementation package). So DIForwardDiff has a weak dependency on ForwardDiff and an extension DIForwardDiffForwardDiffExt, but DIForwardDiff itself is basically empty. These backend-implementation packages can quicky adapt to breaking changes in the AD package they interface to, while only make a patch-increment of their own version number.
-
DifferentiationInterface depends on DifferentiationInterfaceAPI and all of the backend implementation packages - but they will only extremely rarely have breaking version changes. (Breaking changes in DifferentiationInterfaceAPI, however, will obviously have a ripple effect). DifferentiationInterface would be mostly empty then.
This way, users can load AD-backends, and combinations of AD-backends, with much wider version combinations, because the backend-implementations are decoupled, version-wise. So ideally, as long as a set of AD backends can be loaded together at all, in some version combination, it should also be accessible via DifferentiationInterface.
I realize that this approach would introduce a not insignificant management overhead ... but there should basically be no adverse effect on load and compile times. Also, tests would run decoupled for each backend.