{"id":27389241,"url":"https://github.com/vvvvalvalval/supdate","last_synced_at":"2025-04-13T19:13:26.904Z","repository":{"id":62435152,"uuid":"77550382","full_name":"vvvvalvalval/supdate","owner":"vvvvalvalval","description":"Clojure's update with superpowers.","archived":false,"fork":false,"pushed_at":"2022-10-12T14:53:12.000Z","size":32,"stargazers_count":204,"open_issues_count":3,"forks_count":4,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-21T07:47:24.436Z","etag":null,"topics":["clojure","data-structures"],"latest_commit_sha":null,"homepage":"https://vvvvalvalval.github.io/supdate/","language":"Clojure","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/vvvvalvalval.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-12-28T17:39:41.000Z","updated_at":"2025-01-16T15:36:52.000Z","dependencies_parsed_at":"2022-11-01T21:16:19.898Z","dependency_job_id":null,"html_url":"https://github.com/vvvvalvalval/supdate","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fsupdate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fsupdate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fsupdate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fsupdate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vvvvalvalval","download_url":"https://codeload.github.com/vvvvalvalval/supdate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248766747,"owners_count":21158301,"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":["clojure","data-structures"],"created_at":"2025-04-13T19:13:26.355Z","updated_at":"2025-04-13T19:13:26.899Z","avatar_url":"https://github.com/vvvvalvalval.png","language":"Clojure","funding_links":[],"categories":[],"sub_categories":[],"readme":"# supdate\n\nClojure's update with superpowers.\n\n[![Clojars Project](https://img.shields.io/clojars/v/vvvvalvalval/supdate.svg)](https://clojars.org/vvvvalvalval/supdate)\n\nThis library provides a `supdate` macro which lets you transform Clojure data structures\ndeclaratively, using a data-driven specification which structure matches the schema of the input. \n\nThe benefit is that such specifications eliminate a lot of the boilerplate code involved\n when transforming nested data structures. \n \nIn addition, `supdate` is a macro that leverages static information on a best-effort basis \nin order to make the performance comparable to hand-written code.\nDynamic pre-compilation (via `compile`) is also available to achieve better performance while remaining fully dynamic.\n\n## Usage\n\n```clojure\n(require '[vvvvalvalval.supdate.api :as supd :refer [supdate]])\n\n;; canonical example\n(def my-input\n  {:a 1\n   :b [1 2 3]\n   :c {\"d\" [{:e 1 :f 1} {:e 2 :f 2}]}\n   :g 0\n   :h 0\n   :i 0})\n\n(supdate\n  my-input\n  {:a inc\n   :b [inc]\n   :c {\"d\" [{:e inc}]}\n   :g [inc inc inc]\n   :my-missing-key inc\n   :i false\n   })\n=\u003e {:a 2,\n    :b [2 3 4],\n    :c {\"d\" [{:e 2, :f 1} {:e 3, :f 2}]}\n    :g 3,\n    :h 0}\n```\n\nSee also the [tests](https://github.com/vvvvalvalval/supdate/blob/master/test/vvvvalvalval/supdate/test/api.clj)\n for more examples.\n\n### Emulating standard library operations\n\n`supdate` generalizes several functions of Clojure's standard library:\n\n```clojure\n\n;;;; Emulating clojure.core/update\n(update {:a 1 :b 1} :a inc)\n=\u003e {:a 2 :b 1}\n(supdate {:a 1 :b 1} {:a inc})\n=\u003e {:a 2 :b 1}\n\n;;;; Emulating clojure.core/update-in\n(update-in {:a {\"b\" [{:c 1}]}}\n  [:a \"b\" 0 :c] inc)\n=\u003e {:a {\"b\" [{:c 2}]}}\n(supdate {:a {\"b\" [{:c 1}]}}\n  {:a {\"b\" {0 {:c inc}}}})\n=\u003e {:a {\"b\" [{:c 2}]}}\n;; NOTE: unlike update-in, if a key is missing in the input, \n;; the transformation will be skipped instead of creating new maps.\n\n;;;; Emulating clojure.core/map \n(map dec (range 10))\n=\u003e (-1 0 1 2 3 4 5 6 7 8)\n(supdate (range 10) [dec])\n=\u003e (-1 0 1 2 3 4 5 6 7 8)\n;; Note: unlike map, if the input is a vector, the output will also be a vector.\n\n;;;; Emulating dissoc\n(dissoc {:a 1 :b 2 :c 3}\n  :a :b :d)\n=\u003e {:c 3}\n(supdate {:a 1 :b 2 :c 3}\n  {:a false :b false})\n=\u003e {:c 3}\n```\n\n### Pre-compiling transforms\n\nA `compile` function is available to make execution faster:\n\n```clojure\n\n(def transform\n  (supd/compile {:a inc\n                 :b [inc]\n                 :c {\"d\" [{:e inc}]}\n                 :g [inc inc inc]\n                 :missing-key inc\n                 :i false\n                 }))\n\n(transform {:a 1\n            :b [1 2 3]\n            :c {\"d\" [{:e 1 :f 1} {:e 2 :f 2}]}\n            :g 0\n            :h 0\n            :i 0})\n=\u003e {:a 2,\n    :b [2 3 4],\n    :c {\"d\" [{:e 2, :f 1} {:e 3, :f 2}]}\n    :g 3,\n    :h 0}\n\n```\n\n## Comparison to [Specter](https://github.com/nathanmarz/specter)\n\nThis library is in the same space as Specter, but we don't see it as a replacement to Specter.\nWe believe this library is useful in situations where using Specter is overkill.\n\nMore specifically:\n\n* Specter's `transform` is useful for making one sophisticated transformation,\n whereas `supdate` is good at making many basic transformations at once.\n* Specter provides a `select` operation, supdate is only about transformation.\n* Arguably, supdate is easier to learn.\n* Specter is extensible, supdate is not.\n\n## License\n\nCopyright © 2016 Valentin Waeselynck and contributors \n\nDistributed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvvvalvalval%2Fsupdate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvvvvalvalval%2Fsupdate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvvvalvalval%2Fsupdate/lists"}