{"id":22813446,"url":"https://github.com/iamfirecracker/cl-zip","last_synced_at":"2026-01-11T02:42:03.469Z","repository":{"id":239458924,"uuid":"787234453","full_name":"iamFIREcracker/cl-zip","owner":"iamFIREcracker","description":"Common Lisp system implementing Huet zippers","archived":false,"fork":false,"pushed_at":"2024-07-25T08:07:36.000Z","size":43,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-06T02:44:37.130Z","etag":null,"topics":["common-lisp","zipper"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","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/iamFIREcracker.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":"2024-04-16T06:26:26.000Z","updated_at":"2024-07-25T08:07:40.000Z","dependencies_parsed_at":"2024-05-12T16:45:36.289Z","dependency_job_id":"6cf2a3a8-56c0-41d8-abf1-2397574faef1","html_url":"https://github.com/iamFIREcracker/cl-zip","commit_stats":null,"previous_names":["iamfirecracker/cl-zip"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamFIREcracker%2Fcl-zip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamFIREcracker%2Fcl-zip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamFIREcracker%2Fcl-zip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/iamFIREcracker%2Fcl-zip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/iamFIREcracker","download_url":"https://codeload.github.com/iamFIREcracker/cl-zip/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246385415,"owners_count":20768672,"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":["common-lisp","zipper"],"created_at":"2024-12-12T12:42:30.799Z","updated_at":"2026-01-11T02:42:03.463Z","avatar_url":"https://github.com/iamFIREcracker.png","language":"Common Lisp","readme":"\u003ca id=\"x-28ZIP-3A-40ZIP-MANUAL-20MGL-PAX-3ASECTION-29\"\u003e\u003c/a\u003e\n\n# cl-zip\n\n## Table of Contents\n\n- [1 Synopsis][a050]\n- [2 Reference][7152]\n\n###### \\[in package ZIP\\]\nComon lisp system implementing Huet\n[zippers](https://en.wikipedia.org/wiki/Zipper_(data_structure)).\n\n\u003ca id=\"x-28ZIP-3A-40ZIP-SYNOPSIS-20MGL-PAX-3ASECTION-29\"\u003e\u003c/a\u003e\n\n## 1 Synopsis\n\nLet's beging by creating a variable holding the code of a function\nprinting hello world:\n\n```\n(in-package :zip)\n=\u003e #\u003cPACKAGE \"ZIP\"\u003e\n\n(defvar *tree* '(defun hello-world ()\n                    (format t \"Hello, world!\")))\n=\u003e (DEFUN HELLO-WORLD () (FORMAT T \"Hello, world!\"))\n```\n\nLet's *programmatically* change the function definition behind *TREE* to\naccept an argument, `name`, and output a custom message based on its value:\n\n```\n(~\u003e *tree*\n  ;; Create a zipper -- the element under focus (the whole object, initially),\n  ;; is wrapped inside a pare of square brackets\n  zip                        ; [(defun hello-world () (format t \"Hello, World!~%\"))]\n  ;; change hello-world to just hello\n  down                       ; ([defun] hello-world () (format t \"Hello, World!~%\"))\n  right                      ; (defun [hello-world] () (format t \"Hello, World!~%\"))\n  (replace ~ 'hello)         ; (defun [hello] () (format t \"Hello, World!~%\"))\n  ;; change lambda list to include an argument: name\n  right                      ; (defun hello [()] (format t \"Hello, World!~%\"))\n  (insert-child ~ 'name)     ; (defun hello [(name)] (format t \"Hello, World!~%\"))\n  ;; change the FORMAT form to hail the specified person\n  right                      ; (defun hello (name) [(format t \"Hello, World!~%\")])\n  down                       ; (defun hello (name) ([format] t \"Hello, World!~%\"))\n  rightmost                  ; (defun hello (name) (format t [\"Hello, World!~%\"]))\n  (replace ~ \"Hello, ~A!\")   ; (defun hello (name) (format t [\"Hello, ~A!~%\"]))\n  (insert-right ~ 'name)     ; (defun hello (name) (format t [\"Hello, ~A!~%\"] name))\n  ;; Reassembe the tree\n  unzip)\n=\u003e (DEFUN HELLO-WORLD () (FORMAT T \"Hello, world!\"))\n```\n\nLet's eval the form, run it, et voila\\`!\n\n```\n(eval *)\n=\u003e HELLO\n\n(funcall * \"Matteo\")\n..Hello, Matteo!\n=\u003e NIL\n```\n\n\n\u003ca id=\"x-28ZIP-3A-40ZIP-REFERENCE-20MGL-PAX-3ASECTION-29\"\u003e\u003c/a\u003e\n\n## 2 Reference\n\n\u003ca id=\"x-28ZIP-3ALOC-20CLASS-29\"\u003e\u003c/a\u003e\n\n- [class] **LOC** *[STRUCTURE-OBJECT][2038]*\n\n    A zipper's core data structure: a location object.\n    \n    It's composed of the following slots:\n    \n    - `node` represent the currently focused element.\n    \n    - [`nav`][beae] is a `NAV` object, allowing a zipper to efficiently move left, right, and\n      back up.\n    \n    - [`meta`][2d25] is is a `META` object containing pointers to fns used to implement the\n      zipper algorithm.\n\n\n\u003ca id=\"x-28ZIP-3ANAV-20CLASS-29\"\u003e\u003c/a\u003e\n\n- [class] **NAV** *[STRUCTURE-OBJECT][2038]*\n\n    A zipper's navigation object, enabling efficient movements left, right, and\n    up.\n    \n    It's composed of the following slots:\n    \n    - [`ups`][eb16] is the list of nodes visible above: the first element of the list\n      represents the node immediately above, while the last element represents the\n      root.\n    \n    - [`lefts`][4a8b] is the list of nodes visible the left: the first element of the list\n      represents the node immediately to the left, while the last element\n      represents the leftmost element to the left.\n    \n    - [`rights`][3ca6] is the list of nodes visible the right: the first element of the\n      list represents the node immediately to the right, while the last element\n      represents the rightmost element to the right.\n    \n    - `pnav` is a pointer to the `NAV` object of the parent, while `changed?` is\n      a flag indicating whether any mutation has been applied or not.  There are\n      mostly used to avoid cons-ing unless strictly required.\n\n\n\u003ca id=\"x-28ZIP-3AMETA-20CLASS-29\"\u003e\u003c/a\u003e\n\n- [class] **META** *[STRUCTURE-OBJECT][2038]*\n\n    A zipper's metadata object.\n    \n    It's composed of the following slots:\n    \n    - `branch?` is a fn that, given a [`LOC`][3a4a], returns `T` if it can have children, even\n      if it currently doesn't.\n    \n    - `children` is a fn that, given a `LOC`, returns a `LIST`([`0`][79d8] [`1`][6d9f]) of its children.\n    \n    - `make-node` is a fn that, given an existing `LOC` and a `LIST` of children,\n      returns a new branch `LOC` with the supplied children.\n\n\n\u003ca id=\"x-28ZIP-3AZIP-20GENERIC-FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [generic-function] **ZIP** *ROOT*\n\n    Creates a zipper and returns a [`LOC`][3a4a] focused on `root`\n\n\u003ca id=\"x-28ZIP-3AUNZIP-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **UNZIP** *LOC*\n\n    zip all the way up and returns the root node, reflecting any changes\n\n\u003ca id=\"x-28ZIP-3ADOWN-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **DOWN** *LOC*\n\n    Returns the `LOC` of the leftmost child of the node at this location, or nil\n    if no children\n\n\u003ca id=\"x-28ZIP-3AUP-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **UP** *LOC*\n\n    Returns the `LOC` of the parent of the node at this loc, or nil if at the top\n\n\u003ca id=\"x-28ZIP-3ALEFT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **LEFT** *LOC*\n\n    Returns the `LOC` of the left sibling of the node at this loc, or nil\n\n\u003ca id=\"x-28ZIP-3ALEFTMOST-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **LEFTMOST** *LOC*\n\n    Returns the `LOC` of the leftmost siblings of the node at this loc, or self\n\n\u003ca id=\"x-28ZIP-3ARIGHT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **RIGHT** *LOC*\n\n    Returns the `LOC` of the right sibling of the node at this loc, or nil\n\n\u003ca id=\"x-28ZIP-3ARIGHTMOST-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **RIGHTMOST** *LOC*\n\n    Returns the `LOC` of the rightmost siblings of the node at this loc, or self\n\n\u003ca id=\"x-28ZIP-3ANEXT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **NEXT** *LOC*\n\n    Moves to the next `LOC` in the hierarchy, depth-first.  When reaching the end,\n    returns nil.\n\n\u003ca id=\"x-28ZIP-3ANEXT-THAT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **NEXT-THAT** *FN LOC*\n\n    Moves to the next `LOC` in the hierarchy such that (apply fn loc) is `T`.\n    If no such `LOC` exists, returns nil.\n\n\u003ca id=\"x-28ZIP-3APREV-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **PREV** *LOC*\n\n    Moves to the previous `LOC` in the hierarchy, depth-first.  When at the root,\n    return nil.\n\n\u003ca id=\"x-28ZIP-3APREV-THAT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **PREV-THAT** *FN LOC*\n\n    Moves to the prev `LOC` in the hirerachy such that (apply fn loc) is `T`.\n    If no such `LOC` exists, returns nil.\n\n\u003ca id=\"x-28ZIP-3AINSERT-LEFT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **INSERT-LEFT** *LOC ITEM*\n\n    Inserts the item as the left sibling of the node at this loc, without\n    moving\n\n\u003ca id=\"x-28ZIP-3AINSERT-RIGHT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **INSERT-RIGHT** *LOC ITEM*\n\n    Inserts the item as the right sibling of the node at this loc, without\n    moving\n\n\u003ca id=\"x-28ZIP-3AREPLACE-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **REPLACE** *LOC ITEM*\n\n    Replaces the node at this loc, without moving\n\n\u003ca id=\"x-28ZIP-3AEDIT-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **EDIT** *LOC FN \u0026REST ARGS*\n\n    Replaces the node at this loc with the result of (apply fn node args)\n\n\u003ca id=\"x-28ZIP-3AINSERT-CHILD-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **INSERT-CHILD** *LOC ITEM*\n\n    Inserts item as the leftmost child of the node at this loc, without moving\n\n\u003ca id=\"x-28ZIP-3AAPPEND-CHILD-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **APPEND-CHILD** *LOC ITEM*\n\n    Inserts item as the rightmost child of the node at this loc, without moving\n\n\u003ca id=\"x-28ZIP-3AREMOVE-20FUNCTION-29\"\u003e\u003c/a\u003e\n\n- [function] **REMOVE** *LOC*\n\n    Removes the node at loc and moves to the previous loc in the hierarchy,\n    depth-first.\n\n  [2038]: http://www.lispworks.com/documentation/HyperSpec/Body/t_stu_ob.htm \"STRUCTURE-OBJECT (MGL-PAX:CLHS CLASS)\"\n  [2d25]: #x-28ZIP-3AMETA-20CLASS-29 \"ZIP:META CLASS\"\n  [3a4a]: #x-28ZIP-3ALOC-20CLASS-29 \"ZIP:LOC CLASS\"\n  [3ca6]: #x-28ZIP-3ARIGHT-20FUNCTION-29 \"ZIP:RIGHT FUNCTION\"\n  [4a8b]: #x-28ZIP-3ALEFT-20FUNCTION-29 \"ZIP:LEFT FUNCTION\"\n  [6d9f]: http://www.lispworks.com/documentation/HyperSpec/Body/f_list_.htm \"LIST (MGL-PAX:CLHS FUNCTION)\"\n  [7152]: #x-28ZIP-3A-40ZIP-REFERENCE-20MGL-PAX-3ASECTION-29 \"Reference\"\n  [79d8]: http://www.lispworks.com/documentation/HyperSpec/Body/t_list.htm \"LIST (MGL-PAX:CLHS CLASS)\"\n  [a050]: #x-28ZIP-3A-40ZIP-SYNOPSIS-20MGL-PAX-3ASECTION-29 \"Synopsis\"\n  [beae]: #x-28ZIP-3ANAV-20CLASS-29 \"ZIP:NAV CLASS\"\n  [eb16]: #x-28ZIP-3AUP-20FUNCTION-29 \"ZIP:UP FUNCTION\"\n\n* * *\n###### \\[generated by [MGL-PAX](https://github.com/melisgl/mgl-pax)\\]\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiamfirecracker%2Fcl-zip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fiamfirecracker%2Fcl-zip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fiamfirecracker%2Fcl-zip/lists"}