{"id":19016163,"url":"https://github.com/fosskers/cl-nonempty","last_synced_at":"2026-03-19T07:40:45.867Z","repository":{"id":223059976,"uuid":"758909007","full_name":"fosskers/cl-nonempty","owner":"fosskers","description":"Non-empty collections for Common Lisp.","archived":false,"fork":false,"pushed_at":"2024-02-18T11:34:55.000Z","size":15,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-09T05:44:01.092Z","etag":null,"topics":["collections","common-lisp","non-empty"],"latest_commit_sha":null,"homepage":"","language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fosskers.png","metadata":{"files":{"readme":"README.org","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-02-17T12:42:18.000Z","updated_at":"2024-02-26T22:39:30.000Z","dependencies_parsed_at":"2024-02-18T01:27:59.704Z","dependency_job_id":"d8c0af63-0470-4cf5-a88c-eb99328fe2fa","html_url":"https://github.com/fosskers/cl-nonempty","commit_stats":null,"previous_names":["fosskers/cl-nonempty"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/fosskers/cl-nonempty","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fosskers%2Fcl-nonempty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fosskers%2Fcl-nonempty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fosskers%2Fcl-nonempty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fosskers%2Fcl-nonempty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fosskers","download_url":"https://codeload.github.com/fosskers/cl-nonempty/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fosskers%2Fcl-nonempty/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28877876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T10:31:27.438Z","status":"ssl_error","status_checked_at":"2026-01-29T10:31:01.017Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["collections","common-lisp","non-empty"],"created_at":"2024-11-08T19:41:30.681Z","updated_at":"2026-01-29T12:38:36.257Z","avatar_url":"https://github.com/fosskers.png","language":"Common Lisp","readme":"#+title: nonempty\n\n(This README is best viewed on [[https://codeberg.org/fosskers/nonempty][Codeberg]].)\n\nNon-empty collections for Common Lisp.\n\nNon-emptiness can be a powerful guarantee. There are often times when a\ncollection is passed to a function, but must contain some value to be useful. In\nthese cases we must manually check, or otherwise account for NIL in our logic.\nThis can muddle the clarity of the code, especially when emptiness is not a\nvalid state. It is here that non-empty variants of the usual collection types\ncan be used to great effect.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n\n;; Always succeeds, never nil.\n(car (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: 1\n\n* API\n\nThe examples here use ~(in-package :nonempty)~ for brevity, but it is assumed that\nyou will set a nickname in your own code:\n\n#+begin_src lisp\n(defpackage foo\n  (:use :cl)\n  (:local-nicknames (:ne :nonempty)))\n#+end_src\n\n** Non-empty Lists\n\nFunctions specific to non-empty lists.\n\n*** nel, cons\n\nConstruct a non-empty list from at least one input argument.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(nel 1 2 3)\n#+end_src\n\n#+RESULTS:\n: #S(NELIST :HEAD 1 :TAIL (2 3))\n\n\nAppend a new item onto the front of a non-empty list.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(cons 0 (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: #S(NELIST :HEAD 0 :TAIL (1 2 3))\n\n*** car, cdr\n\nThe first element of a non-empty list. Always succeeds.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(car (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: 1\n\nThe possibly-empty tail of a non-empty list.\n\n#+begin_src lisp :exports both :results verbatim\n(in-package :nonempty)\n(cdr (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: (2 3)\n\n*** map, filter, fold\n\nMap some FN over the given ITEMS, yielding a new non-empty list.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(map #'1+ (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: #S(NELIST :HEAD 2 :TAIL (3 4))\n\nKeep ITEMS for which a PRED function succeeds. Not guaranteed to be non-empty.\n\n#+begin_src lisp :exports both :results verbatim\n(in-package :nonempty)\n(filter #'evenp (nel 1 2 3 4 5 6))\n#+end_src\n\n#+RESULTS:\n: (2 4 6)\n\nReduce some ITEMS via a 2-arity FN.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(fold #'+ (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: 6\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(fold #'+ (nel 1 2 3) :seed 10)\n#+end_src\n\n#+RESULTS:\n: 16\n\n** Generics\n\n*** length\n\nThe length of the given non-empty structure.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(length (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: 3\n\n*** reverse\n\nThe reverse of the given non-empty structure.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(reverse (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: #S(NELIST :HEAD 3 :TAIL (2 1))\n\n*** elt, last\n\nThe element of ITEMS specified by INDEX.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(elt (nel 1 2 3) 2)\n#+end_src\n\n#+RESULTS:\n: 3\n\nThe last element of the ITEMS. Guaranteed to exist.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(last (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: 3\n\n*** append\n\nAppend some OTHER collection to a NONEMPTY one.\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(append (nel 1 2 3) (nel 4 5 6))\n#+end_src\n\n#+RESULTS:\n: #S(NELIST :HEAD 1 :TAIL (2 3 4 5 6))\n\n#+begin_src lisp :exports both\n(in-package :nonempty)\n(append (nel 1 2 3) '(4 5 6))\n#+end_src\n\n#+RESULTS:\n: #S(NELIST :HEAD 1 :TAIL (2 3 4 5 6))\n\n\n*** to-list\n\nConvert this non-empty collection into a normal list.\n\n#+begin_src lisp :exports both :results verbatim\n(in-package :nonempty)\n(to-list (nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: (1 2 3)\n** Transducers Support\n\nFor additional high-level collection operations, support for [[https://codeberg.org/fosskers/cl-transducers][Transducers]] is\nprovided by the ~nonempty/transducers~ system. As this incurs additions\ndependencies, it is entirely optional. The examples below use full symbol paths,\nbut it's assumed that you'll set appropriate nicknames:\n\n#+begin_src lisp\n(defpackage foo\n  (:use :cl)\n  (:local-nicknames (:ne :nonempty)\n                    (:nt :nonempty/transducers)\n                    (:t  :transducers)))\n#+end_src\n\nNon-empty lists can be used as \"sources\" as-is:\n\n#+begin_src lisp :exports both :results verbatim\n(in-package :transducers)\n(transduce (map #'1+) #'cons (nonempty:nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: (2 3 4)\n\nAnd you can also reduce back into a non-empty list, provided that something\nactually made it through the transduction:\n\n#+begin_src lisp :exports both :results verbatim\n(in-package :transducers)\n(transduce (map #'1+) #'nonempty/transducers:nelist (nonempty:nel 1 2 3))\n#+end_src\n\n#+RESULTS:\n: #S(NONEMPTY:NELIST :HEAD 2 :TAIL (3 4))\n\n* Further Work\n\n- Non-empty Vectors\n- Non-empty Hash Tables\n\n* See Also\n\n- [[https://lib.rs/crates/nonempty-collections][Rust: nonempty-collections]]\n- [[https://codeberg.org/fosskers/cl-transducers][Transducers]]\n- [[https://codeberg.org/fosskers/nonempty][Codeberg Mirror]]\n- [[https://github.com/fosskers/cl-nonempty][Github Mirror]]\n","funding_links":[],"categories":["Expert Systems"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffosskers%2Fcl-nonempty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffosskers%2Fcl-nonempty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffosskers%2Fcl-nonempty/lists"}