The easiest way to get what you want is obviously gradient(a->2^a, 2), but I am assuming there are other considerations which lead you to the approach you proposed above. We might be able to help further if you share more details.
Edit: Let me provide a little more context. Consider L as “data”, and a as parameters to be estimated later. The derivatives with respect to L have theoretical importance. The derivatives with respect to a are to be used in an optimization procedure later.
I’m no expert, but I would say the main occasion when Params comes in handy is if the function to differentiate consists of many nested, parametrised functions (e.g. a deep neural network). In this case, it can be annoying to explicitly pass the parameters through the callstack, and Params provides a means to avoid that. However, note that the Zygote documentation lists at least two other ways to achieve this and actually recommend against using Params:
However, implicit parameters exist mainly for compatibility with Flux’s current AD; it’s recommended to use the other approaches unless you need this.