Questions regarding Nix evaluation/derivations

Hi, I have been interested in Nix for the last few years, and I have been trying to do something that works around it for my masters project, but I have some problems I haven’t been able to find practical solutions for (also sorry in advance for the rather vague topic title).

In short, I think the two main problems I have right now are:

  • Obtaining information on how a derivation/output in a flake is generated (a nix expression);
  • Comparing two different flake outputs.

To do this, I would like to know if with Nix, or with the available tooling, there is any way to:

  • “Intercept” a function call and obtain its arguments, as in, obtain the attribute set and/or function passed to a outputs.devShells.devShell (e.g. { packages = [ python3 ] … } and/or < function pkgs.mkShell>);
  • Trace back a derivation to its builder function call / passed argument attribute set (?) (since, I think, most builders use mkDerivation I would really actually want to even go farther back if available to a call like mkRustPackage or so). Essentially, my problem is that I would like to obtain information about the derivation that at the end is all mixed together and hard to make sense of.

If not, do you have any idea if these things are possible, how to go about doing them, or alternatives?

I think my problem of comparing two outputs wouldn’t really be if I could obtain a derivation’s builder expression, but I still wanted to include it for context.

Thanks