A few questions about nix expressions

I’ve read the nix-pills a few times now, but when I look at actual nix expressions, there are things that baffle me. Here are some questions I have about some simple expressions I use often.

This is default.nix for a simple Haskell application:

{ pkgs ? import <nixpkgs> {} }:

pkgs.haskellPackages.callCabal2nix "my-package" ./. {}

My understanding is that line 1 declares that this is a function that takes a single parameter, pkgs. The default value of pkgs is import <nixpkgs> {}.

Line 2 invokes callCabal2nix. I’ve figured out that the syntax for doing this is pkgs.haskellPackages.callCabal2nix "gtkhs-tools" "${src}/tools" {}. However,…

Q1: If I didn’t how to invoke callCabal2nix, how would I find out? My search-fu has turned up threads talking about the function, but I haven’t been able to find the actual definition. I also searched in the NixOS/nixpkgs GitHub repo, but found nothing useful.

Q2: What is the {} doing at the end? Is that passing an empty argument set to callCabal2nix? (Related to Q4.)

pkgs.haskellPackages.callCabal2nix <package-name> <source-dir> {}

This is shell.nix:

(import ./. {}).env

That looks like what the Death Eaters had tattooed on their arms.

Q3: If you write import <pathname> instead of import <file>, does Nix automatically look for a file named default.nix and import that?

Q4: Why are we passing an empty agrument set {} to the import? I see that default.nix expects a parameter pkgs, but it has a default value. Is it the case that whenever we import a file that expects a paremeter, we have to supply an argument set, even if it is empty?

Q5: I assume the .env on the end would reference an env defined in default.nix, but there’s no such definition in the file. Is env some sort of magic variable? What does it include? I’m guessing that it includes whatever definitions are needed by nix-shell.

Q1: Sadly the various helper functions in nixpkgs are hard to find without searching for similar examples in Nixpkgs. This is a known problem, but needs a concerted documentation or refactoring effort to resolve.

Q2: The {} calls the function located at PATH_TO_NIXPKGS/default.nix with no arguments (or defaults, if defined). Same with the (import ./. {}).env. That will import the function located in the current directory ./default.nix and then call it with the empty set {}, then access the env item in the result.

Q3: Yes
Q4: No, Nix will not automatically call the function, this is in case you want to pass the function to another higher-kinded function or for some other purpose.
Q5: Not sure about that particular case, but env is probably defined in via a call to buildEnv. We’d have to see the default.nix you are using to track it down.

2 Likes