{"id":24285543,"url":"https://github.com/kchanqvq/lwcells","last_synced_at":"2026-03-11T00:01:29.799Z","repository":{"id":95969968,"uuid":"446270217","full_name":"kchanqvq/lwcells","owner":"kchanqvq","description":"Light Weight Cells","archived":false,"fork":false,"pushed_at":"2024-10-06T03:06:50.000Z","size":48,"stargazers_count":18,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-05T19:50:14.474Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kchanqvq.png","metadata":{"files":{"readme":"README.org","changelog":null,"contributing":null,"funding":null,"license":null,"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-01-10T03:37:01.000Z","updated_at":"2025-02-16T12:00:31.000Z","dependencies_parsed_at":null,"dependency_job_id":"2b021a66-e6bd-4f5e-8941-5423c3202972","html_url":"https://github.com/kchanqvq/lwcells","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kchanqvq/lwcells","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kchanqvq%2Flwcells","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kchanqvq%2Flwcells/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kchanqvq%2Flwcells/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kchanqvq%2Flwcells/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kchanqvq","download_url":"https://codeload.github.com/kchanqvq/lwcells/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kchanqvq%2Flwcells/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30362683,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"ssl_error","status_checked_at":"2026-03-10T21:40:59.357Z","response_time":106,"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":[],"created_at":"2025-01-16T06:45:10.583Z","updated_at":"2026-03-11T00:01:29.746Z","avatar_url":"https://github.com/kchanqvq.png","language":"Common Lisp","readme":"#+TITLE:LWCELLS - Light Weight Cells\n~LWCELLS~ is a dataflow extension to Common Lisp. It maintains a\nconsistent state of cells according to functions specifying their\nrelation.  ~LWCELLS~ is designed to be simple, clean, compositional\nand flexible.\n\n* Tutorial\n  Basic usage:\n#+BEGIN_SRC lisp\n  (use-package :lwcells)\n  (defparameter *cell-1* (cell 1))\n  (defparameter *cell-2* (cell 2))\n  (defparameter *cell-3* (cell (+ (cell-ref *cell-1*) (cell-ref *cell-2*))))\n  (cell-ref *cell-3*) ; =\u003e 3\n  (setf (cell-ref *cell-2*) 5)\n  (cell-ref *cell-3*) ; =\u003e 6\n#+END_SRC\n  *Hackers' note:* The body of each ~cell~ form is wrapped into a\n  function and assigned to the ~cell-function~ slot of constructed\n  ~cell~ object (actually, a ~lazy-cell~). At any moment, ~cell~ with\n  non-nil ~cell-function~ will ensure their observed value matches the\n  result of running ~cell-function~. If you explicitly ~(setf\n  cell-ref)~ a cell, its ~cell-function~ is removed to prevent it from\n  running again and overwrite the explicitly assigned value.\n\n  Fancier syntax sugar that does roughly the same thing as above:\n#+BEGIN_SRC lisp\n  (defcell *cell-1* 1)\n  (defcell *cell-2* 2)\n  (defcell *cell-3* (+ *cell-1* *cell-2*))\n#+END_SRC\n  ~defcell~ have the additional nicety that when you redefine a cell,\n  if an existing cell object is to be overwritten, such cell is also\n  deactivated so that observers (to be explained!) defined on the old\n  cell stop making noises.\n  \n  *Hackers' note:* Under the hood, this stores the cell objects in\n  variable like ~*cell-1*-cell~, and defines symbols like ~*cell-1*~\n  themselves as symbol macros.\n\n  There's also ~let-cell~ and ~let*-cell~ that does the similiar for\n  lexical variables.\n\n  Observers:\n#+BEGIN_SRC lisp\n  (defcell *cell-1* 1)\n  (defcell *cell-2* 2)\n  (defcell *cell-3* (+ *cell-1* *cell-2*))\n  (defun report-assign (cell)\n    (let ((*print-circle* t))\n      (format t \"Assigning ~a to ~a.\" (cell-ref cell) cell)))\n  (add-observer *cell-3*-cell 'report-assign)\n  (setf *cell-2* 4)\n  ;; =\u003e Assigning 5 to #1=#S(CELL ...)\n#+END_SRC\n  \n  *Hackers' note:* Under the hood, observers are implemented as ~observer-cell~,\n  a special kind of ~cell~ whose ~cell-ins~ never change.\n\n  Convenience for CLOS:\n#+BEGIN_SRC lisp\n  (defmodel item () ((weight :cell 0 :initarg :weight)))\n  (defmodel container ()\n    ((items :cell nil)\n     (weight :cell (reduce #'+ (items self) :key #'weight))))\n  (defvar *container* (make-instance 'container))\n  (weight *container*) ; =\u003e 0\n  (push (make-instance 'item :weight 10) (items *container*))\n  (weight *container*) ; =\u003e 10\n#+END_SRC\n  *Hackers' note:* Under the hood, ~defmodel~ expand into a\n  ~defclass~, an ~initialize-instance~ method to store cell objects\n  into slots, and some accessors method to read/write values from cell\n  objects in the slots. You can then use the accessors method to\n  transparently access reactive values. To get and manipulate the\n  underlying cell objects, use ~slot-value~.\n\n  ~defmodel~ doesn't use any MOP magic, and is fully compatible with\n  standard CLOS classes.\n    \n* Related works\n  - [[https://github.com/kennytilton/cells][cells]] :: This is very\n    powerful, but also very complicated. AFAIU cells are also always\n    attached to slots and don't exist on their own. I might be\n    wrong -- I don't understand all the code!\n  - [[https://github.com/hu-dwim/hu.dwim.computed-class][computed-class]] ::\n    A bit more complicated than ~lwcells~. The syntax is also a bit less\n    sweet, requiring lots of ~computed-as~ everywhere.\n    \n* Documentation\n  Read the source code! There isn't lots of code.\n","funding_links":[],"categories":["Miscellaneous ##"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkchanqvq%2Flwcells","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkchanqvq%2Flwcells","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkchanqvq%2Flwcells/lists"}