From 7e930193a98f2d77020a00e4ebd25ab8d5066613 Mon Sep 17 00:00:00 2001 From: Emile Clark-Boman Date: Sun, 25 Jan 2026 13:08:05 +1000 Subject: [PATCH] MAJOR: create nt/primitives/bootstrap --- flake.nix | 4 +- nt/primitives/bootstrap.nix | 15 ------ nt/primitives/bootstrap/README.md | 53 +++++++++++++++++++ nt/primitives/bootstrap/default.nix | 39 ++++++++++++++ nt/primitives/{util => bootstrap}/nt.nix | 0 nt/primitives/bootstrap/parse/bootstrap.nix | 7 +++ nt/primitives/{ => bootstrap}/parse/parse.nix | 0 nt/primitives/{ => bootstrap}/parse/sig.nix | 0 .../{util => bootstrap/parse}/trapdoor.nix | 6 +-- nt/primitives/bootstrap/std/README.md | 8 +++ nt/primitives/{ => bootstrap}/std/attrs.nix | 0 nt/primitives/bootstrap/std/bootstrap.nix | 11 ++++ nt/primitives/{ => bootstrap}/std/fn.nix | 0 nt/primitives/{ => bootstrap}/std/list.nix | 0 nt/primitives/{ => bootstrap}/std/num.nix | 0 nt/primitives/{ => bootstrap}/std/string.nix | 0 nt/primitives/bootstrap/types/bootstrap.nix | 8 +++ nt/primitives/{ => bootstrap}/types/maybe.nix | 0 nt/primitives/{ => bootstrap}/types/null.nix | 0 nt/primitives/{ => bootstrap}/types/wrap.nix | 0 nt/primitives/default.nix | 1 + nt/primitives/mix/bootstrap.nix | 10 ---- nt/primitives/std/README.md | 17 ------ nt/primitives/std/default.nix | 28 ---------- nt/primitives/std/enforce.nix | 2 - nt/primitives/types/default.nix | 8 --- nt/primitives/util/default.nix | 7 --- 27 files changed, 132 insertions(+), 92 deletions(-) delete mode 100644 nt/primitives/bootstrap.nix create mode 100644 nt/primitives/bootstrap/README.md create mode 100644 nt/primitives/bootstrap/default.nix rename nt/primitives/{util => bootstrap}/nt.nix (100%) create mode 100644 nt/primitives/bootstrap/parse/bootstrap.nix rename nt/primitives/{ => bootstrap}/parse/parse.nix (100%) rename nt/primitives/{ => bootstrap}/parse/sig.nix (100%) rename nt/primitives/{util => bootstrap/parse}/trapdoor.nix (90%) create mode 100644 nt/primitives/bootstrap/std/README.md rename nt/primitives/{ => bootstrap}/std/attrs.nix (100%) create mode 100644 nt/primitives/bootstrap/std/bootstrap.nix rename nt/primitives/{ => bootstrap}/std/fn.nix (100%) rename nt/primitives/{ => bootstrap}/std/list.nix (100%) rename nt/primitives/{ => bootstrap}/std/num.nix (100%) rename nt/primitives/{ => bootstrap}/std/string.nix (100%) create mode 100644 nt/primitives/bootstrap/types/bootstrap.nix rename nt/primitives/{ => bootstrap}/types/maybe.nix (100%) rename nt/primitives/{ => bootstrap}/types/null.nix (100%) rename nt/primitives/{ => bootstrap}/types/wrap.nix (100%) delete mode 100644 nt/primitives/mix/bootstrap.nix delete mode 100644 nt/primitives/std/README.md delete mode 100644 nt/primitives/std/default.nix delete mode 100644 nt/primitives/std/enforce.nix delete mode 100644 nt/primitives/types/default.nix delete mode 100644 nt/primitives/util/default.nix diff --git a/flake.nix b/flake.nix index 71e81ef..706358a 100644 --- a/flake.nix +++ b/flake.nix @@ -4,8 +4,8 @@ outputs = _: let # nt depends on the mix subsystem for bootstrapping, # we can fake its dependency on this mwahahahah - this.util = import ./nt/primitives/util/bootstrap.nix; - mix = import ./nt/primitives/mix {inherit this;}; + bootstrap = import ./nt/primitives/bootstrap; + mix = import ./nt/primitives/mix {this = bootstrap;}; in import ./nt {inherit mix;}; } diff --git a/nt/primitives/bootstrap.nix b/nt/primitives/bootstrap.nix deleted file mode 100644 index 9299236..0000000 --- a/nt/primitives/bootstrap.nix +++ /dev/null @@ -1,15 +0,0 @@ -# WARNING: this file is strictly for bootstrapping nt -let - input = {inherit this;}; - this = - import ./util.nix input - // import ./parse.nix input - // import ./trapdoor.nix input - // import ./null.nix input - // import ./maybe.nix input - // import ./wrap.nix input - // import ./enforce.nix input - // import ./sig.nix input - // import ./nt.nix input; -in - this diff --git a/nt/primitives/bootstrap/README.md b/nt/primitives/bootstrap/README.md new file mode 100644 index 0000000..4c67368 --- /dev/null +++ b/nt/primitives/bootstrap/README.md @@ -0,0 +1,53 @@ +## Primitives - /nt/primitives +All expressions in the `/nt/primitives` directory should have no dependencies on NixTypes +because **`/nt/primitives` is the dependency of NixTypes**! However for consistency in +the development process `/nt/primitives` is structured using the Mix Module subsystem +(`/nt/primitives/mix`). + +*"But Emile..."* I hear you say! **How can primitives be a Mix module if Mix depends on primitives??** +Welp I'm sure I could have done some cool exploit of lazy evaluation in recursion, +*but I was alas lazy...* So the solution is **they can't... ;-;** But they can be pretty close! + +Instead we have `/nt/primitives/bootstrap`! Which provides a **miniature dependency-free standard library.** +`import ./nt/primitives/bootstrap/default.nix` is passed as to `import ./nt/primitives/mix` which is +then passed to `import ./nt`. + +Most importantly, `/nt/primitives/bootstrap/default.nix` contains the function `bootstrap:: Path | List | Attrs | Function -> Attrs`: +```nix +# et voilĂ ! +let + this = bootstrap {inherit this bootstrap;} [ + { + std = ./std/bootstrap.nix; + types = ./types/bootstrap.nix; + parse = ./parse/bootstrap.nix; + } + ]; +in + this; +``` +**\~\~!!KABOOM !!\~\~** + +Now **our primitives have a primitive module system!** + +The init process looks like this: +```nix +# REF: flake.nix +{ + outputs = _: let + # Step 1: Bootstrap and blast off (*zooommmmm whoooosshhhhh pppppeeeeeeewww*) + bootstrap = import ./nt/primitives/bootstrap; + # Step 2: Lie to Mix about its real identity (it's not ready for the truth...) + mix = import ./nt/primitives/mix {this = bootstrap;}; + in + # Step 3: Actually import NixTypes + import ./nt {inherit mix;}; + # Step 4: Like and subscripe!!1!11!!!!! +} +``` + + +## A note on /nt/primitives/bootstrap +**None of these functions/types/etc are exported for users of NixTypes!** So they should +remain as simple and minimal as possible to avoid extra work maintaining. +Instead, **most of these will be reimplemented post-bootstrap to be NixType compatible**. diff --git a/nt/primitives/bootstrap/default.nix b/nt/primitives/bootstrap/default.nix new file mode 100644 index 0000000..6fdc608 --- /dev/null +++ b/nt/primitives/bootstrap/default.nix @@ -0,0 +1,39 @@ +# WARNING: /nt/primitives/bootstrap cannot depend on mix! +# WARNING: This file is strictly for bootstrapping nt. +# WARNING: Use it with `import ./nt/primitives/bootstrap` +let + inherit + (builtins) + foldl' + isAttrs + isList + isPath + mapAttrs + ; + + # NOTE: bootstrap does the equivalent to mix's `include.public` option. + bootstrap = inputs: let + delegate = target: + # PATH + if isPath target + then import target inputs + # LIST + else if isList target + then target |> foldl' (acc: el: acc // delegate el) {} + # ATTRS + else if isAttrs target + then target |> mapAttrs (_: value: delegate value) + # FUNCTION (OR FAIL) + else target inputs; + in + delegate; + + this = bootstrap {inherit this bootstrap;} [ + { + std = ./std/bootstrap.nix; + types = ./types/bootstrap.nix; + parse = ./parse/bootstrap.nix; + } + ]; +in + this diff --git a/nt/primitives/util/nt.nix b/nt/primitives/bootstrap/nt.nix similarity index 100% rename from nt/primitives/util/nt.nix rename to nt/primitives/bootstrap/nt.nix diff --git a/nt/primitives/bootstrap/parse/bootstrap.nix b/nt/primitives/bootstrap/parse/bootstrap.nix new file mode 100644 index 0000000..bf91c18 --- /dev/null +++ b/nt/primitives/bootstrap/parse/bootstrap.nix @@ -0,0 +1,7 @@ +# WARNING: /nt/primitives/bootstrap cannot depend on mix +# WARNING: this file is strictly for bootstrapping nt +{bootstrap, ...} @ inputs: +bootstrap inputs [ + ./parse.nix + ./sig.nix +] diff --git a/nt/primitives/parse/parse.nix b/nt/primitives/bootstrap/parse/parse.nix similarity index 100% rename from nt/primitives/parse/parse.nix rename to nt/primitives/bootstrap/parse/parse.nix diff --git a/nt/primitives/parse/sig.nix b/nt/primitives/bootstrap/parse/sig.nix similarity index 100% rename from nt/primitives/parse/sig.nix rename to nt/primitives/bootstrap/parse/sig.nix diff --git a/nt/primitives/util/trapdoor.nix b/nt/primitives/bootstrap/parse/trapdoor.nix similarity index 90% rename from nt/primitives/util/trapdoor.nix rename to nt/primitives/bootstrap/parse/trapdoor.nix index f4e45ca..815f60d 100644 --- a/nt/primitives/util/trapdoor.nix +++ b/nt/primitives/bootstrap/parse/trapdoor.nix @@ -9,7 +9,7 @@ inherit (this.std) enfHasAttr - enfHasAttr' + enfHasAttrUnsafe enfIsAttrs ; in rec { @@ -19,7 +19,7 @@ in rec { mkTrapdoorFn = key: decl: assert enfHasAttr "default" decl "mkTrapdoorFn"; - assert enfHasAttr' "unlock" decl "mkTrapdoorFn"; + assert enfHasAttrUnsafe "unlock" decl "mkTrapdoorFn"; # return trapdoor function (x: let keys = attrNames decl.unlock; @@ -32,7 +32,7 @@ in rec { mkTrapdoorSet = key: decl: assert enfHasAttr "default" decl "mkTrapdoorSet"; - assert enfHasAttr' "unlock" decl "mkTrapdoorSet"; + assert enfHasAttrUnsafe "unlock" decl "mkTrapdoorSet"; # return trapdoor set let keys = attrNames decl.unlock; diff --git a/nt/primitives/bootstrap/std/README.md b/nt/primitives/bootstrap/std/README.md new file mode 100644 index 0000000..02f30ef --- /dev/null +++ b/nt/primitives/bootstrap/std/README.md @@ -0,0 +1,8 @@ +## Primitive Standard Functions - /nt/primitives/bootstrap/std +>[!NOTE] +> This directory is dedicated to porting functions from `nixpkgs.pkgs.lib`. + +**None of these functions/types/etc are exported for users of NixTypes!** So they should +remain as simple and minimal as possible to avoid extra work maintaining. +Instead, **all of these will be reimplemented post-bootstrap to be NixType compatible**. + diff --git a/nt/primitives/std/attrs.nix b/nt/primitives/bootstrap/std/attrs.nix similarity index 100% rename from nt/primitives/std/attrs.nix rename to nt/primitives/bootstrap/std/attrs.nix diff --git a/nt/primitives/bootstrap/std/bootstrap.nix b/nt/primitives/bootstrap/std/bootstrap.nix new file mode 100644 index 0000000..4e8b06e --- /dev/null +++ b/nt/primitives/bootstrap/std/bootstrap.nix @@ -0,0 +1,11 @@ +# WARNING: /nt/primitives/bootstrap cannot depend on mix +# WARNING: this file is strictly for bootstrapping nt +{bootstrap, ...} @ inputs: +bootstrap inputs [ + ./attrs.nix + ./enforce.nix + ./fn.nix + ./list.nix + ./num.nix + ./string.nix +] diff --git a/nt/primitives/std/fn.nix b/nt/primitives/bootstrap/std/fn.nix similarity index 100% rename from nt/primitives/std/fn.nix rename to nt/primitives/bootstrap/std/fn.nix diff --git a/nt/primitives/std/list.nix b/nt/primitives/bootstrap/std/list.nix similarity index 100% rename from nt/primitives/std/list.nix rename to nt/primitives/bootstrap/std/list.nix diff --git a/nt/primitives/std/num.nix b/nt/primitives/bootstrap/std/num.nix similarity index 100% rename from nt/primitives/std/num.nix rename to nt/primitives/bootstrap/std/num.nix diff --git a/nt/primitives/std/string.nix b/nt/primitives/bootstrap/std/string.nix similarity index 100% rename from nt/primitives/std/string.nix rename to nt/primitives/bootstrap/std/string.nix diff --git a/nt/primitives/bootstrap/types/bootstrap.nix b/nt/primitives/bootstrap/types/bootstrap.nix new file mode 100644 index 0000000..b2e0f68 --- /dev/null +++ b/nt/primitives/bootstrap/types/bootstrap.nix @@ -0,0 +1,8 @@ +# WARNING: /nt/primitives/bootstrap cannot depend on mix +# WARNING: this file is strictly for bootstrapping nt +{bootstrap, ...} @ inputs: +bootstrap inputs [ + ./null.nix + ./maybe.nix + ./wrap.nix +] diff --git a/nt/primitives/types/maybe.nix b/nt/primitives/bootstrap/types/maybe.nix similarity index 100% rename from nt/primitives/types/maybe.nix rename to nt/primitives/bootstrap/types/maybe.nix diff --git a/nt/primitives/types/null.nix b/nt/primitives/bootstrap/types/null.nix similarity index 100% rename from nt/primitives/types/null.nix rename to nt/primitives/bootstrap/types/null.nix diff --git a/nt/primitives/types/wrap.nix b/nt/primitives/bootstrap/types/wrap.nix similarity index 100% rename from nt/primitives/types/wrap.nix rename to nt/primitives/bootstrap/types/wrap.nix diff --git a/nt/primitives/default.nix b/nt/primitives/default.nix index 961f6cd..870ead5 100644 --- a/nt/primitives/default.nix +++ b/nt/primitives/default.nix @@ -2,6 +2,7 @@ mix.newMixture inputs (mixture: { includes.public = [ ./nt.nix + ./bootstrap ]; submods.public = [ ./mix diff --git a/nt/primitives/mix/bootstrap.nix b/nt/primitives/mix/bootstrap.nix deleted file mode 100644 index 607f24a..0000000 --- a/nt/primitives/mix/bootstrap.nix +++ /dev/null @@ -1,10 +0,0 @@ -# WARNING: This file is strictly for bootstrapping nt -rec { - # NOTE: bootstrap does the equivalent to mix's `include.public` option. - # NOTE: It also provides itself as input to descendents. - bootstrap = args: paths: let - input = args // {inherit this bootstrap;}; - this = paths |> builtins.foldl' (acc: el: acc // import el input) {}; - in - this; -} diff --git a/nt/primitives/std/README.md b/nt/primitives/std/README.md deleted file mode 100644 index 9563d0b..0000000 --- a/nt/primitives/std/README.md +++ /dev/null @@ -1,17 +0,0 @@ -## Primitive Standard Functions ->[!NOTE] -> This directory is dedicated to porting functions from `nixpkgs.pkgs.lib`. - -The `/nt/primitives` directory should have no dependencies on NixTypes *(with one exception explained below)*. -Thus the **NixTypes system must be constructed from a dependency-free standard library.** - -This includes dependency on `this` (provided by the `nt.mix` module system)! -`/nt/primitives` is structured as a `nt.mix` module, and hence `/nt/primitives/mix` -must also depend on `/nt/primitives/std`. My point is, **`/nt/primitives/std` -cannot use mix at all!** - -### Internal Use Only -**None of these functions are exported for users of NixTypes!** So they should -remain as simple and minimal as possible to avoid extra work maintaining. -Instead, **all of these functions will be reimplemented** post-bootstrap -to be NixType compatible. diff --git a/nt/primitives/std/default.nix b/nt/primitives/std/default.nix deleted file mode 100644 index 130c293..0000000 --- a/nt/primitives/std/default.nix +++ /dev/null @@ -1,28 +0,0 @@ -# {mix, ...} @ inputs: -# mix.newMixture inputs (mixture: { -# includes.public = [ -# ./attrs.nix -# ./fn.nix -# ./list.nix -# ./num.nix -# ./string.nix -# ]; -# }) -# WARNING: /nt/primitives/std cannot depend on mix -# WARNING: this file is strictly for bootstrapping nt -let - # input = {inherit this;}; - this = { - }; - # this = - # import ./util.nix input - # // import ./parse.nix input - # // import ./trapdoor.nix input - # // import ./null.nix input - # // import ./maybe.nix input - # // import ./wrap.nix input - # // import ./enforce.nix input - # // import ./sig.nix input - # // import ./nt.nix input; -in - this diff --git a/nt/primitives/std/enforce.nix b/nt/primitives/std/enforce.nix deleted file mode 100644 index ea8f50d..0000000 --- a/nt/primitives/std/enforce.nix +++ /dev/null @@ -1,2 +0,0 @@ -{...}: { -} diff --git a/nt/primitives/types/default.nix b/nt/primitives/types/default.nix deleted file mode 100644 index 10f58e8..0000000 --- a/nt/primitives/types/default.nix +++ /dev/null @@ -1,8 +0,0 @@ -{mix, ...} @ inputs: -mix.newMixture inputs (mixture: { - includes.public = [ - ./maybe.nix - ./null.nix - ./wrap.nix - ]; -}) diff --git a/nt/primitives/util/default.nix b/nt/primitives/util/default.nix deleted file mode 100644 index 36814cf..0000000 --- a/nt/primitives/util/default.nix +++ /dev/null @@ -1,7 +0,0 @@ -{mix, ...} @ inputs: -mix.newMixture inputs (mixture: { - includes.public = [ - ./nt.nix - ./trapdoor.nix - ]; -})