{"id":13546282,"url":"https://github.com/clojure/data.finger-tree","last_synced_at":"2025-04-07T12:07:23.984Z","repository":{"id":1112165,"uuid":"981178","full_name":"clojure/data.finger-tree","owner":"clojure","description":"Finger Tree data structure","archived":false,"fork":false,"pushed_at":"2024-07-15T17:56:30.000Z","size":143,"stargazers_count":215,"open_issues_count":1,"forks_count":14,"subscribers_count":32,"default_branch":"master","last_synced_at":"2025-03-31T10:07:14.760Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clojure.png","metadata":{"files":{"readme":"README.md","changelog":"Changes.md","contributing":"CONTRIBUTING.md","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":"2010-10-12T13:28:17.000Z","updated_at":"2025-03-23T03:05:21.000Z","dependencies_parsed_at":"2024-01-08T18:03:35.973Z","dependency_job_id":"e21a1814-4f03-4580-86ac-0dbb27636923","html_url":"https://github.com/clojure/data.finger-tree","commit_stats":{"total_commits":92,"total_committers":8,"mean_commits":11.5,"dds":"0.26086956521739135","last_synced_commit":"22983edfa22cd742876c892d462cc04cb44d307e"},"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fdata.finger-tree","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fdata.finger-tree/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fdata.finger-tree/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clojure%2Fdata.finger-tree/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clojure","download_url":"https://codeload.github.com/clojure/data.finger-tree/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247648977,"owners_count":20972945,"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-08-01T12:00:35.098Z","updated_at":"2025-04-07T12:07:23.961Z","avatar_url":"https://github.com/clojure.png","language":"Clojure","funding_links":[],"categories":["Clojure","Advanced datastructures"],"sub_categories":[],"readme":"# Finger Trees\n\nFinger trees are a versatile family of fully persistent collections.  This library includes everything you need to make your own, as well a few ready-to-use collection types:\n\n- **double-list** is a sequential collection that provides constant-time access to both the left and right ends.\n\n- **counted-double-list** provides all the features of double-list plus constant-time `count` and log-n `nth`.\n\n- **counted-sorted-set** is sorted set that also provides log-n `nth`\n\nThere are examples of all these later in the README.\n\n# Finger Tree Quickstart\n\n## [CLI/`deps.edn`](https://clojure.org/reference/deps_and_cli) dependency information:\n```clojure\norg.clojure/data.finger-tree {:mvn/version \"0.1.0\"}\n```\n\n## project.clj\n\nIf you use leiningen or cake, add this to the `:dependencies` in your `project.clj`:\n\n    [org.clojure/data.finger-tree \"0.1.0\"]\n\n## pom.xml\n\nIf you use maven, add this to the `\u003cdependencies\u003e` in your `pom.xml`:\n\n    \u003cdependency\u003e\n      \u003cgroupId\u003eorg.clojure\u003c/groupId\u003e\n      \u003cartifactId\u003edata.finger-tree\u003c/artifactId\u003e\n      \u003cversion\u003e0.1.0\u003c/version\u003e\n    \u003c/dependency\u003e\n\nYou'll need git and maven, then execute the following at a shell prompt to fetch finger trees and all its dependencies (including a recent snapshot of Clojure itself) and start a REPL:\n\n## use/require\n\nRegardless of how you fetch the dependency, to use a finger-tree\nfunction in your project you'll need to add something like this to\nyour `ns` declaration:\n\n    (:use [clojure.data.finger-tree :only [double-list]])\n\n# Talk\n\nThanks to heroku for hosting the [slides for my Clojure Conj talk][1] about this library.  The rather raw sources and enormous PDF of the slides are at [github][2].\n\n# Examples\n\nThe finger-tree lib actually includes several collections built on top\nof [Ralf Hinze and Ross Paterson's finger trees][3].  Here are some\nexamples of each of them:\n\n## double-list\n\nThe double-list is a sequential collection that provides constant-time\naccess to both the left and right ends:\n\n    (def dl (double-list 4 5 6 7))\n\n    dl\n    ;=\u003e (4 5 6 7)\n\n    [(first dl) (rest dl)]\n    ;=\u003e [4 (5 6 7)]\n\n    (conjl dl 'x)\n    ;=\u003e (x 4 5 6 7)\n\n    [(pop dl) (peek dl)]\n    ;=\u003e [(4 5 6) 7]\n\n    (conj dl 'x)\n    ;=\u003e (4 5 6 7 x)\n\n## counted-double-list\n\nThis provides all the features of double-list plus constant-time\n`count` and log-n `nth`:\n\n    (def cdl\n      (apply counted-double-list '[a b c d e f g h i j k l m]))\n\n    (nth cdl 5)\n    ;=\u003e f\n\n    (assoc cdl 5 'XX)\n    ;=\u003e (a b c d e XX g h i j k l m)\n\n    (def parts\n      (let [[left _ right] (ft-split-at cdl 5)]\n        {:left left, :right right}))\n\n    parts\n    ;=\u003e {:left (a b c d e), :right (g h i j k l m)}\n\n    (ft-concat (conj (:left parts) 'XX) (:right parts))\n    ;=\u003e (a b c d e XX g h i j k l m)\n\n    (ft-concat (:left parts) (:right parts))\n    ;=\u003e (a b c d e g h i j k l m)\n    ;             ^-- missing f\n\n    (ft-concat (into (:left parts) '[X Y Z]) (:right parts))\n    ;=\u003e (a b c d e X Y Z g h i j k l m)\n\n## counted-sorted-set\n\nThis is like counted-double-list, but does not support `conjl`.  Instead, `conj` is used to insert items in sorted order.\n\n    (def css (apply counted-sorted-set\n                    '[m j i e d a f k b c f g h l]))\n    css\n    ;=\u003e (a b c d e f g h i j k l m)\n\n    (get css 'e)      ; O(log(n))\n    ;=\u003e e\n\n    (get css 'ee)     ; O(log(n))\n    ;=\u003e nil\n\n    (count css)       ; O(1)\n    ;=\u003e 13\n\n    (nth css 5)       ; O(log(n))\n    ;=\u003e f\n\n## Build-your-own finger tree\n\n    (def empty-cost-tree (finger-tree (meter :cost 0 +)))\n\n    (def ct (conj empty-cost-tree\n                  {:id :h, :cost 5} {:id :i, :cost 1}\n                  {:id :j, :cost 2} {:id :k, :cost 3}\n                  {:id :l, :cost 4}))\n\n    (measured ct)\n    ;=\u003e 15\n\n    (next (split-tree ct #(\u003e % 7)))\n    ;=\u003e ({:cost 2, :id :j}\n         ({:cost 3, :id :k} {:cost 4, :id :l}))\n\n    (next (split-tree (rest ct) #(\u003e % 7)))\n    ;=\u003e ({:cost 4, :id :l} ())\n\n[1]: http://talk-finger-tree.heroku.com/\n[2]: http://github.com/Chouser/talk-finger-tree\n[3]: http://www.soi.city.ac.uk/~ross/papers/FingerTree.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure%2Fdata.finger-tree","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclojure%2Fdata.finger-tree","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclojure%2Fdata.finger-tree/lists"}