{"id":25195870,"url":"https://github.com/s-expressionists/clostrum","last_synced_at":"2026-01-18T18:32:41.271Z","repository":{"id":83294742,"uuid":"279874945","full_name":"s-expressionists/Clostrum","owner":"s-expressionists","description":"First Class Global Environments","archived":false,"fork":false,"pushed_at":"2025-11-04T14:27:00.000Z","size":306,"stargazers_count":15,"open_issues_count":3,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-11-04T16:13:07.462Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://s-expressionists.github.io/Clostrum/","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/s-expressionists.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-07-15T13:24:16.000Z","updated_at":"2025-11-04T14:27:04.000Z","dependencies_parsed_at":"2024-06-28T06:43:15.639Z","dependency_job_id":"191f97d1-4f83-4529-b6dc-72d22aeec4d4","html_url":"https://github.com/s-expressionists/Clostrum","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/s-expressionists/Clostrum","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FClostrum","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FClostrum/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FClostrum/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FClostrum/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/s-expressionists","download_url":"https://codeload.github.com/s-expressionists/Clostrum/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/s-expressionists%2FClostrum/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28547226,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T14:59:57.589Z","status":"ssl_error","status_checked_at":"2026-01-18T14:59:46.540Z","response_time":98,"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":[],"created_at":"2025-02-10T01:38:54.402Z","updated_at":"2026-01-18T18:32:41.266Z","avatar_url":"https://github.com/s-expressionists.png","language":"Common Lisp","funding_links":[],"categories":[],"sub_categories":[],"readme":"Most Common Lisp implementations have a single global environment, and\nit is spread out in various parts of the system.  For example, the\ndefinition of a *named function* may be contained in a slot of the\nsymbol representing the name, whereas the definition of a *type* might\nbe in a hash table that is the value of a special variable.\n\nIn the paper [First-class Global Environments in Common\nLisp](https://metamodular.eu/SICL-documents/environments.pdf),\npresented at the European Lisp Symposium in 2015, we outlined a\nprotocol for an alternative way of representing global environments,\nnamely as first-class instances of a standard classes.  This library\nis a concrete implementation of the ideas in that paper, though\nimproved upon since.\n\nWe provide protocols and default implementations for the three kinds\nof global environments mentioned in the Common Lisp standard, namely\nthe *run-time* environment, the *evaluation* environment and the\n*compilation* environment.\n\nThe use of a *client* parameter for our protocol generic functions\nallows client code to customize the functions defined here, either by\nextending them or by overriding them.  Similarly, the classes defined\nhere are designed to be possible to use as superclasses of\nclient-specific environment classes.\n\n# API\n\nThe Clostrum API is divided into two parts, a \"high level\" package `clostrum`, and a \"low level\" package `clostrum-sys`. `clostrum-sys` has generic functions that access environments directly and simply, without error checking, while `clostrum`'s generic functions mimic standard Common Lisp operators' more complex behavior and account for inheritance. `clostrum` has default methods implemented in terms of `clostrum-sys`, so environment implementation need only specialize the `clostrum-sys` functions in order to make `clostrum`'s high level facilities available. Users (rather than implementors) of the Clostrum protocol should only need to use the `clostrum` package.\n\n## High level interface\n\nFor operating on run-time environments, the `clostrum` package makes available environment manipulation functions and accessors similar to those in the standard: `fdefinition`, `fboundp`, `fmakunbound`, `macro-function`, `special-operator-p` for functions; `symbol-value`, `boundp`, `makunbound`, `symbol-plist` for variables; `find-class` for classes; `find-package` for packages; and `macroexpand-1`, `macroexpand`, and `constantp`.\n\nThere are additional functions and accessors corresponding to some other Lisp operators. `setf-expander` can be used for `define-setf-expander`; `make-variable`, `make-parameter`, `make-constant`, and `make-symbol-macro` for `defvar`, `defparameter`, `defconstant`, and `define-symbol-macro` respectively; `type-expander` for `deftype`, along with `type-expand-1` and `type-expand` to work with type specifiers.\n\nFor proclamations, `proclamation` can be used for `declaration` or CLtL2's `define-declaration`. `variable-type` covers `type`, and `special` proclamations can be done with `make-variable`. `operator-ftype` handles `ftype` and `operator-inline` `inline`. User-defined inlining data, such as a definition, can be associated with an operator through `operator-inline-data`.\n\n`note-function` will declare an operator to be a function without needing a definition for said function. This is useful for the compile-time effect of `defun`.\n\nThe package environment can be accessed via `find-package`. New nicknames for a package can be installed via `(setf find-package)`, and the list of all names for a package in an environment retrieved via `package-names`. All packages in an environment can be iterated over with `map-all-packages`. Additionally, the canonical name of a package is considered part of the environment as well, and can be accessed via `package-name`.\n\n### Compilation environments\n\nCompilation environments support a subset of the runtime environment operations. They lack package mappings, and functions only needed at runtime like `(setf symbol-value)` are not implemented. `macro-function` and `make-constant` still work.\n\n## Cells\n\nEach variable, operator, and type has a _cell_ retrievable by name, and variables and operators have a _status_. The cell is an object of implementation-defined nature, accessed by `-value`, `-boundp`, and `-makunbound` functions, that holds the value of a binding. Cells are an essential part of Clostrum's design and explained more in the paper. The status indicates what kind of binding a variable or operator has, e.g. as a variable or a constant, or a function or a macro. Some statuses can be read but not directly written (in the high-level API).\n\nIn the high level API, cells are retrieved by `ensure-variable-cell`, etc. This will return a cell if it exists or make a new one to return if not. Undefining a variable etc. does _not_ remove the cell, so they can be used for continued access regardless of boundedness.\n\n## Low-level API\n\nThe `clostrum-sys` package contains the functions that must be implemented by environment objects for the high level functions to work. These consist of direct access to cells and statuses, along with additional functions for the non-cell properties such as a compiler macro functions. Additionally, a `parent` function should be supported for inheritance, but the rest of the functions do not need to consult parent environments as this is handled by the high-level API.\n\n# Inheritance semantics\n\nThe Common Lisp standard mentions environments inheriting from each other in the context of compilation (CLHS 3.2.1) but does not describe the semantics in detail. Clostrum supports inherited environments, and the parent of an environment can be read by `parent`; if an environment has no parent, `parent` returns `nil`.\n\nThe basic rule of inherited bindings Clostrum has adopted is as follows: The _values_ in bindings are inherited from parent environments, but the bindings _themselves_ are not. Mutating a binding or making it unbound has no effect on a parent environment; in fact, no operation on a child environment will mutate anything in the parent environment.\n\nSince the standard only contemplates environment inheritance in the context of compilation, these inheritance semantics are designed to allow `compile-file` operations to mutate an evaluation environment without mutating anything in the parent. For example, a function definition or redefinition within `(eval-when (:compile-toplevel) ...)` can affect an evaluation environment, but after `compile-file` returns, this evaluation environment is discarded, and the startup environment leaves no trace.\n\n# Basic\n\nThe `clostrum-basic` system is the reference implementation of Clostrum. It implements the low level interface, and so the high level interface can be used with the basic environments.\n\n# Trucler\n\nThe `clostrum-trucler` system implements the [Trucler](https://github.com/s-expressionists/Trucler/) protocol for Clostrum environments. The system package has no exports, instead just specializing the Trucler protocol methods.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-expressionists%2Fclostrum","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fs-expressionists%2Fclostrum","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fs-expressionists%2Fclostrum/lists"}