{"id":13726087,"url":"https://github.com/art-w/deque","last_synced_at":"2026-01-18T08:20:59.850Z","repository":{"id":49355648,"uuid":"343529194","full_name":"art-w/deque","owner":"art-w","description":"Purely Functional, Real-Time Deques with Catenation (Kaplan \u0026 Tarjan)","archived":false,"fork":false,"pushed_at":"2024-06-28T08:02:06.000Z","size":168,"stargazers_count":104,"open_issues_count":0,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-08-04T01:28:29.887Z","etag":null,"topics":["deques"],"latest_commit_sha":null,"homepage":"https://art-w.github.io/deque/deque/Deque/","language":"OCaml","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/art-w.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":"2021-03-01T19:14:55.000Z","updated_at":"2024-04-07T14:52:44.000Z","dependencies_parsed_at":"2024-01-10T18:34:51.275Z","dependency_job_id":null,"html_url":"https://github.com/art-w/deque","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/art-w%2Fdeque","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/art-w%2Fdeque/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/art-w%2Fdeque/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/art-w%2Fdeque/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/art-w","download_url":"https://codeload.github.com/art-w/deque/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224654127,"owners_count":17347673,"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":["deques"],"created_at":"2024-08-03T01:02:52.202Z","updated_at":"2026-01-18T08:20:59.819Z","avatar_url":"https://github.com/art-w.png","language":"OCaml","funding_links":[],"categories":["OCaml"],"sub_categories":[],"readme":"\u003e **[Purely Functional, Real-Time Deques with Catenation]** \\[284ko postscript\\] \\\n\u003e by Haim Kaplan and Robert E. Tarjan \\\n\u003e journal of the ACM 31:11-16 (1999) 1709-1723 https://doi.org/10.1145/324133.324139\n\nFollowing the paper, this library provides 4 implementations of double-ended\nqueues which let you push, pop and append elements at both ends of an ordered\ncollection in worst-case constant time (strict! not amortized) :\n\n| Module  | cons | uncons | snoc | unsnoc          | append          | rev             | nth                |\n|---------|:----:|:------:|:----:|:---------------:|:---------------:|:---------------:|:------------------:|\n| Dequeue | O(1) | O(1)   | O(1) | O(1)            | :no_entry_sign: | O(1)            | O(log min(i, N-i)) |\n| Steque  | O(1) | O(1)   | O(1) | :no_entry_sign: | O(1)            | :no_entry_sign: | :no_entry_sign:    |\n| Deck    | O(1) | O(1)   | O(1) | O(1)            | O(1)            | :no_entry_sign: | :no_entry_sign:    |\n| Deckrev | O(1) | O(1)   | O(1) | O(1)            | O(1)            | O(1)            | :no_entry_sign:    |\n\nCheck out the [online documentation] for the full interface -- which should be\nmostly compatible with OCaml's standard [List] module.\n\nEven though the algorithmic complexity is great, these deques add a significant\noverhead when compared to lists:\n\n|             | List | Dequeue | Steque | Deck  | Deckrev |\n|------------:|-----:|--------:|-------:|------:|--------:|\n| `cons`      | 1x   | 1.5x    | 1.6x    | 1.6x  | 2.5x    |\n| `uncons`    | 1x   | 13x     | 13x     | 19x   | 22x     |\n| `fold_left` | 1x   | 4.5x    | 4.5x    | 4.5x  | 11.1x   |\n\n![appending a list with itself](https://art-w.github.io/deque/append.png)\n\n---\n\nExample applications include:\n\n- [ngrams.ml](examples/ngrams.ml) uses a sliding window to enumerate the ngrams\n  of a string.\n- [knuth_plass.ml](examples/knuth_plass.ml) implements the optimal line\n  breaking algorithm of Knuth \u0026 Plass (of TeX fame) as described by Oege de\n  Moor and Jeremy Gibbons in [Bridging the algorithm gap: A linear-time\n  functional program for paragraph formatting].\n- [string_builder.ml](examples/string_builder.ml) shows how to improve the\n  asymptotics of a monoidal \"concat\" operator, a common design pattern in\n  purely functional libraries. Surprisingly, this benchmark reveals that the\n  simpler [difference lists] may exhibit weird edge cases in addition to being\n  less flexible. See [Reflection without remorse] by Atze van der Ploeg and\n  Oleg Kiselyov for a non-obvious application to monadic computations.\n- [zipper.ml](examples/zipper.ml) is a classic zipper to iterate over an\n  ordered collection, with the added benefit that one can instantly close the\n  traversal in `O(1)` rather than `O(length traversed)`. Such a zipper is a\n  prerequisite for Brodal's [Fast Join-trees] and the [Functional Link-Cut\n  trees] of Erik Demaine.\n- Finally, these deques are suitable for marshalling and serialization as they\n  do not use lazy or functional values in their spine.\n\n---\n\nNone of this code would have been possible without the fantastic support for\nGADTs in OCaml. The invariants are encoded inside each datatypes: the\nalgorithms then follow, guided by the type checker and the lack of recursion.\nAs this does not result in the most readable code, you should read the paper if\nyou want to understand the big ideas:\n\n- [Skewed number systems] to deamortize carry propagation\n- Recursive slowdown and bootstrapping\n- Datastructures with a hole / with a preferred path to define `O(1)` fingers\n  inside a purely functional tree\n\nThe core types and algorithms described in the paper can be found in the\n`src/*_internal.ml` files.\n\n[Purely Functional, Real-Time Deques with Catenation]: http://www.cs.tau.ac.il/~haimk/papers/jacm-deq.ps\n[online documentation]: https://art-w.github.io/deque/deque/Deque\n[List]: https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html\n[Skewed number systems]: https://en.wikipedia.org/wiki/Skew_binary_number_system\n[Bridging the algorithm gap: A linear-time functional program for paragraph formatting]: https://doi.org/10.1016/S0167-6423(99)00005-2\n[difference lists]: https://en.wikipedia.org/wiki/Difference_list\n[Reflection without remorse]: https://doi.org/10.1145/2775050.2633360\n[Fast Join-trees]: https://doi.org/10.1007/11841036_18\n[Functional Link-Cut trees]: http://erikdemaine.org/papers/ConfluentTries_Algorithmica/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fart-w%2Fdeque","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fart-w%2Fdeque","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fart-w%2Fdeque/lists"}