├── languages ├── o │ └── ocaml │ │ ├── .ocamlformat │ │ ├── README.md │ │ └── lambda_core.ml ├── g │ └── go │ │ ├── go.mod │ │ ├── README.md │ │ └── lambda-core.go ├── l │ ├── language84 │ │ ├── local.make │ │ ├── README.md │ │ └── lambda-core.84 │ └── lua │ │ ├── README.md │ │ └── lambda-core.lua ├── c │ ├── c │ │ ├── app │ │ ├── README.md │ │ └── lambda-core.c │ ├── clojure │ │ ├── lambda-core │ │ │ ├── src │ │ │ │ ├── lambda.clj │ │ │ │ ├── combinators.clj │ │ │ │ ├── booleans.clj │ │ │ │ └── numerals.clj │ │ │ ├── deps.edn │ │ │ └── test │ │ │ │ ├── test_runner.clj │ │ │ │ ├── print_macro.clj │ │ │ │ ├── combinators_test.clj │ │ │ │ ├── booleans_test.clj │ │ │ │ └── numerals_test.clj │ │ └── README.md │ └── c++ │ │ ├── README.md │ │ └── lambda-core.cpp ├── r │ ├── ruby │ │ ├── README.md │ │ └── lambda-core.rb │ └── racket │ │ ├── README.md │ │ └── lambda-core.rkt ├── j │ └── javascript │ │ ├── README.md │ │ └── lambda-core.js ├── f │ ├── fsharp │ │ ├── README.md │ │ └── lambda-core.fsx │ └── fatscript │ │ ├── README.md │ │ └── lambda-core.fat ├── p │ ├── python │ │ ├── README.md │ │ └── lambda-core.py │ └── perl │ │ ├── README.md │ │ └── lambda-core.pl ├── h │ └── haskell │ │ ├── README.md │ │ └── lambda-core.hs ├── e │ └── elixir │ │ ├── README.md │ │ └── lambda-core.exs ├── t │ └── typescript │ │ ├── package.json │ │ ├── README.md │ │ ├── tsconfig.json │ │ ├── bun.lock │ │ ├── .gitignore │ │ └── lambda-core.ts ├── k │ └── kotlin │ │ ├── README.md │ │ └── lambda-core.kt ├── b │ └── bruijn │ │ ├── README.md │ │ └── lambda-core.bruijn └── a │ └── arkscript │ ├── README.md │ └── lambda-core.ark ├── LICENSE └── README.md /languages/o/ocaml/.ocamlformat: -------------------------------------------------------------------------------- 1 | profile=janestreet 2 | -------------------------------------------------------------------------------- /languages/g/go/go.mod: -------------------------------------------------------------------------------- 1 | module lambda-core 2 | 3 | go 1.23.5 4 | -------------------------------------------------------------------------------- /languages/l/language84/local.make: -------------------------------------------------------------------------------- 1 | PROGRAMS = 84 lambda-core 2 | -------------------------------------------------------------------------------- /languages/c/c/app: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kserrec/lambda-core/HEAD/languages/c/c/app -------------------------------------------------------------------------------- /languages/l/lua/README.md: -------------------------------------------------------------------------------- 1 | # Prerequisite 2 | Install lua 5.x 3 | # Run 4 | ```bash 5 | lua ./lambda-core.lua 6 | ``` 7 | -------------------------------------------------------------------------------- /languages/r/ruby/README.md: -------------------------------------------------------------------------------- 1 | Download Ruby version 3 or above 2 | 3 | Run by lambda-core.rb like this: `ruby lambda-core.rb` -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/src/lambda.clj: -------------------------------------------------------------------------------- 1 | (ns lambda) 2 | 3 | (defmacro λ 4 | [args & body] 5 | `(fn [~args] ~@body)) 6 | -------------------------------------------------------------------------------- /languages/g/go/README.md: -------------------------------------------------------------------------------- 1 | ### Install go 2 | 3 | run with: 4 | ``` 5 | go run . 6 | ``` 7 | 8 | *made with go 1.23.5 darwin/arm64* -------------------------------------------------------------------------------- /languages/j/javascript/README.md: -------------------------------------------------------------------------------- 1 | Download NodeJS version 4 or above 2 | 3 | Run by lambda-core.js like this: `node lambda-core.js` -------------------------------------------------------------------------------- /languages/r/racket/README.md: -------------------------------------------------------------------------------- 1 | Download Racket version 6 or above 2 | 3 | Run by lambda-core.rkt like this: `racket lambda-core.rkt` -------------------------------------------------------------------------------- /languages/f/fsharp/README.md: -------------------------------------------------------------------------------- 1 | Download dotnet version 8 or above 2 | 3 | ```shell 4 | # run 5 | dotnet fsi lambda-core.fsx 6 | ``` 7 | 8 | -------------------------------------------------------------------------------- /languages/p/python/README.md: -------------------------------------------------------------------------------- 1 | ### Download Python 3 2 | 3 | Run with: 4 | ``` 5 | python3 lambda-core.py 6 | ``` 7 | 8 | *made with python 3.11.5* -------------------------------------------------------------------------------- /languages/o/ocaml/README.md: -------------------------------------------------------------------------------- 1 | Download OCaml version 5 or above 2 | 3 | ```shell 4 | # build 5 | ocamlc -o lambda_core lambda_core.ml 6 | 7 | # run 8 | ./lambda_core 9 | ``` -------------------------------------------------------------------------------- /languages/h/haskell/README.md: -------------------------------------------------------------------------------- 1 | # Haskell Installation Guide 2 | Follow Installation guide from here https://www.haskell.org/get-started/ 3 | 4 | # Run Code 5 | ```sh 6 | ghc lambda-core.hs 7 | ./lambda-core 8 | ``` 9 | -------------------------------------------------------------------------------- /languages/c/c++/README.md: -------------------------------------------------------------------------------- 1 | # C++ Lambda Core 2 | 3 | ## Requirements 4 | 5 | - GCC 14 or above 6 | 7 | ## Compile and run 8 | 9 | ```sh 10 | g++ lambda-core.cpp -std=c++23 -o app 11 | ./app 12 | ``` 13 | 14 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/deps.edn: -------------------------------------------------------------------------------- 1 | {:paths ["src"] 2 | :deps {org.clojure/clojure {:mvn/version "1.10.0"}} 3 | :aliases 4 | {:test {:extra-paths ["test"] 5 | :main-opts ["-m" "test-runner"]}}} 6 | 7 | -------------------------------------------------------------------------------- /languages/e/elixir/README.md: -------------------------------------------------------------------------------- 1 | # Elixir installation 2 | 3 | https://elixir-lang.org/install.html 4 | 5 | # Run code 6 | 7 | ```sh 8 | chmod +x ./lambda-core.exs 9 | 10 | ./lambda-core.exs 11 | ``` 12 | 13 | 14 | -------------------------------------------------------------------------------- /languages/t/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts", 3 | "module": "src/lambda-core.ts", 4 | "type": "module", 5 | "devDependencies": { 6 | "@types/bun": "latest" 7 | }, 8 | "peerDependencies": { 9 | "typescript": "^5.0.0" 10 | } 11 | } -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/test/test_runner.clj: -------------------------------------------------------------------------------- 1 | (ns test-runner 2 | (:require [clojure.test :as t] 3 | [numerals-test] 4 | [booleans-test] 5 | [combinators-test])) 6 | 7 | (defn -main [& args] 8 | (t/run-tests 'numerals-test 'booleans-test 'combinators-test)) 9 | -------------------------------------------------------------------------------- /languages/k/kotlin/README.md: -------------------------------------------------------------------------------- 1 | # Kotlin instalation 2 | Download Kotlin version 2.1.10 ot above from here https://kotlinlang.org/docs/command-line.html 3 | 4 | # Run code 5 | ```shell 6 | # build 7 | kotlinc lambda-core.kt -include-runtime -d lambda-core.jar 8 | 9 | #run 10 | java -jar lambda-core.jar 11 | ``` -------------------------------------------------------------------------------- /languages/c/c/README.md: -------------------------------------------------------------------------------- 1 | # C Lambda Core 2 | 3 | Program structure is based on C++ Lambda Core by Gryfenfer97 4 | Does leak memory; add GC if you feel like it 5 | 6 | ## Requirements 7 | 8 | - GCC 9 | 10 | ## Compile and run 11 | 12 | ```sh 13 | gcc lambda-core.c -std=c89 -pedantic -o app 14 | ./app 15 | ``` 16 | 17 | -------------------------------------------------------------------------------- /languages/t/typescript/README.md: -------------------------------------------------------------------------------- 1 | # ts 2 | 3 | To install dependencies: 4 | 5 | ```bash 6 | bun install 7 | ``` 8 | 9 | To run: 10 | 11 | ```bash 12 | bun run lambda-core.ts 13 | ``` 14 | 15 | This project was created using `bun init` in bun v1.2.1. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. 16 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/src/combinators.clj: -------------------------------------------------------------------------------- 1 | (ns combinators) 2 | 3 | (def Y (fn [f] 4 | ((fn [x] 5 | (x x)) 6 | (fn [x] 7 | (f (fn [y] 8 | ((x x) y))))))) 9 | 10 | (def Z 11 | (fn [f] 12 | ((fn [x] 13 | (f (fn [y] 14 | ((x x) y)))) 15 | (fn [x] 16 | (f (fn [y] 17 | ((x x) y))))))) 18 | 19 | -------------------------------------------------------------------------------- /languages/f/fatscript/README.md: -------------------------------------------------------------------------------- 1 | # FatScript interpreter setup 2 | 3 | https://fatscript.org/en/general/setup.html 4 | 5 | # Run code 6 | 7 | ```sh 8 | chmod +x ./lambda-core.fat 9 | 10 | ./lambda-core.fat 11 | ``` 12 | 13 | # Run on web playground (alternative) 14 | 15 | > no installation required 16 | 17 | https://fatscript.org/playground/ 18 | 19 | Select `lambda-core.fat` file on "run fat code" input. 20 | -------------------------------------------------------------------------------- /languages/b/bruijn/README.md: -------------------------------------------------------------------------------- 1 | # bruijn 2 | 3 | To run, follow the installation instructions on [bruijn's 4 | wiki](https://bruijn.marvinborner.de/wiki/introduction/installation/) 5 | and run 6 | 7 | ``` bash 8 | # to run main and check the tests! 9 | bruijn -v lambda-core.bruijn 10 | ``` 11 | 12 | Further examples can be found in 13 | [examples](https://bruijn.marvinborner.de/samples/) or in the [standard 14 | library](https://bruijn.marvinborner.de/std/). 15 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/src/booleans.clj: -------------------------------------------------------------------------------- 1 | (ns booleans 2 | (:require [lambda :refer [λ]])) 3 | 4 | (def T 5 | (λ a (λ b a))) 6 | 7 | (def F 8 | (λ a (λ b b))) 9 | 10 | (def And 11 | (λ p (λ q ((p q) p)))) 12 | 13 | (def Or 14 | (λ p (λ q ((p p) q)))) 15 | 16 | (def Not 17 | (λ p ((p F) T))) 18 | 19 | (def Xor 20 | (λ a (λ b ((a (Not b)) b)))) 21 | 22 | (def If 23 | (λ p (λ a (λ b ((p a) b))))) 24 | 25 | (def toBoolean 26 | (λ f ((f true) false))) 27 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/test/print_macro.clj: -------------------------------------------------------------------------------- 1 | (ns print-macro 2 | (:require [clojure.test :as t])) 3 | 4 | (defmacro is-print 5 | ([form] 6 | `(let [form-args# (rest '~form) 7 | first-arg# (first form-args#) 8 | second-arg# (second form-args#)] 9 | (println (format "%s = %s => %s" 10 | t/*testing-contexts* 11 | (pr-str first-arg#) 12 | (pr-str second-arg#))) 13 | (t/is ~form)))) 14 | -------------------------------------------------------------------------------- /languages/c/clojure/README.md: -------------------------------------------------------------------------------- 1 | [Download Clojure](https://clojure.org/guides/install_clojure) 2 | 3 | Run all tests like this: `clj -M:test` 4 | 5 | Sourced from: https://github.com/srodrigo/lambda-calculus-in-clojure 6 | 7 | Blog post by source author (Sergio Rodrigo): 8 | 1. [Booleans in Clojure](https://srodrigo.me/lambda-calculus-in-clojure-part-1/) 9 | 2. [Numerals in Clojure](https://srodrigo.me/lambda-calculus-in-clojure-part-2/) 10 | 11 | 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). 12 | -------------------------------------------------------------------------------- /languages/l/language84/README.md: -------------------------------------------------------------------------------- 1 | 2 | (Note: You need x86 Linux to run this code.) 3 | 4 | Get Language 84 version 0.8 from https://norstrulde.org/language84/ and unpack. 5 | 6 | $ wget https://norstrulde.org/language84/language84-0.8.tar.xz 7 | $ tar xfJ language84-0.8.tar.xz 8 | 9 | Copy `lambda-core.84` and `local.make` from this repo into the `language84-0.8` directory created above. 10 | 11 | Build 12 | 13 | $ make CC=clang 14 | 15 | Run 16 | 17 | $ ./lambda-core 18 | 19 | Note that there are some functions defined with and without syntactic sugar to show both forms and how they relate. Look for `BITTER`, `SWEET`, `SWEETEST`. 20 | -------------------------------------------------------------------------------- /languages/p/perl/README.md: -------------------------------------------------------------------------------- 1 | # Prerequisite 2 | Install perl on your computer. 3 | 4 | # Run 5 | 6 | ```bash 7 | perl ./lambda-core.pl 8 | ``` 9 | 10 | and result: 11 | ```text 12 | LOGIC 13 | ------------- 14 | TRUE: true 15 | FALSE: false 16 | NOT TRUE: false 17 | NOT FALSE: true 18 | TRUE AND TRUE: true 19 | TRUE AND FALSE: false 20 | FALSE AND TRUE: false 21 | FALSE AND FALSE: false 22 | TRUE OR TRUE: true 23 | TRUE OR FALSE: true 24 | FALSE OR TRUE: true 25 | FALSE OR FALSE: false 26 | 27 | CHURCH NUMERALS 28 | ------------- 29 | ZERO: 0 30 | ONE: 1 31 | SUCC ONE: 2 32 | SUCC SUCC ONE: 3 33 | PRED ONE: 0 34 | PRED SUCC ONE: 1 35 | PRED SUCC SUCC ONE: 2 36 | ``` 37 | 38 | -------------------------------------------------------------------------------- /languages/t/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | // Enable latest features 4 | "lib": ["ESNext", "DOM"], 5 | "target": "ESNext", 6 | "module": "ESNext", 7 | "moduleDetection": "force", 8 | "jsx": "react-jsx", 9 | "allowJs": true, 10 | 11 | // Bundler mode 12 | "moduleResolution": "bundler", 13 | "allowImportingTsExtensions": true, 14 | "verbatimModuleSyntax": true, 15 | "noEmit": true, 16 | 17 | // Best practices 18 | "strict": true, 19 | "skipLibCheck": true, 20 | "noFallthroughCasesInSwitch": true, 21 | 22 | // Some stricter flags (disabled by default) 23 | "noUnusedLocals": false, 24 | "noUnusedParameters": false, 25 | "noPropertyAccessFromIndexSignature": false 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /languages/b/bruijn/lambda-core.bruijn: -------------------------------------------------------------------------------- 1 | # ----- 2 | # LOGIC 3 | # ----- 4 | 5 | true [[1]] 6 | 7 | false [[0]] 8 | 9 | ¬‣ [[[2 0 1]]] 10 | 11 | :test (¬true) (false) 12 | :test (¬false) (true) 13 | 14 | …⋀… [[0 1 0]] 15 | 16 | :test (true ⋀ true) (true) 17 | :test (true ⋀ false) (false) 18 | :test (false ⋀ true) (false) 19 | :test (false ⋀ false) (false) 20 | 21 | …⋁… [0 0] 22 | 23 | :test (true ⋁ true) (true) 24 | :test (true ⋁ false) (true) 25 | :test (false ⋁ true) (true) 26 | :test (false ⋁ false) (false) 27 | 28 | # ------ 29 | # CHURCH 30 | # ------ 31 | 32 | zero [[0]] 33 | 34 | ++‣ [[[1 (2 1 0)]]] 35 | 36 | :test (++(++zero)) ([[1 (1 0)]]) 37 | 38 | --‣ [[[[0 [0]] (2 [[0 (1 3)]] [1])]]] 39 | 40 | :test (--(++zero)) (zero) 41 | :test (--[[1 (1 0)]]) ([[1 0]]) 42 | :test (--[[1 (1 (1 0))]]) ([[1 (1 0)]]) 43 | 44 | # aside from tests: empty program 45 | main [[0]] 46 | -------------------------------------------------------------------------------- /languages/a/arkscript/README.md: -------------------------------------------------------------------------------- 1 | # ArkScript 2 | 3 | Running this solution requires either ArkScript 4.0.0 or a pre-release of ArkScript 4.0.0. 4 | 5 | ## Running the solution (docker) 6 | 7 | ``` 8 | docker pull arkscript/nightly:latest 9 | docker run -it --rm -v $(pwd):/tmp:ro arkscript/nightly /tmp/lambda-core.ark 10 | ``` 11 | 12 | ## Running the solution (binary) 13 | 14 | Download the binary for your platform in [the latest 4.0.0 pre-release](https://github.com/ArkScript-lang/Ark/releases/tag/v4.0.0-10). 15 | 16 | Extract the zip, you will need both `arkscript` and `libArkReactor.(so|dll)` in the same directory. 17 | 18 | ``` 19 | chmod u+x arkscript 20 | ./arkscript lambda-core.ark 21 | ``` 22 | 23 | ## Other way of installing ArkScript 24 | 25 | See the documentation: [arkscript-lang.dev/tutorials/building.html](https://arkscript-lang.dev/tutorials/building.html). 26 | 27 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/src/numerals.clj: -------------------------------------------------------------------------------- 1 | (ns numerals 2 | (:require [lambda :refer [λ]])) 3 | 4 | (def zero 5 | (λ f (λ x x))) 6 | 7 | (def one 8 | (λ f (λ x (f x)))) 9 | 10 | (def two 11 | (λ f (λ x (f (f x))))) 12 | 13 | (def succ 14 | (λ n (λ f (λ x (f ((n f) x)))))) 15 | 16 | (def pred 17 | (λ n (λ f (λ x (((n (λ g (λ h (h (g f))))) (λ u x)) (λ u u)))))) 18 | 19 | (def plus 20 | (λ m (λ n ((n succ) m)))) 21 | 22 | (def minus 23 | (λ m (λ n ((n pred) m)))) 24 | 25 | (def mult 26 | (λ m (λ n (λ f (m (n f)))))) 27 | 28 | (def exp 29 | (λ m (λ n (n m)))) 30 | 31 | (def fromInt 32 | (λ n 33 | (if (= n 0) 34 | zero 35 | (succ (fromInt (- n 1)))))) 36 | 37 | (def toInt 38 | (λ f ((f (λ n (+ n 1))) 0))) 39 | 40 | (def λToStr 41 | (λ f ((f (λ n (format "f(%s)" n))) "n"))) 42 | 43 | (def toStr 44 | (λ f (format "λf.λn.(%s)" (λToStr f)))) 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Kyle Serrecchia 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /languages/h/haskell/lambda-core.hs: -------------------------------------------------------------------------------- 1 | true' a b = a 2 | 3 | false' a b = b 4 | 5 | not' p = p false' true' 6 | 7 | and' b1 b2 = b1 b2 false' 8 | 9 | or' b1 = b1 true' 10 | 11 | churchToBool b = b True False 12 | 13 | zero' f x = x 14 | 15 | one' = succ' zero' 16 | 17 | succ' n f x = f $ n f x 18 | 19 | pred' n f x = n (\g h -> h (g f)) (const x) id 20 | 21 | churchToNum n = n (+ 1) 0 22 | 23 | main = do 24 | -- basic booleans 25 | print $ churchToBool true' 26 | print $ churchToBool false' 27 | 28 | -- not 29 | print $ churchToBool $ not' true' 30 | print $ churchToBool $ not' false' 31 | 32 | -- and 33 | print $ churchToBool $ and' false' false' 34 | print $ churchToBool $ and' false' true' 35 | print $ churchToBool $ and' true' false' 36 | print $ churchToBool $ and' true' true' 37 | 38 | -- or 39 | print $ churchToBool $ or' false' false' 40 | print $ churchToBool $ or' false' true' 41 | print $ churchToBool $ or' true' false' 42 | print $ churchToBool $ or' true' true' 43 | 44 | -- numbers 45 | print $ churchToNum zero' 46 | print $ churchToNum one' 47 | print $ churchToNum $ pred' $ succ' one' 48 | print $ churchToNum $ pred' one' 49 | -------------------------------------------------------------------------------- /languages/p/python/lambda-core.py: -------------------------------------------------------------------------------- 1 | # LOGIC 2 | _true = lambda x: lambda y: x 3 | _false = lambda x: lambda y: y 4 | _not = lambda b: b(_false)(_true) 5 | _and = lambda b1: lambda b2: b1(b2)(_false) 6 | _or = lambda b1: lambda b2: b1(_true)(b2) 7 | 8 | # CHURCH NUMERALS 9 | _zero = lambda f: lambda x: x 10 | _succ = lambda n: lambda f: lambda x: f(n(f)(x)) 11 | _pred = lambda n: lambda f: lambda x: n(lambda g: lambda h: h(g(f)))(lambda u: x)(lambda a: a) 12 | _one = _succ(_zero) 13 | 14 | # HELPERS - not pure lambda calculus 15 | read_bool = lambda b: print(b("t")("f")) 16 | read_church = lambda n: print(n(lambda x: x+1)(0)) 17 | 18 | # EXAMPLES 19 | print("LOGIC") 20 | print("-------------") 21 | print("TRUE/FALSE") 22 | read_bool(_true) 23 | read_bool(_false) 24 | 25 | print("NOT") 26 | read_bool(_not(_true)) 27 | read_bool(_not(_false)) 28 | 29 | print("AND") 30 | read_bool(_and(_true)(_true)) 31 | read_bool(_and(_true)(_false)) 32 | read_bool(_and(_false)(_true)) 33 | read_bool(_and(_false)(_false)) 34 | 35 | print("OR") 36 | read_bool(_or(_true)(_true)) 37 | read_bool(_or(_true)(_false)) 38 | read_bool(_or(_false)(_true)) 39 | read_bool(_or(_false)(_false)) 40 | 41 | print() 42 | print("CHURCH NUMERALS") 43 | print("-------------") 44 | print("ZERO/SUCC") 45 | read_church(_zero) 46 | read_church(_one) 47 | read_church(_succ(_one)) 48 | read_church(_succ(_succ(_one))) 49 | 50 | print("PRED") 51 | read_church(_pred(_one)) 52 | read_church(_pred(_succ(_one))) 53 | read_church(_pred(_succ(_succ(_one)))) 54 | -------------------------------------------------------------------------------- /languages/t/typescript/bun.lock: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1, 3 | "workspaces": { 4 | "": { 5 | "name": "ts", 6 | "devDependencies": { 7 | "@types/bun": "latest", 8 | }, 9 | "peerDependencies": { 10 | "typescript": "^5.0.0", 11 | }, 12 | }, 13 | }, 14 | "packages": { 15 | "@types/bun": ["@types/bun@1.2.2", "", { "dependencies": { "bun-types": "1.2.2" } }, "sha512-tr74gdku+AEDN5ergNiBnplr7hpDp3V1h7fqI2GcR/rsUaM39jpSeKH0TFibRvU0KwniRx5POgaYnaXbk0hU+w=="], 16 | 17 | "@types/node": ["@types/node@22.13.1", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-jK8uzQlrvXqEU91UxiK5J7pKHyzgnI1Qnl0QDHIgVGuolJhRb9EEl28Cj9b3rGR8B2lhFCtvIm5os8lFnO/1Ew=="], 18 | 19 | "@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="], 20 | 21 | "bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="], 22 | 23 | "typescript": ["typescript@5.7.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw=="], 24 | 25 | "undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /languages/f/fsharp/lambda-core.fsx: -------------------------------------------------------------------------------- 1 | let _true = fun x -> fun _y -> x 2 | let _false = fun _x -> fun y -> y 3 | 4 | let _not = fun b -> b _false _true 5 | 6 | let _and = fun b1 -> fun b2 -> b1 b2 _false 7 | let _or = fun b1 -> fun b2 -> b1 _true b2 8 | 9 | 10 | let _zero: 'a -> 'b -> 'b = fun _f -> fun x -> x 11 | let _succ = fun n -> fun f -> fun x -> f (n f x) 12 | 13 | let _pred = 14 | fun n -> fun f -> fun x -> n (fun g -> fun h -> h (g f)) (fun _u -> x) (fun a -> a) 15 | 16 | let _one = _succ _zero 17 | 18 | let read_bool = fun b -> (b "true" "false") |> printfn "%s" 19 | let read_church = fun n -> (n (fun x -> x + 1) 0) |> printfn "%d" 20 | 21 | // EXAMPLE 22 | printfn "LOGIC" 23 | printfn "----------------" 24 | printfn "TRUE/FALSE" 25 | read_bool _true 26 | read_bool _false 27 | printfn "NOT" 28 | read_bool (_not _true) 29 | read_bool (_not _false) 30 | printfn "AND" 31 | read_bool (_and _true _true) 32 | read_bool (_and _true _false) 33 | read_bool (_and _false _true) 34 | read_bool (_and _false _false) 35 | printfn "OR" 36 | read_bool (_or _true _true) 37 | read_bool (_or _true _false) 38 | read_bool (_or _false _true) 39 | read_bool (_or _false _false) 40 | 41 | printfn "CHURCH NUMERALS" 42 | printfn "----------------" 43 | printfn "ZERO/SUCC" 44 | read_church _zero 45 | read_church (_one) 46 | read_church (_succ _one) 47 | read_church (_succ (_succ _one)) 48 | printfn "PRED" 49 | read_church (_pred (_succ _zero)) 50 | read_church (_pred (_succ (_succ _zero))) 51 | read_church (_pred (_succ (_succ (_succ _zero)))) 52 | -------------------------------------------------------------------------------- /languages/r/ruby/lambda-core.rb: -------------------------------------------------------------------------------- 1 | # LOGIC 2 | _true = ->(x) { ->(y) { x } } 3 | _false = ->(x) { ->(y) { y } } 4 | _not = ->(b) { b[_false][_true] } 5 | _and = ->(b1) { ->(b2) { b1[b2][_false] } } 6 | _or = ->(b1) { ->(b2) { b1[_true][b2] } } 7 | 8 | # CHURCH NUMERALS 9 | _zero = ->(f) { ->(x) { x } } 10 | _succ = ->(n) { ->(f) { ->(x) { f[n[f][x]] } } } 11 | _pred = ->(n) { 12 | ->(f) { 13 | ->(x) { 14 | n[->(g) { ->(h) { h[g[f]] } }][->(u) { x }][->(a) { a }] 15 | } 16 | } 17 | } 18 | _one = _succ[_zero] 19 | 20 | # HELPERS - not pure lambda calculus 21 | def read_bool(b) 22 | puts b["t"]["f"] 23 | end 24 | 25 | def read_church(n) 26 | puts n[->(x) { x + 1 }][0] 27 | end 28 | 29 | # EXAMPLES 30 | puts "LOGIC" 31 | puts "---------------" 32 | puts "TRUE/FALSE" 33 | read_bool(_true) # t 34 | read_bool(_false) # f 35 | 36 | puts "NOT" 37 | read_bool(_not[_true]) # f 38 | read_bool(_not[_false]) # t 39 | 40 | puts "AND" 41 | read_bool(_and[_true][_true]) # t 42 | read_bool(_and[_true][_false]) # f 43 | read_bool(_and[_false][_true]) # f 44 | read_bool(_and[_false][_false]) # f 45 | 46 | puts "OR" 47 | read_bool(_or[_true][_true]) # t 48 | read_bool(_or[_true][_false]) # t 49 | read_bool(_or[_false][_true]) # t 50 | read_bool(_or[_false][_false]) # f 51 | 52 | puts "\nCHURCH NUMERALS" 53 | puts "---------------" 54 | puts "ZERO/SUCC" 55 | read_church(_zero) # 0 56 | read_church(_one) # 1 57 | read_church(_succ[_one]) # 2 58 | read_church(_succ[_succ[_one]]) # 3 59 | 60 | puts "PRED" 61 | read_church(_pred[_one]) # 0 62 | read_church(_pred[_succ[_one]]) # 1 63 | read_church(_pred[_succ[_succ[_one]]]) # 2 64 | -------------------------------------------------------------------------------- /languages/j/javascript/lambda-core.js: -------------------------------------------------------------------------------- 1 | // LOGIC 2 | const _true = x => y => x; 3 | const _false = x => y => y; 4 | const _not = b => b(_false)(_true) 5 | const _and = b1 => b2 => b1(b2)(_false) 6 | const _or = b1 => b2 => b1(_true)(b2) 7 | 8 | // CHURCH NUMERALS 9 | const _zero = f => x => x; 10 | const _succ = n => f => x => f(n(f)(x)) 11 | const _pred = n => f => x => n(g => h => h(g(f)))(u => x)(a => a) 12 | const _one = _succ(_zero) 13 | 14 | // HELPERS - not pure lambda calculus 15 | const readBool = b => console.log(b("t")("f")) 16 | const readChurch = n => console.log(n(x => x+1)(0)) 17 | 18 | // ------------------------------------------------- 19 | 20 | // EXAMPLES 21 | console.log("LOGIC") 22 | console.log("---------------") 23 | console.log("TRUE/FALSE") 24 | readBool(_true) // t 25 | readBool(_false) // f 26 | 27 | console.log("NOT") 28 | readBool(_not(_true)) // f 29 | readBool(_not(_false)) // t 30 | 31 | console.log("AND") 32 | readBool(_and(_true)(_true)) // t 33 | readBool(_and(_true)(_false)) // f 34 | readBool(_and(_false)(_true)) // f 35 | readBool(_and(_false)(_false)) // f 36 | 37 | console.log("OR") 38 | readBool(_or(_true)(_true)) // t 39 | readBool(_or(_true)(_false)) // t 40 | readBool(_or(_false)(_true)) // t 41 | readBool(_or(_false)(_false)) // f 42 | 43 | console.log("\nCHURCH NUMERALS") 44 | console.log("---------------") 45 | console.log("ZERO/SUCC") 46 | readChurch(_zero) // 0 47 | readChurch(_one) // 1 48 | readChurch(_succ(_one)) // 2 49 | readChurch(_succ(_succ(_one))) // 3 50 | 51 | console.log("PRED") 52 | readChurch(_pred(_one)) // 0 53 | readChurch(_pred(_succ(_one))) // 1 54 | readChurch(_pred(_succ(_succ(_one)))) // 2 55 | 56 | -------------------------------------------------------------------------------- /languages/f/fatscript/lambda-core.fat: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fry 2 | 3 | # LOGIC 4 | _true = x -> y -> x 5 | _false = x -> y -> y 6 | _not = b -> b(_false)(_true) 7 | _and = b1 -> b2 -> b1(b2)(_false) 8 | _or = b1 -> b2 -> b1(_true)(b2) 9 | 10 | # CHURCH NUMERALS 11 | _zero = f -> x -> x 12 | _succ = n -> f -> x -> f(n(f)(x)) 13 | _pred = n -> f -> x -> n(g -> h -> h(g(f)))(u -> x)(a -> a) 14 | _one = _succ(_zero) 15 | 16 | # HELPERS - not pure lambda calculus 17 | readBool = b -> console.log(b('t')('f')) 18 | readChurch = n -> console.log(n(x -> x + 1)(0)) 19 | 20 | # ------------------------------------------------- 21 | 22 | # EXAMPLES 23 | console <- fat.console 24 | 25 | console.log('LOGIC') 26 | console.log('---------------') 27 | console.log('TRUE/FALSE') 28 | readBool(_true) # t 29 | readBool(_false) # f 30 | 31 | console.log('NOT') 32 | readBool(_not(_true)) # f 33 | readBool(_not(_false)) # t 34 | 35 | console.log('AND') 36 | readBool(_and(_true)(_true)) # t 37 | readBool(_and(_true)(_false)) # f 38 | readBool(_and(_false)(_true)) # f 39 | readBool(_and(_false)(_false)) # f 40 | 41 | console.log('OR') 42 | readBool(_or(_true)(_true)) # t 43 | readBool(_or(_true)(_false)) # t 44 | readBool(_or(_false)(_true)) # t 45 | readBool(_or(_false)(_false)) # f 46 | 47 | console.log('\nCHURCH NUMERALS') 48 | console.log('---------------') 49 | console.log('ZERO/SUCC') 50 | readChurch(_zero) # 0 51 | readChurch(_one) # 1 52 | readChurch(_succ(_one)) # 2 53 | readChurch(_succ(_succ(_one))) # 3 54 | 55 | console.log('PRED') 56 | readChurch(_pred(_one)) # 0 57 | readChurch(_pred(_succ(_one))) # 1 58 | readChurch(_pred(_succ(_succ(_one)))) # 2 59 | -------------------------------------------------------------------------------- /languages/o/ocaml/lambda_core.ml: -------------------------------------------------------------------------------- 1 | (* LOGIC *) 2 | let _true = fun x -> fun _y -> x 3 | let _false = fun _x -> fun y -> y 4 | let _not = fun b -> b _false _true 5 | let _and = fun b1 -> fun b2 -> b1 b2 _false 6 | let _or = fun b1 -> fun b2 -> b1 _true b2 7 | 8 | (* CHURCH NUMERALS *) 9 | let _zero = fun _f -> fun x -> x 10 | let _succ = fun n -> fun f -> fun x -> f (n f x) 11 | 12 | let _pred = 13 | fun n -> fun f -> fun x -> n (fun g -> fun h -> h (g f)) (fun _u -> x) (fun a -> a) 14 | ;; 15 | 16 | let _one = _succ _zero 17 | let read_bool = fun b -> b "true" "false" |> print_endline 18 | let read_church = fun n -> n (fun x -> x + 1) 0 |> string_of_int |> print_endline 19 | 20 | let () = 21 | (* EXAMPLE *) 22 | print_endline "LOGIC"; 23 | print_endline "----------------"; 24 | print_endline "TRUE/FALSE"; 25 | read_bool _true; 26 | read_bool _false; 27 | print_endline "NOT"; 28 | read_bool (_not _true); 29 | read_bool (_not _false); 30 | print_endline "AND"; 31 | read_bool (_and _true _true); 32 | read_bool (_and _true _false); 33 | read_bool (_and _false _true); 34 | read_bool (_and _false _false); 35 | print_endline "OR"; 36 | read_bool (_or _true _true); 37 | read_bool (_or _true _false); 38 | read_bool (_or _false _true); 39 | read_bool (_or _false _false); 40 | print_endline "\nCHURCH NUMERALS"; 41 | print_endline "----------------"; 42 | print_endline "ZERO/SUCC"; 43 | read_church _zero; 44 | read_church _one; 45 | read_church (_succ _one); 46 | read_church (_succ (_succ _one)); 47 | print_endline "PRED"; 48 | read_church (_pred (_succ _zero)); 49 | read_church (_pred (_succ (_succ _zero))); 50 | read_church (_pred (_succ (_succ (_succ _zero)))) 51 | ;; 52 | -------------------------------------------------------------------------------- /languages/a/arkscript/lambda-core.ark: -------------------------------------------------------------------------------- 1 | # Logic 2 | (let _true (fun (x) 3 | (fun (y &x) x))) 4 | (let _false (fun (x) 5 | (fun (y) y))) 6 | (let _not (fun (b) 7 | ((b _false) _true))) 8 | (let _and (fun (b1) 9 | (fun (b2 &b1) 10 | ((b1 b2) _false)))) 11 | (let _or (fun (b1) 12 | (fun (b2 &b1) 13 | ((b1 _true) b2)))) 14 | 15 | ## Examples 16 | (let read_bool (fun (b) 17 | (print ((b "true") "false")))) 18 | 19 | (print "Logic 20 | ----- 21 | True / False") 22 | (read_bool _true) 23 | (read_bool _false) 24 | 25 | (print "Not") 26 | (read_bool (_not _true)) 27 | (read_bool (_not _false)) 28 | 29 | (print "And") 30 | (read_bool ((_and _true) _true)) 31 | (read_bool ((_and _true) _false)) 32 | (read_bool ((_and _false) _true)) 33 | (read_bool ((_and _false) _false)) 34 | 35 | (print "Or") 36 | (read_bool ((_or _true) _true)) 37 | (read_bool ((_or _true) _false)) 38 | (read_bool ((_or _false) _true)) 39 | (read_bool ((_or _false) _false)) 40 | 41 | # Church Numerals 42 | (let _zero (fun (f) (fun (x) x))) 43 | (let _succ (fun (n) 44 | (fun (f &n) 45 | (fun (x &n &f) 46 | (f ((n f) x)))))) 47 | (let _pred (fun (n) 48 | (fun (f &n) 49 | (fun (x &n &f) 50 | (((n (fun (g &f) (fun (h &g &f) (h (g f))))) (fun (u &x) x)) (fun (a) a)))))) 51 | (let _one (_succ _zero)) 52 | 53 | ## Examples 54 | (let read_church (fun (n) 55 | (print ((n (fun (x) (+ x 1))) 0)))) 56 | 57 | (print " 58 | Church Numerals 59 | --------------- 60 | Zero / Succ") 61 | (read_church _zero) 62 | (read_church _one) 63 | (read_church (_succ _one)) 64 | (read_church (_succ (_succ _one))) 65 | 66 | (print "Pred") 67 | (read_church (_pred _one)) 68 | (read_church (_pred (_succ _one))) 69 | (read_church (_pred (_succ (_succ _one)))) 70 | 71 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/test/combinators_test.clj: -------------------------------------------------------------------------------- 1 | (ns combinators-test 2 | (:require [lambda :refer [λ]] 3 | [combinators :refer :all] 4 | [booleans :refer :all] 5 | [numerals :refer :all] 6 | [clojure.test :refer :all] 7 | [print-macro :refer [is-print]])) 8 | 9 | (def factorial-gen 10 | ;; Church encoding of functions, such as 'λ', does not 11 | ;; naturally support 'recur'. This is because the 'λ' macro expands into an 12 | ;; anonymous function (created using 'fn'), and functions defined with 'fn' 13 | ;; cannot use 'recur' unless the 'recur' is in the tail position. 14 | ;; 15 | ;; The 'fn' function in Clojure is needed because it allows us to define a 16 | ;; recursive function where 'recur' can be used correctly in the tail position. 17 | ;; When the function is structured with 'fn', 'recur' will correctly jump back 18 | ;; to the function without adding a new stack frame, thus ensuring the recursion 19 | ;; is efficient and won't result in stack overflow. 20 | (fn [f] 21 | (fn [n acc] 22 | ;; Church's 'If' introduces an additional function call, which prevents 'recur' 23 | ;; from being the final operation, thus breaking TCO and causing a stack overflow. 24 | ;; Hence, using native 'if' instead of Church's 'If' because 25 | ;; 'recur' must be the last operation for tail call optimization (TCO). 26 | (if (toBoolean ((n (λ x F)) T)) 27 | acc 28 | (recur (pred n) ((mult acc) n)))))) 29 | 30 | (def Y-factorial (Y factorial-gen)) 31 | (def Z-factorial (Z factorial-gen)) 32 | 33 | (deftest Y-Combinator 34 | (testing "Y-factorial" 35 | (is-print (= (toInt (Y-factorial (fromInt 9) one)) 362880)))) 36 | 37 | (deftest Z-Combinator 38 | (testing "Z-factorial" 39 | (is-print (= (toInt (Z-factorial (fromInt 9) one)) 362880)))) 40 | 41 | -------------------------------------------------------------------------------- /languages/e/elixir/lambda-core.exs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env elixir 2 | 3 | ########### 4 | # LOGIC # 5 | ########### 6 | 7 | _true = fn x -> fn y -> x end end 8 | _false = fn x -> fn y -> y end end 9 | 10 | _not = fn b -> b.(_false).(_true) end 11 | _and = fn b1 -> fn b2 -> b1.(b2).(_false) end end 12 | _or = fn b1 -> fn b2 -> b1.(_true).(b2) end end 13 | 14 | ##################### 15 | # CHURCH NUMERALS # 16 | ##################### 17 | 18 | _zero = fn f -> fn x -> x end end 19 | _succ = fn n -> fn f -> fn x -> f.(n.(f).(x)) end end end 20 | 21 | _pred = fn n -> 22 | fn f -> 23 | fn x -> 24 | n.(fn g -> fn h -> h.(g.(f)) end end).(fn u -> x end).(fn a -> a end) 25 | end 26 | end 27 | end 28 | 29 | _one = _succ.(_zero) 30 | 31 | ######################################## 32 | # HELPERS - not pure lambda calculus # 33 | ######################################## 34 | 35 | read_bool = fn b -> IO.puts(b.("t").("f")) end 36 | read_church = fn n -> IO.puts(n.(fn x -> x + 1 end).(0)) end 37 | 38 | ############## 39 | # EXAMPLES # 40 | ############## 41 | 42 | IO.puts("LOGIC") 43 | IO.puts("--------------") 44 | IO.puts("TRUE/FALSE") 45 | # t 46 | read_bool.(_true) 47 | # f 48 | read_bool.(_false) 49 | 50 | IO.puts("NOT") 51 | # f 52 | read_bool.(_not.(_true)) 53 | # t 54 | read_bool.(_not.(_false)) 55 | 56 | IO.puts("AND") 57 | # t 58 | read_bool.(_and.(_true).(_true)) 59 | # f 60 | read_bool.(_and.(_true).(_false)) 61 | # f 62 | read_bool.(_and.(_false).(_true)) 63 | # f 64 | read_bool.(_and.(_false).(_false)) 65 | 66 | IO.puts("OR") 67 | # t 68 | read_bool.(_or.(_true).(_true)) 69 | # t 70 | read_bool.(_or.(_true).(_false)) 71 | # t 72 | read_bool.(_or.(_false).(_true)) 73 | # f 74 | read_bool.(_or.(_false).(_false)) 75 | 76 | IO.puts("\nCHURCH NUMERALS") 77 | IO.puts("--------------") 78 | IO.puts("ZERO/SUCC") 79 | # 0 80 | read_church.(_zero) 81 | # 1 82 | read_church.(_succ.(_zero)) 83 | # 2 84 | read_church.(_succ.(_succ.(_zero))) 85 | # 3 86 | read_church.(_succ.(_succ.(_succ.(_zero)))) 87 | 88 | IO.puts("PRED") 89 | # 0 90 | read_church.(_pred.(_one)) 91 | # 1 92 | read_church.(_pred.(_succ.(_one))) 93 | # 2 94 | read_church.(_pred.(_succ.(_succ.(_one)))) 95 | -------------------------------------------------------------------------------- /languages/r/racket/lambda-core.rkt: -------------------------------------------------------------------------------- 1 | #lang racket 2 | 3 | ; LOGIC 4 | (define _true 5 | (lambda (x) 6 | (lambda (y) x))) 7 | 8 | (define _false 9 | (lambda (x) 10 | (lambda (y) y))) 11 | 12 | (define _not 13 | (lambda (b) 14 | ((b _false) _true))) 15 | 16 | (define _and 17 | (lambda (b1) 18 | (lambda (b2) 19 | ((b1 b2) _false)))) 20 | 21 | (define _or 22 | (lambda (b1) 23 | (lambda (b2) 24 | ((b1 _true) b2)))) 25 | 26 | 27 | ; CHURCH NUMERALS 28 | (define _zero 29 | (lambda (f) 30 | (lambda (x) x))) 31 | 32 | (define _succ 33 | (lambda (n) 34 | (lambda (f) 35 | (lambda (x) 36 | (f ((n f) x)))))) 37 | 38 | (define _pred 39 | (lambda (n) 40 | (lambda (f) 41 | (lambda (x) 42 | (((n (lambda (g) 43 | (lambda (h) (h (g f))))) 44 | (lambda (u) x)) 45 | (lambda (a) a)))))) 46 | 47 | (define _one (_succ _zero)) 48 | 49 | 50 | ; HELPERS - not pure lambda calculus 51 | (define read-bool 52 | (lambda (b) 53 | (displayln ((b "t") "f")))) 54 | 55 | (define read-church 56 | (lambda (n) 57 | (displayln ((n (lambda (x) (+ x 1))) 0)))) 58 | 59 | ; ------------------------------------------------- 60 | 61 | ; EXAMPLES 62 | (displayln "LOGIC") 63 | (displayln "--------------") 64 | (displayln "TRUE/FALSE") 65 | (read-bool _true) ; t 66 | (read-bool _false) ; f 67 | 68 | (displayln "NOT") 69 | (read-bool (_not _true)) ; f 70 | (read-bool (_not _false)) ; t 71 | 72 | (displayln "AND") 73 | (read-bool ((_and _true) _true)) ; t 74 | (read-bool ((_and _true) _false)) ; f 75 | (read-bool ((_and _false) _true)) ; f 76 | (read-bool ((_and _false) _false)) ; f 77 | 78 | (displayln "OR") 79 | (read-bool ((_or _true) _true)) ; t 80 | (read-bool ((_or _true) _false)) ; t 81 | (read-bool ((_or _false) _true)) ; t 82 | (read-bool ((_or _false) _false)) ; f 83 | 84 | (displayln "\nCHURCH NUMERALS") 85 | (displayln "--------------") 86 | (displayln "ZERO/SUCC") 87 | (read-church _zero) ; 0 88 | (read-church (_succ _zero)) ; 1 89 | (read-church (_succ (_succ _zero))) ; 2 90 | (read-church (_succ (_succ (_succ _zero)))) ; 3 91 | 92 | (displayln "PRED") 93 | (read-church (_pred _one)) ; 0 94 | (read-church (_pred (_succ _one))) ; 1 95 | (read-church (_pred (_succ (_succ _one)))) ; 2 96 | 97 | -------------------------------------------------------------------------------- /languages/k/kotlin/lambda-core.kt: -------------------------------------------------------------------------------- 1 | fun interface T : (T) -> T {} 2 | // LOGIC 3 | val TRUE: T 4 | get() = T {x: T -> T {y: T -> x}} 5 | val FALSE: T 6 | get() = T {x: T -> T {y: T -> y}} 7 | val NOT: T 8 | get() = T {x: T -> x(FALSE)(TRUE)} 9 | val AND: T 10 | get() = T {x: T -> T {y: T -> x(y)(FALSE)}} 11 | val OR: T 12 | get() = T {x: T -> T {y: T -> x(TRUE)(y)}} 13 | 14 | // CHURCH NUMERALS 15 | val ZERO: T 16 | get() = T{f: T -> T {x: T -> x}} 17 | val SUCC: T 18 | get() = T {n: T -> T {f: T -> T {x: T -> f(n(f)(x))}}} 19 | val PRED: T 20 | get() = T {n: T -> T {f: T -> T {x: T -> n(T {g: T -> T {h: T -> h(g(f))}})(T {u -> x})(T {u -> u})}}} 21 | 22 | // HELPERS - not pure lambda calculus 23 | fun readBool(t: T) { 24 | var res: Boolean? = null 25 | val _true: T = T {x -> 26 | res = true 27 | x 28 | } 29 | val _false: T = T {x -> 30 | res = false 31 | x 32 | } 33 | t(_true)(_false)({t: T -> t}) 34 | println(res) 35 | } 36 | 37 | fun readChurchNumber(t: T) { 38 | var res: Int = 0 39 | 40 | val plusOne: T = T {x: T -> 41 | res++ 42 | x 43 | } 44 | 45 | t(plusOne)({t:T -> t}) 46 | println(res) 47 | } 48 | 49 | // ------------------------------------------------- 50 | 51 | // EXAMPLES 52 | fun main() { 53 | println("LOGIC") 54 | println("----------------") 55 | println("TRUE/FALSE") 56 | readBool(TRUE) // true 57 | readBool(FALSE) // false 58 | 59 | println("NOT") 60 | readBool(NOT(TRUE)) // false 61 | readBool(NOT(FALSE)) //true 62 | 63 | println("AND") 64 | readBool(AND(FALSE)(FALSE)) // false 65 | readBool(AND(FALSE)(TRUE)) // false 66 | readBool(AND(TRUE)(FALSE)) // false 67 | readBool(AND(TRUE)(TRUE)) // true 68 | 69 | println("OR") 70 | readBool(OR(FALSE)(FALSE)) // false 71 | readBool(OR(FALSE)(TRUE)) // true 72 | readBool(OR(TRUE)(FALSE)) // true 73 | readBool(OR(TRUE)(TRUE)) // true 74 | 75 | println("CHURCH NUMERALS") 76 | println("---------------") 77 | println("ZERO/SUCC") 78 | readChurchNumber(ZERO) // 0 79 | readChurchNumber(SUCC(ZERO)) // 1 80 | readChurchNumber(SUCC(SUCC(ZERO))) // 2 81 | 82 | println("PRED") 83 | val THREE = SUCC(SUCC(SUCC(ZERO))) // 3 84 | readChurchNumber(PRED(THREE)) // 2 85 | readChurchNumber(PRED(PRED(THREE))) // 1 86 | readChurchNumber(PRED(PRED(PRED(THREE)))) // 0 87 | } -------------------------------------------------------------------------------- /languages/c/c++/lambda-core.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace logic { 4 | constexpr auto _true = [](const auto &x) { 5 | return [&x](const auto &) { return x; }; 6 | }; 7 | 8 | constexpr auto _false = [](const auto &) { 9 | return [](const auto &y) { return y; }; 10 | }; 11 | 12 | constexpr auto _not = [](const auto &x) { return x(_false)(_true); }; 13 | 14 | constexpr auto _and = [](const auto &x) { 15 | return [&x](const auto &y) { return x(y)(_false); }; 16 | }; 17 | 18 | constexpr auto _or = [](const auto &x) { 19 | return [&x](const auto &y) { return x(_true)(y); }; 20 | }; 21 | 22 | namespace test { 23 | constexpr bool convert(const auto &x) { return x(true)(false); } 24 | 25 | void print(const auto &x) { std::println("{}", convert(x)); } 26 | } // namespace test 27 | } // namespace logic 28 | 29 | namespace church { 30 | constexpr auto zero = [](const auto &) { 31 | return [](const auto &x) { return x; }; 32 | }; 33 | 34 | constexpr auto succ = [](const auto &n) { 35 | return [&n](const auto &f) { 36 | return [&n, &f](const auto &x) { return f(n(f)(x)); }; 37 | }; 38 | }; 39 | 40 | constexpr auto one = succ(zero); 41 | 42 | constexpr auto pred = [](const auto &n) { 43 | return [&n](const auto &f) { 44 | return [&n, &f](auto x) { 45 | return n([&f](const auto &g) { 46 | return [&f, g](const auto &h) { return h(g(f)); }; 47 | })([x](const auto &u) { return x; })([](const auto &a) { return a; }); 48 | }; 49 | }; 50 | }; 51 | 52 | namespace test { 53 | constexpr unsigned int convert(const auto &n) { 54 | return n([](const auto &x) { return x + 1; })(0); 55 | } 56 | 57 | void print(const auto &n) { std::println("{}", convert(n)); } 58 | } // namespace test 59 | } // namespace church 60 | 61 | int main() { 62 | using namespace logic; 63 | using namespace church; 64 | 65 | static_assert(logic::test::convert(_true) == true); 66 | static_assert(logic::test::convert(_false) == false); 67 | static_assert(logic::test::convert(_and(_true)(_true)) == true); 68 | static_assert(logic::test::convert(_and(_true)(_false)) == false); 69 | static_assert(logic::test::convert(_or(_true)(_true)) == true); 70 | static_assert(logic::test::convert(_or(_true)(_false)) == true); 71 | logic::test::print(_true); 72 | 73 | static_assert(church::test::convert(zero) == 0); 74 | static_assert(church::test::convert(succ(zero)) == 1); 75 | static_assert(church::test::convert(pred(succ(one))) == 1); 76 | church::test::print(one); 77 | } 78 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/test/booleans_test.clj: -------------------------------------------------------------------------------- 1 | (ns booleans-test 2 | (:require [booleans :refer :all] 3 | [clojure.test :refer :all] 4 | [print-macro :refer [is-print]])) 5 | 6 | (deftest λ-booleans 7 | (testing "true" 8 | (is-print (= (toBoolean T) true))) 9 | 10 | (testing "false" 11 | (is-print (= (toBoolean F) false))) 12 | 13 | (testing "If" 14 | (is-print (= (toBoolean (((If T) T) F)) true)) 15 | (is-print (= (toBoolean (((If F) T) F)) false))) 16 | 17 | (testing "And" 18 | (is-print (= (toBoolean ((And T) T)) true)) 19 | (is-print (= (toBoolean ((And T) F)) false)) 20 | (is-print (= (toBoolean ((And F) T)) false)) 21 | (is-print (= (toBoolean ((And F) F)) false)) 22 | (is-print (= (toBoolean ((And T) ((And T) T))) true)) 23 | (is-print (= (toBoolean ((And T) ((And F) T))) false))) 24 | 25 | (testing "Or" 26 | (is-print (= (toBoolean ((Or T) T)) true)) 27 | (is-print (= (toBoolean ((Or T) F)) true)) 28 | (is-print (= (toBoolean ((Or F) T)) true)) 29 | (is-print (= (toBoolean ((Or F) F)) false)) 30 | (is-print (= (toBoolean ((Or F) ((Or F) F))) false)) 31 | (is-print (= (toBoolean ((Or F) ((Or T) F))) true))) 32 | 33 | (testing "Not" 34 | (is-print (= (toBoolean (Not T)) false)) 35 | (is-print (= (toBoolean (Not F)) true)) 36 | (is-print (= (toBoolean (Not (Not T))) true)) 37 | (is-print (= (toBoolean (Not (Not F))) false))) 38 | 39 | (testing "Xor" 40 | (is-print (= (toBoolean ((Xor T) T)) false)) 41 | (is-print (= (toBoolean ((Xor T) F)) true)) 42 | (is-print (= (toBoolean ((Xor F) T)) true)) 43 | (is-print (= (toBoolean ((Xor F) F)) false))) 44 | 45 | (testing "Expressions" 46 | ;T AND T AND F OR T 47 | (is-print (= (toBoolean ((And T) ((And T) ((Or F) T)))) 48 | true)) 49 | 50 | ;T AND F AND F OR T AND T 51 | (is-print (= (toBoolean ((And T) ((And F) ((Or F) ((And T) T))))) 52 | false)) 53 | 54 | ;T OR (F AND F OR T AND T) 55 | (is-print (= (toBoolean ((Or T) ((And F) ((Or F) ((And T) T))))) 56 | true)) 57 | 58 | ;F OR (F AND F OR F AND T) 59 | (is-print (= (toBoolean ((Or F) ((And F) ((Or F) ((And F) T))))) 60 | false)) 61 | 62 | ;F OR F AND F OR T AND T 63 | (is-print (= (toBoolean ((And ((Or F) F)) ((And T) ((Or F) T)))) 64 | false)) 65 | 66 | ;T OR F AND F OR T AND T 67 | (is-print (= (toBoolean ((And ((Or T) F)) ((And T) ((Or F) T)))) 68 | true)))) 69 | -------------------------------------------------------------------------------- /languages/c/clojure/lambda-core/test/numerals_test.clj: -------------------------------------------------------------------------------- 1 | (ns numerals-test 2 | (:require [numerals :refer :all] 3 | [clojure.test :refer :all] 4 | [print-macro :refer [is-print]])) 5 | 6 | (deftest λ-numbers 7 | (testing "zero" 8 | (is-print (= (toInt zero) 0))) 9 | 10 | (testing "one" 11 | (is-print (= (toInt (succ zero)) 1)) 12 | (is-print (= (toInt one) 1))) 13 | 14 | (testing "two" 15 | (is-print (= (toInt (succ (succ zero))) 2)) 16 | (is-print (= (toInt two) 2))) 17 | 18 | (testing "three" 19 | (is-print (= (toInt (succ (succ (succ zero)))) 3))) 20 | 21 | (testing "predecessor" 22 | (is-print (= (toInt (pred one)) 0)) 23 | (is-print (= (toInt (pred two)) 1)) 24 | (is-print (= (toInt (pred (succ (succ (succ zero))))) 2)) 25 | (is-print (= (toInt (pred (fromInt 10))) 9)))) 26 | 27 | (deftest λ-numerical-operations 28 | (testing "addition" 29 | (is-print (= 30 | (toInt ((plus (fromInt 7)) (fromInt 5))) 31 | 12)) 32 | (is-print (= 33 | (toInt ((plus (fromInt 7)) ((plus (fromInt 6)) (fromInt 2)))) 34 | 15))) 35 | 36 | (testing "subtraction" 37 | (is-print (= 38 | (toInt ((minus (fromInt 7)) (fromInt 5))) 39 | 2)) 40 | (is-print (= 41 | (toInt ((minus (fromInt 7)) ((minus (fromInt 6)) (fromInt 2)))) 42 | 3))) 43 | 44 | (testing "multiplication" 45 | (is-print (= 46 | (toInt ((mult (fromInt 2)) (fromInt 3))) 47 | 6)) 48 | (is-print (= 49 | (toInt ((mult (fromInt 2)) ((mult (fromInt 5)) (fromInt 3)))) 50 | 30))) 51 | 52 | (testing "exponentiation" 53 | (is-print (= 54 | (toInt ((exp (fromInt 2)) (fromInt 3))) 55 | 8)) 56 | (is-print (= 57 | (toInt ((exp (fromInt 2)) ((exp (fromInt 2)) (fromInt 3)))) 58 | 256)))) 59 | 60 | (deftest λ-numeral-expressions 61 | (testing "numeral expressions" 62 | ; 3 * (2 + 5) - 2^3 63 | (is-print (= 64 | (toInt ((minus ((mult (fromInt 3)) 65 | ((plus (fromInt 2)) (fromInt 5)))) 66 | ((exp (fromInt 2)) (fromInt 3)))) 67 | 13)))) 68 | 69 | (deftest λ-toStr 70 | (testing "toStr" 71 | (is-print (= (toStr zero) "λf.λn.(n)")) 72 | (is-print (= (toStr one) "λf.λn.(f(n))")) 73 | (is-print (= (toStr two) "λf.λn.(f(f(n)))")) 74 | (is-print (= (toStr (succ (succ (succ zero)))) "λf.λn.(f(f(f(n))))")) 75 | (is-print (= (toStr (fromInt 5)) "λf.λn.(f(f(f(f(f(n))))))")))) 76 | 77 | -------------------------------------------------------------------------------- /languages/g/go/lambda-core.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | type T func(t T) T 6 | 7 | // LOGIC 8 | var ( 9 | _true T = func(x T) T { return func(y T) T { return x } } 10 | _false T = func(x T) T { return func(y T) T { return y } } 11 | _not T = func(b T) T { return b(_false)(_true) } 12 | _and T = func(b1 T) T { return func(b2 T) T { return b1(b2)(_false) } } 13 | _or T = func(b1 T) T { return func(b2 T) T { return b1(_true)(b2) } } 14 | ) 15 | 16 | // CHURCH NUMERALS 17 | var ( 18 | _zero T = func(f T) T { return func(x T) T { return x } } 19 | _succ T = func(n T) T { 20 | return func(f T) T { 21 | return func(x T) T { 22 | return f(n(f)(x)) 23 | } 24 | } 25 | } 26 | _pred T = func(n T) T { 27 | return func(f T) T { 28 | return func(x T) T { 29 | return n(func(g T) T { return func(h T) T { return h(g(f)) } })(func(u T) T { return x })(func(a T) T { return a }) 30 | } 31 | } 32 | } 33 | _one T = _succ(_zero) 34 | ) 35 | 36 | // HELPERS - not pure lambda calculus 37 | func readBool(b T) bool { 38 | var res bool 39 | var closureTrue T = func(t T) T { 40 | res = true 41 | return t 42 | } 43 | var closureFalse T = func(t T) T { 44 | res = false 45 | return t 46 | } 47 | b(closureTrue)(closureFalse)(func(t T) T { return t }) 48 | return res 49 | } 50 | 51 | func readChurch(n T) int { 52 | res := 0 53 | var closurePlusOne T = func(t T) T { 54 | res++ 55 | return t 56 | } 57 | n(closurePlusOne)(func(t T) T { return t }) 58 | return res 59 | } 60 | 61 | func main() { 62 | fmt.Println("LOGIC") 63 | fmt.Println("-------------") 64 | fmt.Println("TRUE/FALSE") 65 | fmt.Println(readBool(_true)) 66 | fmt.Println(readBool(_false)) 67 | 68 | fmt.Println("NOT") 69 | fmt.Println(readBool(_not(_true))) 70 | fmt.Println(readBool(_not(_false))) 71 | 72 | fmt.Println("AND") 73 | fmt.Println(readBool(_and(_true)(_true))) 74 | fmt.Println(readBool(_and(_true)(_false))) 75 | fmt.Println(readBool(_and(_false)(_true))) 76 | fmt.Println(readBool(_and(_false)(_false))) 77 | 78 | fmt.Println("OR") 79 | fmt.Println(readBool(_or(_true)(_true))) 80 | fmt.Println(readBool(_or(_true)(_false))) 81 | fmt.Println(readBool(_or(_false)(_true))) 82 | fmt.Println(readBool(_or(_false)(_false))) 83 | 84 | fmt.Println("\nCHURCH NUMERALS") 85 | fmt.Println("-------------") 86 | fmt.Println("ZERO/SUCC") 87 | fmt.Println(readChurch(_zero)) 88 | fmt.Println(readChurch(_one)) 89 | fmt.Println(readChurch(_succ(_one))) 90 | fmt.Println(readChurch(_succ(_succ(_one)))) 91 | fmt.Println("PRED") 92 | fmt.Println(readChurch(_pred(_one))) 93 | fmt.Println(readChurch(_pred(_succ(_one)))) 94 | fmt.Println(readChurch(_pred(_succ(_succ(_one))))) 95 | 96 | } 97 | -------------------------------------------------------------------------------- /languages/l/lua/lambda-core.lua: -------------------------------------------------------------------------------- 1 | -- _lc postfix to prevent conflict 2 | -- Bool value 3 | local true_lc = function(x) 4 | return function(y) 5 | return x 6 | end 7 | end 8 | local false_lc = function(x) 9 | return function(y) 10 | return y 11 | end 12 | end 13 | 14 | -- Boolean Operations 15 | local and_lc = function(a) 16 | return function(b) 17 | return a(b)(false_lc) 18 | end 19 | end 20 | 21 | local or_lc = function(a) 22 | return function(b) 23 | return a(true_lc)(b) 24 | end 25 | end 26 | 27 | local not_lc = function(a) 28 | return a(false_lc)(true_lc) 29 | end 30 | 31 | -- Church Numerals 32 | local zero = function(f) 33 | return function(x) 34 | return x 35 | end 36 | end 37 | local one = function(f) 38 | return function(x) 39 | return f(x) 40 | end 41 | end 42 | local succ = function(n) 43 | return function(f) 44 | return function(x) 45 | return f(n(f)(x)) 46 | end 47 | end 48 | end 49 | -- This is ugly 50 | local pred = function(n) 51 | return function(f) 52 | return function(x) 53 | return n(function(g) 54 | return function(h) 55 | return h(g(f)) 56 | end 57 | end)(function(u) 58 | return x 59 | end)(function(u) 60 | return u 61 | end) 62 | end 63 | end 64 | end 65 | -- a slightly better version of pred 66 | local pred_v2 = function(n) 67 | return function(f) 68 | return function(x) 69 | local helper = function(g) 70 | return function(h) 71 | return h(g(f)) 72 | end 73 | end 74 | return n(helper)(function(_) 75 | return x 76 | end)(function(u) 77 | return u 78 | end) 79 | end 80 | end 81 | end 82 | -- Helper functions 83 | local read_bool = function(b) 84 | return b(true)(false) 85 | end 86 | 87 | local read_church = function(n) 88 | return n(function(x) 89 | return x + 1 90 | end)(0) 91 | end 92 | 93 | -- Test Cases 94 | print(read_bool(true_lc)) -- true 95 | print(read_bool(false_lc)) -- false 96 | print(read_bool(not_lc(true_lc))) -- false 97 | print(read_bool(not_lc(false_lc))) -- true 98 | print(read_bool(and_lc(true_lc)(true_lc))) -- true 99 | print(read_bool(and_lc(true_lc)(false_lc))) -- false 100 | print(read_bool(and_lc(false_lc)(true_lc))) -- false 101 | print(read_bool(and_lc(false_lc)(false_lc))) -- false 102 | print(read_bool(or_lc(true_lc)(true_lc))) -- true 103 | print(read_bool(or_lc(true_lc)(false_lc))) -- true 104 | print(read_bool(or_lc(false_lc)(true_lc))) -- true 105 | print(read_bool(or_lc(false_lc)(false_lc))) -- false 106 | 107 | print(read_church(zero)) -- 0 108 | print(read_church(succ(zero))) -- 1 109 | print(read_church(succ(one))) -- 2 110 | print(read_church(succ(succ(one)))) -- 3 111 | print(read_church(pred(one))) -- 0 112 | print(read_church(pred_v2(one))) -- 0 113 | print(read_church(pred(succ(one)))) -- 1 114 | print(read_church(pred_v2(succ(one)))) -- 1 115 | print(read_church(pred(succ(succ(one))))) -- 2 116 | print(read_church(pred_v2(succ(succ(one))))) -- 2 117 | -------------------------------------------------------------------------------- /languages/p/perl/lambda-core.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | # LOGIC 5 | my $_true = sub { 6 | # shift is more convenient 7 | # my $x = $_[0]; 8 | my $x = shift; 9 | sub { $x } 10 | }; 11 | my $_false = sub { 12 | sub { shift } 13 | }; 14 | 15 | my $not = sub { 16 | my $b = shift; 17 | $b->($_false)->($_true) 18 | }; 19 | 20 | my $and = sub { 21 | my $b1 = shift; 22 | sub { 23 | my $b2 = shift; 24 | $b1->($b2)->($_false) 25 | } 26 | }; 27 | 28 | my $or = sub { 29 | my $b1 = shift; 30 | sub { 31 | my $b2 = shift; 32 | $b1->($_true)->($b2) 33 | } 34 | }; 35 | 36 | # CHURCH NUMERALS 37 | my $zero = sub { sub { shift } }; 38 | my $succ = sub { 39 | my $n = shift; 40 | sub { 41 | my $f = shift; 42 | sub { 43 | my $x = shift; 44 | $f->($n->($f)->($x)) 45 | } 46 | } 47 | }; 48 | my $pred = sub { 49 | my $n = shift; 50 | sub { 51 | my $f = shift; 52 | sub { 53 | my $x = shift; 54 | $n->(sub { 55 | my $g = shift; 56 | sub { 57 | my $h = shift; 58 | $h->($g->($f)) 59 | } 60 | })->(sub { $x })->(sub { shift }) 61 | } 62 | } 63 | }; 64 | my $one = $succ->($zero); 65 | 66 | # HELPERS - not pure lambda calculus 67 | sub read_bool { 68 | my $b = shift; 69 | print $b->('true')->('false'); 70 | } 71 | 72 | sub read_church { 73 | my $n = shift; 74 | print $n->(sub { $_[0] + 1 })->(0); 75 | } 76 | 77 | # EXAMPLES 78 | print "LOGIC\n"; 79 | print "-------------\n"; 80 | print " TRUE: "; 81 | read_bool($_true); 82 | print "\n FALSE: "; 83 | read_bool($_false); 84 | 85 | print "\n NOT TRUE: "; 86 | read_bool($not->($_true)); 87 | print "\n NOT FALSE: "; 88 | read_bool($not->($_false)); 89 | 90 | print "\n TRUE AND TRUE: "; 91 | read_bool($and->($_true)->($_true)); 92 | print "\n TRUE AND FALSE: "; 93 | read_bool($and->($_true)->($_false)); 94 | print "\n FALSE AND TRUE: "; 95 | read_bool($and->($_false)->($_true)); 96 | print "\n FALSE AND FALSE: "; 97 | read_bool($and->($_false)->($_false)); 98 | 99 | print "\n TRUE OR TRUE: "; 100 | read_bool($or->($_true)->($_true)); 101 | print "\n TRUE OR FALSE: "; 102 | read_bool($or->($_true)->($_false)); 103 | print "\n FALSE OR TRUE: "; 104 | read_bool($or->($_false)->($_true)); 105 | print "\n FALSE OR FALSE: "; 106 | read_bool($or->($_false)->($_false)); 107 | 108 | print "\n\nCHURCH NUMERALS\n"; 109 | print "-------------\n"; 110 | print " ZERO: "; 111 | read_church($zero); 112 | print "\n ONE: "; 113 | read_church($one); 114 | print "\n SUCC ONE: "; 115 | read_church($succ->($one)); 116 | print "\n SUCC SUCC ONE: "; 117 | read_church($succ->($succ->($one))); 118 | 119 | print "\n PRED ONE: "; 120 | read_church($pred->($one)); 121 | print "\n PRED SUCC ONE: "; 122 | read_church($pred->($succ->($one))); 123 | print "\n PRED SUCC SUCC ONE: "; 124 | read_church($pred->($succ->($succ->($one)))); 125 | -------------------------------------------------------------------------------- /languages/t/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | 23 | pids 24 | _.pid 25 | _.seed 26 | *.pid.lock 27 | 28 | # Directory for instrumented libs generated by jscoverage/JSCover 29 | 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | 47 | bower_components 48 | 49 | # node-waf configuration 50 | 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | 55 | build/Release 56 | 57 | # Dependency directories 58 | 59 | node_modules/ 60 | jspm_packages/ 61 | 62 | # Snowpack dependency directory (https://snowpack.dev/) 63 | 64 | web_modules/ 65 | 66 | # TypeScript cache 67 | 68 | *.tsbuildinfo 69 | 70 | # Optional npm cache directory 71 | 72 | .npm 73 | 74 | # Optional eslint cache 75 | 76 | .eslintcache 77 | 78 | # Optional stylelint cache 79 | 80 | .stylelintcache 81 | 82 | # Microbundle cache 83 | 84 | .rpt2_cache/ 85 | .rts2_cache_cjs/ 86 | .rts2_cache_es/ 87 | .rts2_cache_umd/ 88 | 89 | # Optional REPL history 90 | 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | 95 | *.tgz 96 | 97 | # Yarn Integrity file 98 | 99 | .yarn-integrity 100 | 101 | # dotenv environment variable files 102 | 103 | .env 104 | .env.development.local 105 | .env.test.local 106 | .env.production.local 107 | .env.local 108 | 109 | # parcel-bundler cache (https://parceljs.org/) 110 | 111 | .parcel-cache 112 | 113 | # Next.js build output 114 | 115 | .next 116 | out 117 | 118 | # Nuxt.js build / generate output 119 | 120 | .nuxt 121 | dist 122 | 123 | # Gatsby files 124 | 125 | # Comment in the public line in if your project uses Gatsby and not Next.js 126 | 127 | # https://nextjs.org/blog/next-9-1#public-directory-support 128 | 129 | # public 130 | 131 | # vuepress build output 132 | 133 | .vuepress/dist 134 | 135 | # vuepress v2.x temp and cache directory 136 | 137 | .temp 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | -------------------------------------------------------------------------------- /languages/t/typescript/lambda-core.ts: -------------------------------------------------------------------------------- 1 | type True = (x: T) => (y: V) => T; 2 | type False = (x: T) => (y: V) => V; 3 | 4 | const _true: True = x => y => x; 5 | const _false: False = x => y => y; 6 | 7 | type Not = A extends True ? False : True; 8 | type And = 9 | A1 extends True ? A2 : False; 10 | 11 | type Or = 12 | A1 extends True ? True : A2; 13 | 14 | type ChurchNumeral = (f: (x: T) => T) => (x: T) => T; 15 | 16 | const _zero: ChurchNumeral = f => x => x; 17 | 18 | const _successor = (n: ChurchNumeral): ChurchNumeral => 19 | f => x => f(n(f)(x)); 20 | 21 | // One 22 | const _one: ChurchNumeral = _successor(_zero); 23 | 24 | // Two 25 | const _two: ChurchNumeral = _successor(_one); 26 | 27 | // Three 28 | const _three: ChurchNumeral = _successor(_two); 29 | 30 | // Type tests 31 | type TestTrue = True extends True ? true : false; 32 | type TestFalse = False extends False ? true : false; 33 | 34 | type TestNotTrue = Not extends False ? true : false; 35 | type TestNotFalse = Not extends True ? true : false; 36 | 37 | type TestAndTrueTrue = And extends True ? true : false; 38 | type TestAndTrueFalse = And extends False ? true : false; 39 | type TestAndFalseTrue = And extends False ? true : false; 40 | type TestAndFalseFalse = And extends False ? true : false; 41 | 42 | type TestOrTrueTrue = Or extends True ? true : false; 43 | type TestOrTrueFalse = Or extends True ? true : false; 44 | type TestOrFalseTrue = Or extends True ? true : false; 45 | type TestOrFalseFalse = Or extends False ? true : false; 46 | 47 | // Helper function 48 | const applyNumeral = ( 49 | numeral: ChurchNumeral, 50 | f: (x: T) => T, 51 | initial: T 52 | ): T => numeral(f)(initial); 53 | 54 | // Increment helper 55 | const increment = (n: ChurchNumeral): ChurchNumeral => _successor(n); 56 | 57 | // Pair type for predecessor implementation 58 | type Pair = [A, B]; 59 | 60 | // Predecessor implementation 61 | const predecessor = (n: ChurchNumeral): ChurchNumeral => { 62 | const pair = n((p: Pair) => { 63 | const [_, prev] = p; 64 | return [prev, _successor(prev)] as Pair; 65 | })([_zero, _zero] as Pair); 66 | 67 | return pair[0]; 68 | }; 69 | 70 | const readChurchNumeral = (n: ChurchNumeral): number => { 71 | return applyNumeral(n, (x: number) => x + 1, 0); 72 | }; 73 | 74 | // Tests 75 | const testNumerals = () => { 76 | // Test basic numerals 77 | console.log("Zero:", readChurchNumeral(_zero)); // Should be 0 78 | console.log("One:", readChurchNumeral(_one)); // Should be 1 79 | console.log("Two:", readChurchNumeral(_two)); // Should be 2 80 | console.log("Three:", readChurchNumeral(_three)); // Should be 3 81 | 82 | // Test predecessor 83 | console.log("Pred Zero:", readChurchNumeral(predecessor(_zero))); // Should be 0 84 | console.log("Pred One:", readChurchNumeral(predecessor(_one))); // Should be 0 85 | console.log("Pred Two:", readChurchNumeral(predecessor(_two))); // Should be 1 86 | console.log("Pred Three:", readChurchNumeral(predecessor(_three))); // Should be 2 87 | }; 88 | 89 | testNumerals(); -------------------------------------------------------------------------------- /languages/l/language84/lambda-core.84: -------------------------------------------------------------------------------- 1 | Begin { 2 | (show 'h1 "LOGIC") 3 | 4 | (show 'h2 "TRUE/FALSE") 5 | (show 'bool true) 6 | (show 'bool false) 7 | 8 | (show 'h2 "NOT") 9 | (show 'bool (not true)) 10 | (show 'bool (not false)) 11 | 12 | (show 'h2 "AND") 13 | (show 'bool ((and true) true)) 14 | (show 'bool ((and true) false)) 15 | (show 'bool ((and false) true)) 16 | (show 'bool ((and false) false)) 17 | 18 | (show 'h2 "OR") 19 | (show 'bool ((or true) true)) 20 | (show 'bool ((or true) false)) 21 | (show 'bool ((or false) true)) 22 | (show 'bool ((or false) false)) 23 | 24 | (show 'h1 "CHURCH NUMERALS") 25 | 26 | (show 'h2 "ZERO/SUCC") 27 | (show 'nat zero) 28 | (show 'nat one) 29 | (show 'nat two) 30 | (show 'nat three) 31 | 32 | (show 'h2 "PRED") 33 | (show 'nat (pred zero)) 34 | (show 'nat (pred one)) 35 | (show 'nat (pred two)) 36 | (show 'nat (pred three)) 37 | 38 | (show 'h2 "ADD") 39 | (show 'nat ((add three) two)) 40 | 41 | (show 'h2 "MUL") 42 | (show 'nat ((mul zero) two)) 43 | (show 'nat ((mul two) zero)) 44 | (show 'nat ((mul three) two)) 45 | 46 | (show 'h2 "FACT") 47 | (show 'nat (fact zero)) 48 | (show 'nat (fact one)) 49 | (show 'nat (fact two)) 50 | (show 'nat (fact three)) 51 | (show 'nat (fact four)) 52 | (show 'nat (fact five)) 53 | 54 | (show 'h2 "FIB") 55 | (show 'nat (fib zero)) 56 | (show 'nat (fib one)) 57 | (show 'nat (fib two)) 58 | (show 'nat (fib three)) 59 | (show 'nat (fib four)) 60 | (show 'nat (fib five)) 61 | } 62 | 63 | Where 64 | 65 | Define (show class x) 66 | Open Package "stdio" { :print_line } 67 | Open Package "z" { :Infix + :show show_int } 68 | In 69 | Begin Match class { 70 | | 'h1 71 | (print_line "") 72 | (print_line x) 73 | (print_line "---") 74 | | 'h2 75 | (print_line "") 76 | (print_line x) 77 | | 'bool 78 | (print_line ((x "t") "f")) 79 | | 'nat 80 | Define (increment x) 81 | [x + 1] 82 | (print_line (show_int ((x increment) 0))) 83 | } 84 | 85 | Let fib 86 | Define [[x] -> f] (f x) 87 | In 88 | Define ((f fib) n) 89 | Define (case_small _) 90 | one 91 | Define (case_big _) 92 | ((add (fib (pred n))) (fib (pred (pred n)))) 93 | In 94 | [{} -> (((is_zero (pred n)) case_small) case_big)] 95 | In 96 | (z f) 97 | 98 | Let fact 99 | Define [[x] -> f] (f x) 100 | In 101 | Define ((f fact) n) 102 | Define (case_zero _) 103 | one 104 | Define (case_nonzero _) 105 | ((mul (fact (pred n))) n) 106 | In 107 | [{} -> (((is_zero n) case_zero) case_nonzero)] 108 | In 109 | (z f) 110 | 111 | Where 112 | 113 | Define (not b) 114 | ((b false) true) 115 | 116 | Define ((and b1) b2) 117 | ((b1 b2) false) 118 | 119 | Define ((or b1) b2) 120 | ((b1 true) b2) 121 | 122 | Define ((mul a) b) 123 | Define ([[g] << f] x) (g (f x)) 124 | In 125 | [a << b] 126 | 127 | Let add 128 | Let BITTER 129 | Func a Func b Func f Func x ((a f) ((b f) x)) 130 | Let SWEET 131 | Define ([[g] << f] x) (g (f x)) 132 | In 133 | Define (((add a) b) f) 134 | [(a f) << (b f)] 135 | In 136 | add 137 | In 138 | BITTER 139 | 140 | Define (is_zero n) 141 | ((n (const false)) true) 142 | 143 | Define (((pred n) f) x) 144 | Define ((compose g) h) 145 | (h (g f)) 146 | In 147 | (((n compose) (const x)) id) 148 | 149 | Let one (succ zero) 150 | 151 | Let two (succ (succ zero)) 152 | 153 | Let three (succ (succ (succ zero))) 154 | 155 | Let four (succ (succ (succ (succ zero)))) 156 | 157 | Let five (succ (succ (succ (succ (succ zero))))) 158 | 159 | Where 160 | 161 | Let z 162 | Let BITTER 163 | Func f (Func x (f Func v ((x x) v)) Func x (f Func v ((x x) v))) 164 | Let SWEET 165 | Define (z f) 166 | Define (x x) 167 | Define (self v) 168 | ((x x) v) 169 | In 170 | (f self) 171 | In 172 | (x x) 173 | In 174 | z 175 | Let SWEETEST 176 | Define (z f) 177 | Unfold {} 178 | Define (self v) 179 | ((Fold) v) 180 | In 181 | (f self) 182 | In 183 | z 184 | In 185 | SWEETEST 186 | 187 | Define ((true x) y) 188 | x 189 | 190 | Define ((false x) y) 191 | y 192 | 193 | Define ((zero f) x) 194 | x 195 | 196 | Define (((succ n) f) x) 197 | (f ((n f) x)) 198 | 199 | Define ((const x) u) 200 | x 201 | 202 | Define (id x) 203 | x 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lambda Core 2 | 3 | Welcome to *Lambda Core*, a repository dedicated to showcasing implementations of the "core" of lambda calculus in every programming language. We aim to create a living library of code snippets that demonstrate: 4 | 5 | 1. *Boolean Functions*: true, false, not, and, and or. 6 | 2. *Church Numerals*: zero, successor and predecessor functions, and the numeral one (derived from successor of zero). 7 | 3. *Examples using the above*: Prove they work! 8 | 9 | This project is inspired by the classic "hello-world" repo idea, but takes things a step further by introducing some of the most fundamental concepts in functional programming and lambda calculus. 10 | 11 | --- 12 | 13 | ## What is the "Lambda Core"? 14 | 15 | The *Lambda Core* refers to: 16 | 17 | - *Boolean Operations* in lambda calculus: 18 | - *True* and *False* (often represented as λx.λy.x and λx.λy.y). 19 | - *not* (logical negation). 20 | - *and* (logical conjunction). 21 | - *or* (logical disjunction). 22 | - *Church Numerals*: 23 | - *Zero* (often λf.λx.x). 24 | - *Successor Function* (to increment a Church numeral). 25 | - *Predecessor Function* (to decrement a Church numeral). 26 | - *One* (either defined directly or via successor of zero). 27 | 28 | By implementing these features, you will demonstrate how your chosen language can express or emulate these classic functional concepts. 29 | 30 | --- 31 | 32 | ## How to Contribute 33 | 34 | We invite you to contribute by adding a folder for a programming language that is not yet present. To do so: 35 | 36 | 1. *Create a new folder* under languages/firstletterorsymbol/ named after the language you are implementing (e.g., languages/h/haskell, languages/p/python, languages/g/go, etc.). 37 | 2. Inside this folder, create: 38 | - A file named **lambda-core** with the appropriate file extension (e.g., lambda-core.py, lambda-core.hs, lambda-core.go). 39 | - A *README.md* that explains: 40 | - How to run your implementation (any dependencies, compilation steps, interpreter requirements, etc.). 41 | 42 | 3. *Open a Pull Request*: 43 | - Briefly describe what you did. 44 | - Link to any official references or documentation used if relevant. 45 | 46 | --- 47 | 48 | ## Folder Structure 49 | 50 | The repository is organized as follows: 51 | 52 | Each language's folder should stand on its own. Ideally, someone could clone the repo, enter your language's folder, follow your instructions, and verify your Lambda Core implementation right away. 53 | 54 | --- 55 | 56 | ## Example Contribution Workflow 57 | 58 | Here’s a quick example workflow: 59 | 60 | 1. *Fork* this repository. 61 | 2. Create a branch named after your new language or a feature fix. 62 | 3. Add a new folder languages/letterorsymbol/mylanguage. 63 | 4. Add lambda-core.my-lang and a supporting README.md. 64 | 5. Commit and push your changes. 65 | 6. *Open a Pull Request* from your fork’s branch into the main branch of this repository. 66 | 67 | We will review your submission, ask any clarifying questions, and then merge it once everything looks good. 68 | 69 | --- 70 | 71 | ## Why Contribute? 72 | 73 | By contributing, you can: 74 | - Show how your favorite language handles functional constructs. 75 | - Learn about the power and simplicity of lambda calculus. 76 | - Collaborate with others who share a passion for languages and functional programming. 77 | - Expand your knowledge by seeing how other languages implement the same concepts. 78 | 79 | --- 80 | 81 | ## Need Inspiration? 82 | 83 | If you are unfamiliar with lambda calculus, check out these resources: 84 | - [Wikipedia: Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus) 85 | - [Church Booleans](https://en.wikipedia.org/wiki/Church_boolean) 86 | - [Church Numerals](https://en.wikipedia.org/wiki/Church_encoding#Church_numerals) 87 | - [A Tutorial Introduction to the Lambda Calculus](https://personal.utdallas.edu/~gupta/courses/apl/lambda.pdf) 88 | 89 | --- 90 | 91 | ## License 92 | 93 | This project is licensed under the [MIT License](LICENSE), so please feel free to fork, adapt, and share as you wish. 94 | 95 | --- 96 | 97 | ## Final Thoughts 98 | 99 | Thank you for checking out *Lambda Core*! We encourage you to join this challenge and contribute. The goal is to build a fun, educational resource that demonstrates the universality of lambda calculus across the diverse landscape of programming languages. 100 | 101 | *Happy Coding!* 102 | 103 | --- 104 | 105 | ## Bonus Challenge: Recursion with Combinators! 106 | 107 | Want to take your implementation to the next level? Here's a bonus challenge: 108 | 109 | - Implement recursion using a fixed-point combinator (Y, Z, or another variant) using your already made church numerals and logical operators. 110 | - Write a factorial, fibonacci, or some other classic recursive function using your combinator. 111 | - Include examples showing the recursive function in action. 112 | 113 | Note: In many languages, achieving recursion or advanced combinators in a pure lambda style can be extremely difficult or even impossible without writing or embedding a specialized lambda interpreter. 114 | -------------------------------------------------------------------------------- /languages/c/c/lambda-core.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct lambda; 8 | 9 | typedef struct lambda (*lambda_t)(struct lambda *, struct lambda); 10 | 11 | struct lambda { 12 | lambda_t fn; 13 | struct lambda *ctx; 14 | }; 15 | 16 | struct lambda lambda_call(struct lambda lambda, struct lambda arg) 17 | { 18 | return lambda.fn(lambda.ctx, arg); 19 | } 20 | 21 | struct lambda logic__true_(struct lambda *ctx, struct lambda _) 22 | { 23 | const struct lambda x = ctx[0]; 24 | return x; 25 | } 26 | 27 | struct lambda logic__true(struct lambda *_, struct lambda x) 28 | { 29 | struct lambda result = {logic__true_}; 30 | struct lambda *const ctx = malloc(sizeof(x)); 31 | ctx[0] = x; 32 | result.ctx = ctx; 33 | return result; 34 | } 35 | 36 | const struct lambda logic_true = {logic__true}; 37 | 38 | struct lambda logic__false_(struct lambda *_, struct lambda y) 39 | { 40 | return y; 41 | } 42 | 43 | struct lambda logic__false(struct lambda *_0, struct lambda _1) 44 | { 45 | const struct lambda result = {logic__false_}; 46 | return result; 47 | } 48 | 49 | const struct lambda logic_false = {logic__false}; 50 | 51 | struct lambda logic__not(struct lambda *_, struct lambda x) 52 | { 53 | return lambda_call(lambda_call(x, logic_false), logic_true); 54 | } 55 | 56 | const struct lambda logic_not = {logic__not}; 57 | 58 | struct lambda logic__and_(struct lambda *ctx, struct lambda y) 59 | { 60 | const struct lambda x = ctx[0]; 61 | return lambda_call(lambda_call(x, y), logic_false); 62 | } 63 | 64 | struct lambda logic__and(struct lambda *_, struct lambda x) 65 | { 66 | struct lambda result = {logic__and_}; 67 | struct lambda *const ctx = malloc(sizeof(x)); 68 | ctx[0] = x; 69 | result.ctx = ctx; 70 | return result; 71 | } 72 | 73 | const struct lambda logic_and = {logic__and}; 74 | 75 | struct lambda logic__or_(struct lambda *ctx, struct lambda y) 76 | { 77 | const struct lambda x = ctx[0]; 78 | return lambda_call(lambda_call(x, logic_true), y); 79 | } 80 | 81 | struct lambda logic__or(struct lambda *_, struct lambda x) 82 | { 83 | struct lambda result = {logic__or_}; 84 | struct lambda *const ctx = malloc(sizeof(x)); 85 | ctx[0] = x; 86 | result.ctx = ctx; 87 | return result; 88 | } 89 | 90 | const struct lambda logic_or = {logic__or}; 91 | 92 | bool logic_test_convert(struct lambda x) 93 | { 94 | const struct lambda arg0 = {(lambda_t) true}; 95 | const struct lambda arg1 = {(lambda_t) false}; 96 | return (uintptr_t) lambda_call(lambda_call(x, arg0), arg1).fn; 97 | } 98 | 99 | void logic_test_print(struct lambda x) 100 | { 101 | printf("%hhu\n", logic_test_convert(x)); 102 | } 103 | 104 | struct lambda church__zero_(struct lambda *_, struct lambda x) 105 | { 106 | return x; 107 | } 108 | 109 | struct lambda church__zero(struct lambda *_0, struct lambda _1) 110 | { 111 | const struct lambda result = {church__zero_}; 112 | return result; 113 | } 114 | 115 | const struct lambda church_zero = {church__zero}; 116 | 117 | struct lambda church__succ__(struct lambda *ctx, struct lambda x) 118 | { 119 | const struct lambda n = ctx[0]; 120 | const struct lambda f = ctx[1]; 121 | return lambda_call(f, lambda_call(lambda_call(n, f), x)); 122 | } 123 | 124 | struct lambda church__succ_(struct lambda *ctx, struct lambda f) 125 | { 126 | struct lambda result = {church__succ__}; 127 | struct lambda *const ctx_ = malloc(2 * sizeof(f)); 128 | ctx_[0] = ctx[0]; 129 | ctx_[1] = f; 130 | result.ctx = ctx_; 131 | return result; 132 | } 133 | 134 | struct lambda church__succ(struct lambda *_, struct lambda n) 135 | { 136 | struct lambda result = {church__succ_}; 137 | struct lambda *const ctx = malloc(sizeof(n)); 138 | ctx[0] = n; 139 | result.ctx = ctx; 140 | return result; 141 | } 142 | 143 | const struct lambda church_succ = {church__succ}; 144 | 145 | struct lambda church_one; 146 | 147 | struct lambda church__pred______(struct lambda *_, struct lambda a) 148 | { 149 | return a; 150 | } 151 | 152 | struct lambda church__pred_____(struct lambda *ctx, struct lambda _) 153 | { 154 | const struct lambda x = ctx[1]; 155 | return x; 156 | } 157 | 158 | struct lambda church__pred____(struct lambda *ctx, struct lambda h) 159 | { 160 | const struct lambda f = ctx[0]; 161 | const struct lambda g = ctx[1]; 162 | return lambda_call(h, lambda_call(g, f)); 163 | } 164 | 165 | struct lambda church__pred___(struct lambda *ctx, struct lambda g) 166 | { 167 | struct lambda result = {church__pred____}; 168 | struct lambda *const ctx_ = malloc(2 * sizeof(g)); 169 | ctx_[0] = ctx[0]; 170 | ctx_[1] = g; 171 | result.ctx = ctx_; 172 | return result; 173 | } 174 | 175 | struct lambda church__pred__(struct lambda *ctx, struct lambda x) 176 | { 177 | struct lambda arg0 = {church__pred___}; 178 | struct lambda arg1 = {church__pred_____}; 179 | struct lambda arg2 = {church__pred______}; 180 | struct lambda *const ctx_ = malloc(2 * sizeof(x)); 181 | const struct lambda n = ctx[0]; 182 | ctx_[0] = ctx[1]; 183 | ctx_[1] = x; 184 | arg0.ctx = ctx_; 185 | arg1.ctx = ctx_; 186 | arg2.ctx = ctx_; 187 | return lambda_call(lambda_call(lambda_call(n, arg0), arg1), arg2); 188 | } 189 | 190 | struct lambda church__pred_(struct lambda *ctx, struct lambda f) 191 | { 192 | struct lambda result = {church__pred__}; 193 | struct lambda *const ctx_ = malloc(2 * sizeof(f)); 194 | ctx_[0] = ctx[0]; 195 | ctx_[1] = f; 196 | result.ctx = ctx_; 197 | return result; 198 | } 199 | 200 | struct lambda church__pred(struct lambda *_, struct lambda n) 201 | { 202 | struct lambda result = {church__pred_}; 203 | struct lambda *const ctx = malloc(sizeof(n)); 204 | ctx[0] = n; 205 | result.ctx = ctx; 206 | return result; 207 | } 208 | 209 | const struct lambda church_pred = {church__pred}; 210 | 211 | struct lambda church_test__convert(struct lambda *_, struct lambda x) 212 | { 213 | struct lambda result; 214 | result.fn = (lambda_t) ((uintptr_t) x.fn + 1); 215 | return result; 216 | } 217 | 218 | unsigned int church_test_convert(struct lambda n) 219 | { 220 | const struct lambda arg0 = {church_test__convert}; 221 | const struct lambda arg1 = {(lambda_t) 0}; 222 | return (uintptr_t) lambda_call(lambda_call(n, arg0), arg1).fn; 223 | } 224 | 225 | void church_test_print(struct lambda n) 226 | { 227 | printf("%u\n", church_test_convert(n)); 228 | } 229 | 230 | int main() 231 | { 232 | church_one = lambda_call(church_succ, church_zero); 233 | 234 | assert(logic_test_convert(logic_true) == true); 235 | assert(logic_test_convert(logic_false) == false); 236 | assert(logic_test_convert(lambda_call(logic_not, logic_true)) == false); 237 | assert(logic_test_convert(lambda_call(logic_not, logic_false)) == true); 238 | assert(logic_test_convert(lambda_call(lambda_call(logic_and, logic_true), logic_true)) == true); 239 | assert(logic_test_convert(lambda_call(lambda_call(logic_and, logic_true), logic_false)) == false); 240 | assert(logic_test_convert(lambda_call(lambda_call(logic_and, logic_false), logic_true)) == false); 241 | assert(logic_test_convert(lambda_call(lambda_call(logic_and, logic_false), logic_false)) == false); 242 | assert(logic_test_convert(lambda_call(lambda_call(logic_or, logic_true), logic_true)) == true); 243 | assert(logic_test_convert(lambda_call(lambda_call(logic_or, logic_true), logic_false)) == true); 244 | assert(logic_test_convert(lambda_call(lambda_call(logic_or, logic_false), logic_true)) == true); 245 | assert(logic_test_convert(lambda_call(lambda_call(logic_and, logic_false), logic_false)) == false); 246 | logic_test_print(logic_true); 247 | 248 | assert(church_test_convert(church_zero) == 0); 249 | assert(church_test_convert(lambda_call(church_succ, church_zero)) == 1); 250 | assert(church_test_convert(lambda_call(church_succ, lambda_call(church_succ, church_zero))) == 2); 251 | assert(church_test_convert(lambda_call(church_pred, lambda_call(church_succ, church_one))) == 1); 252 | assert(church_test_convert(lambda_call(church_pred, lambda_call(church_succ, lambda_call(church_succ, church_one)))) == 2); 253 | church_test_print(church_one); 254 | 255 | return EXIT_SUCCESS; 256 | } 257 | --------------------------------------------------------------------------------