1rec {
2
3 # Identity function.
4 id = x: x;
5
6 # Constant function.
7 const = x: y: x;
8
9 # Named versions corresponding to some builtin operators.
10 concat = x: y: x ++ y;
11 or = x: y: x || y;
12 and = x: y: x && y;
13 mergeAttrs = x: y: x // y;
14
15 # Compute the fixed point of the given function `f`, which is usually an
16 # attribute set that expects its final, non-recursive representation as an
17 # argument:
18 #
19 # f = self: { foo = "foo"; bar = "bar"; foobar = self.foo + self.bar; }
20 #
21 # Nix evaluates this recursion until all references to `self` have been
22 # resolved. At that point, the final result is returned and `f x = x` holds:
23 #
24 # nix-repl> fix f
25 # { bar = "bar"; foo = "foo"; foobar = "foobar"; }
26 #
27 # See https://en.wikipedia.org/wiki/Fixed-point_combinator for further
28 # details.
29 fix = f: let x = f x; in x;
30
31 # A variant of `fix` that records the original recursive attribute set in the
32 # result. This is useful in combination with the `extends` function to
33 # implement deep overriding. See pkgs/development/haskell-modules/default.nix
34 # for a concrete example.
35 fix' = f: let x = f x // { __unfix__ = f; }; in x;
36
37 # Modify the contents of an explicitly recursive attribute set in a way that
38 # honors `self`-references. This is accomplished with a function
39 #
40 # g = self: super: { foo = super.foo + " + "; }
41 #
42 # that has access to the unmodified input (`super`) as well as the final
43 # non-recursive representation of the attribute set (`self`). `extends`
44 # differs from the native `//` operator insofar as that it's applied *before*
45 # references to `self` are resolved:
46 #
47 # nix-repl> fix (extends g f)
48 # { bar = "bar"; foo = "foo + "; foobar = "foo + bar"; }
49 #
50 # The name of the function is inspired by object-oriented inheritance, i.e.
51 # think of it as an infix operator `g extends f` that mimics the syntax from
52 # Java. It may seem counter-intuitive to have the "base class" as the second
53 # argument, but it's nice this way if several uses of `extends` are cascaded.
54 extends = f: rattrs: self: let super = rattrs self; in super // f self super;
55
56 # Flip the order of the arguments of a binary function.
57 flip = f: a: b: f b a;
58
59 # Pull in some builtins not included elsewhere.
60 inherit (builtins)
61 pathExists readFile isBool isFunction
62 isInt add sub lessThan
63 seq deepSeq genericClosure;
64
65 inherit (import ./strings.nix) fileContents;
66
67 # Return the Nixpkgs version number.
68 nixpkgsVersion =
69 let suffixFile = ../.version-suffix; in
70 fileContents ../.version
71 + (if pathExists suffixFile then fileContents suffixFile else "pre-git");
72
73 # Whether we're being called by nix-shell.
74 inNixShell = builtins.getEnv "IN_NIX_SHELL" != "";
75
76 # Return minimum/maximum of two numbers.
77 min = x: y: if x < y then x else y;
78 max = x: y: if x > y then x else y;
79
80 /* Reads a JSON file. It is useful to import pure data into other nix
81 expressions.
82
83 Example:
84
85 mkDerivation {
86 src = fetchgit (importJSON ./repo.json)
87 #...
88 }
89
90 where repo.json contains:
91
92 {
93 "url": "git://some-domain/some/repo",
94 "rev": "265de7283488964f44f0257a8b4a055ad8af984d",
95 "sha256": "0sb3h3067pzf3a7mlxn1hikpcjrsvycjcnj9hl9b1c3ykcgvps7h"
96 }
97
98 */
99 importJSON = path:
100 builtins.fromJSON (builtins.readFile path);
101
102 /* See https://github.com/NixOS/nix/issues/749. Eventually we'd like these
103 to expand to Nix builtins that carry metadata so that Nix can filter out
104 the INFO messages without parsing the message string.
105
106 Usage:
107 {
108 foo = lib.warn "foo is deprecated" oldFoo;
109 }
110
111 TODO: figure out a clever way to integrate location information from
112 something like __unsafeGetAttrPos.
113 */
114 warn = msg: builtins.trace "WARNING: ${msg}";
115 info = msg: builtins.trace "INFO: ${msg}";
116}