{"id":14966138,"url":"https://github.com/sjsyrek/malc","last_synced_at":"2025-10-25T13:31:16.613Z","repository":{"id":83075008,"uuid":"89251024","full_name":"sjsyrek/malc","owner":"sjsyrek","description":"Make a lambda calculus.","archived":false,"fork":false,"pushed_at":"2020-11-01T11:35:17.000Z","size":69,"stargazers_count":86,"open_issues_count":1,"forks_count":11,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-31T07:21:45.338Z","etag":null,"topics":["elixir","functional-programming","haskell","javascript","lambda-calculus","lambda-expressions","lambda-functions","perl6","python","ruby"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sjsyrek.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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":"2017-04-24T14:34:33.000Z","updated_at":"2024-08-30T21:33:00.000Z","dependencies_parsed_at":"2023-03-17T03:16:49.887Z","dependency_job_id":null,"html_url":"https://github.com/sjsyrek/malc","commit_stats":{"total_commits":71,"total_committers":3,"mean_commits":"23.666666666666668","dds":0.05633802816901412,"last_synced_commit":"b31605b568bf93388a554fcdfad4084e95274ba7"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjsyrek%2Fmalc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjsyrek%2Fmalc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjsyrek%2Fmalc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sjsyrek%2Fmalc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sjsyrek","download_url":"https://codeload.github.com/sjsyrek/malc/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238147594,"owners_count":19424291,"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":["elixir","functional-programming","haskell","javascript","lambda-calculus","lambda-expressions","lambda-functions","perl6","python","ruby"],"created_at":"2024-09-24T13:35:52.732Z","updated_at":"2025-10-25T13:31:16.246Z","avatar_url":"https://github.com/sjsyrek.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# malc - Make a Lambda Calculus\n\n## About\n\nMalc is a guide and specification for implementing an untyped [lambda calculus](https://en.wikipedia.org/wiki/Lambda_calculus) in any programming language that supports [higher-order functions](https://en.wikipedia.org/wiki/Higher-order_function). The lambda calculus has sometimes been called the world's smallest programming language. It is a notation that consists entirely of functions and applications of functions. Even \"primitive values\" are represented as combinators, i.e. closures without global variables. As the foundation of functional programming, the untyped lambda calculus is simple to learn and worth learning about if you really want to understand the fundamentals of this programming paradigm. \n\nThis project offers some insight into the notion of \"functions as values\" by demonstrating how you can implement the lambda calculus, and thereby a means to use functions alone to compute (in principle) anything that is computable, in a number of familiar programming languages. If you study a few of them, you will realize that functional programming is a universal means of computation and is not determined by the syntax or constraints of any one language. It works the same way no matter the syntax used to represent it.\n\nThe implementations included in this project define, at the least: boolean values, natural numbers, branching, and recursion. From these fundamental elements, any other computation can theoretically be modeled—though not all compilers or interpreters will be able to execute it, which is why this is strictly an educational enterprise. More ambitious implementations may translate a sizable portion of the [Haskell Prelude](https://www.stackage.org/haddock/lts-8.23/base-4.9.1.0/Prelude.html), since Haskell is essentially a lambda calculus with a type system and some syntactic sugar.\n\nContributions that generally follow the specification below, as well as clever or more ambitious extensions of it in the spirit of this project, are welcome.\n\nInspired by the [Make a Lisp](https://github.com/kanaka/mal) project.\n\n## Implementations\n\n* [JavaScript ES2015](https://github.com/sjsyrek/malc/tree/master/javascript)\n* [Perl 6](https://github.com/sjsyrek/malc/tree/master/perl6)\n* [Python 3](https://github.com/sjsyrek/malc/tree/master/python)\n* [Ruby](https://github.com/sjsyrek/malc/tree/master/ruby)\n\n## Specification\n\nThis is only a partial list of functions that each implementation could provide. For other examples, read the code.\n\n```\nID = λx. x\n```\n\nIdentity combinator. Returns `x`.\n\n***\n\n```\nTRUE = λx. λy. x\n\nFALSE = λx. λy. y\n```\n\nBoolean true and false.\n\n***\n\n```\nAND = λx. λy. x y FALSE\n\nOR = λx. λy. x TRUE y\n\nNOT = λx. x FALSE TRUE\n\nXOR = λx. λy. x (NOT y) y\n```\n\nBoolean combinators.\n\n***\n\n```\nIF_THEN_ELSE = λp. λx. λy. p x y\n```\n\nConditional branching. Note that `IF_THEN_ELSE` is identical in value to `ID`.\n\n***\n\n```\nZERO = λf. λx. x\n\nONE = λf. λx. f x\n\nTWO = λf. λx. f(f(x))\n\nTHREE = λf. λx. f(f(f(x)))\n```\n\nNatural numbers.\n\n***\n\n```\nSUCC = λn. λf. λx. f(n f x)\n```\n\nGiven a number, return the following number.\n\n***\n\n```\nPRED = λn. n(λp. λz. z(SUCC(p TRUE))(p TRUE))(λz. z ZERO ZERO) FALSE\n```\n\nGiven a number, return the preceding number down to `ZERO`.\n\n***\n\n```\nPLUS = λn. λm. m SUCC n\n```\n\nAdd two numbers.\n\n***\n\n```\nMINUS = λn. λm. m PRED n\n```\n\nSubtract one number from another, down to `ZERO`.\n\n***\n\n```\nMULT = λn. λm. m(PLUS n) ZERO\n```\n\nMultiply two numbers.\n\n***\n\n```\nEXP = λn. λm. m n\n```\n\nExponentiation. Returns n^m.\n\n***\n\n```\nIS_ZERO = λn. n(λm. FALSE) TRUE\n```\n\nCheck whether a number is equal to `ZERO`.\n\n***\n\n```\nLESS_THAN_OR_EQUAL = λn. λm. IS_ZERO(MINUS n m)\n\nLESS_THAN = λn. λm. AND(LESS_THAN_OR_EQUAL n m)(NOT IS_ZERO(n(PRED m)))\n\nEQUALS = λn. λm. AND(LESS_THAN_OR_EQUAL n m)(LESS_THAN_OR_EQUAL m n)\n\nGREATER_THAN_OR_EQUAL = λn. λm. IS_ZERO(n(PRED m))\n\nGREATER_THAN = λn. λm. AND(GREATER_THAN_OR_EQUAL n m)(NOT(IS_ZERO(MINUS n m)))\n```\n\nGeneral predicates for comparing the ordering of numbers.\n\n***\n\n```\nCOMPOSE = λf. λg. λx. f(g x)\n```\n\nFunction composition.\n\n***\n\n```\nFIX = λy. (λx. y(x x))(λx. y(x x))\n```\n\nThe fixpoint \"Z\" combinator, for defining recursive functions in strict languages.\n\n***\n\n```\nPAIR = λx. λy. λp. p x y\n```\n\nCreate a pair (2-tuple) out of two numbers.\n\n***\n\n```\nFIRST = λp. p(λx. λy. x)\n\nSECOND = λp. p(λx. λy. y)\n```\n\nFirst and second projections on a pair. Return the first or second value, respectively.\n\n***\n\n```\nLIST_ELEMENT = λx. λxs. PAIR FALSE (PAIR x xs)\n```\n\nPrepend an element `x` onto the front of a list `xs`. Use `EMPTY_LIST` for `xs` when creating a new list.\n\n***\n\n```\nEMPTY_LIST = PAIR TRUE TRUE\n```\n\nThe empty list.\n\n***\n\n```\nIS_EMPTY = FIRST\n```\n\nCheck whether a list is `EMPTY_LIST`.\n\n***\n\n```\nHEAD = λxs. FIRST (SECOND xs)\n```\n\nReturn the first element of a list.\n\n***\n\n```\nTAIL = λxs. SECOND(SECOND xs)\n```\n\nReturn the rest of a list after and not including the first element.\n\n***\n\n```\nFACT = FIX(λr. λn. IS_ZERO n ONE)(λx. MULT n (r(PRED n)) x)\n```\n\nReturn the factorial of `n`.\n\n***\n\n```\nFIB = FIX(λr. λn. IS_ZERO n ZERO(IF_THEN_ELSE(EQUALS n ONE)(λx. PLUS(r(MINUS n ONE))(r(MINUS n TWO)) x)))\n```\n\nReturn the `n`th Fibonacci number after `ZERO`.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsjsyrek%2Fmalc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsjsyrek%2Fmalc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsjsyrek%2Fmalc/lists"}