{"id":18938306,"url":"https://github.com/faiface/par-lang","last_synced_at":"2025-04-06T05:15:27.826Z","repository":{"id":261517220,"uuid":"884541769","full_name":"faiface/par-lang","owner":"faiface","description":"Par (⅋) is an experimental concurrent programming language. It's an attempt to bring the expressive power of linear logic into practice.","archived":false,"fork":false,"pushed_at":"2025-04-05T21:40:39.000Z","size":6411,"stargazers_count":155,"open_issues_count":8,"forks_count":9,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-05T22:17:58.153Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","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/faiface.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["faiface"]}},"created_at":"2024-11-07T00:04:04.000Z","updated_at":"2025-04-05T19:55:02.000Z","dependencies_parsed_at":"2024-11-07T01:19:47.009Z","dependency_job_id":"afdd8fba-d7f4-4b3e-8b54-11d640c451d3","html_url":"https://github.com/faiface/par-lang","commit_stats":null,"previous_names":["faiface/par-lang"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fpar-lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fpar-lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fpar-lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/faiface%2Fpar-lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/faiface","download_url":"https://codeload.github.com/faiface/par-lang/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247436284,"owners_count":20938533,"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":[],"created_at":"2024-11-08T12:14:02.167Z","updated_at":"2025-04-06T05:15:27.713Z","avatar_url":"https://github.com/faiface.png","language":"Rust","funding_links":["https://github.com/sponsors/faiface"],"categories":["Rust"],"sub_categories":[],"readme":"# **Par** is an _expressive, concurrent, total*_ language\n## ...with linear types and duality\n\n- 💬 **Join our [Discord](https://discord.gg/8KsypefW99),** or use the\n  [Discussions](https://github.com/faiface/par-lang/discussions) as a forum to ask questions and share ideas!\n\n- 🫶 If you'd like to support my effort to bring the power of linear logic into practical programming, you can do\n  it via [GitHub Sponsors](https://github.com/sponsors/faiface).\n\n- 🦀 If you like this **concurrent paradigm,** and want to use it **in a real programming language,** check out\n  my Rust crate with the same name: **[Par](https://github.com/faiface/par).** It's a full implementation\n  of **session types,** including non-deterministic handling of many clients.\n\n![Screenshot](screenshots/rock_paper_scissors.png)\n\n## 🚀 Get started with the [Language Reference](https://faiface.github.io/par-lang/introduction.html)\n\nIt contains **a full guide** of the language and its type system.\n\n**A live-stream tutorial** on a slightly out-dated version of Par is also up on [YouTube.](https://youtu.be/UX-p1bq-hkU?si=cHD4bzFIHjAiGg81)\n\n**To run the playground:**\n\n1. Install [Rust and Cargo](https://rustup.rs).\n2. `git clone https://github.com/faiface/par-lang.git`\n3. `cd par-lang`\n4. `cargo run`\n\n## 💡 [Examples](examples/)\n\nOpen an example in the interactive playground, and **play with any function.**\n\n# ✨ Features\n\n## 🧩 Expressive\n\n**Duality** gives two sides to every concept, leading to rich composability. Whichever angle you take to\ntackle a problem, there will likely be ways to express it.\n**Par comes with these first-class, structural types:**\n\n_(Dual types are on the same line.)_\n\n- [**Pairs**](https://faiface.github.io/par-lang/types.html#pair-types) (easily extensible to tuples), and [**functions**](https://faiface.github.io/par-lang/types.html#function-types) (naturally curried).\n- [**Eithers**](https://faiface.github.io/par-lang/types.html#either-types) (sum types), and [**choices**](https://faiface.github.io/par-lang/types.html#choice-types) (unusual, but powerful dispatchers).\n- [**Recursive**](https://faiface.github.io/par-lang/types.html#recursive-types) (finite), and [**iterative**](https://faiface.github.io/par-lang/types.html#iterative-types) (co-recursive, potentially infinite) types, with totality checking.\n- [**Universally,**](https://faiface.github.io/par-lang/types.html#universal-types) and [**existentially**](https://faiface.github.io/par-lang/types.html#existential-types) quantified generic functions and values.\n- [**Unit,**](https://faiface.github.io/par-lang/types.html#the-unit-type) and [**continuation.**](https://faiface.github.io/par-lang/types.html#the-bottom-type)\n\nThese **orthogonal concepts** combine to give rise to a rich world of types and semantics.\n\nSome features that require special syntax in other languages fall naturally out of the basic building\nblocks above. For example, constructing a list using the _generator syntax_, like `yield` in Python,\nis possible by operating on the _dual_ of a list:\n\n```\ndec reverse : [type T] [List\u003cT\u003e] List\u003cT\u003e\n\n// We construct the reversed list by destructing its dual: `chan List\u003cT\u003e`.\ndef reverse = [type T] [list] chan yield {\n  let yield: chan List\u003cT\u003e = list begin {\n    .empty!       =\u003e yield,          // The list is empty, give back the generator handle.\n    .item(x) rest =\u003e do {            // The list starts with an item `x`.\n      let yield = rest loop          // Traverse into the rest of the list first.\n      yield.item(x)                  // After that, produce `x` on the reversed list.\n    } in yield                       // Finally, give back the generator handle.\n  }\n  yield.empty!                       // At the very end, signal the end of the list.\n}\n```\n\n## 🔗 Concurrent\n\n**Automatically parallel execution.** Everything that can run in parallel, runs in parallel. Thanks to its\nsemantics based on linear logic, Par programs are easily executed in parallel. Sequential execution is only\nenforced by data dependencies.\n\nPar even compiles to [interaction combinators](https://core.ac.uk/download/pdf/81113716.pdf), which is the\nbasis for the famous [HVM](https://github.com/HigherOrderCO/HVM), and the\n[Bend](https://github.com/HigherOrderCO/Bend) programming language.\n\n**Structured concurrency with session types.** Session types describe concurrent protocols, almost like\nfinite-state machines, and make sure these are upheld in code. Par needs no special library for these.\nLinear types _are_ session types, at least in their full version, which embraces duality.\n\nThis (session) type fully describes the behavior of a player of rock-paper-scissors:\n\n```\ntype Player = iterative :game {\n  .stop =\u003e !                         // Games are over.\n  .play_round =\u003e iterative :round {  // Start a new round.\n    .stop_round =\u003e self :game,       // End current round prematurely.\n    .play_move =\u003e (Move) {           // Pick your next move.\n      .win  =\u003e self :game,           // You won! The round is over.\n      .lose =\u003e self :game,           // You lost! The round is over.\n      .draw =\u003e self :round,          // It's a draw. The round goes on.\n    }\n  }\n}\n```\n\n## 🛡️ Total*\n\n**No crashes.** Runtime exceptions are not supported, except for running out of memory.\n\n**No deadlocks.** Structured concurrency of Par makes deadlocks impossible.\n\n**(Almost) no infinite loops.\\*** By default, recursion using `begin`/`loop` is checked for well-foundedness.\n\n**Iterative (corecursive) types** are distinguished from **recursive types**, and enable constructing\npotentially unbounded objects, such as infinite sequences, with no danger of infinite loops, or a need\nto opt-out of totality.\n\n```\n// An iterative type. Constructed by `begin`/`loop`, and destructed step-by-step.\ntype Stream\u003cT\u003e = iterative {\n  .close =\u003e !                        // Close this stream, and destroy its internal resources.\n  .next =\u003e (T) self                  // Produce an item, then ask me what I want next.\n}\n\n// An infinite sequence of `.true!` values.\ndef forever_true: Stream\u003ceither { .true!, .false! }\u003e = begin {\n  .close =\u003e !                        // No resources to destroy, we just end.\n  .next =\u003e (.true!) loop             // We produce a `.true!`, and repeat the protocol.\n}\n```\n\n_\\*There is an escape hatch. Some algorithms, especially divide-and-conquer, are difficult or impossible\nto implement using easy-to-check well-founded strategies. For those, `unfounded begin` turns this check\noff. Vast majority of code doesn't need to opt-out of totality checking, it naturaly fits its requirements.\nThose few parts that need to opt-out are clearly marked with `unfounded`. They are the only places\nthat can potentially cause infinite loops._\n\n## 📚 Theoretical background\n\nPar is fully based on [linear logic](https://plato.stanford.edu/entries/logic-linear/). It's an attempt to\nbring its expressive power into practice, by interpreting linear logic as _session types_.\n\nIn fact, the language itself is based on a little process language, called _CP_, from a paper called\n[_\"Propositions as Sessions\"_](https://www.pure.ed.ac.uk/ws/portalfiles/portal/18383989/Wadler_2012_Propositions_as_Sessions.pdf)\nby the famous Phil Wadler.\n\nWhile programming in Par feels just like a programming language, even if an unusual one, its programs\nstill correspond one-to-one with linear logic proofs.\n\n## 📝 To Do\n\n**Par is a fresh project in early stages of development.** While the foundations, including some apparently\nadvanced features, are designed and implemented, some basic features are still missing.\n\n**Basic missing features:**\n\n- Strings and numbers\n- Replicable data types (automatically copied and dropped)\n- External I/O implementation\n\nThere are also some **advanced missing features:**\n\n- Non-determinism\n- Traits / type classes\n\n# 🤝 Come help us!\n\nThere's still so much to be done! If this project speaks to you, join us on\n[Discord](https://discord.gg/8KsypefW99).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaiface%2Fpar-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffaiface%2Fpar-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffaiface%2Fpar-lang/lists"}