{"id":48824686,"url":"https://github.com/hyperpolymath/affinescript","last_synced_at":"2026-04-14T17:31:39.984Z","repository":{"id":346571863,"uuid":"1187651353","full_name":"hyperpolymath/affinescript","owner":"hyperpolymath","description":"AffineScript — affine type system programming language","archived":false,"fork":false,"pushed_at":"2026-04-10T22:33:49.000Z","size":1049,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-10T23:20:23.428Z","etag":null,"topics":["hyperpolymath","palimpsest"],"latest_commit_sha":null,"homepage":null,"language":"OCaml","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/hyperpolymath.png","metadata":{"files":{"readme":"README.adoc","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY-SETUP.md","support":null,"governance":"docs/governance/CODE_OF_CONDUCT.md","roadmap":"ROADMAP.adoc","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"hyperpolymath","ko_fi":"hyperpolymath","liberapay":"hyperpolymath"}},"created_at":"2026-03-21T01:23:33.000Z","updated_at":"2026-04-10T22:33:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hyperpolymath/affinescript","commit_stats":null,"previous_names":["hyperpolymath/affinescript"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hyperpolymath/affinescript","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperpolymath%2Faffinescript","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperpolymath%2Faffinescript/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperpolymath%2Faffinescript/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperpolymath%2Faffinescript/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hyperpolymath","download_url":"https://codeload.github.com/hyperpolymath/affinescript/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hyperpolymath%2Faffinescript/sbom","scorecard":{"id":1245239,"data":{"date":"2026-03-24T20:03:17Z","repo":{"name":"github.com/hyperpolymath/affinescript","commit":"467004430f772486816f585a1d53548d08e4f5cb"},"scorecard":{"version":"v5.3.0","commit":"c22063e786c11f9dd714d777a687ff7c4599b600"},"score":6,"checks":[{"name":"Maintained","score":0,"reason":"project was created within the last 90 days. Please review its contents carefully","details":["Warn: Repository was created within the last 90 days."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/7 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#code-review"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dependency-update-tool"}},{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#security-policy"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:18","Info: jobLevel 'contents' permission set to 'read': .github/workflows/guix-nix-policy.yml:11","Info: jobLevel 'contents' permission set to 'read': .github/workflows/npm-bun-blocker.yml:11","Info: jobLevel 'contents' permission set to 'read': .github/workflows/quality.yml:44","Info: jobLevel 'contents' permission set to 'read': .github/workflows/quality.yml:12","Info: jobLevel 'contents' permission set to 'read': .github/workflows/rsr-antipattern.yml:23","Info: jobLevel 'contents' permission set to 'read': .github/workflows/security-policy.yml:11","Info: jobLevel 'contents' permission set to 'read': .github/workflows/semgrep.yml:20","Info: jobLevel 'contents' permission set to 'read': .github/workflows/ts-blocker.yml:11","Info: jobLevel 'contents' permission set to 'read': .github/workflows/wellknown-enforcement.yml:24","Info: jobLevel 'contents' permission set to 'read': .github/workflows/workflow-linter.yml:21","Info: topLevel 'contents' permission set to 'read': .github/workflows/casket-pages.yml:10","Info: topLevel 'contents' permission set to 'read': .github/workflows/ci.yml:11","Info: topLevel permissions set to 'read-all': .github/workflows/codeql.yml:12","Info: topLevel permissions set to 'read-all': .github/workflows/guix-nix-policy.yml:5","Info: topLevel permissions set to 'read-all': .github/workflows/hypatia-scan.yml:14","Info: topLevel 'contents' permission set to 'read': .github/workflows/instant-sync.yml:12","Info: topLevel permissions set to 'read-all': .github/workflows/mirror.yml:10","Info: topLevel permissions set to 'read-all': .github/workflows/npm-bun-blocker.yml:5","Info: topLevel permissions set to 'read-all': .github/workflows/quality.yml:6","Warn: topLevel 'contents' permission set to 'write': .github/workflows/release.yml:10","Info: topLevel permissions set to 'read-all': .github/workflows/rsr-antipattern.yml:17","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard-enforcer.yml:12","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:10","Info: topLevel permissions set to 'read-all': .github/workflows/secret-scanner.yml:10","Info: topLevel permissions set to 'read-all': .github/workflows/security-policy.yml:5","Info: topLevel permissions set to 'read-all': .github/workflows/semgrep.yml:13","Info: topLevel permissions set to 'read-all': .github/workflows/ts-blocker.yml:5","Info: topLevel permissions set to 'read-all': .github/workflows/wellknown-enforcement.yml:18","Info: topLevel permissions set to 'read-all': .github/workflows/workflow-linter.yml:15","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":10,"reason":"all dependencies are pinned","details":["Info:  42 out of  42 GitHub-owned GitHubAction dependencies pinned","Info:  20 out of  20 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#pinned-dependencies"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#license"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#vulnerabilities"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'main'","Warn: could not determine whether codeowners review is allowed","Warn: no status checks found to merge onto branch 'main'","Warn: PRs are not required to make changes on branch 'main'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#signed-releases"}},{"name":"SAST","score":10,"reason":"SAST tool is run on all commits","details":["Info: SAST configuration detected: CodeQL","Info: all commits (4) are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#sast"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#fuzzing"}},{"name":"Contributors","score":3,"reason":"project has 1 contributing companies or organizations -- score normalized to 3","details":["Info: found contributions from: the open university \u0026 national union of journalists"],"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#contributors"}},{"name":"CI-Tests","score":10,"reason":"4 out of 4 merged PRs checked by a CI test -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/c22063e786c11f9dd714d777a687ff7c4599b600/docs/checks.md#ci-tests"}}]},"last_synced_at":"2026-03-26T16:55:55.421Z","repository_id":346571863,"created_at":"2026-03-26T16:55:55.421Z","updated_at":"2026-03-26T16:55:55.421Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31808505,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-14T11:13:53.975Z","status":"ssl_error","status_checked_at":"2026-04-14T11:13:53.299Z","response_time":153,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["hyperpolymath","palimpsest"],"created_at":"2026-04-14T17:31:39.054Z","updated_at":"2026-04-14T17:31:39.974Z","avatar_url":"https://github.com/hyperpolymath.png","language":"OCaml","funding_links":["https://github.com/sponsors/hyperpolymath","https://ko-fi.com/hyperpolymath","https://liberapay.com/hyperpolymath"],"categories":[],"sub_categories":[],"readme":"= AffineScript: A Practical Language for Resource-Safe Systems\n:toc:\n:toclevels: 3\n:sectnums:\n:source-highlighter: rouge\n:icons: font\n\nLicense: PMPL-1.0-or-later +\nBuilt alongside Gossamer, typed-wasm, and Burble\n\nWrite software where the compiler helps enforce resource lifecycles, protocol states, and effect boundaries before bugs become runtime failures.\n\n[NOTE]\n====\nHonest status sync (2026-04-12): affine/QTT and borrow checking are wired into the standard CLI paths today (`check`, `compile`, `eval`) and gate user programs. Dependent/refinement features are still parse-first in places, and some backend features remain incomplete, especially around effect-handler lowering in Wasm targets. See `.machine_readable/6a2/STATE.a2ml` for the authoritative per-feature status.\n====\n\n== What AffineScript Is\n\nAffineScript is a practical programming language for building software where the hard problems are not just “does it parse?” or “does it type-check?”, but:\n\n- is this resource used correctly?\n- are these state transitions valid?\n- are effects explicit?\n- is this extension boundary safe?\n- can this code be portable across runtimes and targets?\n\nIt combines:\n\n- affine and quantitative typing for ownership and usage tracking\n- algebraic effects for explicit side effects and handlers\n- row polymorphism for extensible records and interfaces\n- refinement-oriented type structure for stronger invariants\n- WebAssembly-oriented deployment paths for portable execution\n\nThe goal is not to turn ordinary programming into theorem proving. The goal is to make it easier to write programs whose _resource lifecycles_, _protocol states_, and _effect boundaries_ are correct by construction.\n\nAffineScript is not a “game language.” Games have been one useful proving ground for it, but the language is intended more broadly for:\n\n- plugin systems\n- desktop/runtime shells\n- protocol-driven software\n- real-time systems\n- data and document pipelines\n- simulation and game logic\n- extensible applications and toolchains\n\n== The Core Idea\n\nMany bugs in real software are really _type-system omissions in disguise_.\n\nExamples:\n\n- using a resource after it should have been consumed\n- forgetting to release a resource\n- calling an operation in the wrong protocol state\n- hiding I/O or mutation inside supposedly pure logic\n- making “extensible” interfaces that are really unchecked convention\n- evolving data structures in ways that quietly break consumers\n\nAffineScript moves these constraints into the language.\n\nIt is designed for code where:\n\n- resources matter\n- state matters\n- sequencing matters\n- extensibility matters\n- portability matters\n\n== The Important Distinction: Core Language vs Faces\n\nAffineScript is the semantic core.\n\nOn top of that core, the language supports _faces_: sugared surface syntaxes that let people approach the same semantics through different aesthetic and ergonomic styles.\n\nA face is not a separate language. It is a different presentation layer over the same core model.\n\nExamples include:\n\n- *AffineScript* — the canonical face\n- *JaffaScript* — a JavaScript-like face\n- *RattleScript* — a Python-like face\n- *PseudoScript* — a pseudocode-oriented face\n\nThis means people can bring familiarity from a language family they already love, while still entering a system with stronger guarantees around ownership, effects, state, and resource usage.\n\nIn other words:\n\n[quote]\n____\nDifferent faces, same cube.\n____\n\nThe syntax may feel familiar in different ways, but the semantic guarantees come from the same checked core.\n\n== Why Faces Matter\n\nMost programming languages force a false choice:\n\n- familiar syntax with weak guarantees, or\n- strong guarantees with alien ergonomics\n\nAffineScript’s face system is meant to break that tradeoff.\n\nWith faces, you can let users write in a style that feels:\n\n- JavaScript-like\n- Python-like\n- pseudocode-like\n- domain-specific\n- pedagogy-friendly\n\nwhile still preserving:\n\n- type checking\n- ownership/usage constraints\n- effect tracking\n- state and protocol correctness\n- portable code generation targets\n\nThis is especially useful for:\n\n- onboarding\n- teaching\n- domain experts entering safer systems programming\n- plugin authors\n- teams migrating from dynamic or weakly typed languages\n\n== What Makes AffineScript Distinctive\n\nAffineScript brings together capabilities that are rarely available in one practical system:\n\n[cols=\"1,3\"]\n|===\n|Capability |What it is for\n\n|Affine / QTT-style usage tracking\n|Ownership, resource protocols, “use once / don’t duplicate / don’t forget”\n\n|Algebraic effects\n|Explicit side effects, handler-based composition, safer impurity boundaries\n\n|Row polymorphism\n|Extensible records and interfaces without collapsing into ad hoc objects\n\n|Refinement-oriented typing\n|Stronger invariants over state and structure\n\n|Portable code generation\n|Wasm-oriented deployment and integration paths\n\n|Multiple faces\n|Different surface syntaxes over the same checked semantic core\n|===\n\nThe practical result is a language aimed at software where correctness depends on more than ordinary static typing.\n\n== What AffineScript Helps Express and Verify\n\nAffineScript is especially suited to programs that need guarantees around:\n\n- resource acquisition and disposal\n- protocol state transitions\n- plugin and extension boundaries\n- explicit capability/effect boundaries\n- extensible structured data\n- portable execution targets\n- interpreters, runtimes, and shells\n- host/guest integration layers\n\nThis includes code such as:\n\n- network/session flows\n- document or file pipelines\n- desktop shell logic\n- stateful embedded runtimes\n- simulation/game systems\n- tool plugins\n- language tooling and automation\n\n== Example: Resource-Safe Ownership\n\n[source,affine]\n----\ntype Texture = own { id: Int, width: Int, height: Int }\n\nfn load_texture(path: ref String) -{IO + Exn[LoadError]}-\u003e own Texture {\n  Texture { id: 42, width: 1024, height: 1024 }\n}\n\nfn render(scene: ref Scene, texture: ref Texture) -{Render}-\u003e () {\n  ()\n}\n\nfn unload(@linear texture: own Texture) -{IO}-\u003e () {\n  ()\n}\n\nfn frame() -{IO + Render + Exn[LoadError]}-\u003e () {\n  let texture = load_texture(\"player.png\");\n  render(scene, texture);\n  unload(texture);\n  // texture cannot be used here\n}\n----\n\nWhat the checker is trying to protect you from:\n\n- using a consumed resource\n- forgetting to release a resource\n- duplicating exclusive ownership\n- hiding lifecycle mistakes behind convention\n\n== Example: State-Checked Protocol Transitions\n\n[source,affine]\n----\ntype Connection[..state] = own {\n  socket: own Socket,\n  ..state\n}\n\nfn authenticate(\n  @linear conn: own Connection[{status: Unauthenticated}]\n) -{Session + IO}-\u003e Connection[{status: Authenticated, user: String}] {\n  let creds = recv();\n  Connection { socket: conn.socket, status: Authenticated, user: creds.user }\n}\n\nfn query(\n  conn: ref Connection[{status: Authenticated, ..r}],\n  sql: ref String\n) -{IO}-\u003e Result[Rows, DbError] {\n  // ...\n}\n----\n\nWhat the checker can rule out:\n\n- querying before authentication\n- authenticating twice through the same consumed handle\n- using a connection after close\n- silently invalid protocol transitions\n\n== Example: Effect-Explicit Code\n\n[source,affine]\n----\neffect IO {\n  fn print(s: String) -\u003e ();\n  fn read_line() -\u003e String;\n}\n\neffect State[S] {\n  fn get() -\u003e S;\n  fn put(s: S) -\u003e ();\n}\n\nfn interactive_counter() -{IO + State[Int]}-\u003e Int {\n  let input = read_line();\n  let current = get();\n  let next = current + 1;\n  put(next);\n  print(\"Count: \" ++ int_to_string(next));\n  next\n}\n\nfn add(a: Int, b: Int) -\u003e Int {\n  a + b\n}\n----\n\nThe point is not “effects are fancy.” The point is that effect boundaries become visible and checkable.\n\n== Example: Extensible Data with Row Polymorphism\n\n[source,affine]\n----\nfn greet[..r](person: {name: String, ..r}) -\u003e String {\n  \"Hello, \" ++ person.name\n}\n\nlet alice = {name: \"Alice\", age: 30, role: \"Engineer\"};\nlet bob = {name: \"Bob\", department: \"Sales\"};\n\ngreet(alice);\ngreet(bob);\n----\n\nThis matters for extensible systems, plugins, records, evolving schemas, and interface stability.\n\n== Faces in More Detail\n\nA face is a syntax layer, not a semantic fork.\n\nThat means:\n\n- the same ownership rules still apply\n- the same effect rules still apply\n- the same state/protocol guarantees still apply\n- the same backend targets still apply\n\nThe purpose of faces is not fragmentation. It is _approachability_.\n\nA likely way to think about the stack is:\n\n[listing]\n----\nface syntax  -\u003e  AffineScript core AST  -\u003e  type/effect/ownership checks  -\u003e  backend target\n----\n\nExamples:\n\n- JaffaScript lowers JavaScript-like syntax into the AffineScript core\n- RattleScript lowers Python-like syntax into the same core\n- PseudoScript lowers structured pedagogical pseudocode into the same core\n\nSo the question is not “which face is the real language?”  \nThe answer is: the core semantics are the language; faces are entrances.\n\n== Backends and Targets\n\nAffineScript is intended to support portable deployment, especially through WebAssembly-oriented targets.\n\nDepending on feature maturity and backend coverage, this includes:\n\n- Wasm-oriented deployment paths\n- integration with typed-wasm conventions\n- native/runtime-specific backends where implemented\n- host integration via Gossamer and related infrastructure\n\nThe important point is this:\n\n[quote]\n____\nAffineScript is not “JavaScript with types” and not “Python with ownership syntax.”  \nIt is a checked core language that can be surfaced through multiple familiar faces and lowered into portable execution targets.\n____\n\n== Relationship to typed-wasm\n\nAffineScript and typed-wasm are related, but they are not the same thing.\n\n- *AffineScript* is a source language and semantic system.\n- *typed-wasm* is about typed structure and safety around Wasm-oriented memory/layout/interface conventions.\n- *Gossamer* is a resource-safe host/runtime/shell layer.\n- *Burble* is a high-assurance real-time systems application of the same broader philosophy.\n\nA helpful mental model is:\n\n[listing]\n----\nface syntax -\u003e AffineScript core -\u003e typed-wasm / Wasm conventions -\u003e host/runtime integration\n----\n\ntyped-wasm matters because portable low-level targets need more than “it compiles.” They need conventions, structure, and safe composition across boundaries.\n\n== Games Are a Proving Ground, Not the Definition\n\nGames have been a useful proving ground because they combine:\n\n- stateful logic\n- resources with lifecycles\n- extensible entity data\n- eventful and asynchronous behaviour\n- portability requirements\n- host/runtime integration concerns\n\nThat makes them an excellent stress test.\n\nBut AffineScript is not limited to games, and should not be presented as if that were its sole or primary identity.\n\nGames are one place where the language’s properties are easy to demonstrate. They are not the language’s entire reason for existing.\n\n== Getting Started\n\n=== Prerequisites\n\n- OCaml 5.1+\n- Dune 3.14+\n- opam packages: `sedlex`, `menhir`, `ppx_deriving`, `cmdliner`, `yojson`\n\n=== Build\n\n[source,bash]\n----\ndune build\n----\n\n=== Type check a file\n\n[source,bash]\n----\n_build/default/bin/main.exe check test/e2e/fixtures/affine_basic.affine\n----\n\n=== Evaluate with interpreter\n\n[source,bash]\n----\n_build/default/bin/main.exe eval test/e2e/fixtures/interp_simple.affine\n----\n\n=== Compile\n\n[source,bash]\n----\n_build/default/bin/main.exe compile -o hello.wasm test/e2e/fixtures/wasm_simple.affine\n----\n\n=== Format\n\n[source,bash]\n----\n_build/default/bin/main.exe fmt test/e2e/fixtures/affine_basic.affine\n----\n\n=== Lint\n\n[source,bash]\n----\n_build/default/bin/main.exe lint test/e2e/fixtures/affine_basic.affine\n----\n\n=== JSON diagnostics\n\n[source,bash]\n----\n_build/default/bin/main.exe check --json test/e2e/fixtures/affine_basic.affine\n----\n\n[NOTE]\n====\nThe standard source extension for AffineScript is `.affine`.\n====\n\n== Status\n\nAffineScript is in active development.\n\nThis repository contains a live compiler and tooling stack, but some advanced features remain incomplete or partial. Current state is best understood from the machine-readable status files and current docs rather than from aspirational claims.\n\n[cols=\"2,1,4\"]\n|===\n|Component |Status |Notes\n\n|Lexer + Parser\n|Complete\n|Menhir grammar, sedlex tokenizer, broad syntax coverage\n\n|Name Resolution\n|Complete\n|Module loading, scoping, imports\n\n|Type Checker\n|Wired\n|Active in standard CLI paths\n\n|Quantity Checking\n|Live gate\n|QTT quantity checks fail builds on violations\n\n|Borrow Checker\n|Live gate\n|Compile-time borrow checks active; advanced phases ongoing\n\n|Effect System\n|Interpreter-complete\n|Handlers/interpreter path active; backend parity incomplete\n\n|Trait System\n|Partial\n|Core registry and lookup work exists; advanced coherence remains\n\n|Interpreter\n|High\n|Closures, matching, effects, and recent exception plumbing\n\n|WASM Codegen\n|Advanced but incomplete\n|Primary deployment backend; feature gaps remain\n\n|WASM GC Codegen\n|Partial\n|Available, not full feature parity\n\n|LSP Server\n|Complete\n|Hover, goto-def, completion, diagnostics\n\n|Formatter + Linter\n|Complete\n|AST-based formatter and lint rules\n|===\n\n== Design Principles\n\n- *Correctness should be structural, not ceremonial.*\n- *Types should clarify what code may do, not merely classify data.*\n- *Effects should be explicit.*\n- *Resources should not depend on discipline alone.*\n- *Extensibility should not collapse into unchecked runtime convention.*\n- *Strong guarantees should not require alien syntax.*\n- *Different faces should be able to share one checked core.*\n\n== Repository Structure\n\n[listing]\n----\naffinescript/\n+-- lib/                      # Core compiler (OCaml)\n|   +-- ast.ml\n|   +-- lexer.ml\n|   +-- parser.mly\n|   +-- typecheck.ml\n|   +-- unify.ml\n|   +-- quantity.ml\n|   +-- types.ml\n|   +-- codegen.ml\n|   +-- interp.ml\n|   +-- json_output.ml\n+-- bin/main.ml               # CLI\n+-- tools/affinescript-lsp/   # Language server\n+-- editors/                  # Editor integrations\n+-- stdlib/                   # Standard library modules\n+-- examples/                 # Example programs\n+-- test/                     # Golden tests and fixtures\n+-- docs/                     # Specifications, guides, papers\n+-- .machine_readable/        # Authoritative machine-readable status\n----\n\n== Ecosystem\n\nAffineScript sits inside a broader ecosystem built around correctness-by-construction.\n\n=== Gossamer\nA resource-safe host/runtime shell for desktop and embedded application structures.\n\n=== typed-wasm\nA typed Wasm-oriented layer for memory/layout/interface discipline and safer low-level convergence.\n\n=== Burble\nA high-assurance real-time communications system using similar design principles around correctness, performance, and explicit structure.\n\nThese are related projects, but each has a distinct role.\n\n== What AffineScript Is Not\n\nAffineScript is not:\n\n- merely “Rust with different syntax”\n- merely “TypeScript but safer”\n- merely “a game scripting language”\n- merely “a proof assistant disguised as a language”\n- merely “a Wasm frontend”\n\nIt is better understood as:\n\n[quote]\n____\nA practical language core for resource-aware, stateful, effect-explicit, extensible software — with multiple faces and portable targets.\n____\n\n== Documentation\n\n- `docs/` — language and architecture documentation\n- `.machine_readable/6a2/STATE.a2ml` — authoritative feature status\n- `examples/` — example programs\n- `tools/affinescript-lsp/` — language tooling\n- `editors/` — editor integrations\n\n== License\n\nThis repository is documented and distributed under AGPL-3.0-or-later.\n\nThe broader Palimpsest-MPL licensing layer applies to associated ecosystem technology including:\n\n- Gossamer\n- Burble\n- AffineScript deployment/tooling layers where applicable\n\nSee also:\n\n- AGPL-3.0-or-later: https://www.gnu.org/licenses/agpl-3.0.html\n- PMPL-1.0: https://github.com/hyperpolymath/palimpsest-license\n\n== Final Positioning Summary\n\nAffineScript should be presented as:\n\n[quote]\n____\nA practical checked core language for resource-safe, stateful, extensible software, with multiple familiar faces and portable Wasm-oriented targets.\n____\n\nNot as:\n\n[quote]\n____\nA secret weapon for games.\n____\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperpolymath%2Faffinescript","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhyperpolymath%2Faffinescript","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhyperpolymath%2Faffinescript/lists"}