Skip to content

Commit 0f9034d

Browse files
committed
lib: Discourage use of extend
It creates interoperability issues that can not be reconciled by `lib` or maintainers of projects that use the Nixpkgs library. Occasionally, end users may be able to solve the problems they run into, but most are not prepared to deal with this set of problems, nor should they be. Typical conflict: - User wants to propagate their own lib, because it has some function they like to use throughout their projects - Project maintainer requires the project's lib to be used No sane language uses a single namespace for combining all the things. (Arguably not even C with its extensive use of prefixing) Meanwhile, in Nix, all symbols are first class variables. We don't even have the concept of a global top-level namespace to pour everything into. With `lib` you can try to approximate that, I get the appeal of its apparent simplicity, but since `lib` can't be global, we just don't even get that apparent simplicity. I apologize for not offering concrete solutions to this in the text. The manuals are limited to reference documentation. Alternatives - of which we have multiple - are best provided in task-oriented documentation, e.g. nix.dev.
1 parent d114ef5 commit 0f9034d

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

doc/module-system/module-system.chapter.md

+9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@ An attribute set of module arguments that can be used in `imports`.
3131

3232
This is in contrast to `config._module.args`, which is only available after all `imports` have been resolved.
3333

34+
::: {.warning}
35+
You may be tempted to use `specialArgs.lib` to provide extra library functions. Doing so limits the interoperability of modules, as well as the interoperability of Module System applications.
36+
37+
`lib` is reserved for the Nixpkgs library, and should not be used for custom functions.
38+
39+
Instead, you may create a new attribute in `specialArgs` to provide custom functions.
40+
This clarifies their origin and avoids incompatibilities.
41+
:::
42+
3443
#### `class` {#module-system-lib-evalModules-param-class}
3544

3645
If the `class` attribute is set and non-`null`, the module system will reject `imports` with a different `_class` declaration.

flake.nix

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
2525
- `lib.nixos` for other NixOS-provided functionality, such as [`runTest`](https://nixos.org/manual/nixos/unstable/#sec-call-nixos-test-outside-nixos)
2626
*/
27+
# DON'T USE lib.extend TO ADD NEW FUNCTIONALITY.
28+
# THIS WAS A MISTAKE. See the warning in lib/default.nix.
2729
lib = lib.extend (final: prev: {
2830

2931
/**

lib/default.nix

+29-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,36 @@
55
*/
66
let
77

8-
inherit (import ./fixed-points.nix { inherit lib; }) makeExtensible;
8+
# A copy of `lib.makeExtensible'` in order to document `extend`.
9+
# It has been leading to some trouble, so we have to document it specially.
10+
makeExtensible' =
11+
rattrs:
12+
let self = rattrs self // {
13+
/**
14+
Patch the Nixpkgs library
915
10-
lib = makeExtensible (self: let
16+
The name `extends` is a bit misleading, as it doesn't actually extend the library, but rather patches it.
17+
It is merely a consequence of being implemented by `makeExtensible`.
18+
19+
# Inputs
20+
21+
- An "extension function" `f` that returns attributes that will be updated in the returned Nixpkgs library.
22+
23+
# Output
24+
25+
A patched Nixpkgs library.
26+
27+
:::{.warning}
28+
This functionality is intended as an escape hatch for when the provided version of the Nixpkgs library has a flaw.
29+
30+
If you were to use it to add new functionality, you will run into compatibility and interoperability issues.
31+
:::
32+
*/
33+
extend = f: lib.makeExtensible (lib.extends f rattrs);
34+
};
35+
in self;
36+
37+
lib = makeExtensible' (self: let
1138
callLibs = file: import file { lib = self; };
1239
in {
1340

0 commit comments

Comments
 (0)