{"id":20761845,"url":"https://github.com/james-p-d/lambda","last_synced_at":"2025-03-11T17:21:38.647Z","repository":{"id":170717078,"uuid":"197442518","full_name":"James-P-D/Lambda","owner":"James-P-D","description":"A simple Lambda expression interpreter in Java","archived":false,"fork":false,"pushed_at":"2023-05-29T17:19:07.000Z","size":5136,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-18T05:32:25.753Z","etag":null,"topics":["beta-reduction","console","console-application","functional-programming","java","lambda-calculus","lambda-expressions","repl"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/James-P-D.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-17T18:30:31.000Z","updated_at":"2023-05-29T17:05:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"a80b514c-25f9-4278-94b2-7e6fd0d988d8","html_url":"https://github.com/James-P-D/Lambda","commit_stats":null,"previous_names":["james-p-d/lambda"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/James-P-D%2FLambda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/James-P-D%2FLambda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/James-P-D%2FLambda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/James-P-D%2FLambda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/James-P-D","download_url":"https://codeload.github.com/James-P-D/Lambda/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243076637,"owners_count":20232445,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["beta-reduction","console","console-application","functional-programming","java","lambda-calculus","lambda-expressions","repl"],"created_at":"2024-11-17T10:26:46.923Z","updated_at":"2025-03-11T17:21:38.624Z","avatar_url":"https://github.com/James-P-D.png","language":"Java","readme":"# Lambda\nA simple [Lambda Calculus](https://en.wikipedia.org/wiki/Lambda_calculus) expression interpreter in Java\n\n![Screenshot](https://github.com/James-P-D/Lambda/blob/master/Screenshot.gif)\n\n## Contents\n\n1. [Lambda Calculus](#Lambda-Calculus)\n    1. [History](#History)\n    2. [Beta Reduction](#Beta-Reduction)\n    3. [Alpha Equivalence](#Alpha-Equivalence)\n2. [The Application](#The-Application)\n    1. [Help](#Help)\n    3. [Loading Files](#Loading-Files)    \n    4. [Debug Mode](#Debug-Mode)\n    5. [Alpha Mode](#Alpha-Mode)\n    6. [Quitting](#Quitting)\n    7. [Library Files](#Library-Files)\n    8. [Examples](#Examples)\n3. [Building Notes and Problems](#Building-Notes-and-Problems)\n4. [Acknowledgements](#Acknowledgements)\n    \n## Lambda Calculus\n\nIf you already understand the Lambda Calculus, you can skip this section and head straight to [The Application](#The-Application).  \n\n```\n\u003cexpression\u003e  = \u003cname\u003e | \u003cfunction\u003e | \u003capplication\u003e\n\u003cfunction\u003e    = λ\u003cname\u003e.\u003cexpression\u003e\n\u003capplication\u003e = \u003cexpression\u003e \u003cexpression\u003e\n```\n\n### History\n\n### Beta Reduction\n\n### Alpha Equivalence\n\n## The Application\n\nAfter running the application you will be presented with a short introductory message followed by the prompt into which you can enter lambda expressions or terms:\n\n```\nλ-CALCULUS: Type 'help' for more information\nλ\u003e\n```\n\nWe can enter lambda expressions at the `λ\u003e` prompt, which the application will attempt to beta-reduce:\n\n```\nλ-CALCULUS: Type 'help' for more information\nλ\u003e λx.x\nβ\u003e λx.x\n```\n\nIn the above we entered the expression `λx.x` which cannot be reduced so we see the `β\u003e` prompt followed by our initial expression.\n\nWe can also create terms and then apply them:\n\n```\nλ\u003e id=λx.x\nβ\u003e id = λx.x\nλ\u003e id y\nβ\u003e y\n```\n\nIn the above we create a term called `id` and then apply the symbol `y` to it, which gives `y`.\n\n### Help\n\nIf you enter `help` you will receive the following information:\n\n```\nλ\u003e help\nHELP: Help information\nHELP: Commands: help            - this screen\nHELP:           terms           - display all known terms\nHELP:           debug           - toggle debug mode\nHELP:           load \u003cfilename\u003e - loads file\nHELP:           alpha           - alpha-equivalence\n```\n\n### Loading Files\n\nIt is possible to load files which contain terms or expressions by using the `load` command. For example, the application comes with a [booleans.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/booleans.lbd) file which contains the following:\n\n```\n# True and false values\ntrue = \\x.\\y.x\nfalse = \\x.\\y.y\n\n# Bunch of normal operators for booleans\nand = \\a.\\b.a b a\nor = \\a.\\b.a a b\nnot = \\a.a false true\nxor = \\x.\\y. x (not y) y\n```\n\nIn the above file we have used the `\\` symbol for `λ` character. Either one is fine, just make that if you are consistent and if using greek letters, that you save the file as UTF-8.\n\nAlso note that any line beginning with a `#` symbol will be treated as a comment and ignored.\n\nWe can load the file easily enough:\n\n```\nλ\u003e load booleans.lbd\nLOADING FILE: booleans.lbd\nLOADING FILE: booleans.lbd - 6 term(s) and 0 expression(s) parsed\n```\n\nHaving loaded the file, we can now perform boolean expressions\n\n```\nλ\u003e not true\nβ\u003e false\nλ\u003e or false true\nβ\u003e true\n```\n\nSome files may require terms which exist in *other* files. In these cases we can start the file with a `$` symbol followed by the names of other files we need to include.\n\nFor example [maths.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/maths.lbd) file contains the following:\n\n```\n$ booleans.lbd\n\nzero  = \\f.\\a.a\none   = \\f.\\a.f a\ntwo   = \\f.\\a.f (f a)\nthree = \\f.\\a.f (f (f a))\nfour  = \\f.\\a.f (f (f (f a)))\nfive  = \\f.\\a.f (f (f (f (f a))))\nsix   = \\f.\\a.f (f (f (f (f (f a)))))\nseven = \\f.\\a.f (f (f (f (f (f (f a))))))\neight = \\f.\\a.f (f (f (f (f (f (f (f a)))))))\nnine  = \\f.\\a.f (f (f (f (f (f (f (f (f a))))))))\nten   = \\f.\\a.f (f (f (f (f (f (f (f (f (f a)))))))))\n\nsucc = \\n.\\f.\\a.f (n f a)\nadd = \\m.\\n.\\f.\\a.m f (n f a)\nmult = \\m.\\n.\\f.m (n f)\npow = \\m.\\n.n m\npred = \\n.\\f.\\a.n (\\g.\\h.h (g f)) (\\u.a) (\\u.u)\nsub = \\m.\\n.n pred m\nis_zero = \\n.n (\\m.false) true\n```\n\nWhen we attempt to load the file we will see the following:\n\n```\nλ\u003e load maths.lbd\nLOADING FILE: maths.lbd\nLOADING FILE: booleans.lbd\nLOADING FILE: booleans.lbd - 6 term(s) and 0 expression(s) parsed\nLOADING FILE: maths.lbd - 18 term(s) and 0 expression(s) parsed\n```\n\nAs soon as we start loading the terms in `maths.lbd`, the application finds the line `$ booleans.lbd` and knows it needs to import the terms from that file otherwise there would be errors when we encounter terms like `true` and `false` which are used in `maths.lbd`.\n\nFinally, it is also possible to load files on startup by passing filenames as parameters to the .class file. For more information on building the project, see the [Building Notes and Problems](#Building-Notes-and-Problems) section.\n\n### Debug Mode\n\nYou can enter `debug` to toggle debug-mode:\n\n```\nλ\u003e debug\nDEBUG: Debug mode ON\nλ\u003e debug\nDEBUG: Debug mode OFF\n```\n\nDebug-mode can be useful for showing the intermediate steps during beta-reduction. Below is the result of beta-reducing `or false true` with debug-mode turned on:\n\n```\nλ\u003e debug\nDEBUG: Debug mode ON\nλ\u003e or false true\nβ\u003e ((λa.λb.(a(λx.λy.x))b)(λx.λy.y))(λx.λy.x)\nβ\u003e (λb.((λx.λy.y)(λx.λy.x))b)(λx.λy.x)\nβ\u003e ((λx.λy.y)(λx.λy.x))(λx.λy.x)\nβ\u003e (λy.y)(λx.λy.x)\nβ\u003e λx.λy.x\nβ\u003e true\n```\n\n### Alpha Mode\n\nYou can enter `alpha` to switch into alpha-equivalence mode. Simply enter a number of expressions, each on a separate line and then a blank line:\n\n```\nλ\u003e alpha\nα-EQUIVALENCE: Enter a number of expressions, each on a separate line, and then an empty line to begin comparison\nα1\u003e λa.b a\nα2\u003e λc.d c\nα3\u003e λb.a b\nα4\u003e\nα\u003e TRUE\n```\n\nIn the above example we see `TRUE` reported because `λa.b a`, `λc.d c` and `λb.a b` are all equivalent to each other.\n\nHowever, consider the following example:\n\n```\nλ\u003e alpha\nα-EQUIVALENCE: Enter a number of expressions, each on a separate line, and then an empty line to begin comparison\nα1\u003e λa.b a\nα2\u003e λc.d c\nα3\u003e λb.a a\nα4\u003e\nα\u003e FALSE\n```\n\nThis the above output, we see the result `FALSE`. This is because although `λa.b a` and `λc.d c` are equivalent, `λb.a a` is *not* equivalent to either of them.\n\n### Quitting\n\nFinally, you can terminate the program by entering `quit`, `exit` or pressing the \u003ckbd\u003eESC\u003c/kbd\u003e key.\n\n```\nλ\u003e quit\nQUITTING: Bye!\n```\n\n### Library Files\n\nAs already mentioned, the application comes with a number of library files which contain definitions for boolean operators, maths, conditionals, etc:\n\n* [booleans.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/booleans.lbd) - True, false, and, or, etc.\n* [maths.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/maths.lbd) - Numbers 1-10, add, subtract, etc.\n* [tuples.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/tuples.lbd) - Pairs of values.\n* [conditionals.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/conditionals.lbd) - If..then..else, equality, greater-than-or-equal, etc.\n* [lists.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/lists.lbd) - Head, tail, etc.\n* [functions.lbd](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/functions.lbd) - Recursion, etc.\n\n### Examples\n\nNow that we have a full understanding of Lambda-Calculus and of how the application works, we can start writing some programs.\n\nAfter loading `booleans.lbd` we can perform `and`, `or` and `not` operations:\n\n```\nλ\u003e load booleans.lbd\nλ\u003e not true\nβ\u003e false\nλ\u003e and true false\nβ\u003e false\nλ\u003e or true false\nβ\u003e true\n```\n\nAfter loading `maths.lbd` we can perform basic mathematical operations:\n\n```\nλ\u003e load maths.lbd\nλ\u003e add one two\nβ\u003e three\nλ\u003e mult two two\nβ\u003e four\nλ\u003e succ one\nβ\u003e two\nλ\u003e succ (succ one)\nβ\u003e three\n```\n\nNote that because `maths.lbd` only contains term definitions for the first ten numbers, mathematical operations which return larger numbers will be displayed in lambda-syntax:\n\n```\nλ\u003e load maths.lbd\nλ\u003e add nine nine\nβ\u003e λf.λa.f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f a)))))))))))))))))\n```\n\nAfter loading `tuples.lbd` we can create pairs of values:\n\n```\nλ\u003e load maths.lbd\nλ\u003e load tuples.lbd\nλ\u003e first (pair one two)\nβ\u003e one\nλ\u003e second (pair one two)\nβ\u003e two\n```\n\nWe can even have pairs of pairs:\n\n```\nλ\u003e second (pair one (pair two three))\nβ\u003e λf.(f(λf.λa.f(f a)))(λf.λa.f(f(f a)))\n```\n\nThe application is unable to resolve multiple-terms, but if we check what the expected answer (`pair two three`) is in lambda-syntax, we can see that the lambda sequences matches:\n\n```\nλ\u003e pair two three\nβ\u003e λf.(f(λf.λa.f(f a)))(λf.λa.f(f(f a)))\n```\n\nAfter loading `conditionals.lbd` we can check for equality with `if_then_else`:\n\n```\nλ\u003e if_then_else true one two\nβ\u003e one\nλ\u003e if_then_else false one two\nβ\u003e two\n```\n\n### Building Notes and Problems\n\nThe building instructions can be found [runlambda.bat](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/runlambda.bat) and are also included below:\n\n```\nUPDATE HERE\nUPDATE HERE\nUPDATE HERE\nUPDATE HERE\nUPDATE HERE\nUPDATE HERE\n```\n\nA fair amount of work went into getting the console I/O to work and display nicely. Since Java is fussy about supporting single-keypress-input, displaying Unicode characters (`λ`, `α`, `β` etc.) and using colours, we need to use a bunch of Windows-specific stuff to achieve this. If you are struggling with inputting strings, or are seeing strange, non-printable values in the console, simply set `FANCY_UI` to `false` in [Console.Java](https://github.com/James-P-D/Lambda/blob/master/src/Lambda/src/Lambda/Console.java).\n\n### Acknowledgements\n\nThe application uses [RawConsoleInput](https://www.source-code.biz/snippets/java/RawConsoleInput/) courtesy of [Christian d'Heureuse](https://stackoverflow.com/questions/1066318/how-to-read-a-single-char-from-the-console-in-java-as-the-user-types-it/30008252#30008252) for the single-character-input, and [Yin Shan's](https://stackoverflow.com/a/8921509/930389) code for displaying of Greek symbols.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjames-p-d%2Flambda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjames-p-d%2Flambda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjames-p-d%2Flambda/lists"}