From 14b78847f99524f5fe3156ecd47373df636c0d90 Mon Sep 17 00:00:00 2001 From: James Eversole Date: Mon, 31 Aug 2026 09:01:02 -0500 Subject: [PATCH] pow, even, odd, min, max --- AGENTS.md | 20 +++++++++ lib/base.tri | 18 ++++++++ test/Spec.hs | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) diff --git a/AGENTS.md b/AGENTS.md index cf47efe..d7eb73d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -16,6 +16,26 @@ nix build .# > **Rule of thumb:** if it builds, links, or tests, it goes through `nix`. +### Write and test, don't mentally trace + +`nix flake check` finishes quickly. Use it. + +tricu's minimalism makes it easy to build a confident-sounding but wrong +mental model of evaluation order, branch selection (`matchBool` arg order), +or number encoding. A quick test replaces many minutes of uncertain reasoning. + +Prefer: + +1. Write a candidate implementation. +2. Run the tests or a probe. +3. Fix what's wrong. + +Over: + +1. Reason about semantics across multiple files. +2. Build up a chain of inference. +3. Write code that assumes the chain was correct. + ## Project Overview **tricu** (pronounced "tree-shoe") is a programming-language experiment written primarily in Haskell. diff --git a/lib/base.tri b/lib/base.tri index 620f7a4..d3e7775 100644 --- a/lib/base.tri +++ b/lib/base.tri @@ -246,6 +246,24 @@ mod = y (self a b : (_ : a) (_ : self (sub a b) b))) +pow = y (self a b : + ifLazy + (isZero? b) + (_ : 1) + (_ : mul a (self a (pred b)))) + +even? n = (triage + true + (_ : false) + (bit _ : isZero? bit) + n) + +odd? = (n : not? (even? n)) + +min = (a b : ifLazy (lte? a b) (_ : a) (_ : b)) + +max = (a b : ifLazy (lte? a b) (_ : b) (_ : a)) + -- --------------------------------------------------------------------------- -- Result combinators -- --------------------------------------------------------------------------- diff --git a/test/Spec.hs b/test/Spec.hs index db8d068..8a11a61 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -1435,6 +1435,121 @@ arithmetic = testGroup "Arithmetic Tests" let input = "equal? (add (mul 3 7) 4) 25" env = evalTricu allTestLibsEnv (parseTricu input) result env @?= trueT + + , testCase "pow 2 0 = 1" $ do + let input = "pow 2 0" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 1 + + , testCase "pow 2 3 = 8" $ do + let input = "pow 2 3" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 8 + + , testCase "pow 3 2 = 9" $ do + let input = "pow 3 2" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 9 + + , testCase "pow 0 0 = 1" $ do + let input = "pow 0 0" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 1 + + , testCase "pow 0 5 = 0" $ do + let input = "pow 0 5" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 0 + + , testCase "pow 1 10 = 1" $ do + let input = "pow 1 10" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 1 + + , testCase "pow 5 1 = 5" $ do + let input = "pow 5 1" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 5 + + , testCase "min 3 7 = 3" $ do + let input = "min 3 7" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 3 + + , testCase "min 7 3 = 3" $ do + let input = "min 7 3" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 3 + + , testCase "min 5 5 = 5" $ do + let input = "min 5 5" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 5 + + , testCase "min 0 5 = 0" $ do + let input = "min 0 5" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 0 + + , testCase "max 3 7 = 7" $ do + let input = "max 3 7" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 7 + + , testCase "max 7 3 = 7" $ do + let input = "max 7 3" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 7 + + , testCase "max 5 5 = 5" $ do + let input = "max 5 5" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 5 + + , testCase "max 0 5 = 5" $ do + let input = "max 0 5" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= ofNumber 5 + + , testCase "even? 0 = true" $ do + let input = "even? 0" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= trueT + + , testCase "even? 1 = false" $ do + let input = "even? 1" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= falseT + + , testCase "even? 2 = true" $ do + let input = "even? 2" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= trueT + + , testCase "even? 7 = false" $ do + let input = "even? 7" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= falseT + + , testCase "odd? 0 = false" $ do + let input = "odd? 0" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= falseT + + , testCase "odd? 1 = true" $ do + let input = "odd? 1" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= trueT + + , testCase "odd? 2 = false" $ do + let input = "odd? 2" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= falseT + + , testCase "odd? 7 = true" $ do + let input = "odd? 7" + env = evalTricu allTestLibsEnv (parseTricu input) + result env @?= trueT ] fileEval :: TestTree