{"id":18453294,"url":"https://github.com/quasarbright/miniclass","last_synced_at":"2026-03-19T04:27:53.476Z","repository":{"id":92838902,"uuid":"557101697","full_name":"quasarbright/miniclass","owner":"quasarbright","description":"a few implementations of a small class system in Racket","archived":false,"fork":false,"pushed_at":"2023-03-09T04:15:02.000Z","size":201,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-22T12:19:47.878Z","etag":null,"topics":["dsl","macros","oop","racket"],"latest_commit_sha":null,"homepage":"","language":"Racket","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/quasarbright.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":"2022-10-25T04:33:55.000Z","updated_at":"2023-12-10T07:57:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"3fb7a980-4d69-4af1-9900-c7a4df8f4f02","html_url":"https://github.com/quasarbright/miniclass","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/quasarbright/miniclass","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2Fminiclass","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2Fminiclass/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2Fminiclass/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2Fminiclass/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quasarbright","download_url":"https://codeload.github.com/quasarbright/miniclass/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quasarbright%2Fminiclass/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28730712,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: 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":["dsl","macros","oop","racket"],"created_at":"2024-11-06T07:35:47.227Z","updated_at":"2026-01-24T16:03:01.762Z","avatar_url":"https://github.com/quasarbright.png","language":"Racket","funding_links":[],"categories":[],"sub_categories":[],"readme":"miniclass\n=========\nThis is a collection of implementations of a small version of racket's class system.\n\nThe purpose of this project is for me to understand how dsl expanders used to work,\nhow syntax-spec works, how local expand works, to determine if syntax-spec is expressive enough\nto implement a class system, and to serve as a vanilla-racket motivating example for a change to the\nexpander API that will allow syntax-spec-style suspensions to avoid creating quadratic re-expansions.\nIt is also a good example to motivate syntax-spec, since it shows the manual way and how much simpler\nit is using syntax-spec.\n\nI iterated several times and kept around old versions as comparisons. Here is the organization:\n\n## simple\n\n`simple` is a simple macro. It detects surface literals for simple definitions and overrides their behavior.\nIt does not support macros expanding to method definitions or field declarations, and does not support class-level expressions.\n\n## local expand loop\n\n`local-expand-loop` is a dsl expander. This how `class` and similar dsls were implemented before syntax-spec.\nI local expand each form in the class body stopping at syntax definitions,\nvalue definitions, and field declarations. As I do this, I bind field names, method names, and macro names.\nAfter the \"first pass\" of expansion, I collect the different types of definitions and declarations and compile them to plain\nracket to implement the class.\n\nThis supports the following things that the previous implementation didn't support:\n\n- Multiple field declaration forms\n- Local macro definitions (at the class level)\n- Macro use at the class-level (can expand to a method definition)\n- Class-level expressions (evaluated at construction time)\n\nProblems with this implementation:\n\n- Evaluates the transformer of each syntax definition twice: once in the \"first pass\" for class-level usages and again\nduring the expansion of emitted syntax since the syntax definitions end up in the emitted syntax so class bodies have access to them.\n\n## syntax-spec style\n\n`bs-manual` is similar to what syntax-spec does. To avoid re-evaluation of transformers, we create suspensions that capture the definition context which\nincludes the bindings for the transformers. Instead of emitting syntax definitions for expansion of method bodies, we suspend them with this context such that\nwhen they are expanded, they are local-expanded under the stored definition context which includes the transformer bindings. This reduces the size of the expanded\ncode and avoids re-evaluating transformers.\n\nProblems with this implementation:\n\n- Since method bodies get local-expanded and then re-expanded after emission, nested classes can lead to quadratic re-expansions\n\nThe problem is that the expander doesn't trust our local-expanded code and re-expands it.\nIdeally, we could use `syntax-local-expand-expression`, but that function doesn't accept a definition\ncontext. If a variable binidng was in the context, the expander could not trust that the variable would\nend up being defined in the emitted code. However, if the definition context only contained transformer bindings,\ntheir references would all expand away, and thus, the expander could safely substitute the result.\nIf the expander were to have this change made, we could replace the `local-expand` with a `syntax-local-expand-expression` when we resume suspensions. This would avoid the quadratic re-expansion problem.\n\n## syntax-spec eager style\n\n`bs-manual-eager` is like `bs-manual`, but immediately expands expression positions instead of creating suspensions.\nAdditionally, rather than purely using syntax parameters for `this`, dynamic parameters are used under the hood to allow eager\nexpansion of syntax parameter references. \nI did this just to see if it was possible. No advantages over non-eager that I can think of.\n\nThis method also has potentially quadratic re-expansions, which can be alleviated by the `syntax-local-expand-expression` change in a similar way.\n\n## using syntax-spec\n\n`bs-auto` uses the syntax-spec library. syntax-spec handles making a custom expander.\n\nThis method currently also has potentially quadratic re-expansions.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquasarbright%2Fminiclass","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquasarbright%2Fminiclass","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquasarbright%2Fminiclass/lists"}