Repository: tweag/nickel
Pull request #1064 (2023-01-23 12:37:57)

Update flake lock + fix markdown lint
Same as #1061, but with the CI fixed for markdown documentation. Commented out documentation lines were too wide, and one section actually needed to be restored now that enum types are back.


Patch:
diff --git a/.github/workflows/update-flake-lock.yml b/.github/workflows/update-flake-lock.yml
index 6be77b47..e3da5b7d 100644
--- a/.github/workflows/update-flake-lock.yml
+++ b/.github/workflows/update-flake-lock.yml
@@ -16,7 +16,7 @@ jobs:
           extra_nix_config: |
             access-tokens = github.com=${{ secrets.GITHUB_TOKEN }}
       - name: Update flake.lock
-        uses: DeterminateSystems/update-flake-lock@v16
+        uses: DeterminateSystems/update-flake-lock@v15
         with:
           # Providing a secret token is necessary for the PRs to run CI
           # See https://github.com/DeterminateSystems/update-flake-lock#with-a-personal-authentication-token
diff --git a/Cargo.lock b/Cargo.lock
index 69319d62..a2fe25b0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -200,9 +200,9 @@ dependencies = [
 
 [[package]]
 name = "bumpalo"
-version = "3.12.0"
+version = "3.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
+checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3"
 
 [[package]]
 name = "byte-tools"
diff --git a/RATIONALE.md b/RATIONALE.md
index f98bc504..93b6d3d0 100644
--- a/RATIONALE.md
+++ b/RATIONALE.md
@@ -348,7 +348,8 @@ feature static types, contracts or enriched values, and thus can't type library
 code and has no principled approach to data validation.
 
 ### Comparison with other configuration languages
-<!-- Intentionally duplicated in `README.md`, please update the other one for any change done here -->
+<!-- Intentionally duplicated in `README.md`, please update the other one for
+any change done here -->
 
 | Language | Typing                        | Recursion  | Evaluation | Side-effects                                     |
 |----------|-------------------------------|------------|------------|--------------------------------------------------|
diff --git a/README.md b/README.md
index 938cd64e..3ce71436 100644
--- a/README.md
+++ b/README.md
@@ -249,7 +249,8 @@ See [RATIONALE.md](./RATIONALE.md) for the design rationale and a more detailed
 comparison with these languages.
 
 ### Comparison with other configuration languages
-<!-- Intentionally duplicated in `RATIONALE.md`, please update the other one for any change done here -->
+<!-- Intentionally duplicated in `RATIONALE.md`, please update the other one for
+any change done here -->
 
 | Language | Typing                        | Recursion  | Evaluation | Side-effects                                     |
 |----------|-------------------------------|------------|------------|--------------------------------------------------|
diff --git a/doc/manual/cookbook.md b/doc/manual/cookbook.md
index bcd3a46d..c5f6aac2 100644
--- a/doc/manual/cookbook.md
+++ b/doc/manual/cookbook.md
@@ -44,13 +44,3 @@ record level. It makes code more navigable and `query`-friendly, but at the
 expense of repetition and duplicated contract checks. It is also currently
 required for polymorphic functions because of [the following
 bug](https://github.com/tweag/nickel/issues/360).
-
-<!-- # Note: we already have type wildcard, but they don't "export" the inferred type. -->
-<!-- A better solution will probably be implemented in the future: type wildcard (TODO: -->
-<!--  -->
-<!-- ```nickel -->
-<!-- { -->
-<!--   foo : Num -> Num = fun x => x + 1, -->
-<!--   bar : Num -> Num = foo, -->
-<!-- } : _ -->
-<!-- ``` -->
diff --git a/doc/manual/typing.md b/doc/manual/typing.md
index 5b35734c..0b080d35 100644
--- a/doc/manual/typing.md
+++ b/doc/manual/typing.md
@@ -165,7 +165,7 @@ Let us now have a quick tour of the type system. The basic types are:
 - `Num`: the only number type. Currently implemented as a 64bits float.
 - `Str`: a string, which must always be valid UTF8.
 - `Bool`: a boolean, that is either `true` or `false`.
-<!-- - `Lbl`: a contract label. You usually don't need to use it or worry about it, -->
+<!-- - `Lbl`: a contract label. You usually don't need to use it or worry about it,-->
 <!--     it is more of an internal thing.  -->
 
 The following type constructors are available:
@@ -398,21 +398,21 @@ could still write `addTotal {total = 1, foo = 1} {total = 2, foo = 2}` but not
 What comes before the tail may include several fields, is in e.g. `forall a.
 {total: Num, subtotal: Num ; a} -> Num`.
 
-<!-- Note that row polymorphism also works with enums, with the same intuition of a -->
-<!-- tail that can be substituted for something else. For example: -->
-<!--  -->
-<!-- ```nickel -->
-<!-- let portOf : forall a. <http, ftp | a> -> Num = fun protocol => -->
-<!-- switch { -->
-<!--   `http -> 80, -->
-<!--   `ftp -> 21, -->
-<!--   _ -> 8000, -->
-<!-- } protocol -->
-<!-- ``` -->
-<!--  -->
-<!-- Because the `switch` statement has a catch-all case `_`, this function is indeed -->
-<!-- able to handle other tags than `http` and `ftp`, as expressed by its polymorphic -->
-<!-- type. -->
+Note that row polymorphism also works with enums, with the same intuition of a
+tail that can be substituted for something else. For example:
+
+```nickel
+let port_of : forall a. [| `http, `ftp; a |] -> Num =
+  match {
+    `http => 80,
+    `ftp => 21,
+    _ => 8000,
+  }
+```
+
+Because the `match` statement has a catch-all case `_`, this function is indeed
+able to handle other tags than `http` and `ftp`, as expressed by its polymorphic
+type.
 
 ### Take-away
 
diff --git a/flake.lock b/flake.lock
index 30d00d79..46929e69 100644
--- a/flake.lock
+++ b/flake.lock
@@ -42,11 +42,11 @@
     "flake-compat_2": {
       "flake": false,
       "locked": {
-        "lastModified": 1668681692,
-        "narHash": "sha256-Ht91NGdewz8IQLtWZ9LCeNXMSXHUss+9COoqu6JLmXU=",
+        "lastModified": 1673956053,
+        "narHash": "sha256-4gtG9iQuiKITOjNQQeQIpoIB6b16fm+504Ch3sNKLd8=",
         "owner": "edolstra",
         "repo": "flake-compat",
-        "rev": "009399224d5e398d03b22badca40a37ac85412a1",
+        "rev": "35bb57c0c8d8b62bbfd284272c928ceb64ddbde9",
         "type": "github"
       },
       "original": {
@@ -108,11 +108,11 @@
     },
     "nixpkgs": {
       "locked": {
-        "lastModified": 1673540789,
-        "narHash": "sha256-xqnxBOK3qctIeUVxecydrEDbEXjsvHCPGPbvsl63M/U=",
+        "lastModified": 1674211260,
+        "narHash": "sha256-xU6Rv9sgnwaWK7tgCPadV6HhI2Y/fl4lKxJoG2+m9qs=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "0f213d0fee84280d8c3a97f7469b988d6fe5fcdf",
+        "rev": "5ed481943351e9fd354aeb557679624224de38d5",
         "type": "github"
       },
       "original": {
@@ -123,16 +123,16 @@
     },
     "nixpkgs-stable": {
       "locked": {
-        "lastModified": 1671271954,
-        "narHash": "sha256-cSvu+bnvN08sOlTBWbBrKaBHQZq8mvk8bgpt0ZJ2Snc=",
+        "lastModified": 1673800717,
+        "narHash": "sha256-SFHraUqLSu5cC6IxTprex/nTsI81ZQAtDvlBvGDWfnA=",
         "owner": "NixOS",
         "repo": "nixpkgs",
-        "rev": "d513b448cc2a6da2c8803e3c197c9fc7e67b19e3",
+        "rev": "2f9fd351ec37f5d479556cd48be4ca340da59b8f",
         "type": "github"
       },
       "original": {
         "owner": "NixOS",
-        "ref": "nixos-22.05",
+        "ref": "nixos-22.11",
         "repo": "nixpkgs",
         "type": "github"
       }
@@ -150,11 +150,11 @@
         "nixpkgs-stable": "nixpkgs-stable"
       },
       "locked": {
-        "lastModified": 1673627351,
-        "narHash": "sha256-oppRxEg/7ICcG67ErBvu1UlXt3su6zMcNoQmKaHPs5I=",
+        "lastModified": 1674122161,
+        "narHash": "sha256-9QM4rvgUSEwO8DWtJN9sR/afEqrH1s3b6ACsZT5wiAM=",
         "owner": "cachix",
         "repo": "pre-commit-hooks.nix",
-        "rev": "496e4505c2ddf5f205242eae8064d7d89cd976c0",
+        "rev": "53e766957b73298fa68b47478c48cbcc005cc18a",
         "type": "github"
       },
       "original": {
@@ -207,11 +207,11 @@
         ]
       },
       "locked": {
-        "lastModified": 1673662873,
-        "narHash": "sha256-/YOtiDKPUXKKpIhsAds11llfC42ScGW27bbHnNZebco=",
+        "lastModified": 1674267882,
+        "narHash": "sha256-53sIczqxA5BbrhgO6l54DSisDqHvQ3UUwbSqBryA/k0=",
         "owner": "oxalica",
         "repo": "rust-overlay",
-        "rev": "90163bbbadce526f8b248a5fe545b06c59597108",
+        "rev": "1fd6d280c132f4facad8cd023543fb10121e6487",
         "type": "github"
       },
       "original": {
diff --git a/src/eval/operation.rs b/src/eval/operation.rs
index 6b8c8194..8a7d050d 100644
--- a/src/eval/operation.rs
+++ b/src/eval/operation.rs
@@ -672,11 +672,17 @@ impl<R: ImportResolver, C: Cache> VirtualMachine<R, C> {
                     }
                 }
             }
-            UnaryOp::Seq() => self
-                .stack
-                .pop_arg(&self.cache)
-                .map(|(next, ..)| next)
-                .ok_or_else(|| EvalError::NotEnoughArgs(2, String::from("seq"), pos_op)),
+            UnaryOp::Seq() => {
+                if self.stack.count_args() >= 1 {
+                    let (next, ..) = self
+                        .stack
+                        .pop_arg(&self.cache)
+                        .expect("Condition already checked.");
+                    Ok(next)
+                } else {
+                    Err(EvalError::NotEnoughArgs(2, String::from("seq"), pos_op))
+                }
+            }
             UnaryOp::DeepSeq(_) => {
                 /// Build a RichTerm that forces a given list of terms, and at the end resumes the
                 /// evaluation of the argument on the top of the stack. The argument must iterate over
@@ -1252,24 +1258,6 @@ impl<R: ImportResolver, C: Cache> VirtualMachine<R, C> {
                     ))
                 }
             },
-            UnaryOp::Trace() => {
-                if let Term::Str(s) = &*t {
-                    eprintln!("builtin.trace: {s}");
-                    Ok(())
-                } else {
-                    Err(EvalError::TypeError(
-                        String::from("Str"),
-                        String::from("trace"),
-                        arg_pos,
-                        RichTerm { term: t, pos },
-                    ))
-                }?;
-
-                self.stack
-                    .pop_arg(&self.cache)
-                    .map(|(next, ..)| next)
-                    .ok_or_else(|| EvalError::NotEnoughArgs(2, String::from("trace"), pos_op))
-            }
         }
     }
 
