{"id":22823181,"url":"https://github.com/okeuday/effects","last_synced_at":"2025-03-30T23:42:42.364Z","repository":{"id":180863385,"uuid":"665823417","full_name":"okeuday/effects","owner":"okeuday","description":"An experimental C++ runtime effect system","archived":false,"fork":false,"pushed_at":"2024-04-20T05:50:01.000Z","size":26,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-06T05:16:32.644Z","etag":null,"topics":["effect-system","effects","referential-transparency"],"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/okeuday.png","metadata":{"files":{"readme":"README.markdown","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}},"created_at":"2023-07-13T04:55:27.000Z","updated_at":"2024-04-20T05:50:04.000Z","dependencies_parsed_at":"2023-12-05T23:26:44.619Z","dependency_job_id":"98b45a11-2b26-46a2-97f2-51c2242f7564","html_url":"https://github.com/okeuday/effects","commit_stats":null,"previous_names":["okeuday/effects"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okeuday%2Feffects","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okeuday%2Feffects/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okeuday%2Feffects/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/okeuday%2Feffects/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/okeuday","download_url":"https://codeload.github.com/okeuday/effects/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246395572,"owners_count":20770240,"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":["effect-system","effects","referential-transparency"],"created_at":"2024-12-12T16:14:41.478Z","updated_at":"2025-03-30T23:42:42.343Z","avatar_url":"https://github.com/okeuday.png","language":"C++","readme":"# effects: An experimental C++ runtime effect system\n\n`effects.hpp` provides a header-only library for tracking effects in C++ to\nfacilitate runtime checking of how impure source code currently is.\nRelying on `effects.hpp` for effect tracking helps to prevent source code\nfrom becoming worse in the future as it changes and it encourages source code\nto have more referentially transparent functions.\n\n## What is Referential Transparency?\n\n[Referential transparency](https://en.wikipedia.org/wiki/Referential_transparency)\nis often misunderstood and considered unimportant, though\nreferential transparency provides a clear benefit for ensuring source code\nis reliable, both in its current form and as it changes in the future.\nA function is referentially transparent if a function call with\nspecific arguments can always be substituted with its return value.\n\nWhen functions are referentially transparent, all testing can be limited to\nthe function inputs to ensure the function outputs are valid.\nIf functions are not referentially transparent, their testing will always\nrequire modifying global state in ways that are typically undefined\nand the source code will avoid being maintainable\n(causing both unstable execution as source code changes and\n increased labor costs when the source code is used).\nAll source code generally is unable to have all functions be\nreferentially transparent, due to necessary effects.\nThe goal of `effects.hpp` is to represent all possible effects in\nC++ to make their tracking simpler and easier to understand.\n\nOften IO operations are considered the main processing that prevents a\nfunction from being referentially transparent, but that is an\noversimplification that avoids tracking the types of effects that exist.\n\n## What is \"purity\"?\n\nWhen software developers use the term \"purity\" or \"pure function\"\nthey are describing the least effects common to their programming language.\nMathematical purity is referential transparency in all possible\nexecution environments (any hardware variation with any operating system).\nThe [Haskell](https://en.wikipedia.org/wiki/Haskell) programming language\nhas its purity (in source code outside of monads with lazy evaluation)\nas execution that can be nonterminating, contain (asynchronous) exceptions and\nhave variation due to the Operating System (OS) used or the hardware.used.\n\nA programming language may describe its purity as only relating to a\nsingle execution (in a single execution environment) and that can be\ncalled \"operational purity\" instead of mathematical purity.\nPure functions with operational purity could provide different return values\nwith the same function arguments if different execution environments are\ncompared (different Operating Systems and/or different hardware).\n\n## How is `effects.hpp` used?\n\nThe **effect kind** is the type of effect tracked as\n`effects::kind` bit field values stored with bitwise-OR:\n\n    pure                = 0x0000, // mathematical purity\n    nonterminating      = 0x0001, // execution may not terminate\n    exception           = 0x0002, // throw/(signal)/exit/abort\n    reference           = 0x0004, // reference to global data not owned\n    write               = 0x0008, // write to global (heap) data owned\n    fpe                 = 0x0010, // Floating-Point Exceptions (FPE)\n    variation_os        = 0x0020, // Operating System (OS) variation\n    variation_hardware  = 0x0040, // hardware variation\n\nTo track the effects inside a function or through multiple function calls,\nan `effects::context` object is created to track the use of allocated data.\nAn example from `tests.cpp` is provided below:\n\n    context c(kind::reference | kind::fpe, context_type::terminating);\n    region\u003cdouble\u003e value_rounded = c(2.0 / 3);\n\nThe `effects::context` constructor requires the effects that are considered\nvalid execution and whether execution will always terminate in a finite\namount of time.  The `effects::region` data is created for manipulating the\ndata while the `effects::context` object tracks the related effects during\nexecution.\n\nWhen the `effects::context` usage is complete, the valid function should be\nchecked with an assert function (that is not omitted with compilation options).\n\n    assert(c.valid());\n\n### Limitations\n\n* The `nonterminating` effect depends only on the `effects::context`\n  constructor parameter and whether the developer knows if timeouts\n  are finite and infinite loops are impossible.\n* The `exception` effect requires the developer identifies all usage of\n  throw to throw C++ exceptions, exit/abort function call paths, and\n  any way an unignored signal could be raised.  For each instance,\n  the developer should use the `effects::context` `set_exception` function.\n* The `effects::region\u003cT \u0026\u003e` type is assumed to be a reference to global data.\n* Using stdout, stderr, or other file descriptors is a `reference` effect\n  that could be created as a `effects::region\u003cT \u0026\u003e` type using a local variable\n  but requires the developer is aware of the file descriptors being used.\n* All `effects::region` non-null pointers are assumed to be allocated from\n  the heap (to create a `write` effect).\n* The `variation_os` and `variation_hardware` effects require that the\n  developer is aware of different execution in different environments.\n  For each instance, the developer should use the `effects::context`\n  `set_variation_os` and `set_variation_hardware` functions (respectively).\n\nWhile these limitations may look intimidating, the verification of effects\nis still helpful for ensuring source code is reliable.\n\nA programming language with a compile-time\n[effect system](https://en.wikipedia.org/wiki/Effect_system)\nconnected to the programming language's type system would help to avoid\ndeveloper mistakes and ensure enforcement.\n\n## Futher Information\n\n`effects.hpp` was partly inspired by \"Function Effect Tags\" in the\n[ATS2/Postiats programming language](https://en.wikipedia.org/wiki/ATS_(programming_language))\n(described [here](https://github.com/CloudI/CloudI/blob/ea7d2354951dfc5e26db96cbd019d7f3081e0fe4/src/api/ats/v2/cloudi.sats#L98)\nand [here](https://bluishcoder.co.nz/2010/06/13/functions-in-ats.html)).\n\n## Test\n\n    make\n\n## Author\n\nMichael Truog (mjtruog at protonmail dot com)\n\n## License\n\nMIT License\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokeuday%2Feffects","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fokeuday%2Feffects","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fokeuday%2Feffects/lists"}