Speaking of Docker images and Dockerfiles, that's actually a real-world example of how you can achieve this kind of effect without relying on a specific language. Ironically, you can use Nix to build Docker images; there's a bunch of other alternative builders (e.g. Kaniko, Buildah); you can also just stitch together some files&metadata into tarballs, and then 'docker import' it.
Nix or Guix are of course much more powerful and expressive than Docker images, but there's always a cost to complexity.
If there is something that can be done in the nix language that can't be expressed in the underlying model that needs to be used by another frontend then it should be represented in the underlying model so another frontend can use it.
To put it another way, if you're designing a client-server model where there may be multiple client implementations you don't bake big chunks of the implementation into the clients, you provide it in the server interfaces and data types.
Not having functions as values (true of pretty much any serialization scheme I've ever seen) makes serialized data structures strictly less powerful than data structures in code.
> that needs to be used by another frontend
I don't think this was ever a goal of Nix. But if it was, well, you would end up with something considerably less powerful for the reasons I stated.
For example, see zb: https://www.zombiezen.com/blog/2024/09/zb-early-stage-build-...
Using a different language to depend on packages derived from .nix would be very much akin to depending on a docker image whose Dockerfile you can not inspect.