So far, I have seen two “flavors” of default.nix
/shell.nix
files:
-
Function
{pkgs ? import <nixpkgs> {} }: pkgs.mkShell { # declarations }
Or, a suggested way when used with
niv
:{ sources ? import ./nix/sources.nix , pkgs ? import sources.nixpkgs {} }: # ...
-
Simple expression (not sure what’s the right term here…)
with (import <nixpkgs> {}); mkShell { # declarations }
or, to include the explicit-camp:
let pkgs = import <nixpkgs> {}; in pkgs.mkShell { # declarations }
As far as I know, default.nix
/shell.nix
cannot be given any arguments when used with nix-shell
, so declaring them as functions is only a stylistic choice. Indeed, if called with function with head {pkgs}:
, the result is
error: cannot auto-call a function that has an argument without a default value ('pkgs')
so it is not like NixOS’ configuration.nix
.
Could the function-form be considered an anti-pattern? It threw me off for so long (I may not be alone), and all function heads in default.nix
/shell.nix
files could be re-written in the non-function form. The latter would also better convey that nix-shell
expects a derivation.
For example, the niv
example above,
{ sources ? import ./nix/sources.nix
, pkgs ? import sources.nixpkgs {}
}:
would become
let
sources = import ./nix/sources.nix;
pkgs = import sources.nixpkgs {};
in
(Although, I have to admit, the former looks more appealing, at least to me.)
The title of the topic is not the most fortunate but all my previous attempts were at least two lines long so any suggestions are welcome. Thank you!