The directory name is not meant to be useful to a human - it's a means of storing some data that a human generally never needs to look at. It could be a GUID or anything. It's not like relational data stores use human readable primary key fields is it?
If we were using a relational database and we had a table for packages with "primary key","name","version", it's not sufficient to query name and version to get a package, because it's not guaranteed to be unique. For example, you might have the same version, but built using a different configuration, or having a bug fix. You might have revision 127 and 128 in there, but they're the same "version" of the software (I'm not aware of many packages which put source control revision numbers into their release version numbers.) The only way the developer can tell others precisely what he means is to specify an identity, and the rest of the information can be queried.
The hash serves another useful purpose anyway - the ability to verify a package. At the moment Nix hashes the build instructions of a package, so it's not necessary to create an exact binary, although that would be desirable when we can do so reliably. We could eliminate the need to trust package maintainers we don't know this way, because cryptographic hashes are unlikely to lie. Nobody inspects every binary package released publicly to confirm the packager hasn't inserted some malware, but it would be desirable to have the package checked if the computer can automate it. Oh, and you don't need to install from source with Nix. You can download binary derivations, but until we have exact reproducible builds, you do so at your own risk.
Configuration management and package management are not disjoint ideas, and nor do other systems treat them that way. In puppet for example, you can hook into another package manager to install new packages with a fuzzy match, then configure them. Nix configuration is just the same concept for the Nix package manager - where you can actually specify the identity of some configuration you depend on, and in turn give your configuration an identity that others can depend on.
Of course Nix is not a silver bullet, you trade away some of the convenience of other systems in exchange for having reliable distribution of software exactly as the developer/maintainer meant for it to be, and without having to cross your fingers and hope it builds OK.
The file path (which includes directory names) is indeed meant to be useful to a human, for very good reasons.
All [modern] packages have unique names without the need for a completely unique identifier embedded in the file name. The file name is guaranteed to be unique by the distribution maintainer of said package. Usually for 3rd-party packages a postfix of a revision number and the distribution from whence it came is what makes it unique for that distributor. This ends up not only giving you insight as from whence the package came in the name, but which revision it is (if listing them sequentially, for example).
But it isn't package names that need to be unique, it's file paths delivered by the packages, and that certainly is a useful thing that's good to solve with a package manager. But you still need to be able to discern with your eyes what is what! You can't easily do that by comparing a gigantic SHA hash between two file paths, but you could do that if the difference between each other was very minor, but indicated what each path actually was related to (in terms of version, arch, revision, order of installation, or any other number of criteria).
I get it - you're trying to support a completely universal, will-never-conflict file path. But we don't need that!!! It's simple to maintain a small, mostly-collision-free postfix to a package name that is both human readable and fairly unique.
Another way to point out the ridiculousness of the hash-in-file-path system is in your first paragraph:
> It's not like relational data stores use human readable primary key fields is it?
File paths are not relational data stores. File paths are a human interface. A program can store and retrieve data in any way it chooses, and in much more efficient forms than filesystem paths that use "special character" separators, are subject to various environment changes, language specifics, platform differences, and name length limitations. We use file paths because they're the easiest way for humans to organize data files on the disk. Hell, their inherent crappiness is part of why many applications have to be built to "scale" how they manage files to get around the inherent problems of human-readable file paths. Sticking a grotesque amount of non-human-readable metadata in there is like trying to shove a calculator into a pencil.
> The hash serves another useful purpose anyway - the ability to verify a package.
What the hell is this doing in the file name, though? Packages already include hashes of themselves and their files. You can verify any of them with the record they create in the package management database, or in the original package.
I don't get what your point is about people "lying" about the binary package or inserting malware. We've had public key-signed packages for decades. This is a non-issue.
Config management is completely different from package management. I know there are systems out there that try to build in hooks so you can use one from the other, and i'm not saying it's completely useless. But in general it's crap to try to do the functions of one tool in another tool. They need to exist independently for obvious management reasons. The more you tie them together, the more of a maintenance headache you are left with.
Lastly, i'll just say that my favorite Linux distribution (in terms of stability, reliability, etc) is Slackware. It basically defies all of the reasons Nix seems to exist for, yet it works beautifully in spite of it. It turns out that you don't have to wrestle and fight with your packages to make a system work well.
Package names are not guaranteed to be unique at all - they might be unique for a particular repository, that's all. Secondly, the user can craft his own derivations of the same software that some maintainer has already released, which might use the same version but different configuration options. And as I stated previously, the DVCS revision number does not become part of the package name. They typically have a separate major-minor versioning scheme which covers a broad range of commits to the code.
I don't disagree that they could do better, by perhaps using a postfix of some smaller signature of the package, but I just think the argument is irrelevant, because they're were not intended to be read by humans - they are handled by the Nix software. I've not needed to manually browse into /nix/store to find something yet.
File paths are primary keys in a relational data store which is the filesystem. The filesystem is crafted for quite a specific purpose, so is not as general as say, sqlite. Nix has relational data and uses the filesystem because it needs to be compatible with the rest of the system. We could in theory use sqlite to store everything we need for nix, then mount the database with some hypothetical FUSE filesystem to reveal it to the common namespace in some pretty way. That just requires additional effort for no real gain.
Public-key signing does absolutely nothing to verify that a package was built from an unmodified source using an unmodified build process. Signing merely proves who the package came from (that nobody has modified it since the packager built it). It does not identify whether or not they have ill intent. We should learn from recent NSA revelations and cases like Lavabit, that they may be forced to insert malicious code against their own volition. We can't inspect binaries and make sure they match up to the source code, but if we had reproducible builds, then N people could build the same software, resulting in the same binaries, and we could have a web-of-trust model, where you only install a binary package if there's a consensus on it's hash, and have a pretty high confidence rate that it's safe (A malicous party would need to produce a hash collision). Trusting N > 1 randomly selected people is probably better than trusting 1.
Part of the reason for having configuration management on top of Nix is much the same reason as the package manager itself. The aim is to remove "hidden knowledge" that the packager or administrator used to build or configure some service, so that everything required to reproduce it exactly is well defined in a declarative programming language. Existing CM services like Puppet are unsuitable for the task because they make many assumptions (such as how other package managers work, or that there's only one derivation of a package on the system), that are broken with Nix. A new CM service which removes those assumptions was needed, and it happened to be built on top of Nix because it can assign identity to a configuration.
There model has other uses. Hydra for example, is a continuous build system which uses nixpkgs. There's potential for replacement or improvement of existing build tools like make (which have plenty of flaws). pkg-config isn't necessary for example, when we're dealing with dependencies which are specific by design. It's not that it's "combining many different things into one", but rather, rebuilding a bunch of services upon different assumptions than what is already available.
It should be noted that you can use the package manager without any CM, but NixOS uses the CM ubiquitously to give a clear specification of the OS and how to reproduce it from scratch.
For me, Nix is a step towards removing the distinction between developer and user. The future I see is where there is zero friction to go from using an app to hacking on it, because you have the source code readily available, plus a completely automated build process you probably don't need to mess with. There's no hidden knowledge. I cannot count the amount of time I've wasted in the past trying to build software and dependencies of software because they're not well defined or documented. Quite often a day has passed before I can actually start modifying the code.
Oh, I see what you mean about the source now - to make sure the binary I have is the direct product of only the developers' original code, or thereabout. This is what source packages (SRPMs) are for; you can download the SRPM, look at the code in it, and rebuild it if you're really paranoid. You can compare SHA hashes of the code you have with those of either the package builder or the original developers of the code. This requires no web of trust.
You don't need a declarative programming language to for your configuration management or your package management. It just makes for a maintenance headache. And using a dedicated CM tool like Puppet is a better idea because it makes the software more portable and flexible.
When you deploy your application, your package manager has to execute certain things in order to set it up for the first time. A CM can handle this, too. And once it's installed, you may need to change the configuration in a unified way. A CM handles this. At uninstall, your package manager cleans up after the package's setup, which a CM can also handle. By bundling these two, the application now only supports one system (the Nix system). If the software's configuration is completely handled by an independent CM tool like Puppet, it will be supported on any platform Puppet resides on, and because it's not tied to a single package manager you can install the software on any system.
I think the only way you're going to win the development war is to provide a portable, compatible, simple, maintainable, easy to use tool that everyone will want because it solves all of their problems without creating new ones. It can't be a programming language because most people can't program. It can't be complicated or overly powerful because most people will shoot themselves in the foot if you give them ammunition. And it has to work everywhere, on anything. Good luck!
If we were using a relational database and we had a table for packages with "primary key","name","version", it's not sufficient to query name and version to get a package, because it's not guaranteed to be unique. For example, you might have the same version, but built using a different configuration, or having a bug fix. You might have revision 127 and 128 in there, but they're the same "version" of the software (I'm not aware of many packages which put source control revision numbers into their release version numbers.) The only way the developer can tell others precisely what he means is to specify an identity, and the rest of the information can be queried.
The hash serves another useful purpose anyway - the ability to verify a package. At the moment Nix hashes the build instructions of a package, so it's not necessary to create an exact binary, although that would be desirable when we can do so reliably. We could eliminate the need to trust package maintainers we don't know this way, because cryptographic hashes are unlikely to lie. Nobody inspects every binary package released publicly to confirm the packager hasn't inserted some malware, but it would be desirable to have the package checked if the computer can automate it. Oh, and you don't need to install from source with Nix. You can download binary derivations, but until we have exact reproducible builds, you do so at your own risk.
Configuration management and package management are not disjoint ideas, and nor do other systems treat them that way. In puppet for example, you can hook into another package manager to install new packages with a fuzzy match, then configure them. Nix configuration is just the same concept for the Nix package manager - where you can actually specify the identity of some configuration you depend on, and in turn give your configuration an identity that others can depend on.
Of course Nix is not a silver bullet, you trade away some of the convenience of other systems in exchange for having reliable distribution of software exactly as the developer/maintainer meant for it to be, and without having to cross your fingers and hope it builds OK.