diff --git a/src/parser/grammar.lalrpop b/src/parser/grammar.lalrpop
index b754c3ba..06310566 100644
--- a/src/parser/grammar.lalrpop
+++ b/src/parser/grammar.lalrpop
@@ -596,7 +596,6 @@ UOp: UnaryOp = {
     "rec_force_op" => UnaryOp::RecForce(),
     "rec_default_op" => UnaryOp::RecDefault(),
     "record_empty_with_tail" => UnaryOp::RecordEmptyWithTail(),
-    "trace" => UnaryOp::Trace(),
 };
 
 MatchCase: MatchCase = {
@@ -938,7 +937,6 @@ extern {
         "pow" => Token::Normal(NormalToken::Pow),
         "rec_force_op" => Token::Normal(NormalToken::RecForceOp),
         "rec_default_op" => Token::Normal(NormalToken::RecDefaultOp),
-        "trace" => Token::Normal(NormalToken::Trace),
 
         "has_field" => Token::Normal(NormalToken::HasField),
         "map" => Token::Normal(NormalToken::Map),
diff --git a/src/parser/lexer.rs b/src/parser/lexer.rs
index 89ece5a0..9dd785ed 100644
--- a/src/parser/lexer.rs
+++ b/src/parser/lexer.rs
@@ -223,8 +223,6 @@ pub enum NormalToken<'input> {
     ValuesOf,
     #[token("%pow%")]
     Pow,
-    #[token("%trace%")]
-    Trace,
 
     #[token("%has_field%")]
     HasField,
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 599e2b45..a839ffaa 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -1066,11 +1066,6 @@ pub enum UnaryOp {
     /// define a `field_diff` function that preserves the sealed polymorphic
     /// tail of its argument.
     RecordEmptyWithTail(),
-
-    /// Print a message when encountered during evaluation and proceed with the evaluation of the argument
-    /// on the top of the stack. Operationally the same as the identity
-    /// function
-    Trace(),
 }
 
 // See: https://github.com/rust-lang/regex/issues/178
diff --git a/src/typecheck/operation.rs b/src/typecheck/operation.rs
index 0dc67b18..eaa25a3f 100644
--- a/src/typecheck/operation.rs
+++ b/src/typecheck/operation.rs
@@ -211,12 +211,6 @@ pub fn get_uop_type(
             (ty.clone(), ty)
         }
         UnaryOp::RecordEmptyWithTail() => (mk_uniftype::dynamic(), mk_uniftype::dynamic()),
-
-        // forall a. Str -> a -> a
-        UnaryOp::Trace() => {
-            let ty = UnifType::UnifVar(state.table.fresh_type_var_id());
-            (mk_uniftype::str(), mk_uty_arrow!(ty.clone(), ty))
-        }
     })
 }
 
