> how that's even possible given that distros make their own modifications?
Own modifications to what? All the packages in nixpkgs depend only on other packages in nixpkgs. If you install nix on an ubuntu system and then install a package from nixpkgs, then that package won't use any ubuntu libraries.
> Own modifications to what?
To the packages. e.g. I believe Ubuntu modifies Python so that sudo pip install uses /usr/local instead of /usr. Lots of other patches and backports I'm not necessarily aware of. That's basically what makes Ubuntu Ubuntu, otherwise it'd be more like Arch. So how does Nix deal with this? Do you get the value-add from your distro or do you basically end up with pseudo-Arch wherever you start?
If you install python through nix, you get the nix version.
If you install python through apt, you get the ubuntu version.
I get that part. I'm asking what the Nix version is like. Is it like the Ubuntu version with all the patches and backports and everything, or is it like the Arch (i.e. basically original unmodified) version?
Nix packages are typically close to upstream, but low-level packages sometimes have patches to make them more reproducible and deterministic, so that they work better with Nix's efforts for determinism and purely-functional packaging.
Nix packages are created from scratch, not copied from another distro. Nix is typically one of the most up-to-date distros: https://repology.org/
Okay thanks, so it sounds like I'll (roughly) end up with Arch (i.e. mostly-unmodified) whether I start on Ubuntu, Fedora, or whatever. I have another on that front: what about things like kernels? Don't those conflict with the OS?
If you install the "linux" package using nix on Debian, you get a directory in your nix store (the collection of "installed" packages) containing a bzImage, a System.map, and a `lib` directory containing all of the kernel modules. It would then be up to you to build an initrd and wire it into your bootloader, if that's what you wanted to do.
In other words, Nix packages are just files in their own special place on the disk (under /nix). If you want to configure binaries from those packages to run as daemons, or otherwise be wired into the system globally, that's up to you.
In fact, this is also true for the packages that you've "installed"! The nix package manager creates a package that represents your "user environment", and that package just merges all of the packages you installed using symlinks, and a symlink to that package is added to your $PATH.
"Just files" doesn't quite capture the complexity of the situation to me though. Say I happen to install package X via apt and Y via nix, and both of them depend on Z (in apt and nix respectively), and Z needs to bind to a port, then I imagine both will install but one of them will break, possibly including their dependents. Or if I install a package on Nix that expects a certain syscall that's not in the Ubuntu kernel yet (maybe like the recent /usr/bin/sleep issue with WSL), then that either breaks Nix or my ability to keep using an Ubuntu kernel. Right? And there are probably other things I'm just lacking the imagination for right now. But it seems to me there are all sorts of conflicts that can come up in practice. I've seen enough trainwrecks when upgrading even across OS versions that I have a hard time seeing how running 2 package managers can work on a single OS without breaking something?
That actually is impossible, Nix will only depend on packages in nix, and nothing else. So whatever you have installed won't affect it.
The important part of Nix on Linux is patchelf[1] basically binaries generated are processed by it, this rewrites elfs to link to libraries in the /nix/store
Regarding syscalls, if you use NixOS then you're tied to specific state of nixpkgs, which also dictates the kernel installed. So you shouldn't run into it. You probably might run if you install Nix on Ubuntu. I don't remember running into it, and I think it should be rare since linux ABI supposed to not break compatibility.