From 178a5e67814fdcc3c11678b7696074b33844f6b7 Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 16:18:01 +0530 Subject: ADD: Lambda Calculus in Clojure Source: https://github.com/srodrigo/lambda-calculus-in-clojure --- languages/c/clojure/lambda-core/deps.edn | 6 ++ languages/c/clojure/lambda-core/src/booleans.clj | 29 +++++++++ languages/c/clojure/lambda-core/src/numerals.clj | 47 ++++++++++++++ .../c/clojure/lambda-core/test/booleans_test.clj | 67 +++++++++++++++++++ .../c/clojure/lambda-core/test/numerals_test.clj | 75 ++++++++++++++++++++++ .../c/clojure/lambda-core/test/test_runner.clj | 7 ++ 6 files changed, 231 insertions(+) create mode 100644 languages/c/clojure/lambda-core/deps.edn create mode 100644 languages/c/clojure/lambda-core/src/booleans.clj create mode 100644 languages/c/clojure/lambda-core/src/numerals.clj create mode 100644 languages/c/clojure/lambda-core/test/booleans_test.clj create mode 100644 languages/c/clojure/lambda-core/test/numerals_test.clj create mode 100644 languages/c/clojure/lambda-core/test/test_runner.clj (limited to 'languages') diff --git a/languages/c/clojure/lambda-core/deps.edn b/languages/c/clojure/lambda-core/deps.edn new file mode 100644 index 0000000..6cb68b3 --- /dev/null +++ b/languages/c/clojure/lambda-core/deps.edn @@ -0,0 +1,6 @@ +{:paths ["src"] + :deps {org.clojure/clojure {:mvn/version "1.10.0"}} + :aliases + {:test + {:extra-paths ["test"] + :main-opts ["-m" "test-runner"]}}} diff --git a/languages/c/clojure/lambda-core/src/booleans.clj b/languages/c/clojure/lambda-core/src/booleans.clj new file mode 100644 index 0000000..e48f9a7 --- /dev/null +++ b/languages/c/clojure/lambda-core/src/booleans.clj @@ -0,0 +1,29 @@ +(ns booleans) + +(defmacro λ + [args & body] + `(fn [~args] ~@body)) + +(def T + (λ a (λ b a))) + +(def F + (λ a (λ b b))) + +(def And + (λ p (λ q ((p q) p)))) + +(def Or + (λ p (λ q ((p p) q)))) + +(def Not + (λ p ((p F) T))) + +(def Xor + (λ a (λ b ((a (Not b)) b)))) + +(def If + (λ p (λ a (λ b ((p a) b))))) + +(def toBoolean + (λ f ((f true) false))) diff --git a/languages/c/clojure/lambda-core/src/numerals.clj b/languages/c/clojure/lambda-core/src/numerals.clj new file mode 100644 index 0000000..e18da0f --- /dev/null +++ b/languages/c/clojure/lambda-core/src/numerals.clj @@ -0,0 +1,47 @@ +(ns numerals) + +(defmacro λ + [args & body] + `(fn [~args] ~@body)) + +(def zero + (λ f (λ x x))) + +(def one + (λ f (λ x (f x)))) + +(def two + (λ f (λ x (f (f x))))) + +(def succ + (λ n (λ f (λ x (f ((n f) x)))))) + +(def pred + (λ n (λ f (λ x (((n (λ g (λ h (h (g f))))) (λ u x)) (λ u u)))))) + +(def plus + (λ m (λ n ((n succ) m)))) + +(def minus + (λ m (λ n ((n pred) m)))) + +(def mult + (λ m (λ n (λ f (m (n f)))))) + +(def exp + (λ m (λ n (n m)))) + +(def fromInt + (λ n + (if (= n 0) + zero + (succ (fromInt (- n 1)))))) + +(def toInt + (λ f ((f (λ n (+ n 1))) 0))) + +(def λToStr + (λ f ((f (λ n (format "f(%s)" n))) "n"))) + +(def toStr + (λ f (format "λf.λn.(%s)" (λToStr f)))) diff --git a/languages/c/clojure/lambda-core/test/booleans_test.clj b/languages/c/clojure/lambda-core/test/booleans_test.clj new file mode 100644 index 0000000..8a75125 --- /dev/null +++ b/languages/c/clojure/lambda-core/test/booleans_test.clj @@ -0,0 +1,67 @@ +(ns booleans-test + (:require [booleans :refer :all] + [clojure.test :refer :all])) + +(deftest λ-booleans + (testing "true" + (is (= (toBoolean T) true))) + + (testing "false" + (is (= (toBoolean F) false))) + + (testing "If" + (is (= (toBoolean (((If T) T) F)) true)) + (is (= (toBoolean (((If F) T) F)) false))) + + (testing "And" + (is (= (toBoolean ((And T) T)) true)) + (is (= (toBoolean ((And T) F)) false)) + (is (= (toBoolean ((And F) T)) false)) + (is (= (toBoolean ((And F) F)) false)) + (is (= (toBoolean ((And T) ((And T) T))) true)) + (is (= (toBoolean ((And T) ((And F) T))) false))) + + (testing "Or" + (is (= (toBoolean ((Or T) T)) true)) + (is (= (toBoolean ((Or T) F)) true)) + (is (= (toBoolean ((Or F) T)) true)) + (is (= (toBoolean ((Or F) F)) false)) + (is (= (toBoolean ((Or F) ((Or F) F))) false)) + (is (= (toBoolean ((Or F) ((Or T) F))) true))) + + (testing "Not" + (is (= (toBoolean (Not T)) false)) + (is (= (toBoolean (Not F)) true)) + (is (= (toBoolean (Not (Not T))) true)) + (is (= (toBoolean (Not (Not F))) false))) + + (testing "Xor" + (is (= (toBoolean ((Xor T) T)) false)) + (is (= (toBoolean ((Xor T) F)) true)) + (is (= (toBoolean ((Xor F) T)) true)) + (is (= (toBoolean ((Xor F) F)) false))) + + (testing "Expressions" + ;T AND T AND F OR T + (is (= (toBoolean ((And T) ((And T) ((Or F) T)))) + true)) + + ;T AND F AND F OR T AND T + (is (= (toBoolean ((And T) ((And F) ((Or F) ((And T) T))))) + false)) + + ;T OR (F AND F OR T AND T) + (is (= (toBoolean ((Or T) ((And F) ((Or F) ((And T) T))))) + true)) + + ;F OR (F AND F OR F AND T) + (is (= (toBoolean ((Or F) ((And F) ((Or F) ((And F) T))))) + false)) + + ;F OR F AND F OR T AND T + (is (= (toBoolean ((And ((Or F) F)) ((And T) ((Or F) T)))) + false)) + + ;T OR F AND F OR T AND T + (is (= (toBoolean ((And ((Or T) F)) ((And T) ((Or F) T)))) + true)))) diff --git a/languages/c/clojure/lambda-core/test/numerals_test.clj b/languages/c/clojure/lambda-core/test/numerals_test.clj new file mode 100644 index 0000000..44458dc --- /dev/null +++ b/languages/c/clojure/lambda-core/test/numerals_test.clj @@ -0,0 +1,75 @@ +(ns numerals-test + (:require [numerals :refer :all] + [clojure.test :refer :all])) + +(deftest λ-numbers + (testing "zero" + (is (= (toInt zero) 0))) + + (testing "one" + (is (= (toInt (succ zero)) 1)) + (is (= (toInt one)) 1)) + + (testing "two" + (is (= (toInt (succ (succ zero))) 2)) + (is (= (toInt two)) 2)) + + (testing "three" + (is (= (toInt (succ (succ (succ zero)))) 3))) + + (testing "predecessor" + (is (= (toInt (pred one)) 0)) + (is (= (toInt (pred two)) 1)) + (is (= (toInt (pred (succ (succ (succ zero))))) 2)) + (is (= (toInt (pred (fromInt 10))) 9)))) + +(deftest λ-numerical-operations + (testing "addition" + (is (= + (toInt ((plus (fromInt 7)) (fromInt 5))) + 12)) + (is (= + (toInt ((plus (fromInt 7)) ((plus (fromInt 6)) (fromInt 2)))) + 15))) + + (testing "subtraction" + (is (= + (toInt ((minus (fromInt 7)) (fromInt 5))) + 2)) + (is (= + (toInt ((minus (fromInt 7)) ((minus (fromInt 6)) (fromInt 2)))) + 3))) + + (testing "multiplication" + (is (= + (toInt ((mult (fromInt 2)) (fromInt 3))) + 6)) + (is (= + (toInt ((mult (fromInt 2)) ((mult (fromInt 5)) (fromInt 3)))) + 30))) + + (testing "exponentiation" + (is (= + (toInt ((exp (fromInt 2)) (fromInt 3))) + 8)) + (is (= + (toInt ((exp (fromInt 2)) ((exp (fromInt 2)) (fromInt 3)))) + 256)))) + +(deftest λ-numeral-expressions + (testing "numeral expressions" + ; 3 * (2 + 5) - 2^3 + (is (= + (toInt ((minus ((mult (fromInt 3)) + ((plus (fromInt 2)) (fromInt 5)))) + ((exp (fromInt 2)) (fromInt 3)))) + 13)))) + +(deftest λ-toStr + (testing "toStr" + (is (= (toStr zero) "λf.λn.(n)")) + (is (= (toStr one) "λf.λn.(f(n))")) + (is (= (toStr two) "λf.λn.(f(f(n)))")) + (is (= (toStr (succ (succ (succ zero)))) "λf.λn.(f(f(f(n))))")) + (is (= (toStr (fromInt 5)) "λf.λn.(f(f(f(f(f(n))))))")))) + diff --git a/languages/c/clojure/lambda-core/test/test_runner.clj b/languages/c/clojure/lambda-core/test/test_runner.clj new file mode 100644 index 0000000..038b818 --- /dev/null +++ b/languages/c/clojure/lambda-core/test/test_runner.clj @@ -0,0 +1,7 @@ +(ns test-runner + (:require [clojure.test :as t] + [numerals-test] + [booleans-test])) + +(defn -main [& args] + (t/run-tests 'numerals-test 'booleans-test)) -- cgit v1.2.3 From 6c0f7d5cce40262df141f27730bdaa919d1ec33c Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 16:46:21 +0530 Subject: ADD: README file --- languages/c/clojure/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 languages/c/clojure/README.md (limited to 'languages') diff --git a/languages/c/clojure/README.md b/languages/c/clojure/README.md new file mode 100644 index 0000000..b451b10 --- /dev/null +++ b/languages/c/clojure/README.md @@ -0,0 +1,2 @@ +[Download Clojure](https://clojure.org/guides/install_clojure) +Run all tests like this: `clj -M:test` -- cgit v1.2.3 From 14c7e33c4fead0bacdc8829b12e2d95f4084ab1b Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 16:47:37 +0530 Subject: FIX: Add New line in README file --- languages/c/clojure/README.md | 1 + 1 file changed, 1 insertion(+) (limited to 'languages') diff --git a/languages/c/clojure/README.md b/languages/c/clojure/README.md index b451b10..f01bc45 100644 --- a/languages/c/clojure/README.md +++ b/languages/c/clojure/README.md @@ -1,2 +1,3 @@ [Download Clojure](https://clojure.org/guides/install_clojure) + Run all tests like this: `clj -M:test` -- cgit v1.2.3 From 3293e18952cf91aee1686ad6718b4293f6d7a047 Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 16:56:31 +0530 Subject: ADD: Source to repo + blog posts from author --- languages/c/clojure/README.md | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'languages') diff --git a/languages/c/clojure/README.md b/languages/c/clojure/README.md index f01bc45..d84137b 100644 --- a/languages/c/clojure/README.md +++ b/languages/c/clojure/README.md @@ -1,3 +1,9 @@ [Download Clojure](https://clojure.org/guides/install_clojure) Run all tests like this: `clj -M:test` + +Sourced from: https://github.com/srodrigo/lambda-calculus-in-clojure + +Blog post by source author (Sergio Rodrigo): +1. [Booleans in Clojure](https://srodrigo.me/lambda-calculus-in-clojure-part-1/) +2. [Numerals in Clojure](https://srodrigo.me/lambda-calculus-in-clojure-part-2/) -- cgit v1.2.3 From 2f3dcfd450c4e82f99f55996a991659769f18a9f Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 17:24:06 +0530 Subject: ADD: Y-Combinator in Clojure --- languages/c/clojure/README.md | 2 ++ languages/c/clojure/lambda-core/src/y_combinator.clj | 9 +++++++++ languages/c/clojure/lambda-core/test/test_runner.clj | 5 +++-- languages/c/clojure/lambda-core/test/y_combinator_test.clj | 14 ++++++++++++++ 4 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 languages/c/clojure/lambda-core/src/y_combinator.clj create mode 100644 languages/c/clojure/lambda-core/test/y_combinator_test.clj (limited to 'languages') diff --git a/languages/c/clojure/README.md b/languages/c/clojure/README.md index d84137b..cbeeb34 100644 --- a/languages/c/clojure/README.md +++ b/languages/c/clojure/README.md @@ -7,3 +7,5 @@ Sourced from: https://github.com/srodrigo/lambda-calculus-in-clojure Blog post by source author (Sergio Rodrigo): 1. [Booleans in Clojure](https://srodrigo.me/lambda-calculus-in-clojure-part-1/) 2. [Numerals in Clojure](https://srodrigo.me/lambda-calculus-in-clojure-part-2/) + +Blog post about [Y-Combinator in Clojure](https://blog.klipse.tech/lambda/2016/08/07/pure-y-combinator-clojure.html) by different author (Yehonathan Sharvit). diff --git a/languages/c/clojure/lambda-core/src/y_combinator.clj b/languages/c/clojure/lambda-core/src/y_combinator.clj new file mode 100644 index 0000000..c474fbf --- /dev/null +++ b/languages/c/clojure/lambda-core/src/y_combinator.clj @@ -0,0 +1,9 @@ +(ns y-combinator) + +(def Y (fn [f] + ((fn [x] + (x x)) + (fn [x] + (f (fn [y] + ((x x) y))))))) + diff --git a/languages/c/clojure/lambda-core/test/test_runner.clj b/languages/c/clojure/lambda-core/test/test_runner.clj index 038b818..a851d4c 100644 --- a/languages/c/clojure/lambda-core/test/test_runner.clj +++ b/languages/c/clojure/lambda-core/test/test_runner.clj @@ -1,7 +1,8 @@ (ns test-runner (:require [clojure.test :as t] [numerals-test] - [booleans-test])) + [booleans-test] + [y-combinator-test])) (defn -main [& args] - (t/run-tests 'numerals-test 'booleans-test)) + (t/run-tests 'numerals-test 'booleans-test 'y-combinator-test)) diff --git a/languages/c/clojure/lambda-core/test/y_combinator_test.clj b/languages/c/clojure/lambda-core/test/y_combinator_test.clj new file mode 100644 index 0000000..c5396a0 --- /dev/null +++ b/languages/c/clojure/lambda-core/test/y_combinator_test.clj @@ -0,0 +1,14 @@ +(ns y-combinator-test + (:require [y-combinator :refer :all] + [clojure.test :refer :all])) + + +(def factorial-gen (fn [func] + (fn [n] + (if (zero? n) + 1 + (* n (func (dec n))))))) + +(deftest λ-Y-Combinator + (testing "factorial" + (is (= ((Y factorial-gen) 19) 121645100408832000)))) -- cgit v1.2.3 From 95d4385866643afd5bd27ad318b7dffca3b66ba3 Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 21:30:13 +0530 Subject: FIX: Factorial with church numerals --- languages/c/clojure/lambda-core/src/booleans.clj | 7 ++-- .../c/clojure/lambda-core/src/combinators.clj | 18 ++++++++++ languages/c/clojure/lambda-core/src/lambda.clj | 5 +++ languages/c/clojure/lambda-core/src/numerals.clj | 7 ++-- .../c/clojure/lambda-core/src/y_combinator.clj | 9 ----- .../clojure/lambda-core/test/combinators_test.clj | 39 ++++++++++++++++++++++ .../clojure/lambda-core/test/y_combinator_test.clj | 14 -------- 7 files changed, 66 insertions(+), 33 deletions(-) create mode 100644 languages/c/clojure/lambda-core/src/combinators.clj create mode 100644 languages/c/clojure/lambda-core/src/lambda.clj delete mode 100644 languages/c/clojure/lambda-core/src/y_combinator.clj create mode 100644 languages/c/clojure/lambda-core/test/combinators_test.clj delete mode 100644 languages/c/clojure/lambda-core/test/y_combinator_test.clj (limited to 'languages') diff --git a/languages/c/clojure/lambda-core/src/booleans.clj b/languages/c/clojure/lambda-core/src/booleans.clj index e48f9a7..fa94183 100644 --- a/languages/c/clojure/lambda-core/src/booleans.clj +++ b/languages/c/clojure/lambda-core/src/booleans.clj @@ -1,8 +1,5 @@ -(ns booleans) - -(defmacro λ - [args & body] - `(fn [~args] ~@body)) +(ns booleans + (:require [lambda :refer [λ]])) (def T (λ a (λ b a))) diff --git a/languages/c/clojure/lambda-core/src/combinators.clj b/languages/c/clojure/lambda-core/src/combinators.clj new file mode 100644 index 0000000..6746e29 --- /dev/null +++ b/languages/c/clojure/lambda-core/src/combinators.clj @@ -0,0 +1,18 @@ +(ns combinators) + +(def Y (fn [f] + ((fn [x] + (x x)) + (fn [x] + (f (fn [y] + ((x x) y))))))) + +(def Z + (fn [f] + ((fn [x] + (f (fn [y] + ((x x) y)))) + (fn [x] + (f (fn [y] + ((x x) y))))))) + diff --git a/languages/c/clojure/lambda-core/src/lambda.clj b/languages/c/clojure/lambda-core/src/lambda.clj new file mode 100644 index 0000000..6580bff --- /dev/null +++ b/languages/c/clojure/lambda-core/src/lambda.clj @@ -0,0 +1,5 @@ +(ns lambda) + +(defmacro λ + [args & body] + `(fn [~args] ~@body)) diff --git a/languages/c/clojure/lambda-core/src/numerals.clj b/languages/c/clojure/lambda-core/src/numerals.clj index e18da0f..53e08fa 100644 --- a/languages/c/clojure/lambda-core/src/numerals.clj +++ b/languages/c/clojure/lambda-core/src/numerals.clj @@ -1,8 +1,5 @@ -(ns numerals) - -(defmacro λ - [args & body] - `(fn [~args] ~@body)) +(ns numerals + (:require [lambda :refer [λ]])) (def zero (λ f (λ x x))) diff --git a/languages/c/clojure/lambda-core/src/y_combinator.clj b/languages/c/clojure/lambda-core/src/y_combinator.clj deleted file mode 100644 index c474fbf..0000000 --- a/languages/c/clojure/lambda-core/src/y_combinator.clj +++ /dev/null @@ -1,9 +0,0 @@ -(ns y-combinator) - -(def Y (fn [f] - ((fn [x] - (x x)) - (fn [x] - (f (fn [y] - ((x x) y))))))) - diff --git a/languages/c/clojure/lambda-core/test/combinators_test.clj b/languages/c/clojure/lambda-core/test/combinators_test.clj new file mode 100644 index 0000000..586946d --- /dev/null +++ b/languages/c/clojure/lambda-core/test/combinators_test.clj @@ -0,0 +1,39 @@ +(ns combinators-test + (:require [lambda :refer [λ]] + [combinators :refer :all] + [booleans :refer :all] + [numerals :refer :all] + [clojure.test :refer :all])) + +(def factorial-gen + ;; Church encoding of functions, such as 'λ', does not + ;; naturally support 'recur'. This is because the 'λ' macro expands into an + ;; anonymous function (created using 'fn'), and functions defined with 'fn' + ;; cannot use 'recur' unless the 'recur' is in the tail position. + ;; + ;; The 'fn' function in Clojure is needed because it allows us to define a + ;; recursive function where 'recur' can be used correctly in the tail position. + ;; When the function is structured with 'fn', 'recur' will correctly jump back + ;; to the function without adding a new stack frame, thus ensuring the recursion + ;; is efficient and won't result in stack overflow. + (fn [f] + (fn [n acc] + ;; Church's 'If' introduces an additional function call, which prevents 'recur' + ;; from being the final operation, thus breaking TCO and causing a stack overflow. + ;; Hence, using native 'if' instead of Church's 'If' because + ;; 'recur' must be the last operation for tail call optimization (TCO). + (if (toBoolean ((n (λ x F)) T)) + acc + (recur (pred n) ((mult acc) n)))))) + +(def Y-factorial (Y factorial-gen)) +(def Z-factorial (Z factorial-gen)) + +(deftest Y-Combinator + (testing "Y-factorial" + (is (= (toInt (Y-factorial (fromInt 9) one)) 362880)))) + +(deftest Z-Combinator + (testing "Z-factorial" + (is (= (toInt (Z-factorial (fromInt 9) one)) 362880)))) + diff --git a/languages/c/clojure/lambda-core/test/y_combinator_test.clj b/languages/c/clojure/lambda-core/test/y_combinator_test.clj deleted file mode 100644 index c5396a0..0000000 --- a/languages/c/clojure/lambda-core/test/y_combinator_test.clj +++ /dev/null @@ -1,14 +0,0 @@ -(ns y-combinator-test - (:require [y-combinator :refer :all] - [clojure.test :refer :all])) - - -(def factorial-gen (fn [func] - (fn [n] - (if (zero? n) - 1 - (* n (func (dec n))))))) - -(deftest λ-Y-Combinator - (testing "factorial" - (is (= ((Y factorial-gen) 19) 121645100408832000)))) -- cgit v1.2.3 From 49c6d561b08746d65a45690fee5516376459c901 Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 21:35:22 +0530 Subject: FIX: Test runner --- languages/c/clojure/lambda-core/test/test_runner.clj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'languages') diff --git a/languages/c/clojure/lambda-core/test/test_runner.clj b/languages/c/clojure/lambda-core/test/test_runner.clj index a851d4c..404df1d 100644 --- a/languages/c/clojure/lambda-core/test/test_runner.clj +++ b/languages/c/clojure/lambda-core/test/test_runner.clj @@ -2,7 +2,7 @@ (:require [clojure.test :as t] [numerals-test] [booleans-test] - [y-combinator-test])) + [combinators-test])) (defn -main [& args] - (t/run-tests 'numerals-test 'booleans-test 'y-combinator-test)) + (t/run-tests 'numerals-test 'booleans-test 'combinators-test)) -- cgit v1.2.3 From 72b58af387946428b0d6b3a12da3eb38adaa882a Mon Sep 17 00:00:00 2001 From: nitincodery Date: Fri, 31 Jan 2025 23:36:34 +0530 Subject: ADD: Print tests and results to stdout --- languages/c/clojure/lambda-core/deps.edn | 6 +-- .../c/clojure/lambda-core/test/booleans_test.clj | 63 +++++++++++----------- .../clojure/lambda-core/test/combinators_test.clj | 7 +-- .../c/clojure/lambda-core/test/numerals_test.clj | 53 +++++++++--------- .../c/clojure/lambda-core/test/print_macro.clj | 13 +++++ 5 files changed, 79 insertions(+), 63 deletions(-) create mode 100644 languages/c/clojure/lambda-core/test/print_macro.clj (limited to 'languages') diff --git a/languages/c/clojure/lambda-core/deps.edn b/languages/c/clojure/lambda-core/deps.edn index 6cb68b3..7c90c0d 100644 --- a/languages/c/clojure/lambda-core/deps.edn +++ b/languages/c/clojure/lambda-core/deps.edn @@ -1,6 +1,6 @@ {:paths ["src"] :deps {org.clojure/clojure {:mvn/version "1.10.0"}} :aliases - {:test - {:extra-paths ["test"] - :main-opts ["-m" "test-runner"]}}} + {:test {:extra-paths ["test"] + :main-opts ["-m" "test-runner"]}}} + diff --git a/languages/c/clojure/lambda-core/test/booleans_test.clj b/languages/c/clojure/lambda-core/test/booleans_test.clj index 8a75125..6c4dc63 100644 --- a/languages/c/clojure/lambda-core/test/booleans_test.clj +++ b/languages/c/clojure/lambda-core/test/booleans_test.clj @@ -1,67 +1,68 @@ (ns booleans-test (:require [booleans :refer :all] - [clojure.test :refer :all])) + [clojure.test :refer :all] + [print-macro :refer [is-print]])) (deftest λ-booleans (testing "true" - (is (= (toBoolean T) true))) + (is-print (= (toBoolean T) true))) (testing "false" - (is (= (toBoolean F) false))) + (is-print (= (toBoolean F) false))) (testing "If" - (is (= (toBoolean (((If T) T) F)) true)) - (is (= (toBoolean (((If F) T) F)) false))) + (is-print (= (toBoolean (((If T) T) F)) true)) + (is-print (= (toBoolean (((If F) T) F)) false))) (testing "And" - (is (= (toBoolean ((And T) T)) true)) - (is (= (toBoolean ((And T) F)) false)) - (is (= (toBoolean ((And F) T)) false)) - (is (= (toBoolean ((And F) F)) false)) - (is (= (toBoolean ((And T) ((And T) T))) true)) - (is (= (toBoolean ((And T) ((And F) T))) false))) + (is-print (= (toBoolean ((And T) T)) true)) + (is-print (= (toBoolean ((And T) F)) false)) + (is-print (= (toBoolean ((And F) T)) false)) + (is-print (= (toBoolean ((And F) F)) false)) + (is-print (= (toBoolean ((And T) ((And T) T))) true)) + (is-print (= (toBoolean ((And T) ((And F) T))) false))) (testing "Or" - (is (= (toBoolean ((Or T) T)) true)) - (is (= (toBoolean ((Or T) F)) true)) - (is (= (toBoolean ((Or F) T)) true)) - (is (= (toBoolean ((Or F) F)) false)) - (is (= (toBoolean ((Or F) ((Or F) F))) false)) - (is (= (toBoolean ((Or F) ((Or T) F))) true))) + (is-print (= (toBoolean ((Or T) T)) true)) + (is-print (= (toBoolean ((Or T) F)) true)) + (is-print (= (toBoolean ((Or F) T)) true)) + (is-print (= (toBoolean ((Or F) F)) false)) + (is-print (= (toBoolean ((Or F) ((Or F) F))) false)) + (is-print (= (toBoolean ((Or F) ((Or T) F))) true))) (testing "Not" - (is (= (toBoolean (Not T)) false)) - (is (= (toBoolean (Not F)) true)) - (is (= (toBoolean (Not (Not T))) true)) - (is (= (toBoolean (Not (Not F))) false))) + (is-print (= (toBoolean (Not T)) false)) + (is-print (= (toBoolean (Not F)) true)) + (is-print (= (toBoolean (Not (Not T))) true)) + (is-print (= (toBoolean (Not (Not F))) false))) (testing "Xor" - (is (= (toBoolean ((Xor T) T)) false)) - (is (= (toBoolean ((Xor T) F)) true)) - (is (= (toBoolean ((Xor F) T)) true)) - (is (= (toBoolean ((Xor F) F)) false))) + (is-print (= (toBoolean ((Xor T) T)) false)) + (is-print (= (toBoolean ((Xor T) F)) true)) + (is-print (= (toBoolean ((Xor F) T)) true)) + (is-print (= (toBoolean ((Xor F) F)) false))) (testing "Expressions" ;T AND T AND F OR T - (is (= (toBoolean ((And T) ((And T) ((Or F) T)))) + (is-print (= (toBoolean ((And T) ((And T) ((Or F) T)))) true)) ;T AND F AND F OR T AND T - (is (= (toBoolean ((And T) ((And F) ((Or F) ((And T) T))))) + (is-print (= (toBoolean ((And T) ((And F) ((Or F) ((And T) T))))) false)) ;T OR (F AND F OR T AND T) - (is (= (toBoolean ((Or T) ((And F) ((Or F) ((And T) T))))) + (is-print (= (toBoolean ((Or T) ((And F) ((Or F) ((And T) T))))) true)) ;F OR (F AND F OR F AND T) - (is (= (toBoolean ((Or F) ((And F) ((Or F) ((And F) T))))) + (is-print (= (toBoolean ((Or F) ((And F) ((Or F) ((And F) T))))) false)) ;F OR F AND F OR T AND T - (is (= (toBoolean ((And ((Or F) F)) ((And T) ((Or F) T)))) + (is-print (= (toBoolean ((And ((Or F) F)) ((And T) ((Or F) T)))) false)) ;T OR F AND F OR T AND T - (is (= (toBoolean ((And ((Or T) F)) ((And T) ((Or F) T)))) + (is-print (= (toBoolean ((And ((Or T) F)) ((And T) ((Or F) T)))) true)))) diff --git a/languages/c/clojure/lambda-core/test/combinators_test.clj b/languages/c/clojure/lambda-core/test/combinators_test.clj index 586946d..ba32fd2 100644 --- a/languages/c/clojure/lambda-core/test/combinators_test.clj +++ b/languages/c/clojure/lambda-core/test/combinators_test.clj @@ -3,7 +3,8 @@ [combinators :refer :all] [booleans :refer :all] [numerals :refer :all] - [clojure.test :refer :all])) + [clojure.test :refer :all] + [print-macro :refer [is-print]])) (def factorial-gen ;; Church encoding of functions, such as 'λ', does not @@ -31,9 +32,9 @@ (deftest Y-Combinator (testing "Y-factorial" - (is (= (toInt (Y-factorial (fromInt 9) one)) 362880)))) + (is-print (= (toInt (Y-factorial (fromInt 9) one)) 362880)))) (deftest Z-Combinator (testing "Z-factorial" - (is (= (toInt (Z-factorial (fromInt 9) one)) 362880)))) + (is-print (= (toInt (Z-factorial (fromInt 9) one)) 362880)))) diff --git a/languages/c/clojure/lambda-core/test/numerals_test.clj b/languages/c/clojure/lambda-core/test/numerals_test.clj index 44458dc..e7e5526 100644 --- a/languages/c/clojure/lambda-core/test/numerals_test.clj +++ b/languages/c/clojure/lambda-core/test/numerals_test.clj @@ -1,65 +1,66 @@ (ns numerals-test (:require [numerals :refer :all] - [clojure.test :refer :all])) - + [clojure.test :refer :all] + [print-macro :refer [is-print]])) + (deftest λ-numbers (testing "zero" - (is (= (toInt zero) 0))) + (is-print (= (toInt zero) 0))) (testing "one" - (is (= (toInt (succ zero)) 1)) - (is (= (toInt one)) 1)) + (is-print (= (toInt (succ zero)) 1)) + (is-print (= (toInt one) 1))) (testing "two" - (is (= (toInt (succ (succ zero))) 2)) - (is (= (toInt two)) 2)) + (is-print (= (toInt (succ (succ zero))) 2)) + (is-print (= (toInt two) 2))) (testing "three" - (is (= (toInt (succ (succ (succ zero)))) 3))) + (is-print (= (toInt (succ (succ (succ zero)))) 3))) (testing "predecessor" - (is (= (toInt (pred one)) 0)) - (is (= (toInt (pred two)) 1)) - (is (= (toInt (pred (succ (succ (succ zero))))) 2)) - (is (= (toInt (pred (fromInt 10))) 9)))) + (is-print (= (toInt (pred one)) 0)) + (is-print (= (toInt (pred two)) 1)) + (is-print (= (toInt (pred (succ (succ (succ zero))))) 2)) + (is-print (= (toInt (pred (fromInt 10))) 9)))) (deftest λ-numerical-operations (testing "addition" - (is (= + (is-print (= (toInt ((plus (fromInt 7)) (fromInt 5))) 12)) - (is (= + (is-print (= (toInt ((plus (fromInt 7)) ((plus (fromInt 6)) (fromInt 2)))) 15))) (testing "subtraction" - (is (= + (is-print (= (toInt ((minus (fromInt 7)) (fromInt 5))) 2)) - (is (= + (is-print (= (toInt ((minus (fromInt 7)) ((minus (fromInt 6)) (fromInt 2)))) 3))) (testing "multiplication" - (is (= + (is-print (= (toInt ((mult (fromInt 2)) (fromInt 3))) 6)) - (is (= + (is-print (= (toInt ((mult (fromInt 2)) ((mult (fromInt 5)) (fromInt 3)))) 30))) (testing "exponentiation" - (is (= + (is-print (= (toInt ((exp (fromInt 2)) (fromInt 3))) 8)) - (is (= + (is-print (= (toInt ((exp (fromInt 2)) ((exp (fromInt 2)) (fromInt 3)))) 256)))) (deftest λ-numeral-expressions (testing "numeral expressions" ; 3 * (2 + 5) - 2^3 - (is (= + (is-print (= (toInt ((minus ((mult (fromInt 3)) ((plus (fromInt 2)) (fromInt 5)))) ((exp (fromInt 2)) (fromInt 3)))) @@ -67,9 +68,9 @@ (deftest λ-toStr (testing "toStr" - (is (= (toStr zero) "λf.λn.(n)")) - (is (= (toStr one) "λf.λn.(f(n))")) - (is (= (toStr two) "λf.λn.(f(f(n)))")) - (is (= (toStr (succ (succ (succ zero)))) "λf.λn.(f(f(f(n))))")) - (is (= (toStr (fromInt 5)) "λf.λn.(f(f(f(f(f(n))))))")))) + (is-print (= (toStr zero) "λf.λn.(n)")) + (is-print (= (toStr one) "λf.λn.(f(n))")) + (is-print (= (toStr two) "λf.λn.(f(f(n)))")) + (is-print (= (toStr (succ (succ (succ zero)))) "λf.λn.(f(f(f(n))))")) + (is-print (= (toStr (fromInt 5)) "λf.λn.(f(f(f(f(f(n))))))")))) diff --git a/languages/c/clojure/lambda-core/test/print_macro.clj b/languages/c/clojure/lambda-core/test/print_macro.clj new file mode 100644 index 0000000..5fc4de6 --- /dev/null +++ b/languages/c/clojure/lambda-core/test/print_macro.clj @@ -0,0 +1,13 @@ +(ns print-macro + (:require [clojure.test :as t])) + +(defmacro is-print + ([form] + `(let [form-args# (rest '~form) + first-arg# (first form-args#) + second-arg# (second form-args#)] + (println (format "%s = %s => %s" + t/*testing-contexts* + (pr-str first-arg#) + (pr-str second-arg#))) + (t/is ~form)))) -- cgit v1.2.3