| NixOS got this right. Declarative configuration is great in theory but it doesn't scale well. See Amazon's CloudFront configuration files for what configuration in JSON looks like. (For example, https://s3-us-west-2.amazonaws.com/cloudformation-templates-...) It quickly gets hard to manage the syntax and balance all the quotes, parentheses, braces and brackets, with careful use of whitespace being critical for even a hope of understanding it. When you add in semantics, it gets even worse. Take the "Ref" construct in CloudFront to work around the fact that JSON doesn't have a way to name something and refer to it elsewhere. As the amount of configuration grows, you have to introduce abstractions to encapsulate common patterns, break out of deep nesting, name things etc. I guess it's possible to do that declaratively, but that leads to things like XSLT. (Or, open the CloudFormation JSON linked above and search for "Fn::". It makes me shudder). S-expressions would indeed be better than JSON, but they still wouldn't scale without macros. So either all programs would have to know lisp, or you need a dedicated program for executing the configuration. That's what NixOS has. It does all configuration via "nix expresssions" which are written in a lazy, functional language. The functional bit allows for the abstraction necessary to make large amounts of configuration readable and maintainable. The lazy bit makes executing large configurations efficient, given that you're usually only interested in certain parts of it at any one time. The result is that you can write a configuration that describes a cluster of machines from top to bottom: from how many app servers to put behind the load-balancer to which version of zlib to link node.js against. It takes a bit of effort to learn nix, and for many, the functional paradigm will be strange and scary. But's so worth it. |