From d5843aad06703e83b9f97eac970035b52a8e1462 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Fri, 2 Aug 2024 12:33:28 -0600 Subject: [PATCH 1/4] fix: super should be recursive So you can access the grandparent via `super.super`, etc. --- default.nix | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/default.nix b/default.nix index 336129e..ee3a212 100644 --- a/default.nix +++ b/default.nix @@ -3,6 +3,7 @@ let filterMap = scopedImport { std = builtins; } ./std/set/filterMap.nix; parse = scopedImport { std = builtins; } ./std/file/parse.nix; compose = import ./.; + cond = set: if set._if or true then set else { }; filterMod = builtins.filterSource ( path: type: @@ -32,8 +33,14 @@ let outPath = filterMod dir; }; } - // (if super != { } then { inherit super; } else { }) - // (if pub != { } then { inherit pub; } else { }) + // cond { + _if = super != { }; + inherit super; + } + // cond { + _if = pub != { }; + inherit pub; + } ); mod = if contents ? "mod.nix" && contents."mod.nix" == "regular" then @@ -48,7 +55,15 @@ let file = parse name; in if type == "directory" then - { ${name} = f self path; } + { + ${name} = f ( + self + // cond { + _if = super != { }; + inherit super; + } + ) path; + } else if type == "regular" && file.ext or null == "nix" && name != "mod.nix" then { ${file.name} = import' "${path}"; } else From a2486f906a196005f7627a8a4c6d0212df48095e Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Fri, 2 Aug 2024 13:03:08 -0600 Subject: [PATCH 2/4] fix(direnv): avoid superflous reloads --- .envrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.envrc b/.envrc index 1d953f4..cf9181a 100644 --- a/.envrc +++ b/.envrc @@ -1 +1 @@ -use nix +eval "$(nix print-dev-env -f shell.nix)" From 6a7cceee59bd9ab71e6e6c64c83c8e9d15392136 Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Fri, 2 Aug 2024 13:10:35 -0600 Subject: [PATCH 3/4] style: refactor --- default.nix | 91 ++++++++++++++++++++++++++--------------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/default.nix b/default.nix index ee3a212..185b667 100644 --- a/default.nix +++ b/default.nix @@ -19,59 +19,58 @@ in }: dir: let + std = compose { } ./std // builtins; atom = fix ( f: super: dir: let contents = builtins.readDir dir; - self = + + hasMod = contents."mod.nix" or null == "regular"; + + mod = if hasMod then scope "${dir + "/mod.nix"}" else { }; + + scope = scopedImport ( + { + inherit atom std; + self = self // { + outPath = filterMod dir; + }; + } + // cond { + _if = super != { }; + inherit super; + } + // cond { + _if = pub != { }; + inherit pub; + } + ); + + g = + name: type: let - import' = scopedImport ( - { - inherit atom; - std = compose { } ./std // builtins; - self = self // { - outPath = filterMod dir; - }; - } - // cond { - _if = super != { }; - inherit super; - } - // cond { - _if = pub != { }; - inherit pub; - } - ); - mod = - if contents ? "mod.nix" && contents."mod.nix" == "regular" then - import' "${dir + "/mod.nix"}" - else - { }; + path = dir + "/${name}"; + file = parse name; in - filterMap ( - name: type: - let - path = dir + "/${name}"; - file = parse name; - in - if type == "directory" then - { - ${name} = f ( - self - // cond { - _if = super != { }; - inherit super; - } - ) path; - } - else if type == "regular" && file.ext or null == "nix" && name != "mod.nix" then - { ${file.name} = import' "${path}"; } - else - null # Ignore other file types - ) contents - // mod; + if type == "directory" then + { + ${name} = f ( + self + // cond { + _if = super != { }; + inherit super; + } + ) path; + } + else if type == "regular" && file.ext or null == "nix" && name != "mod.nix" then + { ${file.name} = scope "${path}"; } + else + null # Ignore other file types + ; + + self = filterMap g contents // mod; in - if !(contents."mod.nix" or null == "regular") then + if !hasMod then { } # Base case: no module else self From 1aefe95c87263a54a1b82af7d445ade363fdb71c Mon Sep 17 00:00:00 2001 From: Timothy DeHerrera Date: Fri, 2 Aug 2024 15:51:38 -0600 Subject: [PATCH 4/4] feat: refine scoping rules & names resolves #1 * `self` -> `mod` * `super` -> `pre` * external dependencies are merged with `atom` in scope. * on collision, local references take precedent. * externals are always available via `atom.extern`. --- README.md | 11 ++++---- default.nix | 25 ++++++++++--------- dev/pkgs.nix | 2 +- dev/shell.nix | 2 +- shell.nix | 2 +- test/bld/bar/mod.nix | 2 +- test/bld/bar/next/mod.nix | 4 +-- test/bld/buzz/bar/mod.nix | 2 +- test/bld/buzz/bar/next/mod.nix | 4 +-- test/bld/buzz/fuzz/bar/mod.nix | 2 +- test/bld/buzz/fuzz/bar/next/mod.nix | 4 +-- test/bld/buzz/fuzz/mod.nix | 4 +-- test/bld/buzz/fuzz/next/mod.nix | 4 +-- test/bld/buzz/fuzz/wuzz/bar/mod.nix | 2 +- test/bld/buzz/fuzz/wuzz/bar/next/mod.nix | 4 +-- test/bld/buzz/fuzz/wuzz/cuzz/bar/mod.nix | 2 +- test/bld/buzz/fuzz/wuzz/cuzz/bar/next/mod.nix | 4 +-- test/bld/buzz/fuzz/wuzz/cuzz/mod.nix | 2 +- test/bld/buzz/fuzz/wuzz/cuzz/next/mod.nix | 4 +-- test/bld/buzz/fuzz/wuzz/mod.nix | 4 +-- test/bld/buzz/fuzz/wuzz/next/mod.nix | 4 +-- test/bld/buzz/mod.nix | 4 +-- test/bld/buzz/next/mod.nix | 4 +-- test/bld/mod.nix | 4 +-- test/bld/next/mod.nix | 4 +-- 25 files changed, 55 insertions(+), 55 deletions(-) diff --git a/README.md b/README.md index 479a678..1041456 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ code without having to perform a full evaluation. This could be used, e.g. to sh - **Isolation**: Modules are imported into the Nix store, enforcing boundaries and preventing relative path access. - **Introspection**: Unlike legacy modules, code is specified in its final form instead of as prototypes (functions), leading to much better and simpler introspective analysis. - **Simplicity**: The system is kept purposefully simple and flexible in order to remain performant and flexible. -- **Scoping**: Each module and member has access to `self`, `super`, `atom`, `pub` and `std`. +- **Scoping**: Each module and member has access to `mod`, `pre`, `atom`, and `std`. - **Standard Library**: Includes a standard library (`std`) augmented with `builtins`. ## How It Works @@ -27,11 +27,10 @@ code without having to perform a full evaluation. This could be used, e.g. to sh - Subdirectories with `mod.nix`: Treated as nested modules. 2. **Scoping**: - - `self`: Current module, includes `outPath` for accessing non-Nix files. - - `super`: Parent module (if applicable). - - `atom`: Top-level module. + - `mod`: Current module, includes `outPath` for accessing non-Nix files. + - `pre`: Parent module (if applicable). + - `atom`: Top-level module and external dependencies. - `std`: Standard library and `builtins`. - - `pub`: External resources, such as other atoms, free-form nix expressions, remote sources, etc. 3. **Composition**: Modules are composed recursively, with `mod.nix` contents taking precedence. @@ -53,7 +52,7 @@ in * Break out large functions or code blocks into their own files * Organize related functionality into subdirectories with their own "mod.nix" files. * Leverage provided scopes for clean, modular code. -* Use `"${self}"` when needing to access non-Nix files within a module. +* Use `"${mod}/foo.nix"` when needing to access non-Nix files within a module. ## Future Work diff --git a/default.nix b/default.nix index 185b667..2ca6775 100644 --- a/default.nix +++ b/default.nix @@ -15,13 +15,17 @@ let in { - pub ? { }, + extern ? { }, }: dir: let std = compose { } ./std // builtins; + atom' = builtins.removeAttrs (extern // atom // { inherit extern; }) [ + "atom" + (baseNameOf dir) + ]; atom = fix ( - f: super: dir: + f: pre: dir: let contents = builtins.readDir dir; @@ -31,18 +35,15 @@ let scope = scopedImport ( { - inherit atom std; - self = self // { + inherit std; + atom = atom'; + mod = builtins.removeAttrs self [ "mod" ] // { outPath = filterMod dir; }; } // cond { - _if = super != { }; - inherit super; - } - // cond { - _if = pub != { }; - inherit pub; + _if = pre != { }; + inherit pre; } ); @@ -57,8 +58,8 @@ let ${name} = f ( self // cond { - _if = super != { }; - inherit super; + _if = pre != { }; + inherit pre; } ) path; } diff --git a/dev/pkgs.nix b/dev/pkgs.nix index 4cf593e..18f9084 100644 --- a/dev/pkgs.nix +++ b/dev/pkgs.nix @@ -1,4 +1,4 @@ let - inherit (pub.pins) nixpkgs; + inherit (atom.pins) nixpkgs; in import nixpkgs { } diff --git a/dev/shell.nix b/dev/shell.nix index ae900bc..07c3995 100644 --- a/dev/shell.nix +++ b/dev/shell.nix @@ -1,5 +1,5 @@ { - pkgs ? self.pkgs, + pkgs ? mod.pkgs, }: pkgs.mkShell { packages = with pkgs; [ diff --git a/shell.nix b/shell.nix index f1d30ea..52e62ec 100644 --- a/shell.nix +++ b/shell.nix @@ -1,6 +1,6 @@ let dev = import ./. { - pub = { + extern = { pins = import ./npins; }; } ./dev; diff --git a/test/bld/bar/mod.nix b/test/bld/bar/mod.nix index 885c6ee..f49b8c3 100644 --- a/test/bld/bar/mod.nix +++ b/test/bld/bar/mod.nix @@ -1,5 +1,5 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; } diff --git a/test/bld/bar/next/mod.nix b/test/bld/bar/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/bar/next/mod.nix +++ b/test/bld/bar/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/bar/mod.nix b/test/bld/buzz/bar/mod.nix index 885c6ee..f49b8c3 100644 --- a/test/bld/buzz/bar/mod.nix +++ b/test/bld/buzz/bar/mod.nix @@ -1,5 +1,5 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/bar/next/mod.nix b/test/bld/buzz/bar/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/bar/next/mod.nix +++ b/test/bld/buzz/bar/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/fuzz/bar/mod.nix b/test/bld/buzz/fuzz/bar/mod.nix index 885c6ee..f49b8c3 100644 --- a/test/bld/buzz/fuzz/bar/mod.nix +++ b/test/bld/buzz/fuzz/bar/mod.nix @@ -1,5 +1,5 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/fuzz/bar/next/mod.nix b/test/bld/buzz/fuzz/bar/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/fuzz/bar/next/mod.nix +++ b/test/bld/buzz/fuzz/bar/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/fuzz/mod.nix b/test/bld/buzz/fuzz/mod.nix index e4e8ed3..1ac0511 100644 --- a/test/bld/buzz/fuzz/mod.nix +++ b/test/bld/buzz/fuzz/mod.nix @@ -1,5 +1,5 @@ { foo = 1; - bar = super.bar + 2; - baz = self.bar + 4; + bar = pre.bar + 2; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/fuzz/next/mod.nix b/test/bld/buzz/fuzz/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/fuzz/next/mod.nix +++ b/test/bld/buzz/fuzz/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/fuzz/wuzz/bar/mod.nix b/test/bld/buzz/fuzz/wuzz/bar/mod.nix index 885c6ee..f49b8c3 100644 --- a/test/bld/buzz/fuzz/wuzz/bar/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/bar/mod.nix @@ -1,5 +1,5 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/fuzz/wuzz/bar/next/mod.nix b/test/bld/buzz/fuzz/wuzz/bar/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/fuzz/wuzz/bar/next/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/bar/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/fuzz/wuzz/cuzz/bar/mod.nix b/test/bld/buzz/fuzz/wuzz/cuzz/bar/mod.nix index 885c6ee..f49b8c3 100644 --- a/test/bld/buzz/fuzz/wuzz/cuzz/bar/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/cuzz/bar/mod.nix @@ -1,5 +1,5 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/fuzz/wuzz/cuzz/bar/next/mod.nix b/test/bld/buzz/fuzz/wuzz/cuzz/bar/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/fuzz/wuzz/cuzz/bar/next/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/cuzz/bar/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/fuzz/wuzz/cuzz/mod.nix b/test/bld/buzz/fuzz/wuzz/cuzz/mod.nix index 885c6ee..f49b8c3 100644 --- a/test/bld/buzz/fuzz/wuzz/cuzz/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/cuzz/mod.nix @@ -1,5 +1,5 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/fuzz/wuzz/cuzz/next/mod.nix b/test/bld/buzz/fuzz/wuzz/cuzz/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/fuzz/wuzz/cuzz/next/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/cuzz/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/fuzz/wuzz/mod.nix b/test/bld/buzz/fuzz/wuzz/mod.nix index e4e8ed3..1ac0511 100644 --- a/test/bld/buzz/fuzz/wuzz/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/mod.nix @@ -1,5 +1,5 @@ { foo = 1; - bar = super.bar + 2; - baz = self.bar + 4; + bar = pre.bar + 2; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/fuzz/wuzz/next/mod.nix b/test/bld/buzz/fuzz/wuzz/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/fuzz/wuzz/next/mod.nix +++ b/test/bld/buzz/fuzz/wuzz/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/buzz/mod.nix b/test/bld/buzz/mod.nix index d890562..e0d1d03 100644 --- a/test/bld/buzz/mod.nix +++ b/test/bld/buzz/mod.nix @@ -1,5 +1,5 @@ { foo = 1; - bar = super.foo + 2; - baz = self.bar + 4; + bar = pre.foo + 2; + baz = mod.bar + 4; } diff --git a/test/bld/buzz/next/mod.nix b/test/bld/buzz/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/buzz/next/mod.nix +++ b/test/bld/buzz/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; } diff --git a/test/bld/mod.nix b/test/bld/mod.nix index d5fbf8d..698bdd4 100644 --- a/test/bld/mod.nix +++ b/test/bld/mod.nix @@ -1,7 +1,7 @@ { foo = 1; bar = atom.foo + 2; - baz = self.bar + 4; + baz = mod.bar + 4; test = std.set.filterMap; - x = builtins.readFile "${self}/bum"; + x = builtins.readFile "${mod}/bum"; } diff --git a/test/bld/next/mod.nix b/test/bld/next/mod.nix index d89f820..464f617 100644 --- a/test/bld/next/mod.nix +++ b/test/bld/next/mod.nix @@ -1,5 +1,5 @@ { - g = super.foo + 4; - h = self.g + 3; + g = pre.foo + 4; + h = mod.g + 3; }