{"id":15661167,"url":"https://github.com/siraben/r5rs-denot","last_synced_at":"2025-05-05T21:33:55.213Z","repository":{"id":111748517,"uuid":"178302174","full_name":"siraben/r5rs-denot","owner":"siraben","description":"A correct Scheme interpreter derived from the R5RS spec's formal semantics, written in Haskell.","archived":false,"fork":false,"pushed_at":"2023-01-19T22:37:02.000Z","size":329,"stargazers_count":21,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-30T23:51:11.183Z","etag":null,"topics":["denotational-semantics","haskell","monad-transformers","r5rs-scheme","scheme","scheme-interpreter"],"latest_commit_sha":null,"homepage":"","language":"Haskell","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/siraben.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-03-29T00:21:41.000Z","updated_at":"2024-11-07T14:51:12.000Z","dependencies_parsed_at":"2024-01-16T13:51:50.795Z","dependency_job_id":null,"html_url":"https://github.com/siraben/r5rs-denot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siraben%2Fr5rs-denot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siraben%2Fr5rs-denot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siraben%2Fr5rs-denot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siraben%2Fr5rs-denot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/siraben","download_url":"https://codeload.github.com/siraben/r5rs-denot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252580045,"owners_count":21771254,"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":["denotational-semantics","haskell","monad-transformers","r5rs-scheme","scheme","scheme-interpreter"],"created_at":"2024-10-03T13:26:13.771Z","updated_at":"2025-05-05T21:33:55.206Z","avatar_url":"https://github.com/siraben.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# An interpreter for R5RS Scheme based on denotational semantics\n![R5RS denotational semantics for evaluating lambdas](lambda-def.png)\n\n**Note:** monadic interpreter available at the\n[monad-transformers](https://github.com/siraben/r5rs-denot/tree/monad-transformers)\nbranch.\n\n## Quick Start\n```ShellSession\n$ nix run github:siraben/r5rs-denot # with Nix\n$ cabal run # with Cabal\n```\n\n## Background\n\nThe [R5RS Scheme specification](https://www.schemers.org/Documents/Standards/R5RS/r5rs.pdf) is a 50-page beauty, outlining the\nsyntax and semantics of Scheme in easy to understand prose, and\nconcludes with a denotational semantics.  The semantics looks a lot\nlike Haskell because in a sense it _is_ Haskell!  We can turn the\nabove image into a Haskell code fragment:\n\n```haskell\n-- Evaluate a lambda expression with an environment e0, continuation κ\n-- and store σ.\neval (Lambda is gs e0) ρ κ =\n  \\σ -\u003e\n    send\n      (Ef\n         ( new σ\n         , \\εs κ' -\u003e\n             if length εs == length is\n               then tievals\n                      ((\\ρ' -\u003e evalc gs ρ' (eval e0 ρ' κ')) . extends ρ is)\n                      εs\n               else wrong \"wrong number of arguments\"))\n      κ\n      (update (new σ) (Em Unspecified) σ)\n```\n\nCurrently, the standard environment contains the following primitive\nprocedures:\n\n```text\n+ * - / modulo \u003c \u003e = \u003e= \u003c= cons car cdr list eqv? boolean? symbol?\nprocedure? pair? number? set-car! set-cdr! null? apply\ncall-with-values values call-with-current-continuation call/cc\nstring? symbol-\u003estring string-\u003esymbol string-append number-\u003estring\nrecursive\n```\n\nAnd the following core special forms:\n\n```text\n(if \u003cexpr\u003e \u003cexpr\u003e \u003cexpr\u003e)\n(if \u003cexpr\u003e \u003cexpr\u003e)\n(set! \u003cid\u003e \u003cexpr\u003e)\n(lambda \u003cid\u003e* \u003cexpr\u003e*)\n(lambda \u003cid\u003e \u003cexpr\u003e*)\n(lambda (\u003cid\u003e* . \u003cid\u003e) \u003cexpr\u003e*)\n(\u003cexpr\u003e \u003cexpr\u003e*)\n```\n\nThe following derived forms have been implemented.  Currently they are\nparsed and expanded in Haskell, but a hygienic macro system will take\ntheir place.\n\n```text\n(define \u003cid\u003e \u003cexpr\u003e)\n(define (\u003cid\u003e \u003cid\u003e*) \u003cexpr\u003e*)\n(define (\u003cid\u003e* . \u003cid\u003e) \u003cexpr\u003e*)\n'\u003cexpr\u003e\n(begin \u003cexpr\u003e*)\n(cond (\u003cexpr\u003e \u003cexpr\u003e)*)\n(let ((\u003cid\u003e \u003cexpr\u003e)*) \u003cexpr\u003e*)\n(letrec ((\u003cid\u003e \u003cexpr\u003e)) \u003cexpr\u003e*)\n(and \u003cexpr\u003e*)\n(or \u003cexpr\u003e*)\n```\n\nEnsure Cabal is installed and build this project by running `cabal\nrun`.  The REPL will boot up.  Type an expression and hit ENTER to\nevaluate it.\n\n### Usage Examples\n```scheme\nr5rs-denot\u003e (define (fact n) (if (= n 0) 1 (* n (fact (- n 1))))) (fact 6)\n720\nMemory used: 10 cells\n```\nAlternatively, read it from a file in the `demo` folder, using GHCi:\n```text\n-- Factorial\nλ\u003e repf \"demo/factorial.scm\"\n720\nMemory used: 10 cells\n\n-- Primes via streams\nλ\u003e repf \"demo/primes.scm\"\n(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71)\nMemory used: 3196 cells\n\n-- Mutable state\nλ\u003e repf \"demo/counter.scm\"\n(1 2 3 4)\nMemory used: 15 cells\n```\n## Scheme AST as a Haskell Datatype\nThe Scheme program:\n```scheme\n((lambda (x) (+ x x)) 10)\n```\nCan be written in the Haskell `Expr` datatype as:\n```haskell\nprog = App (Lambda [\"x\"] [] (App (Id \"+\") [Id \"x\", Id \"x\"])) [Const (Number 10)]\n```\nWhich can be evaluated in a standard environment and infinite store by running.\n\n```haskell\nevalStd prog\n```\nThe result is a triple `(String, [E], S)`, consisting of a string, a\nlist of results, and the final store (up to the first empty cell).\n\n## Performance notes\nThe performance has been greatly improved due to the use of the\n`Data.IntMap` library to implement the store.  Thus, the Scheme\ninterpreter runs reasonably fast.\n\n### Performance Statistics\n```text\nλ\u003e repf \"demo/primes.scm\"\n(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71)\nMemory used: 6410 cells\nλ\u003e repf \"demo/eval/eval-define.scm\"\na\nMemory used: 409 cells\nλ\u003e repf \"demo/counter.scm\"\n(1 2 3 4)\nMemory used: 15 cells\nλ\u003e repf \"demo/meta-circ.scm\"\n\"\\n720\"\nMemory used: 16142 cells\n```\n\n## Future Plans\n- [x] Strings\n- [x] `define` program declarations\n  - [x] Desugar into `let` and `set!`\n- [x] Escaping characters in strings\n- [ ] quasiquote/unquote\n- [ ] Hygienic macro expansion, according to [this\n      paper](https://legacy.cs.indiana.edu/~dyb/pubs/LaSC-5-4-pp295-326.pdf)\n- [ ] Vectors (using IntMap as representation)\n- [ ] Rewrite `eval` from a store-passing, continuation-passing\n      interpreter to a monadic style\n  - In progress: at [monad-transformers](https://github.com/siraben/r5rs-denot/tree/monad-transformers)\n    branch, Scheme monad `Scheme m u r s a` representing a Scheme\n    computation in environment `u`, store `s`, continuation `r`, over\n    monad `m` returning a value of type `a`\n  - [x] Inject `IO` computations into the Scheme monad\n    - [ ] Implement ports, and user I/O\n- [ ] Automated test suite\n\n## Limitations\nThis is also a good example of the problems with \"unstable\ndenotations\", as the specification is quite rigid and would have to be\nre-written from scratch in the face of new effects.\n\nFurthermore, the semantics does not cover all of the language, and\nseveral language features are missing semantics.  Thus, we can only\nguess at the appropriate semantics for this, and test them against the\nexamples in the earlier sections of the paper.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiraben%2Fr5rs-denot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsiraben%2Fr5rs-denot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiraben%2Fr5rs-denot/lists"}