Hi, I'm a NixOS/Nixpkgs comitter and package maintainer for plenty of stuff -- including X11/XQuartz for OSX.

Nope. They both do package management, but that's where the similarities end.

Homebrew packages are not patched to point at precisely the version of the stuff they were built against. For example, if you have program that dynamically links to openssl, that program is built with the expectation that the dynamic linker will be able to find e.g. libssl.dylib in either /usr/lib or /usr/local/lib (the specifics are harrier, but that's a decent approximation). If you later upgrade openssl and the ABI changes, you've now silently broken everything that uses it -- you'll now get a segfault at runtime (I've had this happen with openssl and many other libs on Homebrew, and is part of why I was (and still am) very excited about Nix).

When you compile a package with Homebrew, you're not guaranteed to end up with the same result as someone else, even if they have the same checkout of the formulae. Why? Well, each project's Makefile (or what have you) will try to run whatever's on $PATH, and poke around elsewhere on your system to e.g. automatically enable build flags (oh, luajit is installed? I guess I'll just go ahead and enable Lua scripting and link to it).

How does that compare with Nix?

Nix packages are patched so that their runtime dependencies (dynamic libraries, programs to be execed, shebang lines, etc) are locked down to the precise build that was specified as part of the package. The obvious implication here is that Nix packages can be trivially installed with differing versions of dependencies as necessary (back in the day, I wanted to play with both the Elixir langauge and the Riak DB, but they required two different major versions of Erlang. Unfortunately, I could only install one version, as the packages for both versions wanted to be placed in the exact same prefix and the filenames would overlap. This was on Ubuntu, but it applies equally to Homebrew).

When compiling a Nix package, I can rest assured that the build artifacts will be equivalent between two different machines (not bit-for-bit, but at least functionally equivalent -- excepting compiler bugs). Why? Because the build happens in an isolated environment where, as far as the build process is concerned (we take advantage of a number of kernel features on Linux (chroot) and OSX (Sandboxes)), the system only consists of the packages explicitly listed as build inputs -- nothing else. Excepting esoteric stuff like someone intentionally trying to subvert chroots and such, if you were to put a gun to my head and tell me that you were going to shoot me if you could find a case of non-determism, I'd shrug. We're serious about that whole determinism thing -- it's a core selling point of Nix, and the reason for Nix's "quirks" (the per package prefixes, hashing of build inputs, chroots, lack of network access, etc).

If the above doesn't make the differences obvious, I'll challenge you to answer some questions (the socratic method):

1. How does Homebrew support having two versions of openssl installed concurrently? Describe the paths involved, how the dynamic linker would be guaranteed to load the respective version of libssl, etc.

2. How does Homebrew ensure packages are built exactly the same way across two different machines (e.g. using the same version of autotools, clang, make, etc)? Be sure to explain how the build is guaranteed to not auto detect/enable stuff because of things present on my system that may not be present on your system. Note that Nix will deterministically fail if you fail to explicitly list all of its dependencies (rather than working because, say, cmake just so happened to be installed on the formula author's machine) -- so you'll need to describe how Homebrew achieves this when running a formula.