This is a function of two arguments, which returns a name/value pair set.
The statement is replaced by the value of the expression in the file specified, by grabbing it from the Nix github site.
And what I’m guessing is:
Nix actually passes some values of “config” and “pkgs” to this function.
The return value of this function is essentially the state of my system
What I don’t understand is:
What is the return value? A list of packages? A list of “actions”? Something else? I know it’s a key/value map in this form, but that doesn’t give me much of a hint about how that translates into what’s installed on my system.
What exactly is passed in to “pkgs” and “config”? Surely I don’t know these things until I have the result of the configuration.nix function. Or is there something loopy going on here with laziness where I pass the result of the function in as an argument?
How can I just add an additional package to my system? Say VSCode for example. I’d like to just add to the demo system, eventually I’ll probably customise my own, but for the moment just adding some packages to the demo system will work fine. I’d like to do this declaratively though not just use command line tools.
I have done a bit of work with Haskell so the functional programming aspect of Nix I should be comfortable with, I’m just having trouble contextualising it all, and I feel the answers to these questions may sort this out.
a function that needs at least two arguments, but that allows the passed in mapping to have more (due to the ...)
mmm, you need to clarify
of course, where config contains the the global configuration and pkgs is the a mapping (or attrs) containing all the packages defined by the nixpkgs distribution, tailored to your system architecture.
The result of the evaluation of all the configuration modules, is indeed what your system is or will be. It’s in part state and in part code that will realize the final configuration.
The configuration expressed as a tree of mappings is used to produce a tree of derivations, a core concept of Nix, you will find it explained many times in the documentation. Each derivation produces a package under /nix/store.
For example, you can see the list of the actual packages installed (i.e. the realization of all the derivations created by your configuration) by executing:
Thanks for all the answers @azazel75. Just one follow-up (at least initially):
How do I “Add it to the environment.systemPackages list”? Isn’t this immutable? Can you show what will need to be done to my current configuration.nix to add a package (any package, assuming the concept is the same for all of them)?
@azazel75 but how does my system currently have any packages if environment.systemPackages is not yet defined? Wouldn’t it already be defined somewhere in <nixpkgs/nixos/modules/installer/virtualbox-demo.nix>?
It would be very difficult to extend and customize a system configuration if a single value could be defined only in one place. That’s one of the strengths of the NixOS module system, each key defined in a module gets merged with all the other keys defined in the other configuration modules. How that merging happens is defined by the type of the option that the programmer has decided that option to be. In the case of lists, they get concatenated.
Another reason why your definition wouldn’t wipe out all the other packages from your system is because Nix has a way of implicitly install required packages: for example if your dear vscode package needs the bash shell package at runtime, that will be automatically installed on your system. It will be much more clear once you experiment a bit with Nix, if you want to.