{"id":16219759,"url":"https://github.com/neu-rah/lpp","last_synced_at":"2025-10-04T23:15:39.210Z","repository":{"id":70925878,"uuid":"202308359","full_name":"neu-rah/lpp","owner":"neu-rah","description":"\u003cλ++\u003e type-level lambda calculus for C++ meta-programming","archived":false,"fork":false,"pushed_at":"2022-07-27T14:22:15.000Z","size":73,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-07T23:44:52.365Z","etag":null,"topics":["compile-time","cpp-library","idiom","lambda-calculus","metaprograming","types"],"latest_commit_sha":null,"homepage":"","language":"C++","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/neu-rah.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-08-14T08:30:56.000Z","updated_at":"2023-03-02T01:47:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"3685da3a-d599-44c8-b5f3-e05aa4b6ca78","html_url":"https://github.com/neu-rah/lpp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/neu-rah/lpp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neu-rah%2Flpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neu-rah%2Flpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neu-rah%2Flpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neu-rah%2Flpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neu-rah","download_url":"https://codeload.github.com/neu-rah/lpp/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neu-rah%2Flpp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278386130,"owners_count":25978113,"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","status":"online","status_checked_at":"2025-10-04T02:00:05.491Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["compile-time","cpp-library","idiom","lambda-calculus","metaprograming","types"],"created_at":"2024-10-10T11:55:40.813Z","updated_at":"2025-10-04T23:15:39.193Z","avatar_url":"https://github.com/neu-rah.png","language":"C++","funding_links":["https://www.paypal.me/ruihfazevedo"],"categories":[],"sub_categories":[],"readme":"# \u003cλ++\u003e\n#### turing-complete idiom to express types in C++\n\n[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/ruihfazevedo)\n[![License: MIT](https://img.shields.io/github/license/neu-rah/lpp)](https://spdx.org/licenses/MIT.html)\n\u003c!-- [![Build Status](https://travis-ci.com/neu-rah/lpp.svg?branch=master)](https://travis-ci.org/neu-rah/lpp) --\u003e\n\n**see https://github.com/neu-rah/yolanda for a runtime/compile time alternative to this.**\n\nBased on lambda calculus, therefor using functional paradigm on top of modern C++ metaprogramming. Expressions on this idiom are metaprogramming and evaluate at compile time, yelding C++ types as a result.  \n\ninspired by the excellent videos of @glebec (https://youtu.be/3VQ382QG-y4) (thank you!)\n\n### Scope  \nThis idiom uses lambda calculus as its background on a close cope with c++ templates.\nIt only operates at compile time.  \nResults in β normal form translate to C++ types (native or user defined).  \nSo this expressions can only be used in replacement of C++ types.  \nA layer to provide `constexpr` values is available through dependent types.\nIt is therefor a turing-complete idiom to decide types at compile time.\nTypes have to be extracted after expression evaluation (::App) to yeld valid C++ types.\nUsing Lazyness, static immutable \"data\" (here expressed as c++ types) and partial application.\n\n## lambda base\n\nlambda calculus base [lambda core doc.](./LAMBDA.md)\n\n## lpp\n\nSyntatic sugar for \"lambda.h\"\n\n because `Head\u003cL2\u003e` looks much better that `Expr\u003cHead,L2\u003e::App`\n\n[LPP doc.](./LPP.md)\n\n## r-lambda\n\nRCurry (runtime curry)\nturns regular c++ functions into curry versions.\n\nA C++ function that accepts lets say 2 arguments `a` and `b`, and returns `c` is then turned into a function that accepts one argument `a` and return a second function that accepts `b` and returns `c` (considering the previous `a`).\n\n_curry is the only part implemented, and still testing. No lambda calculus yet_\n\n```c++\n#include \u003ciostream\u003e\nusing namespace std;\n\n#include \u003cr-lambda.h\u003e//runtime lambda core\nusing namespace rlambda;\n\ntemplate\u003ctypename I\u003e\ninline I _id(I i) {return i;}\ntemplate\u003ctypename I\u003e\nconstexpr auto id=RCurry\u003cdecltype(_id\u003cI\u003e),_id,I\u003e();\n\n//regular function with single param\nint _d(int x){return x\u003c\u003c1;}\nconstexpr auto d=RCurry\u003cdecltype(_d),_d,int\u003e();\n// constexpr auto d=typename decltype(fun(_d))::template curried\u003cdecltype(_d),_d\u003e;\n\n//regular function with multiple param\nint _m(int x,int y){return x*y;}\nconstexpr auto m=RCurry\u003cdecltype(_m),_m,int,int\u003e();\n\ntemplate\u003ctypename O\u003e constexpr auto _true=rK\u003cO\u003e;\n\ntemplate\u003ctypename O\u003e O __false(O,O o) {return o;}\ntemplate\u003ctypename O\u003e constexpr auto _false=RCurry\u003cdecltype(__false\u003cO\u003e),__false\u003cO\u003e,O,O\u003e();\n\nint main(int argc, char **argv) {\n  cout\u003c\u003c\"d(2):\"\u003c\u003cd(2)\u003c\u003cendl;\n  cout\u003c\u003c\"m(2)(3):\"\u003c\u003cm(2)(3)\u003c\u003cendl;\n  auto x=d(d);\n  cout\u003c\u003c\"x(2):\"\u003c\u003cx(2)\u003c\u003cendl;\n  cout\u003c\u003c\"id\u003cint\u003e(d)(1967:\"\u003c\u003cid\u003cint\u003e(d)(1967)\u003c\u003cendl;\n  cout\u003c\u003c\"m(d)(5)(3):\"\u003c\u003cm(d)(5)(3)\u003c\u003cendl;\n  cout\u003c\u003c\"d(m)(2)(3):\"\u003c\u003cd(m)(2)(3)\u003c\u003cendl;\n  cout\u003c\u003c\"m(5)(d)(3):\"\u003c\u003cm(5)(d)(3)\u003c\u003cendl;\n  cout\u003c\u003c\"d(m)(10)(2):\"\u003c\u003cd(m)(10)(2)\u003c\u003cendl;\n  cout\u003c\u003c\"d(m(10))(2):\"\u003c\u003cd(m(10))(2)\u003c\u003cendl;//same as above\n  cout\u003c\u003c\"d(m)(5)(m)(3)(2):\"\u003c\u003cd(m)(5)(m)(3)(2)\u003c\u003cendl;\n  cout\u003c\u003c_true\u003cconst char*\u003e(\"Ok\")(\"Fail\")\u003c\u003cendl;\n  cout\u003c\u003c_false\u003cconst char*\u003e(\"Fail\")(\"Ok\")\u003c\u003cendl;\n  return 0;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneu-rah%2Flpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneu-rah%2Flpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneu-rah%2Flpp/lists"}