{"id":10918769,"url":"https://github.com/dtenny/clj-arrows","last_synced_at":"2025-09-17T08:32:36.381Z","repository":{"id":217157218,"uuid":"743203535","full_name":"dtenny/clj-arrows","owner":"dtenny","description":"Clojure-compatible threading/transformation/arrow macros for Common Lisp","archived":false,"fork":false,"pushed_at":"2024-01-14T16:56:01.000Z","size":8,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-06-08T15:06:41.566Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dtenny.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}},"created_at":"2024-01-14T16:35:51.000Z","updated_at":"2024-05-21T14:30:00.000Z","dependencies_parsed_at":"2024-01-14T21:54:36.295Z","dependency_job_id":null,"html_url":"https://github.com/dtenny/clj-arrows","commit_stats":null,"previous_names":["dtenny/clj-arrows"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtenny%2Fclj-arrows","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtenny%2Fclj-arrows/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtenny%2Fclj-arrows/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtenny%2Fclj-arrows/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dtenny","download_url":"https://codeload.github.com/dtenny/clj-arrows/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219852432,"owners_count":16553424,"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":[],"created_at":"2024-06-08T14:19:06.224Z","updated_at":"2025-09-17T08:32:31.099Z","avatar_url":"https://github.com/dtenny.png","language":"Common Lisp","funding_links":[],"categories":["Clojure"],"sub_categories":[],"readme":"# About\n\nProvides the threading and/or transformation macros of Clojure to an arguably\nstupid level of compatibility. Also provides some diamond wand macros\nnot found (at the time of this writing) in Clojure just so I can avoid importing\nother arrow macro packages.\n\nMost people will have no need of this package unless they've been doing a lot of Clojure.\nIt isn't like the world needs another arrow macro package.\nSee the 'prior art' section if you want the nitty gritty details.\n\n# Clojure Compatability / Rationale\n\nI don't generally try for exact CL replicas of Clojure syntax and semantics\nwith Clojure tooling adaptations to Common Lisp (see my various CLJ-* repos). Instead I try\nto adapt Clojure idioms to CL style, perhaps returning a list instead of a\nvector, or multiple values instead of a list. \n\nThat said, all symbols in _this_ package (CLJ-ARROWS) with namesakes\nin Clojure's core library provide _exactly_ the same behavior\nas Clojure at the time of this writing (Dec 2022), AFAIK.\n\n# Usage\n\n    (ql:quickload :clj-arrows)\n\nAdd it to the USE list of your package, or not, it will work either way with regard\nto `\u003c\u003e` symbol processing in diamond want macros, e.g.\n\n   (clj-arrows:-\u003c\u003e 1 (list 2 3) (list 4 \u003c\u003e 5)) =\u003e (4 (1 2 3) 5)\n\nTo run the tests:\n\n    (ql:quickload :clj-arrows-test)\n    (clj-arrows-test:run-tests)\n\nTested with sbcl 2.3.0 and abcl 1.9.0 in a Fedora 35 linux, \nACL 11.0 on Fedora 38, and CCL 1.12.2 on Fedora 38.\n\n# Documentation\n\nRefer to docstrings on the exported symbols which provide both semantic descriptions\nas well as examples of usage.  If you have used similar macros elsewhere note\nthe following potential compatability issues\n(described in more detail in 'prior art' below).\n\n1. If the macro has a clojure.core namesake in Clojure, it behaves identically.\n2. Point #1 means that the `cond-\u003e` and `cond-\u003e\u003e` macros use unparenthesized test + expr pairs, unlike CL's `cond` function and some `cond-\u003e` macro implementations.\n3. The diamond-wand implementation allows multiple `\u003c\u003e` substitutions, and does not evaluate the substituted expression more than once.\n\n\n# Exported symbols\n\n   ;; Clojure compatible macros\n\n   #:-\u003e\n   #:-\u003e\u003e\n   #:as-\u003e\n   #:cond-\u003e\n   #:cond-\u003e\u003e\n   #:some-\u003e\n   #:some-\u003e\u003e\n\n   ;; Additional macros not in clojure at the time of this writing.\n\n   #:-\u003c\u003e\n   #:-\u003c\u003e\u003e\n   #:some-\u003c\u003e\n   #:some-\u003c\u003e\u003e\n\n\n# Prior art (and license notes FMI)\n\nClojure, of course, and the following packages while looking for Clojure substitutes\nin Common Lisp.\n\n## [arrow-macros](https://github.com/hipeta/arrow-macros/)\n\nMIT license.\n\nI'm guessing this is what most Common Lisp users use. It is a nice library and\nit was my go-to library for a while in CL. It's the only one that supports\nClojure `cond-\u003e` semantics (yay!), and it also supports multiple `\u003c\u003e` substitutions \nin diamond wand macros.\n\nI had three issues with the library:\n\n1. There are no docstrings on the exported macros. If ever macros deserved docstrings, it's these.\n2. There is a bug (IMO) in the diamond wand macros.\n3. The behavior of `-\u003e` and similar macros is not consistent with Clojure (see below).\n\nOn 2, the bug is such that diamond wand substitutions won't work unless you\n:USE the package (or are in the :arrow-macros package) so that its internal\n`(eq '\u003c\u003e x)` checks will work.  If `\u003c\u003e` reference was interned in\nanother package, which it will be if you don't :USE the arrow-macros package, then\nyou'll get syntax errors. See [issues](https://github.com/hipeta/arrow-macros/issues/4).\n\nOn 3, basically ARROW-MACROS is smart enough to recognize lambda forms, and avoid\ninserting the threaded value into the form. E.g.\n\nIn Clojure:\n`(-\u003e 1 (fn [x] (+ x 1)))` expands to `(fn 1 [x] (+ x 1))`.  Oops. \n\nIn CLJ-ARROWS and perhaps other packages, the same thing happens:\n`(-\u003e 1 (lambda (x) (+ x 1)))` expands to `(lambda 1 (x) (+ x 1))`.  \nOops, but compatible with clojure.\n\nHowever the ARROW-MACROS package will expand it to `(funcall (lambda (x) (+ x 1)) 1)`. \nIt also do some funcall transformations on FUNCTION references.\n\nWhat ARROW-MACROS does with respect to functions is nice, but inconsistent with Clojure.\nNice experiment, but \"do what I mean\" taste.  If you're\ntrying to keep your brain from breaking because you switch-hit between the two\nlanguages (and perhaps share code between the two), stupid consistency may be\nbetter.  Or not. Whatever. For now the CLJ-ARROWS package does it the Clojure way\nand my mental hobgoblins are at rest.\n\nThe way you normally work around this FN/LAMBDA or similar problem in Clojure\n(and in CL with CLJ-ARROWS) is to simply\nadd a set of parens, e.g. `(-\u003e 1 ((lambda (x) (+ x 1))))`.\n\n## [arrows](https://github.com/Harleqin/arrows)\n\nIncompatible `cond-\u003e` semantics.  CC0 license.\n\n## [cl-swiss-arrows](https://github.com/andy128k/cl-swiss-arrows/)\n\nFocuses only on diamond wand macros, doesn't have the clojure macros.  No license stated.\n\nCL-SWISS-ARROWS supports multiple `\u003c\u003e` substitutions in forms, and avoids\nre-evaluating the substituted expression.  This is unlike some implementations\nincluding the Clojure SWISS-ARROWS implementation that appears to have been\nthe inspiration for diamond wand macros. CLJ-ARROWS adopts the behavior of CL-SWISS-ARROWS.\n\n## [cl-threading-macros](https://github.com/horellana/cl-threading-macros)\n\nOnly has `-\u003e` and `-\u003e\u003e`.  GPL3 license.\n\n## [simple-arrows](https://github.com/digikar99/simple-arrows)\n\nOnly has `-\u003e` and `-\u003e\u003e`. No license stated.\n\n## [swiss-arrows](https://github.com/rplevy/swiss-arrows)\n\nThis is the primary clojure addon package \n(in clojure, for clojure, but not in clojure.core) cited\nas inspiration for some of the above Common Lisp arrow packages.\n\nNote that this clojure version of diamond wand macros allows only a single substitution\nin a form, while CLJ-ARROWS supports CL-SWISS-ARROWS behavior that allows multiple\nsubstutitions (evaluated only once).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtenny%2Fclj-arrows","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdtenny%2Fclj-arrows","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtenny%2Fclj-arrows/lists"}