From 0f9034d8b5c5c26f42a6b036d171044d4b11fb5d Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Thu, 23 Jan 2025 08:27:29 +0100 Subject: 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. --- lib/default.nix | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index 849d6ce8f9d6..e77d053b8cc0 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -5,9 +5,36 @@ */ let - inherit (import ./fixed-points.nix { inherit lib; }) makeExtensible; + # A copy of `lib.makeExtensible'` in order to document `extend`. + # It has been leading to some trouble, so we have to document it specially. + makeExtensible' = + rattrs: + let self = rattrs self // { + /** + Patch the Nixpkgs library - lib = makeExtensible (self: let + The name `extends` is a bit misleading, as it doesn't actually extend the library, but rather patches it. + It is merely a consequence of being implemented by `makeExtensible`. + + # Inputs + + - An "extension function" `f` that returns attributes that will be updated in the returned Nixpkgs library. + + # Output + + A patched Nixpkgs library. + + :::{.warning} + This functionality is intended as an escape hatch for when the provided version of the Nixpkgs library has a flaw. + + If you were to use it to add new functionality, you will run into compatibility and interoperability issues. + ::: + */ + extend = f: lib.makeExtensible (lib.extends f rattrs); + }; + in self; + + lib = makeExtensible' (self: let callLibs = file: import file { lib = self; }; in { -- cgit v1.2.3 From 55a11de1b0474788e59d6af6da77b858d7c582c1 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 29 Jan 2025 22:05:21 +0100 Subject: lib/default.nix: Update extend doc Co-authored-by: Johannes Kirschbauer --- lib/default.nix | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/default.nix') diff --git a/lib/default.nix b/lib/default.nix index e77d053b8cc0..1557f33b5dd3 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -13,8 +13,13 @@ let /** Patch the Nixpkgs library + A function that applies patches onto the nixpkgs library. + Usage is discouraged for most scenarios. + + :::{.note} The name `extends` is a bit misleading, as it doesn't actually extend the library, but rather patches it. It is merely a consequence of being implemented by `makeExtensible`. + ::: # Inputs -- cgit v1.2.3