diff --git a/stdlib/builtin.ncl b/stdlib/builtin.ncl
index 404e2747..b35d7f7b 100644
--- a/stdlib/builtin.ncl
+++ b/stdlib/builtin.ncl
@@ -207,22 +207,8 @@
         "Foo"
       from null =>
         "null"
-      ```
       "%
     = fun x => %to_str% x,
 
-    trace : forall a. Str -> a -> a
-    | doc m%"
-      `builtin.trace msg x` prints `msg` to standard output when encountered by the evaluator,
-      and proceed with the evaluation of `x`.
-
-      For example:
-      ```nickel
-      builtin.trace "Hello, world!" true =>
-        builtin.trace: Hello, world!
-        true
-      ```
-      "%
-    = fun msg x => %trace% msg x,
   },
 }


Test patch:
diff --git a/tests/snapshot/inputs/export/trace.ncl b/tests/snapshot/inputs/export/trace.ncl
deleted file mode 100644
index f18fbcde..00000000
--- a/tests/snapshot/inputs/export/trace.ncl
+++ /dev/null
@@ -1,1 +0,0 @@
-builtin.trace "Hello, world!" true
diff --git a/tests/snapshot/snapshots/snapshot__export_trace.ncl.snap b/tests/snapshot/snapshots/snapshot__export_trace.ncl.snap
deleted file mode 100644
index 109fa87b..00000000
--- a/tests/snapshot/snapshots/snapshot__export_trace.ncl.snap
+++ /dev/null
@@ -1,5 +0,0 @@
----
-source: tests/snapshot/main.rs
-expression: snapshot
----
-true