[
  {
    "path": ".github/FUNDING.yml",
    "content": "github: cnuernber\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "content": "name: Automated tests\n\non:\n  push:\n\njobs:\n  test:\n    runs-on: ubuntu-22.04\n    steps:\n    - uses: actions/checkout@v3\n    - name: Restore cached dependencies\n      uses: actions/cache/restore@v3\n      with:\n        path: |\n           ~/.m2/repository\n           ~/.deps.clj\n        key: cljdeps-${{ hashFiles('deps.edn') }}\n    - name: Mise-en-place setup\n      uses: jdx/mise-action@v2\n      with:\n        install: true\n        cache: true\n    - name: Setup Clojure\n      uses: DeLaGuardo/setup-clojure@12.1\n      with:\n        cli: 1.11.1.1413\n    - name: Run automated tests - Java 11\n      run: |\n        mise use java@corretto-11\n        java -version\n        scripts/run-tests\n    - name: Run automated tests - Java 17\n      run: |\n        mise use java@corretto-17\n        java -version\n        scripts/run-tests\n    - name: Run automated tests - Java 19\n      run: |\n        mise use java@corretto-19\n        java -version\n        scripts/run-tests\n    - name: Run automated tests - Java 21\n      run: |\n        mise use java@corretto-21\n        java -version\n        scripts/run-tests\n    - name: Run automated tests - Java 22\n      run: |\n        mise use java@corretto-22\n        java -version\n        scripts/run-tests\n    - name: Cache dependencies\n      uses: actions/cache@v3\n      with:\n        path: |\n           ~/.m2/repository\n           ~/.deps.clj\n        key: cljdeps-${{ hashFiles('deps.edn') }}\n        restore-keys: cljdeps-\n"
  },
  {
    "path": ".gitignore",
    "content": ".cpcache\ntarget\n.nrepl-port\npom.xml\n*.asc\nissue-data\njdk-*\n.clj-kondo\n.lsp\n.dir-locals.el\n"
  },
  {
    "path": ".mise.toml",
    "content": "[tools]\njava = \"corretto-8\"\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# 3.029\n * Much more thorough support for spliterators and forkjoinpool. See spliterator and fjp namespaces\n   respectively.\n \n# 3.025\n * bloom filters handle java.time.Instants automatically\n \n# 3.023\n * fix - process/launch invalid stdout for very quick processes.\n \n# 3.022\n * merge-iterable returns a seq-iterable so it plays nice with the REPL.\n \n# 3.020\n * seq-iterables cannot be `counted?`\n \n# 3.019\n * Fix bug in with empty sequences and pmap-io.\n \n# 3.018\n * iterator/merge-iterable has to be stable w/r/t iterator order - leftmost wins.\n \n# 3.017\n * Fix for concat, apply-concat to make their iterators a bit lazier than they were before.\n \n# 3.015\n * Fix for issue 10 - partition-all works different.\n * new partition fns - partition-by-cost and partition-by-comparator.\n * new iterator fns - iter-take-while, wrap-iter, iter-take\n \n# 3.013\n * iterators created via iterator/once-iterable and iterator/iterable are as lazy as possible\n   avoiding certain types of lookahead and hanging behavior.\n \n# 3.010\n * Reduce require time for defprotocol by avoiding primitive-invoke namespace.\n \n# 3.009\n * Issue fixed in process namespace.\n \n# 3.008\n * [issue 22](https://github.com/cnuernber/ham-fisted/issues/21) - better clj-condo support.\n * new [process](https://cnuernber.github.io/ham-fisted/ham-fisted.process.html) namespace for \n   launching and controlling sub processes.\n \n# 3.003\n * New functions and docs added to 'iterator' namespace.\n \n# 3.000\n * All protocols replaced with hamf's defprotocol impl.\n \n# 2.039\n * Slightly faster protocol dispatch as avoids instance check for interface impl in favor of\n   only using map lookup.\n * Implementation of cond that can be used in functions that need to avoid boxing.\n \n# 2.038\n * Fixing some small perf issues with primitive protocol implementations.\n \n# 2.037\n * Object constants work when explicitly specified via 'extend'.\n * Object arrays explicitly checked for protocol dispatch when \n   dealing with array types.\n * 'true' and 'false' supported as object constant types - nil unsupported.\n * Namespace comments.\n \n# 2.036\n * Work on defprotocol to support primitive and constant return types.\n \n# 2.035\n * Mutable treelists now result in less data on sublist and error on double persistent call.\n\n# 2.034\n * Fix to smarter sublist impl - incorrect in some cases -- tests updated to catch in future.\n \n# 2.033\n * MAJOR UPGRADE - implemented vec and vector as treelists.  This matches Clojure's\n   persistent vector implementation in performance for mutable and immutable conj,\n   reduce pathways but has a much smarter subvec implementation and faster\n   conversion to and from object arrays.\n \n# 2.032\n * Two merge-iterator implementations used to N-way merging of sorted sequences.  Linear is for small n <= 32 and\n   the priority queue method is for larger N's.  The exact cutoff where performance will matter will depend on\n   the dataset and the relative cost of the comparator.\n * Attempted to move all sorts to Arrays/parallelSort as it outperforms fastutils parallel sort by a bit.\n * added lsum, lsummary, dsummary for long-space sum, and simple summary statistics [min max mean sum n-elems] in long and double space respectively.\n\n# 2.031\n * `(reduce + 0 (lznc/apply-concat nil))` works.\n\n# 2.030\n * pmap-opts could produce an empty incorrect result if a custom pool was provided and parallelism was not specified.\n\n# 2.029\n * Error in hash-map compute - did not remove key if compute fn was nil.\n\n# 2.028\n * First class bloom filter support - uses apache parquet block-split-bloom-filter.\n\n# 2.027\n * Fix for api/difference when left hand side is a java map.\n\n# 2.026\n * Somewhat faster byte and short array creation when input is an IMutList impl.\n\n# 2.025\n * Bugfix so update-values is consistent with persistent maps.\n\n# 2.024\n * Bugfix for add-constant! default impls.\n\n# 2.023\n * Bulk add-constant interface for all growable lists.\n\n# 2.022\n * growable lists support clear.\n\n# 2.021\n * `lines` - replacement for line-seq that returns an auto-closeable iterable and cannot cache nor hold-onto-head\n    the data.\n * `re-matches` - faster version of re-matches.\n\n# 2.020\n * split caffeine support off into its own namespace.\n\n# 2.019\n * impl/pmap really does support user-defined thread pool.\n\n# 2.018\n * Add clj-kondo exports and config, fix linting errors\n * Remove support for and call to `take-last` 1-arity, which was not valid.\n * Fix variable arity `merge-with`, which was not correctly implemented.\n * `apply-concat`, `concat-opts` accept cat-parallelism option allow you to specify how the concatenation\n   should be parallelized at the creation source as opposed to at the preduce/parallel reduction callsite.\n\n# 2.017\n * Faster compose-reducers especially where there really are a lot of reducers.\n\n# 2.015\n * [issue 13](https://github.com/cnuernber/ham-fisted/issues/13) - any IMutList chunkedSeq was partially incorrect.\n\n# 2.014\n * frequencies respects map-fn option to allow concurrent hashmaps to be used.\n\n# 2.013\n * `cartesian-map` no longer has a random access variant.  The cooler version of this uses the tensor\n   address mechanism to allow parallel redution.\n * fixed major issue with parallel frequencies.\n\n# 2.011\n * Much faster every? implementation esp. for primitive arrays and persistent vectors.\n * More hlet extensions - `lng-fns` and `dbl-fns` which are faster in the general case\n   then `lngs` and `dbls` as they avoid RT/nth.\n * efficient `cartesian-map` which does a cartesian join across its inputs and calls f on\n   each value.\n```clojure\nuser> (hamf/sum-fast (lznc/cartesian-map\n                      #(h/let [[a b c d](lng-fns %)]\n                         (-> (+ a b) (+ c) (+ d)))\n                      [1 2 3]\n                      [4 5 6]\n                      [7 8 9]\n                      [10 11 12 13 14]))\n3645.0\n```\n\n# 2.010\n * Extensible let - hlet and helpers make using the primitive overloads of clojure functions easier.\n   See the ham-fisted.hlet and ham-fisted.primtive-invoke namespaces.\n\n# 2.009\n * typed 'nth' methods efficient for primitive manipulations - 'dnth', 'fnth', 'inth', 'lnth'.\n\n\n# 2.008\n * Custom reduce implemented for object array wrappers.\n\n\n2.007\n* reduce namespace now has helper to create a parallel reducer.\n* hashset has optimized addall pathway when input is another hashset.\n\n# 2.006\n * partition-by accepts a predicate function in options - example in docs.\n\n# 2.005\n * implemented lazy noncaching partition-all - similar perf to partition-by.\n * Faster default dispatch for pgroups, upgroups.\n * Faster sum-fast if input is random access.\n\n# 2.004\n * Faster sort implemented as default in several places.\n\n# 2.004\n * Ensure all object sorting is done with parallelQuickSort.\n * Small fix to array macros to use l2i instead of RT.intCast.\n\n# 2.003\n * Major issue in compose-reducers - object composition was typed to double reduction.\n\n# 2.002\n * slightly faster partition-by - inner loop written in java.\n\n# 2.001\n * Added lazy-noncaching partition-by.  This method has somewhat higher performance than\n   clojure.core/partition-by as it does not make intermediate containers and is strictly\n   lazy-noncaching.\n\n# 2.000\n * Rebuilt hashmaps on faster foundation especially for micro benchmarks.\n * Removed bits and pieces that do not provide enough return on investment.\n * For more in-depth comments see [PR-7](https://github.com/cnuernber/ham-fisted/pull/7).\n\n# 1.009\n * new linked hashmap implementation with equiv-semantics and fast union op.\n\n# 1.008\n * Fast set intersection for longer sequencers of sets (intersect-sets).\n\n# 1.007\n * Fast pathways for finding min/max index of a collection of objects in a similar way to min-key and max-key.\n\n# 1.006\n * Very specific upgrade to combine-reducers pathways.\n\n# 1.005\n * pmap, upmap pathways now return an object that full implements seqable and ireduceinit.\n\n# 1.002\n * Added n-lookahead to the parallel options pathway as for some problems\n   this makes a major difference in the efficiency of the pmap pathway.\n\n# 1.001\n * Fixed pmap implementation to release memory much more aggressively.\n\n# 1.000-beta-98\n * Fixed serious but subtle issue when a transient hash map is resized.  This should be\n   considered a must-have upgrade.\n\n# 1.000-beta-96\n * Fixed from upgrading dtype-next.\n * Major breaking changes!! API functions have been moved to make the documentation\n   clearer and the library more maintainable in the long run.\n * map-union of mutable or transient maps produces mutable or transient maps!\n * Final refactoring before 1.000 release.\n * Functions to make creating java.util.function objects are moved to ham-fisted.function.\n * Reduction-related systems are moved to ham-fisted.reduce.\n * java.util.Map helpers are moved to ham-fisted.mut-map.\n\n# 1.000-beta-93\n * java implementation of a batched stream reducer.  This avoids adding java to\n   the stream api.\n\n# 1.000-beta-92\n * pure java reductions for situations where you have an index fn a count.  These mainly\n   just make benchmarks a bit more stable.\n\n# 1.000-beta-91\n * IFnDef supports interfaces for long supplier (L), double supplier (D), and\n   Supplier (O).\n\n# 1.000-beta-90\n * Accelerated map boolean union, intersection, difference  for hashtable, long hashtable.\n * Major bugfix in map dissoc.\n\n\n# 1.000-beta-89\n * Added inc-consumer - returns a generic consumer that increments a long.  Useful for the various\n   situations where you need to track an incrementing variable but don't want the overhead of\n   using a volatile variable.\n\n# 1.000-beta-88\n * Immutable maps and vectors derive from APersistentMap and APersistentVector so that downtream\n   libraries can pick them up transparently.\n\n# 1.000-beta-86\n * Error in reduction of empty ranges.\n\n# 1.000-beta-85\n * Slightly faster map construction pathways.\n * In fact both the hamf base map `mut-map` and the integer-specialized `mut-long-hashtable-map` are\n   faster than the default `clojure.data.int-map` pathway for construction and value lookup according\n   to the benchmarks in `clojure.data.int-map`.  Interestingly enough they are fastest if you create\n   an intermediate object array using lznc/apply-concat:\n\n```clojure\nuser> (count entries)\n1000000\nuser> (c/quick-bench (into (persistent! (hamf/mut-long-hashtable-map))  entries))\nEvaluation count : 6 in 6 samples of 1 calls.\n             Execution time mean : 366.247830 ms\n    Execution time std-deviation : 11.024896 ms\n   Execution time lower quantile : 348.564420 ms ( 2.5%)\n   Execution time upper quantile : 376.625750 ms (97.5%)\n                   Overhead used : 1.492920 ns\nnil\nuser> (c/quick-bench (into (i/int-map) entries))\nEvaluation count : 6 in 6 samples of 1 calls.\n             Execution time mean : 568.189038 ms\n    Execution time std-deviation : 1.677163 ms\n   Execution time lower quantile : 566.564884 ms ( 2.5%)\n   Execution time upper quantile : 570.564253 ms (97.5%)\n                   Overhead used : 1.492920 ns\nnil\nuser> (def ll (into (persistent! (hamf/mut-long-hashtable-map)) entries))\n#'user/ll\nuser> (def il (into (i/int-map) entries))\n#'user/il\nuser> (c/quick-bench\n       (dotimes [idx (count entries)]\n         (.get ^java.util.Map ll idx)))\n\nEvaluation count : 84 in 6 samples of 14 calls.\n             Execution time mean : 7.399383 ms\n    Execution time std-deviation : 62.314286 µs\n   Execution time lower quantile : 7.297162 ms ( 2.5%)\n   Execution time upper quantile : 7.451677 ms (97.5%)\n                   Overhead used : 1.492920 ns\nnil\nuser> (c/quick-bench\n       (dotimes [idx (count entries)]\n         (.get ^java.util.Map il idx)))\n\nEvaluation count : 30 in 6 samples of 5 calls.\n             Execution time mean : 22.936125 ms\n    Execution time std-deviation : 583.510734 µs\n   Execution time lower quantile : 22.334216 ms ( 2.5%)\n   Execution time upper quantile : 23.654541 ms (97.5%)\n                   Overhead used : 1.492920 ns\nnil\nuser>\n\nuser> (c/quick-bench (hamf/mut-long-hashtable-map (hamf/into-array Object (lznc/apply-concat entries))))\nEvaluation count : 6 in 6 samples of 1 calls.\n             Execution time mean : 271.755568 ms\n    Execution time std-deviation : 1.545379 ms\n   Execution time lower quantile : 270.184413 ms ( 2.5%)\n   Execution time upper quantile : 273.736344 ms (97.5%)\n                   Overhead used : 1.492920 ns\nnil\n```\n\n\n# 1.000-beta-84\n * `wrap-array`, `wrap-array-growable`, major into-array optimizations and better\n   `map-reducible`.\n\n# 1.000-beta-83\n * Opening the door to custom IReduce implementations.\n\n# 1.000-beta-82\n * convert hashsets to use hashtables instead of bitmap tries.\n * careful analysis of various vec-like object creation mechanisms.\n\n# 1.000-beta-81\n * long primitive hashtables - these are quite a bit faster but especially when used directly.\n\n# 1.000-beta-80\n * Helpers for very high performance scenarios.  lazy-noncaching/map-reducible,\n   api/->long-predicate.\n\n# 1.000-beta-78\n * fill-range is now property accelerated making all downstream projects that use addAll and\n   friends far faster.\n\n# 1.000-beta-77\n * see [commit 38596d8](https://github.com/cnuernber/ham-fisted/commit/38596d85541de7d2c926ac8b16522a764fcb6af9)\n\n# 1.000-beta-76\n * Added group-by-consumer - this has different performance and functionality characteristics\n   than group-by-reducer.  For instance, group-by-consumer with a linked hashmap will return\n   a map with keys in the order of keys initially encounted.  group-by-reducer with the same\n   hashmap will return a map with keys in the order of latest encountered.  Group-by-consumer\n   uses `computeIfAbsent` which is a slightly faster primitive than `compute` as it doesn't\n   need to check the return value of the reducer, only of the initialization of the map\n   entry.\n\n# 1.000-beta-75\n * MapForward class so we can use normal java maps in normal Clojure workflows.\n\n# 1.000-beta-74\n * bugfix - Map's `compute` has to accept nil keys.\n\n# 1.000-beta-73\n * memoize now supports `:eviction-fn` - for callbacks when things get evicted.\n * More helpers for memoized fns - cache-as-map, evict-memoized-call.\n\n# 1.000-beta-72\n * Switch to caffeine for memoize cache and standard java library priority queue for take-min.\n This removed the dependency on google guava thus drastically cutting the chances for dependency\n conflicts.\n\n# 1.000-beta-71\n * HUGE CHANGES!!! - moved to hashtable implementation for main non-array map instead of\n   bitmap trie.  This is because in all my tests it is *much* faster for everything *aside*\n   from non-transient (reduce assoc ...) type loops which are a waste of time to begin with.\n * Because there are now three full map implementations  (array, trie, hashtable) there is a\n   more defined map structure making it less error prone to test out different map backends.\n * Lots of inner class renaming and such - however `frequencies`, `group-by-reduce`, and\n   `mapmap` now a bit faster - about 2X.  Here is a telling performance metric:\n\n```clojure\n({:construct-μs 2.726739663709692,\n  :access-μs 1.784634592104282,\n  :iterate-μs 2.7345543552812073,\n  :ds-name :java-hashmap}\n {:construct-μs 3.5414584143710885,\n  :access-μs 2.761234751112207,\n  :iterate-μs 2.1730894775185403,\n  :ds-name :hamf-hashmap}\n {:construct-μs 6.475808180747403,\n  :access-μs 2.484804237281106,\n  :iterate-μs 1.8564705765641765,\n  :ds-name :hamf-transient}\n {:construct-μs 11.43649782981362,\n  :access-μs 5.152473242630386,\n  :iterate-μs 8.793332955848225,\n  :ds-name :clj-transient})\nham-fisted.hash-map-test>\n```\n\n\n# 1.000-beta-69\n * Faster `mode`.\n * Faster map iteration.\n * Corrected clojure persistent hash map iteration.\n\n# 1.000-beta-67\n * Faster `mode`.\n * `mmax-key` - use `(mmax-key f data)` as opposed to `(apply max-key f data)`.  It is faster\n   and handles empty sequences.  Same goes for `mmin-key`.\n\n\n# 1.000-beta-66\n * Fixed `make-comparator`.\n * Added `mode`.\n\n# 1.000-beta-65\n * Better obj->long and obj->double pathways that will always apply the appropriate cast\n   and thus have 0 arg variants.\n * Better/faster sort-by pathway that avoids potential intermediate data creation.\n\n# 1.000-beta-64\n * Fixed predicate, long-consumer, double-consumer and consumer pathways.\n * Faster dispatch for preduce.\n\n# 1.000-beta-62\n * Faster dispatch for preduce.\n\n# 1.000-beta-61\n * All lists are comparable.\n\n# 1.000-beta-60\n * nil is convertible to iterable and collections without fail.\n\n# 1.000-beta-59\n * Container reduction must respect reduced - I think this is a design flaw but not a\n serious or impactful one aside from requiring more complex per-container reduction code.\n\n# 1.000-beta-58\n * Perf tweaks and small fixes from TMD.\n\n# 1.000-beta-57\n * Additional round of optimizations around creation of persistent vector objects.\n * renamed a few of the functor-creation macros.\n * lznc/map explicity supports long->obj transformations as these are often used as\n   index->obj lookup systems.\n * Rebuilt IMutList's toArray pathway to use reduction.\n\n# 1.000-beta-56\n * Switched completely to clojure.core.protocols/CollReduce.\n * Removed a solid amount of cruft and simplified reduction architecture.\n * Now loading hamf transparently makes reductions on all arrays and many\n   java such as hashmaps datastructures faster.\n\n\n# 1.000-beta-55\n * Removed lots of old cruft.\n * Added IFnDef predicates so you can use IFn-based predicates from java.\n\n# 1.000-beta-54\n * Removed lots of old cruft.\n * Added IFnDef predicates so you can use IFn-based predicates from java.\n\n# 1.000-beta-53\n * `:unmerged-result?`, `:skip-finalize?` options for `preduce` and `preduce-reducer`.  This\n   allows you to use the parallelized reductions pathway but get a sequence of results back\n   as opposed to a single result.  It also allows you to used reducers or\n   transducing-compatible rfn's that have no parallel merge pathway and handle the parallel\n   merge yourself after the parallelized reduction.\n * Fixed issue with single-map parallel reductions to ensure that it passes the parallel\n   reduction request to its source data.\n\n# 1.000-beta-52\n * bulk union, intersection operations.\n * Faster `equiv` for longs and doubles but equivalent for everything else.\n\n# 1.000-beta-51\n * additional set operation - parallelized `unique`.\n * exposed indexed accumulator macros in api for use outside library.\n * generic protocol fn add-fn that must return a reduction compatible function\n   for a given collection.\n\n# 1.000-beta-50\n * forgot type hints on array constructors.\n\n# 1.000-beta-49\n * Final round of optimizations for double array creation.  Turns out reductions really\n   are faster.\n\n# 1.000-beta-48\n * macros for double, float, long, and int array creation that will inline a fastpath\n   if the argument is a compile-time vector or integer.  Bugfix for casting floats\n   to longs.\n * shorthand macros, ivec, lvec, fvec, dvec to create array-backed containers that\n   allow nth destructuring.\n\n# 1.000-beta-47\n * major double-array, float-array, long-array, int-array optimizations.\n\n# 1.000-beta-46\n * Set protocol to supercede the set protocol from dtype-next.\n * lots and lots of fixes from dataset work.\n\n# 1.000-beta-45\n * Small fixes and making helpers public for dtype-next work.\n\n# 1.000-beta-43\n * long lists really are long lists - copy-paste mistake from int lists.\n\n# 1.000-beta-42\n * declare-double-consumer-preducer! - given type derived from DoubleConsumer\n   and a few others, create a parallel reducer.\n * declare-consumer-preducer! - similar to above, incoming data is not expected\n   to be a stream of double values.\n\n# 1.000-beta-41\n * ->collection is protocol driven allowing new non-collection things like bitmaps\n   to be turned temporarily into collections.  This means that reductions and collection\n   conversion are protocol driven.\n\n# 1.000-beta-40\n * maps are iterable...\n\n# 1.000-beta-39\n * Explicit protocols for serial and parallel reduction and reducers.\n * Explicit support for BitSet objects.\n * Updated (->reducible) pathways to check for protocol reducer support.\n * Protocol for conversion of arbitrary types to iterable for map, filter support.\n\n# 1.000-beta-38\n * Fixed comparison of seq with nonseq.\n\n# 1.000-beta-37\n * Small perf enhancements from tmd perf regression\n\n# 1.000-beta-36\n * Added in explicit checks for long, double, and predicate objects in filter's reduction\n   specializations.  Potentially these are too expensive but it does help a bit with\n   longer sequences.\n * Changed things such that Double/NaN evaluates to false.  This matches that the null\n   object evaluates to false and null evaluates to Double/NaN.\n\n\n# 1.000-beta-35\n * Added finalize method to reducers to match transducer spec.\n * Exposed `compose-reducers` that produces a new reducer from a map or sequence of\n   other reducers.\n * These changes simplfied `reduce-reducers` and `preduce-reducers`, `sum` and `sum-fast`.\n\n\n# 1.000-beta-34\n * Enable parallelization for instances of clojure.core.PersistentHashMap.\n * protocol-based parallelization of reductions so you can extend the parallelization\n   to new undiscovered classes.\n * reducer-xform->reducer - Given a reducer and a transducer xform produce a new reducer\n   that will apply the transform to the reduction function of the reducer:\n\n```clojure\nham-fisted.api> (reduce-reducer (reducer-xform->reducer (Sum.) (clojure.core/filter even?))\n                                (range 1000))\n#<Sum@70149930: {:sum 249500.0, :n-elems 500}>\n```\n\n# 1.000-beta-33\n * Finally a better api to group-by-reduce and group-by can now be implemented\n   via group-by-reduce.  group-by-reduce uses same 3 function arguments as\n   preduce so your reduction systems are interchangable between these two\n   systems.\n * Fixed `conj` for all growable array lists.\n * Added a protocol for parallel reductions.  This allows you to pass in one object\n   and transform it into the three functions required to do a parallel reduction.\n * Added preduce-reducer, preduce-reducers for a single reducer or a sequence or\n   map of reducers, respectively.\n\n\n# 1.000-beta-32\n * group-by, group-by-reduced fixed for large n.\n\n# 1.000-beta-31\n * min-n is now a long with parallel options.\n * lazy-noncaching namespace now has map-indexed.  Faster reductions and random access\n   objects stay random access.\n\n# 1.000-beta-30\n * Various bugfixes from dtype work.\n\n# 1.000-beta-29\n * Ranges with more than Integer/MAX_VALUE elems can be accessed via their IFn overloads\n  and support custom lgetLong and lgetDouble methods that take long indexes for long and\n  double ranges.\n\n\n# 1.000-beta-28\n * Use lookahead and put timeouts for all parallelization primitives so that if a long\n  running parallelization is cancelled the forkjoin pool itself isn't hung.\n * Enable long and double ranges whose size is larger than Integer/MAX_VALUE.  This includes\n   parallelized reductions which even optimized take basically forever.\n * Add better defaults for reductions to long and double -specific IMutList interfaces.\n * Ensure reduction implementations do not dereference a reduced accumulator.\n * Fix reducible interface to it matches preduce.\n * Added persistent! implementation which fails gracefully if input is already persistent.\n * Fixed group-by, group-by-reduce, and pfrequencies implementation to use preduce.\n * conj works on map, filter, and concat from the lazy-noncaching library.\n\n# 1.000-beta-27\n * Remove explicit support for boolean primitives.\n\n# 1.000-beta-26\n * IFnDef overloads implement their appropriate java.util.function counterparts.\n\n# 1.000-beta-25\n * Removed claypoole from dependencies.\n * Move typed clojure function interface definitions from Reductions to IFnDef.\n * Added overrides of keys, vals that produce parallelizable collections if the input\n   itself is a parallelizable collection - either maps from this library or any java\n   hashmap.\n\n# 1.000-beta-24\n * preduce has new option to help parallelize concat operations - they can be parallelized\n   two different ways, either elemwise where each container parallelizes its reduction or\n   by sequence where an initial reduction is done with pmap then the results are merged.\n * all random access contains support spliterator and typed stream construction.\n * Fix bug in upmap causing hanging with short sequences.\n\n# 1.000-beta-23\n * double conversion to long fails for NaN.\n * Careful combining of typed map/filter chains to avoid causing inaccuracies when\n   converting from double to long.\n * Major parallelism upgrade - spliterator-based objects such as java.util.hashmap and\n   all the hashmaps/hashsets from this library now support parallelized reduction.\n\n# 1.000-beta-22\n * Numeric values are range checked on input to addLong.\n\n# 1.000-beta-21\n * Removed ensureCapacity from IMutList.\n\n# 1.000-beta-20\n * Moved to double reduction as opposed to double foreach.  Perftested heavily and found that reduce\n   is just as fast and more general.\n\n# 1.000-beta-18\n * expose sublistcheck.\n\n# 1.000-beta-17\n * Stricter correctness checking for sublist types, everything implements Associative.\n\n# 1.000-beta-16\n * Correctness fixes for pmap, upmap, pgroups, upgroups.\n\n# 1.000-beta-15\n * Fixed sum for large n-elems.\n * upgroups - Unordered parallel groupings for random access systems.\n * Indexed consumers for copying, broadcasting type operations.\n * Reducible interface for objects that can reduce themselves.\n\n# 1.000-beta-14\n * ArraySection is now first-class, will rebase dtype-next array pathways on this.\n\n# 1.000-beta-12\n * pmap is guaranteed *not* to require `shutdown-agents`.\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright © 2021 Chris Nuernberger\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "README.md",
    "content": "# HAM-Fisted\n\n[![Clojars Project](https://clojars.org/com.cnuernber/ham-fisted/latest-version.svg)](https://clojars.org/com.cnuernber/ham-fisted)\n* [API docs](https://cnuernber.github.io/ham-fisted/)\n* [Clojure Conj Talk](https://www.youtube.com/watch?v=ralZ4j_ruVg)\n\n## Summary\n\nClojure-style immutable collections (and mutable counterparts), together with\nsome operations, all aimed at high performance.\n\nIn particular, high-performance in large-`n` and parallel contexts. Included are\na namespace of lazy but not caching operations, a `ForkJoinPool` oriented\n`pmap`, and a system of parallel reductions. This gives the user\nsomewhat-drop-in replacements for familiar Clojure tools that can be faster.\n\n## History\n\nWhat started as a collection of efficient mutable and immutable data structures based\non Phil Bagwell's bitmap trie concept became an overall reimplementation of\nClojure's core datastructures and some of its base concepts specifically with\nperformance in mind.  This means, for instance, that the library prefers iterators\nover sequences in many situations.  There are also new functional primitives developed\nfrom my experience processing data and working with Clojure over the last 10 years.\n\n\nMy hope is this library becomes a platform to experiment and develop new and/or better\nfunctional datastructures and algorithmic primitives.\n\n\nHere are a few concepts to keep in mind -\n\n\n## In-place Mutable -> Persistent\n\nThe mutable hashmap and vector implementations allow in-place instantaneous conversion to\ntheir persistent counterparts.  This allows you to build a dataset using the sometimes much\nfaster mutable primitives (.compute and friends for instance in the hashmap case) and then\nreturn data to the rest of the program in persistent form.  Using this method, for example\n`frequencies` is quite a bit faster while still returning a persistent datastructure.\n\n\nAlong those lines construction of a persistent vector from an object array is very fast\nso it is very efficient to construct a persistent vector from an object-array-list - the\narray list being much faster to build.\n\n\n## New Primitive Operations\n\nThere are many new primitive operations than listed below - please take a moment to scan\nthe api docs.  Some standouts are:\n\n#### Map Union, Difference, Intersection\n\nAside from simply a reimplementation of hashmaps and persistent vectors this library\nalso introduces a few new algorithms namely map-union, map-intersection, and\nmap-difference.  These are implemented at the trie level so they avoid rehashing any\nkeys and use the structure of the hashmap in order to boost performance.  This means\n`merge` and `merge-with` are much faster especially if you have larger maps.  But it\nalso means you can design novel set-boolean operations as you provide a\nvalue-resolution operator for the map values.\n\n\nBecause the hamf hashmaps have fast unions, you can now design systems where for\ninstance each thread builds up a separate hashmap and the results are unioned together\nback in the main thread in a map-reduce type design.  This type of design was the\noriginal target of the union system.\n\nThese systems are substantially faster if the objects have a high cost to hash and do\nnot cache their hashcode but  this is rare for Clojure systems as persistent vectors, maps\nand keywords cache their hash values.  Strings, however, are an example of something where\nthese primitives (and things like frequencies) will perform substantially better.\n\n\n### Casting and Finite Numbers\n\nFloat and double values are only allowed to cast to long if they are\n[finite](https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#isFinite-double-).\nBoolean values casted to long or double are 0 for false and 1 for true.  Any nonzero\nfinite number casted to boolean is true, 0 is false, non-finite numbers are errors.  `nil`\ncasted to a floating point number is NaN.  NaN casted to an object is NaN.  If objects\nare not number then nil is false and non-nil is true.  Any undefined cast falls back to\n`clojure.lang.RT.xCast` where `x` denotes the target type.\n\n\nReading data from contains leads to unchecked casts while writing data to contains\nleads to checked casts.\n\n\n\n#### update-values, group-by-reduce, mapmap\n\n* `update-vals` - is far faster than map->map pathways if you want to update every\n  value in the map but leave the keys unchanged.\n* `group-by-reduce` - perform a reduction during the group-by.  This avoids keeping\n   a large map of the complete intermediate values which can be both faster and more\n   memory efficient.\n* `mapmap` - A techascent favorite, equivalent to:\n```clojure\n(->> (map map-fn src-map) (remove nil?) (into {}))\n```\n\n#### Parallelized Reductions - preduce\n\n\nI have an entire topic on [Reductions](https://cnuernber.github.io/ham-fisted/Reductions.html) -\ngive it a read and then send me an email with your thoughts :-).\n\n* [preduce](https://cnuernber.github.io/ham-fisted/ham-fisted.api.html#var-preduce)\n* [preduce-reducer](https://cnuernber.github.io/ham-fisted/ham-fisted.api.html#var-preduce-reducer)\n* [preduce-reducers](https://cnuernber.github.io/ham-fisted/ham-fisted.api.html#var-preduce-reducers)\n\n\nThese parallelization primitives allow users to pass in their own forkjoin pools\nso you can use it for blocking tasks although it is setup be default for\ncpu-bound operations.  Concat operations can parallelize reductions over\nnon-finite or non-parallelizable containers using the default `:seq-wise`\n`:cat-parallelization` option.\n\n\n#### All Arrays Are First Class\n\n* Any array including any primitive array can be converted to an indexed operator\n with efficient sort, reduce, etc. implementations using the `lazy-noncaching`\n namespace's `->random-access` operator.  This allows you to pass arrays as is to\n the rest of your clojure program without conversion to a persistent vector -\n something that is both not particularly efficient and explodes the data size.\n\n\n#### Random Access Containers Support Negative Indexes\n\nAll random access containers, be it vectors, lists, or array lists support\nnth, ifn interfaces taking -1 to index from the end of the vector.  For performance\nreasons, the implementation of List.get does not -\n\n```clojure\nham-fisted.persistent-vector-test> ((api/vec (range 10)) -1)\n9\nham-fisted.persistent-vector-test> (nth (api/vec (range 10)) -1)\n9\nham-fisted.persistent-vector-test> (.get (api/vec (range 10)) -1)\nExecution error (IndexOutOfBoundsException) at ham_fisted.ChunkedList/indexCheck (ChunkedList.java:210).\nIndex underflow: -1\nham-fisted.persistent-vector-test> ((api/->random-access (api/int-array (range 10))) -1)\n9\nham-fisted.persistent-vector-test> (nth (api/->random-access (api/int-array (range 10))) -1)\n9\n```\nSimilarly `last` is constant time for all any list implementation deriving from\n`java.util.RandomAccess`.\n\n## Other ideas\n\n * `lazy-noncaching` namespace contains very efficient implementations of map,\n   filter, concat, and repeatedly which perform as good as or better than the\n   eduction variants without chunking or requiring you to convert your code from\n   naive clojure to transducer form.  The drawback is they are lazy noncaching so\n   for instance `(repeatedly 10 rand)` will produce 10 random values every time it\n   is evaluated.  Furthermore `map` will produce a random-access return value if\n   passed in all random-access inputs thus preserving the random-access property of\n   the input.\n\n * lazy-caching namespace contains inefficient implementations that do in fact\n   cache - it appears that Clojure's base implementation is very good or at least\n   good enough I can't haven't come up with one better.  Potentially the decision\n   to use chunking is the best optimization available here.\n\n\n## Contributing\n\nThe best way to contribute is to fund me through github sponsors linked to\nthe right or to engage [TechAscent](https://techascent.com) - we are always\nlooking for new interesting projects and partners.\n\n\nAside from that as mentioned earlier my hope is this library becomes\na platform that enables experimentation with various functional primitives and\noverall optimized ways of doing the type of programming that the Clojure community\nenjoys.  Don't hesitate to file issues and PR's - I am happy to accept both.\n\nIf you want to work on the library you need to enable the `:dev` alias.\n\n\n## Benchmarks\n\nLies, damn lies, and benchmarks - you can run the benchmarks with `./scripts/benchmark`.\nResults will be printed to the console and saved to results directory prefixed by the\ncommit, your machine name and the jdk version.\n\nResults will print normalized to either the base time for clojure.core (clj) or for\njava.util (java).  One interesting thing here is in general how much better JDK-17\nis for many of these tests than JDK-8.\n\nHere are some example timings taken using my laptop plugged in with an external cooling\nsupply (frozen peas) applied to the bottom of the machine.  An interesting side note is\nthat I get better timings often when running from the REPL for specific benchmarks than\nfrom the benchmark - perhaps due to the machine's heat management systems.\n\n\n#### JDK-17\n\n\n|                  :test | :n-elems | :java | :clj | :eduction | :hamf | :norm-factor-μs |\n|------------------------|---------:|------:|-----:|----------:|------:|----------------:|\n|              :assoc-in |        5 |       |  1.0 |           | 0.646 |           0.245 |\n|          :assoc-in-nil |        5 |       |  1.0 |           | 0.371 |           0.120 |\n|               :concatv |      100 |       |  1.0 |           | 0.099 |           9.827 |\n|           :frequencies |    10000 |       |  1.0 |           | 0.412 |         966.154 |\n|                :get-in |        5 |       |  1.0 |           | 0.564 |           0.124 |\n|              :group-by |    10000 |       |  1.0 |           | 0.333 |        1414.480 |\n|       :group-by-reduce |    10000 |       |  1.0 |           | 0.313 |        1408.028 |\n|        :hashmap-access |    10000 | 0.700 |  1.0 |           | 0.989 |         549.468 |\n|        :hashmap-access |       10 | 0.837 |  1.0 |           | 0.826 |           0.400 |\n|  :hashmap-cons-obj-ary |        4 |       |  1.0 |           | 0.355 |           0.392 |\n|  :hashmap-cons-obj-ary |       10 |       |  1.0 |           | 0.584 |           0.864 |\n|  :hashmap-cons-obj-ary |     1000 |       |  1.0 |           | 0.541 |         124.811 |\n|  :hashmap-construction |    10000 | 0.563 |  1.0 |           | 0.923 |        1331.130 |\n|  :hashmap-construction |       10 | 0.240 |  1.0 |           | 0.357 |           2.337 |\n|        :hashmap-reduce |    10000 | 0.792 |  1.0 |           | 0.860 |         316.433 |\n|        :hashmap-reduce |       10 | 0.703 |  1.0 |           | 0.735 |           0.360 |\n|              :int-list |    20000 | 1.000 |      |           | 1.147 |         467.994 |\n|                :mapmap |     1000 |       |  1.0 |           | 0.276 |         275.786 |\n|          :object-array |    20000 |       |  1.0 |           | 0.240 |        1560.975 |\n|           :object-list |    20000 | 1.000 |      |           | 0.987 |         518.878 |\n|    :sequence-summation |    20000 |       |  1.0 |      0.29 | 0.409 |        1380.496 |\n|               :shuffle |    10000 |       |  1.0 |           | 0.353 |         329.709 |\n|                  :sort |    10000 |       |  1.0 |           | 0.337 |        2418.307 |\n|          :sort-doubles |    10000 |       |  1.0 |           | 0.374 |        2272.143 |\n|             :sort-ints |    10000 |       |  1.0 |           | 0.291 |        2514.779 |\n|                 :union |       10 | 0.155 |  1.0 |           | 0.088 |           1.785 |\n|                 :union |    10000 | 0.275 |  1.0 |           | 0.174 |        1664.823 |\n|            :union-disj |       10 | 0.156 |  1.0 |           | 0.085 |           1.798 |\n|            :union-disj |    10000 | 0.279 |  1.0 |           | 0.178 |        1641.344 |\n|          :union-reduce |       10 | 0.139 |  1.0 |           | 0.220 |          23.954 |\n|          :union-reduce |    10000 | 0.100 |  1.0 |           | 0.159 |       41261.663 |\n|             :update-in |        5 |       |  1.0 |           | 1.153 |           0.276 |\n|         :update-in-nil |        5 |       |  1.0 |           | 0.276 |           0.158 |\n|         :update-values |     1000 |       |  1.0 |           | 0.090 |         158.994 |\n|         :vector-access |       10 | 1.568 |  1.0 |           | 1.008 |          77.945 |\n|         :vector-access |    10000 | 0.957 |  1.0 |           | 1.027 |         125.778 |\n| :vector-cons-obj-array |       10 | 1.184 |  1.0 |           | 0.356 |           0.071 |\n| :vector-cons-obj-array |    10000 | 0.083 |  1.0 |           | 0.048 |         112.192 |\n|   :vector-construction |       10 | 0.460 |  1.0 |           | 1.124 |           0.078 |\n|   :vector-construction |    10000 | 0.082 |  1.0 |           | 0.078 |         117.432 |\n|         :vector-reduce |       10 | 1.996 |  1.0 |           | 1.088 |           0.150 |\n|         :vector-reduce |    10000 | 1.228 |  1.0 |           | 0.863 |         194.194 |\n|       :vector-to-array |       10 | 0.256 |  1.0 |           | 0.503 |           0.041 |\n|       :vector-to-array |    10000 | 0.063 |  1.0 |           | 0.124 |          69.590 |\n\n\n#### JDK-1.8\n\n\n|                  :test | :n-elems | :java | :clj | :eduction | :hamf | :norm-factor-μs |\n|------------------------|---------:|------:|-----:|----------:|------:|----------------:|\n|              :assoc-in |        5 |       |  1.0 |           | 0.801 |           0.274 |\n|          :assoc-in-nil |        5 |       |  1.0 |           | 0.275 |           0.142 |\n|               :concatv |      100 |       |  1.0 |           | 0.120 |           6.810 |\n|           :frequencies |    10000 |       |  1.0 |           | 0.421 |         960.710 |\n|                :get-in |        5 |       |  1.0 |           | 0.598 |           0.125 |\n|              :group-by |    10000 |       |  1.0 |           | 0.335 |        1410.690 |\n|       :group-by-reduce |    10000 |       |  1.0 |           | 0.293 |        1433.528 |\n|        :hashmap-access |    10000 | 0.817 |  1.0 |           | 1.046 |         541.540 |\n|        :hashmap-access |       10 | 0.791 |  1.0 |           | 0.904 |           0.402 |\n|  :hashmap-cons-obj-ary |        4 |       |  1.0 |           | 0.398 |           0.407 |\n|  :hashmap-cons-obj-ary |       10 |       |  1.0 |           | 0.696 |           0.682 |\n|  :hashmap-cons-obj-ary |     1000 |       |  1.0 |           | 0.449 |         130.423 |\n|  :hashmap-construction |    10000 | 0.586 |  1.0 |           | 0.927 |        1281.371 |\n|  :hashmap-construction |       10 | 0.278 |  1.0 |           | 0.401 |           2.238 |\n|        :hashmap-reduce |    10000 | 0.625 |  1.0 |           | 0.704 |         321.295 |\n|        :hashmap-reduce |       10 | 0.714 |  1.0 |           | 0.862 |           0.312 |\n|              :int-list |    20000 | 1.000 |      |           | 1.017 |         497.492 |\n|                :mapmap |     1000 |       |  1.0 |           | 0.325 |         226.518 |\n|          :object-array |    20000 |       |  1.0 |           | 0.391 |        1374.725 |\n|           :object-list |    20000 | 1.000 |      |           | 0.981 |         493.795 |\n|    :sequence-summation |    20000 |       |  1.0 |      0.37 | 0.227 |        1342.562 |\n|               :shuffle |    10000 |       |  1.0 |           | 0.430 |         286.478 |\n|                  :sort |    10000 |       |  1.0 |           | 0.284 |        2839.552 |\n|          :sort-doubles |    10000 |       |  1.0 |           | 0.424 |        2485.058 |\n|             :sort-ints |    10000 |       |  1.0 |           | 0.279 |        2885.107 |\n|                 :union |       10 | 0.147 |  1.0 |           | 0.093 |           1.938 |\n|                 :union |    10000 | 0.278 |  1.0 |           | 0.198 |        1446.922 |\n|            :union-disj |       10 | 0.144 |  1.0 |           | 0.091 |           1.938 |\n|            :union-disj |    10000 | 0.285 |  1.0 |           | 0.198 |        1440.777 |\n|          :union-reduce |       10 | 0.114 |  1.0 |           | 0.230 |          25.724 |\n|          :union-reduce |    10000 | 0.081 |  1.0 |           | 0.159 |       37008.010 |\n|             :update-in |        5 |       |  1.0 |           | 1.401 |           0.292 |\n|         :update-in-nil |        5 |       |  1.0 |           | 0.289 |           0.138 |\n|         :update-values |     1000 |       |  1.0 |           | 0.083 |         166.794 |\n|         :vector-access |       10 | 1.563 |  1.0 |           | 1.131 |          86.023 |\n|         :vector-access |    10000 | 0.945 |  1.0 |           | 1.047 |         139.996 |\n| :vector-cons-obj-array |       10 | 1.150 |  1.0 |           | 0.365 |           0.075 |\n| :vector-cons-obj-array |    10000 | 0.066 |  1.0 |           | 0.040 |         103.369 |\n|   :vector-construction |       10 | 0.508 |  1.0 |           | 1.119 |           0.073 |\n|   :vector-construction |    10000 | 0.062 |  1.0 |           | 0.070 |         109.040 |\n|         :vector-reduce |       10 | 2.041 |  1.0 |           | 1.031 |           0.152 |\n|         :vector-reduce |    10000 | 1.392 |  1.0 |           | 1.026 |         146.636 |\n|       :vector-to-array |       10 | 0.284 |  1.0 |           | 0.569 |           0.036 |\n|       :vector-to-array |    10000 | 0.052 |  1.0 |           | 0.068 |          65.946 |\n\n\n## CAVEATS!!\n\nThis code is minimally tested.  The datastructures especially need serious testing, potentially generative\ntesting of edge cases.\n\nAlso, microbenchmarks do not always indicate how your system will perform overall.  For instance- when\ntesting `assoc-in`, `update-in` in this project we see better performance.  In at least one real\nworld project, however, the inlining that makes the microbenchmark perform better definitely did\n*not* result in the project running faster -- it ran a bit slower even though the profiler of the\noriginal code indicated the sequence operations performed during assoc-in and update-in were a source\nof some time.\n\nThe JVM is a complicated machine and there are issues with using, for instance, too many classes\nat a particular callsite.  Overall I would recommend profiling and being careful.  My honest opinion\nright now is that `assoc-in` and `update-in` do not improve program performance at least in\nsome of the use cases I have tested.\n\n\n## Other Interesting Projects\n\n* [clj-fast](https://github.com/bsless/clj-fast) - Great and important library more focused on compiler upgrades.\n* [bifurcan](https://github.com/lacuna/bifurcan) - High speed functional datastructures for Java.  Perhaps ham-fisted should\nbe based on this or we should measure the differences and take the good parts.\n* [Clojure Goes Fast](http://clojure-goes-fast.com/) - Grandaddy aggregator project with a lot of important information and a set of crucial github projects such as [clj-memory-meter](https://github.com/clojure-goes-fast/clj-memory-meter).\n"
  },
  {
    "path": "build.clj",
    "content": "(ns build\n  (:require [clojure.tools.build.api :as b]\n            [clojure.edn :as edn])\n  (:refer-clojure :exclude [compile]))\n\n(def deps-data (edn/read-string (slurp \"deps.edn\")))\n(def codox-data (get-in deps-data [:aliases :codox :exec-args]))\n(def lib (symbol (codox-data :group-id) (codox-data :artifact-id)))\n(def version (codox-data :version))\n(def class-dir \"target/classes\")\n(def basis (b/create-basis {:project \"deps.edn\"}))\n(def jar-file (format \"target/%s.jar\" (name lib)))\n(def uber-file (format \"target/uber-%s.jar\" (name lib)))\n\n(defn clean [_]\n  (b/delete {:path \"target\"}))\n\n(defn compile [_]\n  (b/javac {:src-dirs [\"java\"]\n            :class-dir class-dir\n            :basis basis\n            :javac-opts [\"-source\" \"8\" \"-target\" \"8\" \"-Xlint:unchecked\"\n                         ]}))\n\n(def pom-template\n  [[:licenses\n    [:license\n     [:name \"MIT License\"]\n     [:url \"https://github.com/cnuernber/charred/blob/master/LICENSE\"]]]])\n\n\n(defn jar [_]\n  (compile nil)\n  (b/write-pom {:class-dir class-dir\n                :lib lib\n                :version version\n                :basis basis\n                :src-dirs [\"src\"]\n                :pom-data pom-template})\n  (b/copy-dir {:src-dirs [\"src\" \"resources\"]\n               :target-dir class-dir})\n  (b/jar {:class-dir class-dir\n          :jar-file jar-file}))\n\n\n(defn perftest [_]\n  (let [basis (b/create-basis {:aliases [:dev]})]\n    (clean nil)\n    (compile nil)\n    (b/copy-dir {:src-dirs [\"src\" \"dev/resources\" \"dev/src\"]\n                 :target-dir class-dir})\n    (b/compile-clj {:basis basis\n                    :src-dirs [\"dev/src\"]\n                    :class-dir class-dir\n                    :compile-opts {:direct-linking true}\n                    })\n    (b/uber {:class-dir class-dir\n             :uber-file uber-file\n             :basis basis\n             :main 'ham-fisted.protocol-perf})))\n"
  },
  {
    "path": "codegen/gen_prim_invoke.clj",
    "content": "(ns gen-prim-invoke\n  (:require [clojure.java.io :as io]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [ham-fisted.api :as hamf]))\n\n\n(defn single-arg-sigs\n  [rv]\n  (for [arg1 [:o :l :d]]\n    [arg1 rv]))\n\n(defn dual-arg-sigs\n  [rv arg1]\n  (for [arg2 [:o :l :d]]\n    [arg1 arg2 rv]))\n\n\n(defn triple-arg-sigs\n  [rv arg1 arg2]\n  (for [arg3 [:o :l :d]]\n    [arg1 arg2 arg3 rv]))\n\n\n(defn quad-arg-sigs\n  [rv arg1 arg2 arg3]\n  (for [arg4 [:o :l :d]]\n    [arg1 arg2 arg3 arg4 rv]))\n\n\n\n(def ifn-sigs\n  (hamf/concatv\n   [[:l]\n    [:d]]\n   (->> (lznc/concat\n         (for [rv [:o :l :d]]\n           (single-arg-sigs rv))\n         (for [rv [:o :l :d]\n               arg1 [:o :l :d]]\n           (dual-arg-sigs rv arg1))\n         (for [rv [:o :l :d]\n               arg1 [:o :l :d]\n               arg2 [:o :l :d]]\n           (triple-arg-sigs rv arg1 arg2))\n         (for [rv [:o :l :d]\n               arg1 [:o :l :d]\n               arg2 [:o :l :d]\n               arg3 [:o :l :d]]\n           (quad-arg-sigs rv arg1 arg2 arg3)))\n        lznc/apply-concat\n        (lznc/remove #(every? (fn [a](= :o a)) %)))))\n\n\n(defn writeit\n  []\n  (with-open [w (io/writer (io/output-stream \"src/ham_fisted/primitive_invoke.clj\"))]\n    (.write w (str \"(ns ham-fisted.primitive-invoke\n\\\"For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions\n  and this makes quite a difference in tight loops.  Often times, however, functions are passed by values\n  or returned from if-statements and then you need to explicitly call the primitive overload - this makes\n  that pathway less verbose.\\\")\\n\\n\"))\n    (doseq [sig ifn-sigs]\n      (let [sname (apply str (map name sig))\n            ifn-name (str \"clojure.lang.IFn$\" (.toUpperCase sname))]\n        (.write w (str \"(defn ->\" sname \" ^\" ifn-name \" [f]\n  (if (instance? \" ifn-name \" f)\n    f\n    (throw (RuntimeException. (str f \\\" is not an instance of\" ifn-name \"\\\")))))\\n\"))\n        (.write w (str \"(defmacro \" sname \" [f\"))\n        (dotimes [i (dec (count sig))]\n          (.write w (str \" \"))\n          (.write w (str \"arg\" i)))\n        (.write w \"]\\n\")\n        (.write w (str \"`(.invokePrim ~f\"))\n        (dotimes [i (dec (count sig))]\n          (.write w (str \" \"))\n          (.write w (str \"~arg\" i)))\n        (.write w \"))\\n\")))))\n\n\n(comment\n  (writeit)\n  )\n"
  },
  {
    "path": "deps.edn",
    "content": "{:paths [\"src\" \"resources\" \"target/classes\"]\n :deps {it.unimi.dsi/fastutil-core {:mvn/version \"8.5.14\"}\n        com.github.ben-manes.caffeine/caffeine {:mvn/version \"2.9.3\"}\n        net.openhft/zero-allocation-hashing {:mvn/version \"0.27ea0\"}}\n\n :aliases\n {;; Run with clj -T:build function-in-build\n  :dev\n  {:extra-deps {;;org.clojure/clojure {:mvn/version \"1.12.0-CN-SNAPSHOT\"}\n                org.clojure/clojure {:mvn/version \"1.12.0\"}\n                criterium/criterium {:mvn/version \"0.4.6\"}\n                techascent/tech.ml.dataset {:mvn/version \"7.032\"}\n                ch.qos.logback/logback-classic {:mvn/version \"1.1.3\"}\n                kixi/stats {:mvn/version \"0.5.5\"}\n                org.clojure/data.int-map {:mvn/version \"1.3.0\"}\n                techascent/tech.viz {:mvn/version \"6.00-beta-16-4\"}\n                com.clojure-goes-fast/clj-java-decompiler {:mvn/version \"0.3.6\"}\n                com.clojure-goes-fast/clj-memory-meter {:mvn/version \"0.3.0\"}\n                com.clojure-goes-fast/clj-async-profiler {:mvn/version \"1.6.2\"}}\n   :extra-paths [\"dev/src\" \"test\"]\n   :jvm-opts [\"-Djdk.attach.allowAttachSelf=true\"\n              \"-XX:+EnableDynamicAgentLoading\"\n              \"--illegal-access=permit\"]}\n  :nospec {:jvm-opts [\"-Dclojure.spec.skip-macros=true\" \"-Xverify:none\"]}\n  :jdk-19 {:jvm-opts [\"-Djdk.attach.allowAttachSelf=true\" \"--illegal-access=permit\"]}\n  :build\n  {:deps {io.github.clojure/tools.build {:mvn/version \"0.10.5\"}}\n   :ns-default build}\n  :clj-kondo {:extra-deps {clj-kondo/clj-kondo {:mvn/version \"2024.08.29\"}}\n              :main-opts [\"-m\" \"clj-kondo.main\"]}\n  :kaocha-test\n  {:extra-deps {lambdaisland/kaocha {:mvn/version \"1.91.1392\"}\n                lambdaisland/kaocha-junit-xml {:mvn/version \"1.17.101\"}\n                lambdaisland/kaocha-cloverage {:mvn/version \"1.1.89\"}}\n   :extra-paths [\"test\"]\n   :main-opts [\"-m\" \"kaocha.runner\"]}\n  :test\n  {:extra-deps {com.cognitect/test-runner\n                {:git/url \"https://github.com/cognitect-labs/test-runner\"\n                 :sha \"209b64504cb3bd3b99ecfec7937b358a879f55c1\"}\n                ch.qos.logback/logback-classic {:mvn/version \"1.1.3\"}}\n   :extra-paths [\"test\"]\n   :main-opts [\"-m\" \"cognitect.test-runner\"]}\n  :codox\n  {:extra-deps {codox-theme-rdash/codox-theme-rdash {:mvn/version \"0.1.2\"}\n                nrepl/nrepl {:mvn/version \"1.3.0\"}\n                cider/cider-nrepl {:mvn/version \"0.50.2\"}\n                com.cnuernber/codox {:mvn/version \"1.001\"}}\n   :exec-fn codox.main/-main\n   :exec-args {:group-id \"com.cnuernber\"\n               :artifact-id \"ham-fisted\"\n               :version \"3.029\"\n               :name \"Ham-Fisted\"\n               :description \"High Performance Clojure Primitives\"\n               :metadata {:doc/format :markdown}\n               :html {:transforms [[:head] [:append [:script {:async true\n                                                              :src \"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"}]]\n                                   [:head] [:append [:script \"window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');\"]]]}\n               :themes [:rdash]\n               :source-paths [\"src\"]\n               :output-path \"docs\"\n               :doc-paths [\"topics\"]\n               :source-uri \"https://github.com/cnuernber/ham-fisted/blob/master/{filepath}#L{line}\"\n               :namespaces [ham-fisted.api\n                            ham-fisted.lazy-noncaching\n                            ham-fisted.protocols\n                            ham-fisted.set\n                            ham-fisted.function\n                            ham-fisted.mut-map\n                            ham-fisted.reduce\n                            ham-fisted.hlet\n                            ham-fisted.primitive-invoke\n                            ham-fisted.bloom-filter\n                            ham-fisted.defprotocol\n                            ham-fisted.iterator\n                            ham-fisted.process\n                            ham-fisted.profile\n                            ham-fisted.fjp\n                            ham-fisted.spliterator]}}\n  :deploy\n  {:replace-deps {slipset/deps-deploy {:mvn/version \"0.2.2\"}}\n   :exec-fn deps-deploy.deps-deploy/deploy\n   :exec-args {:installer :remote\n               :sign-releases? true\n               :artifact \"target/ham-fisted.jar\"}}\n  :install\n  {:replace-deps {slipset/deps-deploy {:mvn/version \"0.2.2\"}}\n   :exec-fn deps-deploy.deps-deploy/deploy\n   :exec-args {:installer :local\n               :artifact \"target/ham-fisted.jar\"}}}}\n"
  },
  {
    "path": "dev/resources/logback.xml",
    "content": "<configuration debug=\"false\">\n  <appender name=\"STDOUT\" class=\"ch.qos.logback.core.ConsoleAppender\">\n    <!-- encoders are assigned the type\n         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->\n    <encoder>\n      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>\n    </encoder>\n  </appender>\n\n  <root level=\"info\">\n    <appender-ref ref=\"STDOUT\" />\n  </root>\n</configuration>\n"
  },
  {
    "path": "dev/src/ham_fisted/analysis.clj",
    "content": "(ns ham-fisted.analysis\n  (:require [clojure.edn :as edn]\n            [charred.api :as charred]\n            [applied-science.darkstar :as darkstar]\n            [clojure.java.io :as io]))\n\n\n\n(defn plot-perf-test\n  [testgroup options]\n  (let [group-item (first testgroup)\n        testname (:test group-item)\n        numeric? (:numeric? group-item)\n        bytes? (= (:test group-item)\n                  :hashmap-bytes)\n        baseline (or (:baseline options) :clj)\n        testdata (->> testgroup\n                      (mapcat (if bytes?\n                                (fn [group-item]\n                                  (let [n-elems (:n-elems group-item)\n                                        clj-bytes (:clj group-item)]\n                                    (->> (dissoc group-item :test :numeric? :n-elems)\n                                         (map (fn [kv]\n                                                {:datastructure (key kv)\n                                                 :n-elems n-elems\n                                                 :norm-bytes (double (/ (val kv) clj-bytes))})))))\n                                (fn [group-item]\n                                  (let [n-elems (:n-elems group-item)\n                                        clj-val (get-in group-item [baseline :mean-μs])]\n                                    (->> group-item\n                                         (map (fn [kv]\n                                                (let [k (key kv)\n                                                      val (val kv)]\n                                                  (when-let [us (get val :mean-μs)]\n                                                    {:datastructure k\n                                                     :norm-mean-μs (double (/ us clj-val))\n                                                     :n-elems n-elems}))))\n                                         (remove nil?))))))\n                      (sort-by :datastructure)\n                      (vec))\n        chart-title (str (name testname) \"-\" (if numeric?\n                                               \"numeric\"\n                                               \"non-numeric\"))\n        chartname (str \"charts/\" chart-title \".svg\")]\n    (io/make-parents chartname)\n    (if bytes?\n      (spit chartname\n            (-> {:$schema \"https://vega.github.io/schema/vega-lite/v5.1.0.json\"\n                 :mark {:type :line\n                        :point true}\n                 :title chart-title\n                 :width 800\n                 :height 600\n                 :data {:values testdata}\n                 :encoding\n                 {:y {:field :norm-bytes, :type :quantitative :axis {:grid false}}\n                  :x {:field :n-elems :type :quantitative :scale {:type :log}}\n                  :color {:field :datastructure :type :nominal}\n                  :shape {:field :datastructure :type :nominal}}}\n                (charred/write-json-str)\n                (darkstar/vega-lite-spec->svg)))\n      (spit chartname\n            (-> {:$schema \"https://vega.github.io/schema/vega-lite/v5.1.0.json\"\n                 :mark {:type :line\n                        :point true}\n                 :title chart-title\n                 :width 800\n                 :height 600\n                 :data {:values testdata}\n                 :encoding\n                 {:y {:field :norm-mean-μs, :type :quantitative :axis {:grid false}}\n                  :x {:field :n-elems :type :quantitative :scale {:type :log}}\n                  :color {:field :datastructure :type :nominal}\n                  :shape {:field :datastructure :type :nominal}}}\n                (charred/write-json-str)\n                (darkstar/vega-lite-spec->svg))))\n    ;;testdata\n    ))\n\n(defn- process-files\n  ([fnames] (process-files fnames nil))\n  ([fnames options]\n   (->> fnames\n        (mapcat #(edn/read-string (slurp %)))\n        (group-by (juxt :numeric? :test))\n        (vals)\n        (map #(plot-perf-test % options))\n        (dorun))\n   :ok))\n\n(defn general-hashmap-analysis\n  []\n  (process-files [\"results/general-hashmap.edn\"])\n  )\n\n\n(defn random-update-analysis\n  []\n  (process-files [\"results/random-update.edn\"]))\n\n\n(defn union-analysis\n  []\n  (process-files [\"results/union-overlapping.edn\"\n                  \"results/union-disj.edn\"\n                  \"results/union-reduce.edn\"\n                  \"results/update-values.edn\"]))\n\n(defn typed-reduction-analysis\n  []\n  (process-files [\"results/typed-reductions.edn\"]))\n\n\n(defn typed-parallel-reduction-analysis\n  []\n  (process-files [\"results/typed-parallel-reductions.edn\"]))\n\n(defn union-reduce-transient\n  []\n  (process-files [\"results/union-reduce-transient.edn\"] {:baseline :hamf-hashmap})\n  )\n\n\n(defn persistent-vector\n  []\n  (process-files [\"results/persistent-vector.edn\"]))\n\n\n(defn sort-by-analysis\n  []\n  (process-files [\"results/sort-by.edn\"]))\n"
  },
  {
    "path": "dev/src/ham_fisted/benchmark.clj",
    "content": "(ns ham-fisted.benchmark\n  (:require [criterium.core :as c]))\n\n\n(defmacro benchmark-us\n  \"Benchmark an op, returning a map of :mean and :variance in μs.\"\n  [op]\n  `(let [bdata# (c/quick-benchmark ~op nil)]\n     {:mean-μs (* (double (first (:mean bdata#))) 1e6)\n      :variance-μs (* (double (first (:variance bdata#))) 1e6)}))\n"
  },
  {
    "path": "dev/src/ham_fisted/protocol_perf.clj",
    "content": "(ns ham-fisted.protocol-perf\n  (:require [ham-fisted.defprotocol :as hamf-defproto]\n            [ham-fisted.protocols :as hamf-proto]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [ham-fisted.api :as hamf]\n            [ham-fisted.reduce :as hamf-rf]\n            [clojure.pprint :as pp])\n  (:import [java.util LongSummaryStatistics]\n           [java.util.function LongConsumer])\n  (:gen-class))\n\n(set! *unchecked-math* :warn-on-boxed)\n(set! *warn-on-reflection* true)\n\n(hamf-defproto/defprotocol HamfMemsize\n  (^long hamf-memsize [m]))\n\n(hamf-defproto/extend Double HamfMemsize {:hamf-memsize 24})\n(hamf-defproto/extend Long HamfMemsize {:hamf-memsize 24})\n(hamf-defproto/extend clojure.lang.Keyword HamfMemsize {:hamf-memsize 48})\n\n(hamf-defproto/extend-protocol HamfMemsize\n  String\n  (hamf-memsize [s] (+ 24 (.length ^String s)))\n  java.util.Collection\n  (hamf-memsize [c] (hamf/lsum (lznc/map (fn ^long [d] (+ 24 (hamf-memsize d))) c)))\n  java.util.Map\n  (hamf-memsize [c] (hamf/lsum (lznc/map (fn ^long [kv]\n                                           (+ 36 (+ (hamf-memsize (key kv)) (hamf-memsize (val kv)))))\n                                         c))))\n\n(clojure.core/defprotocol CoreMemsize\n  (core-memsize [m]))\n\n(clojure.core/extend-protocol CoreMemsize\n  Double (core-memsize [d] 24)\n  Long (core-memsize [l] 24)\n  clojure.lang.Keyword (core-memsize [k] 48)\n  String (core-memsize [s] (+ 24 (.length ^String s)))\n  java.util.Collection\n  (core-memsize [c]\n    (hamf/lsum (lznc/map (fn ^long [d] (+ 24 (long (core-memsize d)))) c))\n    #_(reduce\n       (fn [s v] (+ s 24 (core-memsize v)))\n       0\n       c))\n  java.util.Map\n  (core-memsize [m]\n    (hamf/lsum (lznc/map (fn ^long [kv]\n                           (+ 36 (+ (long (core-memsize (key kv)))\n                                    (long (core-memsize (val kv))))))\n                         m))\n    #_(reduce\n       (fn [s [k v]] (+ s 36 (core-memsize k) (core-memsize v)))\n       0\n       m)))\n\n(def test-datastructure\n  {:a \"hello\"\n   :b 24\n   :c (into [] (repeat 1000 (rand)))\n   :d (into [] (repeat 1000 1))})\n\n\n(def measure-data (into [] (repeat 10000 test-datastructure)))\n\n(defn multithread-test\n  [measure-fn]\n  (hamf/lsum (hamf/pmap measure-fn measure-data)))\n\n(hamf-defproto/defprotocol PPrimitiveArgs\n  (^double pargs [m ^long b]))\n\n(hamf-defproto/extend-type String\n  PPrimitiveArgs\n  (pargs [m b]\n    (+ 1.0 (+ (.length m) b))))\n\n(hamf-defproto/extend-type Double\n  PPrimitiveArgs\n  (pargs [m b]\n    (+ 1.0 (+ (double m) b))))\n\n(defprotocol CorePPrimitiveArgs\n  (core-pargs [m b]))\n\n(extend-type String\n  CorePPrimitiveArgs\n  (core-pargs [m b]\n    (+ 1.0 (+ (.length m) (long b)))))\n\n(extend-type Double\n  CorePPrimitiveArgs\n  (core-pargs [m b]\n    (+ 1.0 (+ (double b) (long b)))))\n\n(def strs (mapv str (range 100000)))\n(def strs-and-doubles (vec (take 100000 (interleave strs (map double (range 100000))))))\n\n(defn reduce-count\n  [data]\n  (reduce (fn [^long acc v] (inc acc)) 0 data))\n\n(defprotocol TestProto\n  (f [this a b]))\n\n(extend-protocol TestProto\n  String\n  (f [this a b] 1)\n  Long\n  (f [this a b] 1)\n  Double\n  (f [this a b] 1)\n  java.util.Collection\n  (f [this a b]\n    (reduce-count (lznc/map #(f % [] :x) this))))\n\n(hamf-defproto/defprotocol HFTestProto\n  (hf [this a b]))\n\n(hamf-defproto/extend-protocol HFTestProto\n  String\n  (hf [this a b] 1)\n  Long\n  (hf [this a b] 1)\n  Double\n  (hf [this a b] 1)\n  java.util.Collection\n  (hf [this a b]\n    (reduce-count (lznc/map #(hf % [] :x) this))))\n\n(defn explore!\n  [n]\n  (println \"========= Exploring general protocol pathways ========\")\n  (let [l (vec (take 10000 (cycle [\"foo\" 5678 3.14 (vec (take 10000 (cycle [\"foo\" 5678 3.14])))])))]\n    (dotimes [i n]\n      (println \"attempt\" i)\n      (println \"map f\")\n      (time (reduce-count (lznc/map #(f % [] :x) l)))\n      (println \"map fast-f\")\n      (time (reduce-count (lznc/map #(hf % [] :x) l)))\n      (println \"pmap f\")\n      (time (reduce-count (hamf/pmap #(f % [] :x) l)))\n      (println \"pmap fast-f\")\n      (time (reduce-count (lznc/map identity (hamf/pmap #(hf % [] :x) l))))))\n  :done)\n\n(defn -main\n  [& args]\n  (println \"Core protocols\")\n  (dotimes [idx 5]\n    (time (multithread-test core-memsize)))\n\n  (println \"hamf protocols\")\n  (dotimes [idx 5]\n    (time (multithread-test hamf-memsize)))\n\n  (println \"serial single type core pargs\")\n  (dotimes [idx 5]\n    (time \n     (dotimes [idx 10]\n       (hamf/sum-fast (lznc/map (fn ^double [s] (core-pargs s 100)) strs)))))\n\n  (println \"serial single type hamf pargs\")\n  (dotimes [idx 5]\n    (time\n     (dotimes [idx 10]\n       (hamf/sum-fast (lznc/map (fn ^double [s] (pargs s 100)) strs)))))\n\n  (println \"parallel single type core pargs\")\n  (dotimes [idx 5]\n    (time \n     (dotimes [idx 10]\n       (hamf/sum (lznc/map (fn ^double [s] (core-pargs s 100)) strs)))))\n\n  (println \"parallel single type hamf pargs\")\n  (dotimes [idx 5]\n    (time \n     (dotimes [idx 10]\n       (hamf/sum (lznc/map (fn ^double [s] (pargs s 100)) strs)))))\n\n\n  (println \"serial dual type core pargs\")\n  (dotimes [idx 5]\n    (time \n     (dotimes [idx 10]\n       (hamf/sum-fast (lznc/map (fn ^double [s] (core-pargs s 100)) strs-and-doubles)))))\n\n  (println \"serial dual type hamf pargs\")\n  (dotimes [idx 5]\n    (time\n     (dotimes [idx 10]\n       (hamf/sum-fast (lznc/map (fn ^double [s] (pargs s 100)) strs-and-doubles)))))\n\n  (println \"parallel dual type core pargs\")\n  (dotimes [idx 5]\n    (time \n     (dotimes [idx 10]\n       (hamf/sum (lznc/map (fn ^double [s] (core-pargs s 100)) strs-and-doubles)))))\n\n  (println \"parallel dual type hamf pargs\")\n  (dotimes [idx 5]\n    (time \n     (dotimes [idx 10]\n       (hamf/sum (lznc/map (fn ^double [s] (pargs s 100)) strs-and-doubles)))))\n\n  (explore! 4)\n \n  :ok)\n"
  },
  {
    "path": "dev/src/perftest.clj",
    "content": "(ns perftest\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [ham-fisted.benchmark :refer [benchmark-us] :as bench]\n            [clojure.data.int-map :as i]\n            [tech.v3.datatype :as dtype]\n            [tech.v3.datatype.functional :as dfn]\n            [clojure.tools.logging :as log]\n            [clojure.pprint :as pp]\n            [clojure.java.shell :as sh]\n            [clojure.java.io :as io]\n            [clojure.string :as str]\n            [criterium.core :as crit]\n            [clj-memory-meter.core :as mm])\n  (:import [java.util HashMap ArrayList Map List Map$Entry ArrayList]\n           [java.util.function BiFunction]\n           [ham_fisted IMutList Sum$SimpleSum Sum Consumers$IncConsumer]\n           [clojure.lang PersistentHashMap])\n  (:gen-class))\n\n\n(set! *unchecked-math* :warn-on-boxed)\n\n\n\n(defn long-map-data\n  [^long n-elems]\n  (lznc/->random-access\n   (lznc/object-array\n    (lznc/map\n     #(hamf/vector % %)\n     (lznc/repeatedly n-elems #(long (rand-int 100000)))))))\n\n\n(defn kwd-map-data\n  [^long n-elems]\n  (lznc/->random-access\n   (lznc/object-array\n    (lznc/map\n     #(hamf/vector (keyword (str %)) %)\n     (lznc/repeatedly n-elems #(rand-int 100000))))))\n\n\n(def map-non-numeric-constructors\n  {:clj #(into {} %)\n   #_#_:hamf-trie hamf/mut-trie-map\n   :hamf-hashmap hamf/mut-map\n   :java hamf/java-hashmap})\n\n\n(def map-numeric-constructors\n  {:hamf-long-map hamf/mut-long-hashtable-map\n   :clj-int-map #(into (i/int-map) %)})\n\n(defn map-constructors\n  [numeric?]\n  (merge map-non-numeric-constructors\n         (when numeric?\n           map-numeric-constructors)))\n\n\n(defn initial-maps\n  [mapsc data]\n  (hamf/mapmap #(vector (key %) ((val %) data)) mapsc))\n\n\n(defn hashmap-perftest\n  [data]\n  (let [numeric? (number? (ffirst data))\n        n-elems (count data)\n        _ (log/info (str \"Running map benchmark on \" (if numeric?\n                                                       \"numeric \"\n                                                       \"non-numeric \")\n                         \"data with n=\" n-elems))\n        map-constructors (map-constructors numeric?)\n        map-data (initial-maps map-constructors data)]\n    [(merge (hamf/mapmap (fn [entry]\n                           [(key entry) (benchmark-us ((val entry) data))])\n                         map-constructors)\n            {:n-elems n-elems :test :hashmap-construction :numeric? numeric?})\n     (merge (hamf/mapmap #(vector (key %)\n                                  (benchmark-us\n                                   (reduce (fn [acc data]\n                                             (.get ^Map acc (data 0)) acc)\n                                           (val %)\n                                           data)))\n                         map-data)\n            {:n-elems n-elems :test :hashmap-access :numeric? numeric?})\n     (merge (hamf/mapmap #(vector (key %)\n                                  (benchmark-us\n                                   (fn [acc map]\n                                     (reduce (fn [& kv] kv)\n                                             nil\n                                             (val %)))))\n                         map-data)\n            {:n-elems n-elems :test :hashmap-reduction :numeric? numeric?})\n     (merge (hamf/mapmap #(vector (key %) (mm/measure (val %) :bytes true))\n                         map-data)\n            {:n-elems n-elems :test :hashmap-bytes  :numeric? numeric?})]))\n\n\n(defn- spit-data\n  [testname data]\n  (let [data (vec data)\n        fname (str \"results/\" testname \".edn\")]\n    (io/make-parents fname)\n    (spit fname (pr-str data))))\n\n\n(defn general-hashmap\n  []\n  (->> (for [n-elems [4 10 100 1000 10000 1000000\n                      ]\n             numeric? [true false\n                       ]]\n         (hashmap-perftest (if numeric?\n                             (long-map-data n-elems)\n                             (kwd-map-data n-elems))))\n       (lznc/apply-concat)\n       (vec)\n       (spit-data \"general-hashmap\")))\n\n\n(defn random-updates\n  []\n  (->> (for [n-elems [ 4 10\n                      100\n                       1000 10000 1000000\n                      ]\n             numeric? [true false\n                       ]\n             ]\n         (do\n           (log/info (str \"random-update benchmark on \" (if numeric?\n                                                          \"numeric \"\n                                                          \"non-numeric \")\n                          \"data with n=\" n-elems))\n           (let [cycle-size 1000\n                 n-elems (long n-elems)\n                 data (vec (take (max cycle-size n-elems) (cycle (repeatedly (min n-elems cycle-size) #(long (rand-int 1000))))))\n                 data (if numeric? data (map (comp keyword str) data))\n                 init-maps (initial-maps (map-constructors numeric?) nil)]\n             (merge (hamf/mapmap (fn [kv]\n                                   (let [m (val kv)\n                                         immut-path? (instance? clojure.lang.IPersistentMap m)]\n                                     [(key kv)\n                                      (if immut-path?\n                                        (benchmark-us (reduce (fn [acc v]\n                                                                (assoc! acc v (unchecked-inc (long (get acc v 0)))))\n                                                              (transient m)\n                                                              data))\n                                        (let [cfn (hamf-fn/function _v (Consumers$IncConsumer.))]\n                                          (benchmark-us (reduce (fn [^Map acc v]\n                                                                  (.inc ^Consumers$IncConsumer\n                                                                        (.computeIfAbsent acc v cfn))\n                                                                  acc)\n                                                                m\n                                                                data))))]))\n                                 init-maps)\n                    {:n-elems n-elems :numeric? numeric? :test :random-update}))))\n       (vec)\n       (spit-data \"random-update\")))\n\n\n#_(defn union-overlapping\n  []\n  (->> (for [n-elems [4 10\n                      100\n                      1000 10000 1000000\n                      ]\n             numeric? [true false\n                       ]\n             ]\n         (do\n           (log/info (str \"union-overlapping benchmark on \" (if numeric?\n                                                              \"numeric \"\n                                                              \"non-numeric \")\n                          \"data with n=\" n-elems))\n           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))\n                 constructors (map-constructors numeric?)\n                 init-maps (initial-maps constructors data)\n                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]\n             (merge (hamf/mapmap (fn [kv]\n                                   (let [m (hamf/persistent! (val kv))]\n                                     [(key kv)\n                                      (cond\n                                        (instance? clojure.lang.IPersistentMap m)\n                                        (benchmark-us (merge-with merge-bfn m m))\n                                        (instance? BitmapTrieCommon$MapSet m)\n                                        (benchmark-us (.union ^BitmapTrieCommon$MapSet m m merge-bfn))\n                                        :else\n                                        (let [map-c (get constructors (key kv))]\n                                          (benchmark-us (hamf/map-union merge-bfn (map-c m) m))))]))\n                                 init-maps)\n                    {:n-elems n-elems :numeric? numeric? :test :union-overlapping}))))\n       (vec)\n       (spit-data \"union-overlapping\")\n       ))\n\n\n#_(defn union-disj\n  []\n  (->> (for [n-elems [4 10\n                      100\n                      1000 10000 1000000\n                      ]\n             numeric? [true false\n                       ]\n             ]\n         (do\n           (log/info (str \"union-disj benchmark on \" (if numeric?\n                                                              \"numeric \"\n                                                              \"non-numeric \")\n                          \"data with n=\" n-elems))\n           (let [n-elems (long n-elems)\n                 data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))\n                 lhs-data (vec (take (quot n-elems 2) data))\n                 rhs-data (vec (drop (- n-elems (count lhs-data)) data))\n                 constructors (map-constructors numeric?)\n                 lhs-maps (initial-maps constructors lhs-data)\n                 rhs-maps (initial-maps constructors rhs-data)\n                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]\n             (merge (hamf/mapmap (fn [kv]\n                                   ;;Make sure we can't edit lhs\n                                   (let [lhs (hamf/persistent! (val kv))\n                                         rhs (rhs-maps (key kv))]\n                                     [(key kv)\n                                      (cond\n                                        (instance? clojure.lang.IPersistentMap lhs)\n                                        (benchmark-us (merge-with merge-bfn lhs rhs))\n                                        (instance? BitmapTrieCommon$MapSet lhs)\n                                        (benchmark-us (.union ^BitmapTrieCommon$MapSet (hamf/transient lhs) rhs merge-bfn))\n                                        :else\n                                        (let [map-c (get constructors (key kv))]\n                                          (benchmark-us (hamf/map-union merge-bfn (map-c lhs ) rhs))))]))\n                                 lhs-maps)\n                    {:n-elems n-elems :numeric? numeric? :test :union-disj}))))\n       (vec)\n       (spit-data \"union-disj\")\n       ))\n\n\n#_(defn union-reduce\n  []\n  (->> (for [n-elems [ 4 10\n                      100\n                       1000 10000 1000000\n                      ]\n             numeric? [true false\n                       ]\n             ]\n         (do\n           (log/info (str \"union-reduce benchmark on \" (if numeric?\n                                                              \"numeric \"\n                                                              \"non-numeric \")\n                          \"data with n=\" n-elems))\n           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))\n                 constructors (map-constructors numeric?)\n                 init-maps (initial-maps constructors data)\n                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]\n             (merge (hamf/mapmap (fn [kv]\n                                   (let [m (hamf/persistent! (val kv))\n                                         mseq (vec (repeat 16 m))]\n                                     [(key kv)\n                                      (cond\n                                        (instance? clojure.lang.IPersistentMap m)\n                                        (benchmark-us (reduce #(merge-with merge-bfn %1 %2)\n                                                              m\n                                                              mseq))\n                                        (instance? BitmapTrieCommon$MapSet m)\n                                        (benchmark-us (reduce #(.union ^BitmapTrieCommon$MapSet %1 %2 merge-bfn)\n                                                              m\n                                                              mseq))\n                                        :else\n                                        (let [map-c (get constructors (key kv))]\n                                          (benchmark-us (reduce #(hamf/map-union merge-bfn %1 %2)\n                                                                (map-c m)\n                                                                mseq))))]))\n                                 init-maps)\n                    {:n-elems n-elems :numeric? numeric? :test :union-reduce}))))\n       (vec)\n       (spit-data \"union-reduce\")))\n\n\n(defn union-reduce-transient\n  \"Comparing reducing into a single transient container vs. doing a shallow clone every union call.\"\n  []\n  (->> (for [n-elems [ 4 10\n                      100\n                       1000 10000 1000000\n                      ]\n             numeric? [true\n                       ]\n             ]\n         (do\n           (log/info (str \"union-reduce-transient benchmark on \" (if numeric?\n                                                                   \"numeric \"\n                                                                   \"non-numeric \")\n                          \"data with n=\" n-elems))\n           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))\n                 constructors (map-constructors numeric?)\n                 hashmap (hamf/mut-map data)\n                 long-hashmap (hamf/mut-map data)\n                 init-maps {:hamf-hashmap (persistent! hashmap)\n                            :hamf-long-map (persistent! long-hashmap)\n                            :hamf-trans-hashmap (with-meta (persistent! hashmap) {:transient? true})\n                            :hamf-trans-long-map (with-meta (persistent! long-hashmap) {:transient? true})}\n                 merge-bfn (hamf-fn/bi-function a b (+ (long a) (long b)))]\n             (merge (hamf/mapmap (fn [kv]\n                                   (let [m (val kv)\n                                         mseq (vec (repeat 16 m))]\n                                     [(key kv)\n                                      (benchmark-us (reduce #(.union (hamf/as-map-set %1) %2 merge-bfn)\n                                                            (if (:transient? (meta m))\n                                                              (transient m)\n                                                              m)\n                                                            mseq))]))\n                                 init-maps)\n                    {:n-elems n-elems :numeric? numeric? :test :union-reduce-transient}))))\n       (vec)\n       (spit-data \"union-reduce-transient\")))\n\n\n#_(defn update-values\n  []\n  (->> (for [n-elems [ 4 10\n                      100\n                       1000 10000 1000000\n                      ]\n             numeric? [true false\n                       ]\n             ]\n         (do\n           (log/info (str \"update-values benchmark on \" (if numeric?\n                                                          \"numeric \"\n                                                          \"non-numeric \")\n                          \"data with n=\" n-elems))\n           (let [data (if numeric? (long-map-data n-elems) (kwd-map-data n-elems))\n                 constructors (map-constructors numeric?)\n                 init-maps (initial-maps constructors data)\n                 update-bfn (hamf-fn/bi-function k v (unchecked-inc (long v)))]\n             (merge (hamf/mapmap (fn [kv]\n                                   (let [m (val kv)]\n                                     [(key kv)\n                                      (cond\n                                        ;;for whatever reason update-vals isn't found during uberjar build\n                                        (instance? clojure.lang.IPersistentMap m)\n                                        (benchmark-us (update-vals m unchecked-inc))\n                                        (instance? ImmutValues m)\n                                        (benchmark-us (.immutUpdateValues ^ImmutValues m update-bfn))\n                                        :else\n                                        (benchmark-us (.replaceAll ^Map ((constructors (key kv)) m) update-bfn)))]))\n                                 init-maps)\n                    {:n-elems n-elems :numeric? numeric? :test :update-values}))))\n       (vec)\n       (spit-data \"update-values\")))\n\n\n(deftype LongAccum [^{:unsynchronized-mutable true\n                      :tag long} val]\n  clojure.lang.IDeref\n  (deref [this] val)\n  java.util.function.LongConsumer\n  (accept [this v] (set! val (+ v val))))\n\n\n(defn typed-reductions\n  []\n  (->>\n   (for [n-elems [ 4 10\n                  100\n                  1000 10000 1000000                  ]]\n     (do\n       (log/info (str \"typed reduction benchmark on \" (if true\n                                                        \"numeric \"\n                                                        \"non-numeric \")\n                      \"data with n=\" n-elems))\n       (merge\n        {:clj (benchmark-us (transduce (comp (map #(+ (long %) 10)) (filter #(== 0 (rem (long %) 2))))\n                                       + 0 (hamf/range n-elems)))\n         :clj-typed (benchmark-us (transduce (comp (map (hamf-fn/long-unary-operator a (+ a 10)))\n                                                   (filter (hamf-fn/long-predicate a (== 0 (rem a 2)))))\n                                             (reify ham_fisted.IFnDef$LLL\n                                               (invokePrim [this a b] (+ a b))\n                                               (invoke [this a] a)) 0\n                                             (hamf/range n-elems)))\n         :hamf-partial (benchmark-us (->> (hamf/range n-elems)\n                                          (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))\n                                          (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))\n                                          (reduce (hamf-fn/long-binary-operator a b (+ a b)) 0)))\n         :hamf-deftype-consumer (benchmark-us (->> (hamf/range n-elems)\n                                                   (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))\n                                                   (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))\n                                                   (reduce hamf-rf/long-consumer-accumulator (LongAccum. 0))))\n         :hamf-java-consumer (benchmark-us (->> (hamf/range n-elems)\n                                                (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))\n                                                (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))\n                                                (reduce hamf-rf/long-consumer-accumulator (ham_fisted.LongAccum. 0))))}\n        {:n-elems n-elems :numeric? true :test :typed-reductions})))\n   (vec)\n   (spit-data \"typed-reductions-intel\")))\n\n\n(defn typed-parallel-reductions\n  []\n  (->>\n   (for [n-elems [1000 1000000\n                  100000000\n                  ]]\n     (do\n       (log/info (str \"parallel reduction benchmark on \" (if true\n                                                        \"numeric \"\n                                                        \"non-numeric \")\n                      \"data with n=\" n-elems))\n       (let [ops (hamf-rf/options->parallel-options {:min-n 10})]\n         (merge\n          {:clj (benchmark-us (transduce (comp (map #(+ (long %) 10)) (filter #(== 0 (rem (long %) 2))))\n                                         + 0 (hamf/range n-elems)))\n           :hamf-untyped (benchmark-us (->> (hamf/range n-elems)\n                                            (lznc/map #(+ (long %) 10))\n                                            (lznc/filter #(== 0 (rem (long %) 2)))\n                                            (hamf-rf/preduce (constantly 0)\n                                                          #(+ (long %1) (long %2))\n                                                          #(+ (long %1) (long %2))\n                                                          ops)))\n           :hamf-typed (benchmark-us (->> (hamf/range n-elems)\n                                          (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))\n                                          (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))\n                                          (hamf-rf/preduce (constantly 0)\n                                                        (hamf-fn/long-binary-operator a b (+ a b))\n                                                        (hamf-fn/long-binary-operator a b (+ a b))\n                                                        ops)))\n           :hamf-consumer (benchmark-us (->> (hamf/range n-elems)\n                                             (lznc/map (hamf-fn/long-unary-operator a (+ a 10)))\n                                             (lznc/filter (hamf-fn/long-predicate a(== 0 (rem a 2))))\n                                             (hamf-rf/preduce #(ham_fisted.LongAccum. 0)\n                                                           hamf-rf/long-consumer-accumulator\n                                                           hamf-rf/reducible-merge\n                                                           ops)))}\n          {:n-elems n-elems :numeric? true :test :typed-parallel-reductions}))))\n   (vec)\n   (spit-data \"typed-parallel-reductions\")\n   ))\n\n\n(def persistent-vector-constructors\n  {:clj vec\n   :hamf hamf/immut-list\n   :hamf-objary #(hamf/immut-list (hamf/object-array %))\n   :java #(doto (ArrayList.)\n            (.addAll (hamf/->random-access %)))})\n\n\n(defn persistent-vector-perftest\n  []\n  (->> (for [n-elems [4 10\n                      100\n                      1000 10000 100000]]\n         (do\n           (log/info (str \"persistent vector perftest with n= \" n-elems))\n           [(merge (hamf/mapmap (fn [kv]\n                                  [(key kv)\n                                   (benchmark-us ((val kv) (range n-elems)))])\n                                persistent-vector-constructors)\n                   {:n-elems n-elems :numeric? true :test :vector-construction})\n            (merge (hamf/mapmap (fn [kv]\n                                  (let [data ((val kv) (range n-elems))]\n                                    [(key kv)\n                                     (benchmark-us (dotimes [idx n-elems]\n                                                     (.get ^List data idx)))]))\n                                persistent-vector-constructors)\n                   {:n-elems n-elems :numeric? true :test :vector-access})\n            (merge (hamf/mapmap (fn [kv]\n                                  (let [data ((val kv) (range n-elems))]\n                                    [(key kv)\n                                     (benchmark-us (.toArray ^List data))]))\n                                persistent-vector-constructors)\n                   {:n-elems n-elems :numeric? true :test :to-object-array})\n            (merge (hamf/mapmap (fn [kv]\n                                  (let [data (double-array (range n-elems))]\n                                    [(key kv)\n                                     (benchmark-us ((val kv) data))]))\n                                persistent-vector-constructors)\n                   {:n-elems n-elems :numeric? true :test :from-double-array})\n            ]))\n       (lznc/apply-concat)\n       (vec)\n       (spit-data \"persistent-vector\")))\n\n\n(defn sort-by-perftest\n  []\n  (->>\n   (for [n-elems [4 10\n                  100\n                  1000 10000 100000\n                  1000000\n                  ]]\n     (do\n       (log/info (str \"sort-by perftest with n= \" n-elems))\n       (let [data (mapv (fn [idx]\n                          {:a 1\n                           :b idx})\n                        (shuffle (range n-elems)))]\n         {:clj (benchmark-us (sort-by :b data))\n          :hamf (benchmark-us (hamf/sort-by :b data))\n          :hamf-typed (benchmark-us (hamf/sort-by (hamf-fn/obj->long d (long (d :b))) data))\n          :n-elems n-elems\n          :test :sort-by\n          :numeric? true})))\n   (vec)\n   (spit-data \"sort-by\")))\n\n\n(defn concatv-perftest\n  []\n  (->>\n   (for [n-elems [4 10\n                  100\n                  1000 10000 100000\n                  1000000\n                  ]]\n     (do\n       (log/info (str \"concatv perftest with n= \" n-elems))\n       (let [data (vec (repeat 10 (range n-elems)))]\n         {:clj (benchmark-us (into [] cat data))\n          :hamf (benchmark-us (hamf/apply-concatv data))\n          :hamf-objarry (benchmark-us (apply hamf/concata data))\n          :n-elems n-elems\n          :test :concatv\n          :numeric? true})))\n   (vec)\n   (spit-data \"concatv\")))\n\n\n(defn vec-equals-perftest\n  []\n  (->>\n   (for [n-elems [4 10\n                  100\n                  1000 10000 100000\n                  ]\n         numeric [true false]]\n     (do\n       (log/info (str \"concatv perftest with n= \" n-elems))\n       (let [src-data (if numeric\n                        (range n-elems)\n                        (map (comp str keyword) (range n-elems)))]\n         {:clj (let [lhs (vec src-data)\n                     rhs (vec src-data)]\n                 (benchmark-us (= lhs rhs)))\n          :hamf (let [lhs (hamf/vec src-data)\n                      rhs (hamf/vec src-data)]\n                  (benchmark-us (= lhs rhs)))\n          :n-elems n-elems\n          :test :equals\n          :numeric? numeric})))\n   (vec)\n   (spit-data \"vec-equals\")))\n\n\n\n(defn -main\n  [& args]\n  ;;shutdown test\n  (persistent-vector-perftest)\n  #_(concatv-perftest)\n  #_(vec-equals-perftest)\n  #_(let [perf-data (process-dataset (profile))\n        vs (System/getProperty \"java.version\")\n        mn (machine-name)\n        gs (git-sha)\n        fname (str \"results/\" gs \"-\" mn \"-jdk-\" vs \".edn\")]\n    (print-dataset perf-data)\n    (println \"Results stored to:\" fname)\n    ;;(spit fname (with-out-str (pp/pprint {:machine-name mn :git-sha gs :jdk-version vs :dataset perf-data})))\n    )\n  (println \"exiting\"))\n"
  },
  {
    "path": "docs/Reductions.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>Reductions</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1  current\"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"document\" id=\"content\"><div class=\"doc\"><div class=\"markdown\"><h1>Reductions</h1>\n<p>The ham-fisted project extends the concept of Clojure's <code>reduce</code> in a few ways,\ntaking influence from java streams and Clojure transducers.  The most important\nway is a formal definition of a parallel reduction (analogous to <code>pmap</code> for <code>map</code>).</p>\n<p>Most interesting is the 3 argument form of <code>(reduce rfn init coll)</code>.  Problems\nexist with the 2 argument form <code>(reduce rfn coll)</code> as the reduction function -\n<code>rfn</code>'s leftmost argument is sometimes a value from the collection and at other\ntimes an accumulated value.  Some reductions have the property that the\naccumulator is in the set of objects in the collection (such as numeric <code>+</code>),\nthese reductions are not the most general. They are a special case of a\nreduction where the accumulator may be a different type entirely than the values\nin the collection.</p>\n<h2>Parallelizable Containers</h2>\n<p>Efficient parallel reductions depend on parallelizable containers.</p>\n<p>Java has three types of containers that operate efficiently in parallel.</p>\n<ol>\n<li>Finite random access containers (ex: an array)</li>\n<li>Containers that can provide spliterators (ex: hashtable)</li>\n<li>A concatenation of containers suitable for parallel computation over the parts</li>\n</ol>\n<p>These three types of containers we can parallelize; random access containers,\nmaps and sets (or more generally anything with a correct spliterator\nimplementation), and concatenations of sub-containers each of which may not\nitself have a parallelizable reduction.</p>\n<h2>Parallelized Reduction</h2>\n<p>A parallelized reduction works by splitting up elements of the data source.\nMany reduction contexts operate simultaneous each of which will perform a serial\nreduction.  A separate step merges the results back together.  This may be\nthought of as the \"true\" map-reduce, but either way it may be useful to compare\na parallelized reduction in detail to a serial reduction.</p>\n<p>To perform a parallel reduction, four things must be provided:</p>\n<ul>\n<li><code>init-val-fn</code> - a function to produce initial accumulators for each reduction context</li>\n<li><code>rfn</code> - a function that takes an accumulator and a value and updates the accumulator ---  This\nis the typical reduction function passed as the first argument to Clojure's <code>reduce</code></li>\n<li><code>merge-fn</code> - a function that takes two accumulators and merges them to produces one\nresult accumulator.</li>\n<li><code>coll</code> - a collection of items to reduce to a single output</li>\n</ul>\n<p>Here are the function signatures (Keep in mind ... <code>preduce</code>:<code>reduce</code> :: <code>pmap</code>:<code>map</code>):</p>\n<pre><code class=\"language-clojure\">(defn preduce [init-val-fn rfn merge-fn coll] ...)\n</code></pre>\n<p>Notably Java streams have a 'collect' method that takes the same four arguments\nwhere the collection is the <code>this</code> object:</p>\n<pre><code class=\"language-java\">interface Stream&lt;E&gt; {\n&lt;R&gt; R collect(Supplier&lt;R&gt; supplier,\n              BiConsumer&lt;R,? super T&gt; accumulator,\n              BiConsumer&lt;R,R&gt; combiner);\n}\n</code></pre>\n<p>The parallelizable reduction operates as a a serial reduction if the init-val-fn\nis called exactly once with no arguments and the entire collection is passed\nalong with rfn to reduce:</p>\n<pre><code class=\"language-clojure\">(reduce rfn (init-val-fn) coll)\n</code></pre>\n<p>From there <code>preduce</code> essentially switches on the type of coll and performs one\nof four distinct types of reductions:</p>\n<ul>\n<li>serial</li>\n<li>parallel over and index space</li>\n<li>parallel over and spliterator space</li>\n<li>parallel over sub-containers</li>\n</ul>\n<h2>Map, Filter, Concat Chains</h2>\n<p>It is common in functional programming to implement data transformations as\nchains of <code>map</code>, <code>filter</code>, and <code>concat</code> operations.  Analyzing sequences of\nthese operations is insight with regards to reduction in general and\nparallelization of reductions.</p>\n<p>The first insight is found in the Clojure transducer pathways and involves collapsing\nthe reduction function when possible for map and filter applications.  Let's start with\na reduction of the form <code>(-&gt;&gt; coll (map x) (filter y) (reduce ...))</code>.</p>\n<p>The filter operator can specialize its reduce implementation by producing a new reduction\nfunction and reducing over its source collection:</p>\n<pre><code class=\"language-java\">public Object reduce(IFn rfn, Object init) {\n\treturn source.reduce(new IFn() {\n\t  public Object invoke(Object acc, Object v) {\n\t    if(pred.test(v))\n\t\t  return rfn.invoke(acc, v);\n\t    else\n\t\t  return acc;\n\t  }\n\t}, init);\n}\n</code></pre>\n<p>This results in 'collapsing' the reduction allowing the source to perform the\niteration across its elements and simply dynamically creating a slightly more\ncomplex reduction function, <code>rfn</code>.  A similar pathway exists for <code>map</code> as we can\nalways delegate up the chain making a slightly more complex reduction function\nas long as we are reducing over a single source of data.  This optimization\nleads to many fewer function calls and intermediate collections when compared\nwith naive implementations of <code>map</code> and <code>filter</code>. Clojure's transducers do this\nautomatically.</p>\n<p>Collapsing the reduction also allows us to parallelize reductions like the initial one\nstated before as if the filter object has a parallelReduction method that does an identical\ncollapsing pathway then if the source is parallelizable then the reduction itself can\nstill parallelize:</p>\n<pre><code class=\"language-java\">public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn) {\n  return source.parallelReduction(initValFn, new IFn() {...}, mergeFn);\n}\n</code></pre>\n<p>If the source collection itself allows for parallel reduction, then it's\npossible to achieve similar 'collapsing' in <code>preduce</code>.  Clojure's transducers do\nnot have this particular optimization for parallel reduction, but Java streams\ndo.</p>\n<p>Also worth noting, these optimizations are only available if we use the 4\nargument form of reduce <em>and</em> if we assume that <code>map</code>, <code>filter</code>, and <code>concat</code> are lazy\nand non-caching.</p>\n<p>With those assumptions in place it is possible to parallelize a reduction over\nthe entries, keys or values of map using simple primitive composition:</p>\n<pre><code class=\"language-clojure\">user&gt; (require '[ham-fisted.api :as hamf])\nnil\nuser&gt; (require '[ham-fisted.lazy-noncaching :as lznc])\nnil\nuser&gt; (def data (hamf/immut-map (lznc/map #(vector % %) (range 20000))))\n#'user/data\nuser&gt; (type data)\nham_fisted.PersistentHashMap\nuser&gt; (hamf/preduce + + + (lznc/map key data))\n199990000\n</code></pre>\n<h2>Stream-based Reductions</h2>\n<p>Java streams have a notion of parallel reduction built-in. Their design suffers\nfrom two flaws, one minor and one major.</p>\n<p>The first minor flaw is that you can ask a stream for a parallel version of\nitself and it will give you one if possible else return a copy of itself.\nUnfortunately this only works on the first stream in a pipeline so for instance:</p>\n<pre><code class=\"language-java\">  coll.stream().map().filter().parallel().collect();\n</code></pre>\n<p>yields a serial reduction while:</p>\n<pre><code class=\"language-java\">  coll.stream().parallel().map().filter().collect();\n</code></pre>\n<p>yields a parallel reduction.</p>\n<p>This is unfortunate because it means you must go back in time to get a parallel\nversion of the stream if you want to perform a parallel collection; something\nthat may or may not be easily done at the point in time when you decide you do\nin fact want to parallel reduction (especially in library code).</p>\n<p>The second and more major flaw is that stream-based parallelization does not\nallow the user to pass in their own fork-join pool at any point. This limits use\nto the built in pool where it's pad form to park threads or do blocking\noperations.</p>\n<h2>reducers.clj And Parallel Folds</h2>\n<p>Clojure has an alpha namespace that provides a parallel reduction, <a href=\"https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj\">reducers.clj</a>.  The signature\nfor this method is:</p>\n<pre><code class=\"language-clojure\">(defn fold\n  \"Reduces a collection using a (potentially parallel) reduce-combine\n  strategy. The collection is partitioned into groups of approximately\n  n (default 512), each of which is reduced with reducef (with a seed\n  value obtained by calling (combinef) with no arguments). The results\n  of these reductions are then reduced with combinef (default\n  reducef). combinef must be associative, and, when called with no\n  arguments, (combinef) must produce its identity element. These\n  operations may be performed in parallel, but the results will\n  preserve order.\"\n  {:added \"1.5\"}\n  ([reducef coll] (fold reducef reducef coll))\n  ([combinef reducef coll] (fold 512 combinef reducef coll))\n  ([n combinef reducef coll]\n     (coll-fold coll n combinef reducef)))\n</code></pre>\n<p>In this case we use overloads of <code>combinef</code> or <code>reducef</code> to provider the initial accumulator\n(called the identity element), the rfn, finalization and the merge function.  <code>combinef</code> called\nwith no arguments provides each thread context's accumulator and called with two arguments\nperforms a merge of two accumulators.  <code>reducef</code> called with 2 arguments provides\nthe reduction from a value into the accumulator and when called with one argument\nfinalizes both the potentially stateful reducing function and finalizes the\naccumulator.  It prescribes the parallelization system but users can override a protocol\nto do it themselves.</p>\n<p>This the same major drawback as the java stream system, namely users cannot provide\ntheir own pool for parallelization.</p>\n<p>An interesting decision was made here as to whether one can actually parallelize the\nreduction or not.  Transducers, the elements providing <code>reducef</code>, may be stateful\nsuch as <code>(take 15)</code>.  One interesting difference is that state is done with a closure in\nthe reduction function as opposed to providing a custom accumulator that wraps the user's\naccumulator but tracks state.</p>\n<p>One aspect we haven't discussed but that is also handled here in an interesting\nmanner is that whether a reduction can be parallelized or not is a function both\nof the container <em>and</em> of the reducer.  <code>reducers.clj</code> does a sort of\ndouble-dispatch where the transducer may choose to implement the parallel\nreduction, called <code>coll-fold</code> or not and is queried first and if it allows\nparallel reduction then the collection itself is dispatched.  Overall this is a\ngreat, safe choice because it disallows completely parallel dispatch if the\ntransducer or the collection do not support it.</p>\n<h2>Parallel Reducers</h2>\n<p>If we combine all three functions: <code>init-val-fn</code>, <code>rfn</code>, and <code>merge-fn</code> into one object\nthen we get a ParallelReducer, defined in protocols.clj.  This protocol allows the\nuser to pass a single object into a parallelized reduction as opposed to three functions\nwhich is useful when we want to have many reducers reduce over a single source of data.\nA <code>finalize</code> method is added in order to allow compositions of reducers, and to allow\nreducers to hide state and information from end users:</p>\n<pre><code class=\"language-clojure\">(defprotocol ParallelReducer\n  \"Parallel reducers are simple a single object that you can pass into preduce as\n  opposed to 3 separate functions.\"\n  (-&gt;init-val-fn [item]\n    \"Returns the initial values for a parallel reduction.  This function\ntakes no arguments and returns the initial reduction value.\")\n  (-&gt;rfn [item]\n    \"Returns the reduction function for a parallel reduction. This function takes\ntwo arguments, the initial value and a value from the collection and returns a new\ninitial value.\")\n  (-&gt;merge-fn [item]\n    \"Returns the merge function for a parallel reduction.  This function takes\ntwo initial values and returns a new initial value.\")\n  (finalize [item v]\n    \"A finalize function called on the result of the reduction after it is\nreduced but before it is returned to the user.  Identity is a reasonable default.\"))\n</code></pre>\n<p>There are defaults to the reducer protocol for an IFn which assumes it can be\ncalled with no arguments for a initial value and two arguments for both\nreduction and merge.  This works for things like <code>+</code> and <code>*</code>.  Additionally\nthere are implementations provided for the ham_fisted Sum (Kahans compensated)\nand SimpleSum\n<a href=\"https://docs.oracle.com/javase/8/docs/api/java/util/function/DoubleConsumer.html\">DoubleConsumer</a>\nclasses.</p>\n<p>With the three functions bundled into one logical protocol or object it is easy then\nto create complex (aggregate) and efficient parallelized reductions:</p>\n<pre><code class=\"language-clojure\">user&gt; (require '[ham-fisted.reduce :as hamf-rf])\nnil\nuser&gt; (hamf-rf/preduce-reducers {:sum + :product *} (range 1 20))\n{:product 121645100408832000, :sum 190}\nuser&gt;\n</code></pre>\n<p>This goes over the data in parallel, exactly once.</p>\n<h2>Consumers, Transducers, and <code>rfn</code> Chains</h2>\n<p>If we look at the reduction in terms of a push model as opposed to a pull model\nwhere the stream will push data into a consumer then we can implement similar\nchains or map and filter.  These are based on creating a new consumer that takes\nthe older consumer and the filter predicate or mapping function.  In this way\none can implement a pipeline on the input stream, or perhaps diverging pipelines\non each reduction function in a multiple reducer scenario.  Since the init and\nmerge functions operate in accumulator space, which remains unchanged, one can\ndevelop up increasingly sophisticated reduction functions and still perform a\nparallelized reduction.  Naturally, everything is composed in reverse (push\ninstead of pull), which is the reason that <code>comp</code> works in reverse when working\nwith transducers.</p>\n<p>In fact, given that the covers are pulled back on composing reduction functions,\nthe definition of the single argument <code>clojure.core/filter</code> becomes more clear:</p>\n<pre><code class=\"language-clojure\">(defn filter\n  \"Returns a lazy sequence of the items in coll for which\n  (pred item) returns logical true. pred must be free of side-effects.\n  Returns a transducer when no collection is provided.\"\n  {:added \"1.0\"\n   :static true}\n  ([pred]\n    (fn [rf]\n      (fn\n        ([] (rf))\n        ([result] (rf result))\n        ([result input]\n           (if (pred input)\n             (rf result input)\n             result)))))))\n</code></pre>\n<p>It returns a function that, when given a reduction function, returns a new reduction\nfunction that when called in the two argument form is identical to the result above\n(although expressed in pure Clojure as opposed to Java).</p>\n<p>Starting with the concept that a reduction begins at the collection, flows\ndownward through the pipeline and bottoms out at the reducer then the\nlazy-noncaching namespace and Java streams implement parallelization flowing\nfrom the container downward. Separately consumer chains and transducers\nimplement the pipeline flowing up from the reducer itself.  Thus building the\npipeline either downward from the source or upward from the final reduction\nproduces subtly different properties.  Regardless, every system must disable\nparallelization where it will cause an incorrect answer (to ensure correctness)</p>\n<ul>\n<li>such as in a stateful transducer.</li>\n</ul>\n<p>Broadly speaking, however, it can be faster to enable full parallelization and\nfilter invalid results than it is to force an early serialization our problem\nand thus lose lots of our parallelization potential.  When concerned with\nperformance, attempt to move transformations as much as possible into a\nparallelizable domain.</p>\n<p>For the <code>take-n</code> use case specifically mentioned above and potentially for others we\ncan parallelize the reduction and do the take-n both in the parallelized phase and\nin the merge phase assuming we are using an ordered parallelization, so that doesn't\nitself necessarily force a serialized reduction but there are of course\ntransformations and reductions that do.  There are intermediate points however that are\nperhaps somewhat wasteful in terms of cpu load but do allow for more parallelization - a\ntradeoff that is sometimes worth it. Generically speaking we can visualize this sort\nof a tradeoff as triangle of three points where one point is data locality, one\npoint parallelism, and one point redundancy.  Specifically if we are willing to\ntrade some cpu efficiency for some redundancy, for instance, then we often get more\nparallelization.  Likewise if we are willing to save/load data from 'far' away from\nthe CPU, then we can cut down on redundancy but at the cost of locality.  For more\non this line of thinking please take a moment and read at least some of Jonathan Ragan-Kelly's\n<a href=\"http://people.csail.mit.edu/jrk/jrkthesis.pdf\">excellent PhD thesis</a> - a better explanation\nof the above line of reasoning begins on page 20.</p>\n<h2>Primitive Typed Serial Reductions</h2>\n<p>This comes last for a good reason :-) - it doesn't make a huge difference in performance\nbut it should be noted allowing objects to implemented typed reductions:</p>\n<pre><code class=\"language-java\">default Object doubleReduction(IFn.ODO op, Object init);\ndefault Object longReduction(IFn.OLO op, Object init)\n</code></pre>\n<p>where the next incoming value is a primitive object but the accumulator is still\na generic object allows us to use things like <code>DoubleConsumers</code> and\n<code>LongConsumers</code> and avoid boxing the stream.  Furthermore if the aforementioned\n<code>map</code> and <code>filter</code> primitives are careful about their rfn composition we can\nmaintain a completely primitive typed pipeline through an entire processing\nchain.</p>\n<h2>One Final Note About Performance</h2>\n<p>Collapsing reductions brings the source iteration pathway closer to the final\nreduction pathway in terms of machine stack space which allows HotSpot to\noptimize the entire chain more readily.  Regardless of how good HotSpot gets,\nhowever, parallelizing will nearly always result in a larger win but both work\ntogether to enable peak performance on the JVM given arbitrary partially typed\ncompositions of sequences and reductions.</p>\n<p>When increasing the data size yet again, one can of course use the same design\nto distribute the computations to different machines.  As some people have\nfigured out, however, simply implementing the transformations you need\nefficiently reduces or completely eliminates the need to distribute computation\nin the first place leading to a simpler, easier to test and more robust system.</p>\n<p>Ideally we can make achieving great performance for various algorithms clear and easy and\nthus avoid myriad of issues regarding distributing computing in the first place.</p>\n<ul>\n<li>The first rule of distributed systems is to avoid distributing your computation in the first place - <a href=\"https://bravenewgeek.com/service-disoriented-architecture/\">1</a>, <a href=\"https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing\">2</a>.</li>\n<li>The first law of distributed objects is to avoid using distributed objects. <a href=\"https://martinfowler.com/bliki/FirstLaw.html\">3</a>.</li>\n</ul>\n</div></div></div></body></html>"
  },
  {
    "path": "docs/css/default.css",
    "content": "@import url('https://fonts.googleapis.com/css?family=PT+Sans');\n\nbody {\n    font-family: 'PT Sans', Helvetica, sans-serif;\n    font-size: 14px;\n}\n\na {\n    color: #337ab7;\n    text-decoration: none;\n}\n\na:hover {\n    color: #30426a;\n    text-decoration: underline;\n}\n\npre, code {\n    font-family: Monaco, DejaVu Sans Mono, Consolas, monospace;\n    font-size: 9pt;\n    margin: 15px 0;\n}\n\nh1 {\n    font-weight: normal;\n    font-size: 29px;\n    margin: 10px 0 2px 0;\n    padding: 0;\n}\n\nh2 {\n    font-weight: normal;\n    font-size: 25px;\n}\n\nh3 > a:hover {\n    text-decoration: none;\n}\n\n.document h1, .namespace-index h1 {\n    font-size: 32px;\n    margin-top: 12px;\n}\n\n#header, #content, .sidebar {\n    position: fixed;\n}\n\n#header {\n    top: 0;\n    left: 0;\n    right: 0;\n    height: 22px;\n    color: #f5f5f5;\n    padding: 5px 7px;\n}\n\n#content {\n    top: 32px;\n    right: 0;\n    bottom: 0;\n    overflow: auto;\n    background: #fff;\n    color: #333;\n    padding: 0 18px;\n}\n\n.sidebar {\n    position: fixed;\n    top: 32px;\n    bottom: 0;\n    overflow: auto;\n}\n\n.sidebar.primary {\n    background: #30426a;\n    border-right: solid 1px #cccccc;\n    left: 0;\n    width: 250px;\n    color: white;\n    font-size: 110%;\n}\n\n.sidebar.secondary {\n    background: #f2f2f2;\n    border-right: solid 1px #d7d7d7;\n    left: 251px;\n    width: 200px;\n    font-size: 110%;\n}\n\n#content.namespace-index, #content.document {\n    left: 251px;\n}\n\n#content.namespace-docs {\n    left: 452px;\n}\n\n#content.document {\n    padding-bottom: 10%;\n}\n\n#header {\n    background: #2d3e63;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);\n    z-index: 100;\n}\n\n#header h1 {\n    margin: 0;\n    padding: 0;\n    font-size: 18px;\n    font-weight: lighter;\n    text-shadow: -1px -1px 0px #333;\n}\n\n#header h1 .project-version {\n    font-weight: normal;\n}\n\n.project-version {\n    padding-left: 0.15em;\n}\n\n#header a, .sidebar a {\n    display: block;\n    text-decoration: none;\n}\n\n#header a {\n    color: #f5f5f5;\n}\n\n.sidebar.primary, .sidebar.primary a {\n    color: #b2bfdc;\n}\n\n.sidebar.primary a:hover {\n    color: white;\n}\n\n.sidebar.secondary, .sidebar.secondary a {\n    color: #738bc0;\n}\n\n.sidebar.secondary a:hover {\n    color: #2d3e63;\n}\n\n#header h2 {\n    float: right;\n    font-size: 9pt;\n    font-weight: normal;\n    margin: 4px 3px;\n    padding: 0;\n    color: #bbb;\n}\n\n#header h2 a {\n    display: inline;\n}\n\n.sidebar h3 {\n    margin: 0;\n    padding: 10px 13px 0 13px;\n    font-size: 19px;\n    font-weight: lighter;\n}\n\n.sidebar.primary h3.no-link {\n    text-transform: uppercase;\n    font-size: 12px;\n    color: #738bc0;\n}\n\n.sidebar.secondary h3 a {\n    text-transform: uppercase;\n    font-size: 12px;\n    color: #2d3e63;\n}\n\n.sidebar ul {\n    padding: 7px 0 6px 0;\n    margin: 0;\n}\n\n.sidebar ul.index-link {\n    padding-bottom: 4px;\n}\n\n.sidebar li {\n    display: block;\n    vertical-align: middle;\n}\n\n.sidebar li a, .sidebar li .no-link {\n    border-left: 3px solid transparent;\n    padding: 0 10px;\n    white-space: nowrap;\n}\n\n.sidebar li .inner {\n    display: inline-block;\n    padding-top: 7px;\n    height: 24px;\n}\n\n.sidebar li a, .sidebar li .tree {\n    height: 31px;\n}\n\n.depth-1 .inner { padding-left: 2px; }\n.depth-2 .inner { padding-left: 6px; }\n.depth-3 .inner { padding-left: 20px; }\n.depth-4 .inner { padding-left: 34px; }\n.depth-5 .inner { padding-left: 48px; }\n.depth-6 .inner { padding-left: 62px; }\n\n.sidebar li .tree {\n    display: block;\n    float: left;\n    position: relative;\n    top: -10px;\n    margin: 0 4px 0 0;\n    padding: 0;\n}\n\n.sidebar li.depth-1 .tree {\n    display: none;\n}\n\n.sidebar li .tree .top, .sidebar li .tree .bottom {\n    display: block;\n    margin: 0;\n    padding: 0;\n    width: 7px;\n}\n\n.sidebar li .tree .top {\n    border-left: 1px solid #aaa;\n    border-bottom: 1px solid #aaa;\n    height: 19px;\n}\n\n.sidebar li .tree .bottom {\n    height: 22px;\n}\n\n.sidebar li.branch .tree .bottom {\n    border-left: 1px solid #aaa;\n}\n\n.sidebar.primary li.current a {\n    border-left: 3px solid #e99d1a;\n    color: white;\n}\n\n.sidebar.secondary li.current a {\n    border-left: 3px solid #2d3e63;\n    color: #33a;\n}\n\n.namespace-index h2 {\n    margin: 30px 0 0 0;\n}\n\n.namespace-index h3 {\n    font-size: 16px;\n    font-weight: bold;\n    margin-bottom: 0;\n    letter-spacing: 0.05em;\n    border-bottom: solid 1px #ddd;\n    max-width: 680px;\n    background-color: #fafafa;\n    padding: 0.5em;\n}\n\n.namespace-index .topics {\n    padding-left: 30px;\n    margin: 11px 0 0 0;\n}\n\n.namespace-index .topics li {\n    padding: 5px 0;\n}\n\n.namespace-docs h3 {\n    font-size: 18px;\n    font-weight: bold;\n}\n\n.public h3 {\n    margin: 0;\n    float: left;\n}\n\n.usage {\n    clear: both;\n}\n\n.public {\n    margin: 0;\n    border-top: 1px solid #e0e0e0;\n    padding-top: 14px;\n    padding-bottom: 6px;\n}\n\n.public:last-child {\n    margin-bottom: 20%;\n}\n\n.members .public:last-child {\n    margin-bottom: 0;\n}\n\n.members {\n    margin: 15px 0;\n}\n\n.members h4 {\n    color: #555;\n    font-weight: normal;\n    font-variant: small-caps;\n    margin: 0 0 5px 0;\n}\n\n.members .inner {\n    padding-top: 5px;\n    padding-left: 12px;\n    margin-top: 2px;\n    margin-left: 7px;\n    border-left: 1px solid #bbb;\n}\n\n#content .members .inner h3 {\n    font-size: 12pt;\n}\n\n.members .public {\n    border-top: none;\n    margin-top: 0;\n    padding-top: 6px;\n    padding-bottom: 0;\n}\n\n.members .public:first-child {\n    padding-top: 0;\n}\n\nh4.type,\nh4.dynamic,\nh4.added,\nh4.deprecated {\n    float: left;\n    margin: 3px 10px 15px 0;\n    font-size: 15px;\n    font-weight: bold;\n    font-variant: small-caps;\n}\n\n.public h4.type,\n.public h4.dynamic,\n.public h4.added,\n.public h4.deprecated {\n    font-size: 13px;\n    font-weight: bold;\n    margin: 3px 0 0 10px;\n}\n\n.members h4.type,\n.members h4.added,\n.members h4.deprecated {\n    margin-top: 1px;\n}\n\nh4.type {\n    color: #717171;\n}\n\nh4.dynamic {\n    color: #9933aa;\n}\n\nh4.added {\n    color: #508820;\n}\n\nh4.deprecated {\n    color: #880000;\n}\n\n.namespace {\n    margin-bottom: 30px;\n}\n\n.namespace:last-child {\n    margin-bottom: 10%;\n}\n\n.index {\n    padding: 0;\n    font-size: 80%;\n    margin: 15px 0;\n    line-height: 1.6em;\n}\n\n.index * {\n    display: inline;\n}\n\n.index p {\n    padding-right: 3px;\n}\n\n.index li {\n    padding-right: 5px;\n}\n\n.index ul {\n    padding-left: 0;\n}\n\n.type-sig {\n    clear: both;\n    color: #088;\n}\n\n.type-sig pre {\n    padding-top: 10px;\n    margin: 0;\n}\n\n.usage code {\n    display: block;\n    color: #008;\n    margin: 2px 0;\n}\n\n.usage code:first-child {\n    padding-top: 10px;\n}\n\np {\n    margin: 15px 0;\n}\n\n.public p:first-child, .public pre.plaintext {\n    margin-top: 12px;\n}\n\n.doc {\n    margin: 0 0 26px 0;\n    clear: both;\n}\n\n.public .doc {\n    margin: 0;\n}\n\n.namespace-index {\n  font-size: 120%;\n}\n\n.namespace-index .doc {\n    margin-bottom: 20px;\n}\n\n.namespace-index .namespace .doc {\n    margin-bottom: 10px;\n}\n\n.markdown p, .markdown li, .markdown dt, .markdown dd, .markdown td {\n    line-height: 1.6em;\n}\n\n.markdown h2 {\n    font-weight: normal;\n    font-size: 25px;\n}\n\n#content .markdown h3 {\n    font-size: 20px;\n}\n\n.markdown h4 {\n    font-size: 15px;\n}\n\n.doc, .public, .namespace .index {\n    max-width: 680px;\n    overflow-x: visible;\n}\n\n.markdown pre > code {\n    display: block;\n    padding: 10px;\n}\n\n.markdown pre > code, .src-link a {\n    border: 1px solid #e4e4e4;\n    border-radius: 2px;\n}\n\n.src-link a {\n    background: #f6f6f6;\n}\n\n.markdown code:not(.hljs) {\n    color: #c7254e;\n    background-color: #f9f2f4;\n    border-radius: 4px;\n    font-size: 90%;\n    padding: 2px 4px;\n}\n\npre.deps {\n    display: inline-block;\n    margin: 0 10px;\n    border: 1px solid #e4e4e4;\n    border-radius: 2px;\n    padding: 10px;\n    background-color: #f6f6f6;\n}\n\n.markdown hr {\n    border-style: solid;\n    border-top: none;\n    color: #ccc;\n}\n\n.doc ul, .doc ol {\n    padding-left: 30px;\n}\n\n.doc table {\n    border-collapse: collapse;\n    margin: 0 10px;\n}\n\n.doc table td, .doc table th {\n    border: 1px solid #dddddd;\n    padding: 4px 6px;\n}\n\n.doc table th {\n    background: #f2f2f2;\n}\n\n.doc dl {\n    margin: 0 10px 20px 10px;\n}\n\n.doc dl dt {\n    font-weight: bold;\n    margin: 0;\n    padding: 3px 0;\n    border-bottom: 1px solid #ddd;\n}\n\n.doc dl dd {\n    padding: 5px 0;\n    margin: 0 0 5px 10px;\n}\n\n.doc abbr {\n    border-bottom: 1px dotted #333;\n    font-variant: none;\n    cursor: help;\n}\n\n.src-link {\n    margin-bottom: 15px;\n}\n\n.src-link a {\n    font-size: 70%;\n    padding: 1px 4px;\n    text-decoration: none;\n    color: #5555bb;\n    background-color: #f6f6f6;\n}\n\nblockquote {\n    opacity: 0.6;\n    border-left: solid 2px #ddd;\n    margin-left: 0;\n    padding-left: 1em;\n}\n\n/* Responsiveness Theme */\n\n@media (max-device-width: 480px) {\n  .sidebar {\n    display:none;\n  }\n\n  #content {\n    position: relative;\n    left: initial !important;\n    top: 110px;\n    padding: 0 1em;\n  }\n\n  #header {\n    display: flex;\n    flex-direction: column-reverse;\n    height: 100px;\n  }\n\n  #header > h1 {\n    font-size: 52px;\n  }\n\n  #header h2 {\n    float: none;\n    font-size: 20px;\n  }\n\n  .namespace-index > h1 {\n    display: none;\n  }\n\n  .public, .doc, .namespace > .index, .namespace > .doc, .namespace > h3 {\n    max-width: initial;\n  }\n\n  .doc {\n    text-align: justify;\n  }\n\n  .public {\n    padding-top: 2em;\n    padding-bottom: 2em;\n  }\n\n  .public > h3 {\n    font-size: 300%;\n  }\n\n  .public > h4.type, .public > h4.added, .public > h4.deprecated {\n    font-size: 150%;\n    margin-top: 1em;\n  }\n\n  pre > code {\n    font-size: 200%;\n  }\n}\n"
  },
  {
    "path": "docs/ham-fisted.api.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.api documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var--.3Ecollection\"><div class=\"inner\"><span>-&gt;collection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var--.3Erandom-access\"><div class=\"inner\"><span>-&gt;random-access</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var--.3Ereducible\"><div class=\"inner\"><span>-&gt;reducible</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-add-all.21\"><div class=\"inner\"><span>add-all!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-add-constant.21\"><div class=\"inner\"><span>add-constant!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-apply-concat\"><div class=\"inner\"><span>apply-concat</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-apply-concatv\"><div class=\"inner\"><span>apply-concatv</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-argsort\"><div class=\"inner\"><span>argsort</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-array-list\"><div class=\"inner\"><span>array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-assoc.21\"><div class=\"inner\"><span>assoc!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-binary-search\"><div class=\"inner\"><span>binary-search</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-boolean-array\"><div class=\"inner\"><span>boolean-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-boolean-array-list\"><div class=\"inner\"><span>boolean-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-byte-array\"><div class=\"inner\"><span>byte-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-byte-array-list\"><div class=\"inner\"><span>byte-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-char-array\"><div class=\"inner\"><span>char-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-char-array-list\"><div class=\"inner\"><span>char-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-clear.21\"><div class=\"inner\"><span>clear!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-clear-memoized-fn.21\"><div class=\"inner\"><span>clear-memoized-fn!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-complement\"><div class=\"inner\"><span>complement</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-concata\"><div class=\"inner\"><span>concata</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-concatv\"><div class=\"inner\"><span>concatv</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-cond\"><div class=\"inner\"><span>cond</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-conj.21\"><div class=\"inner\"><span>conj!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-constant-count\"><div class=\"inner\"><span>constant-count</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-constant-countable.3F\"><div class=\"inner\"><span>constant-countable?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-constantly\"><div class=\"inner\"><span>constantly</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-count\"><div class=\"inner\"><span>count</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-custom-counted-ireduce\"><div class=\"inner\"><span>custom-counted-ireduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-custom-ireduce\"><div class=\"inner\"><span>custom-ireduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-darange\"><div class=\"inner\"><span>darange</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-dbl-ary-cls\"><div class=\"inner\"><span>dbl-ary-cls</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-difference\"><div class=\"inner\"><span>difference</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-dnth\"><div class=\"inner\"><span>dnth</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-double-array\"><div class=\"inner\"><span>double-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-double-array-list\"><div class=\"inner\"><span>double-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-drop\"><div class=\"inner\"><span>drop</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-drop-last\"><div class=\"inner\"><span>drop-last</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-drop-min\"><div class=\"inner\"><span>drop-min</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-dsummary\"><div class=\"inner\"><span>dsummary</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-dvec\"><div class=\"inner\"><span>dvec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-empty-map\"><div class=\"inner\"><span>empty-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-empty-set\"><div class=\"inner\"><span>empty-set</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-empty-vec\"><div class=\"inner\"><span>empty-vec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-empty.3F\"><div class=\"inner\"><span>empty?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-evict-memoized-call\"><div class=\"inner\"><span>evict-memoized-call</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-filterv\"><div class=\"inner\"><span>filterv</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-first\"><div class=\"inner\"><span>first</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-float-array\"><div class=\"inner\"><span>float-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-float-array-list\"><div class=\"inner\"><span>float-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-fnth\"><div class=\"inner\"><span>fnth</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-freq-reducer\"><div class=\"inner\"><span>freq-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-frequencies\"><div class=\"inner\"><span>frequencies</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-fvec\"><div class=\"inner\"><span>fvec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-group-by\"><div class=\"inner\"><span>group-by</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-group-by-consumer\"><div class=\"inner\"><span>group-by-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-group-by-reduce\"><div class=\"inner\"><span>group-by-reduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-group-by-reducer\"><div class=\"inner\"><span>group-by-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-hash-map\"><div class=\"inner\"><span>hash-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-iarange\"><div class=\"inner\"><span>iarange</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-immut-list\"><div class=\"inner\"><span>immut-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-immut-map\"><div class=\"inner\"><span>immut-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-immut-set\"><div class=\"inner\"><span>immut-set</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-in-fork-join-task.3F\"><div class=\"inner\"><span>in-fork-join-task?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-inc-consumer\"><div class=\"inner\"><span>inc-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-inc-consumer-reducer\"><div class=\"inner\"><span>inc-consumer-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-int-array\"><div class=\"inner\"><span>int-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-int-array-list\"><div class=\"inner\"><span>int-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-intersect-sets\"><div class=\"inner\"><span>intersect-sets</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-intersection\"><div class=\"inner\"><span>intersection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-inth\"><div class=\"inner\"><span>inth</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-into\"><div class=\"inner\"><span>into</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-into-array\"><div class=\"inner\"><span>into-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-ivec\"><div class=\"inner\"><span>ivec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-java-concurrent-hashmap\"><div class=\"inner\"><span>java-concurrent-hashmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-java-hashmap\"><div class=\"inner\"><span>java-hashmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-java-hashset\"><div class=\"inner\"><span>java-hashset</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-java-linked-hashmap\"><div class=\"inner\"><span>java-linked-hashmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-keys\"><div class=\"inner\"><span>keys</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-larange\"><div class=\"inner\"><span>larange</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-last\"><div class=\"inner\"><span>last</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-linear-merge-iterable\"><div class=\"inner\"><span>linear-merge-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-lines\"><div class=\"inner\"><span>lines</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-linked-hashmap\"><div class=\"inner\"><span>linked-hashmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-lnth\"><div class=\"inner\"><span>lnth</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-long-array\"><div class=\"inner\"><span>long-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-long-array-list\"><div class=\"inner\"><span>long-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-lsum\"><div class=\"inner\"><span>lsum</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-lsummary\"><div class=\"inner\"><span>lsummary</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-lvec\"><div class=\"inner\"><span>lvec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-make-map-entry\"><div class=\"inner\"><span>make-map-entry</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-map-intersection\"><div class=\"inner\"><span>map-intersection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-map-union\"><div class=\"inner\"><span>map-union</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-map-union-java-hashmap\"><div class=\"inner\"><span>map-union-java-hashmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mapmap\"><div class=\"inner\"><span>mapmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mapv\"><div class=\"inner\"><span>mapv</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mean\"><div class=\"inner\"><span>mean</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-memoize\"><div class=\"inner\"><span>memoize</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-memoize-cache-as-map\"><div class=\"inner\"><span>memoize-cache-as-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-merge\"><div class=\"inner\"><span>merge</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-merge-iterator\"><div class=\"inner\"><span>merge-iterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-merge-with\"><div class=\"inner\"><span>merge-with</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mmax-idx\"><div class=\"inner\"><span>mmax-idx</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mmax-key\"><div class=\"inner\"><span>mmax-key</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mmin-idx\"><div class=\"inner\"><span>mmin-idx</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mmin-key\"><div class=\"inner\"><span>mmin-key</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mode\"><div class=\"inner\"><span>mode</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-hashtable-map\"><div class=\"inner\"><span>mut-hashtable-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-list\"><div class=\"inner\"><span>mut-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-long-hashtable-map\"><div class=\"inner\"><span>mut-long-hashtable-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-long-map\"><div class=\"inner\"><span>mut-long-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-map\"><div class=\"inner\"><span>mut-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-map-rf\"><div class=\"inner\"><span>mut-map-rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-map-union.21\"><div class=\"inner\"><span>mut-map-union!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mut-set\"><div class=\"inner\"><span>mut-set</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-mutable-map.3F\"><div class=\"inner\"><span>mutable-map?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-not\"><div class=\"inner\"><span>not</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-obj-ary\"><div class=\"inner\"><span>obj-ary</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-object-array\"><div class=\"inner\"><span>object-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-object-array-list\"><div class=\"inner\"><span>object-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-ovec\"><div class=\"inner\"><span>ovec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-persistent.21\"><div class=\"inner\"><span>persistent!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-pgroups\"><div class=\"inner\"><span>pgroups</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-pmap\"><div class=\"inner\"><span>pmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-pmap-io\"><div class=\"inner\"><span>pmap-io</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-pmap-opts\"><div class=\"inner\"><span>pmap-opts</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-range\"><div class=\"inner\"><span>range</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-re-matches\"><div class=\"inner\"><span>re-matches</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-reduced-.3E\"><div class=\"inner\"><span>reduced-&gt;</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-reindex\"><div class=\"inner\"><span>reindex</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-repeat\"><div class=\"inner\"><span>repeat</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-rest\"><div class=\"inner\"><span>rest</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-reverse\"><div class=\"inner\"><span>reverse</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-short-array\"><div class=\"inner\"><span>short-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-short-array-list\"><div class=\"inner\"><span>short-array-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-shuffle\"><div class=\"inner\"><span>shuffle</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-sort\"><div class=\"inner\"><span>sort</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-sort-by\"><div class=\"inner\"><span>sort-by</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-sorta\"><div class=\"inner\"><span>sorta</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-splice\"><div class=\"inner\"><span>splice</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-subvec\"><div class=\"inner\"><span>subvec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-sum\"><div class=\"inner\"><span>sum</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-sum-fast\"><div class=\"inner\"><span>sum-fast</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-sum-stable-nelems\"><div class=\"inner\"><span>sum-stable-nelems</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-take\"><div class=\"inner\"><span>take</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-take-last\"><div class=\"inner\"><span>take-last</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-take-min\"><div class=\"inner\"><span>take-min</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-transient\"><div class=\"inner\"><span>transient</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-transient-map-rf\"><div class=\"inner\"><span>transient-map-rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-union\"><div class=\"inner\"><span>union</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-union-reduce-maps\"><div class=\"inner\"><span>union-reduce-maps</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-update-vals\"><div class=\"inner\"><span>update-vals</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-update-values\"><div class=\"inner\"><span>update-values</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-upgroups\"><div class=\"inner\"><span>upgroups</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-upmap\"><div class=\"inner\"><span>upmap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-vals\"><div class=\"inner\"><span>vals</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-vec\"><div class=\"inner\"><span>vec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-vector\"><div class=\"inner\"><span>vector</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-wrap-array\"><div class=\"inner\"><span>wrap-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.api.html#var-wrap-array-growable\"><div class=\"inner\"><span>wrap-array-growable</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.api</h1><div class=\"doc\"><div class=\"markdown\"><p>Fast mutable and immutable associative data structures based on bitmap trie\nhashmaps. Mutable pathways implement the <code>java.util.Map</code> or <code>Set</code> interfaces\nincluding in-place update features such as compute or computeIfPresent.</p>\n<p>Mutable maps or sets can be turned into their immutable counterparts via the\nClojure <code>persistent!</code> call. This allows working in a mutable space for\nconvenience and performance then switching to an immutable pathway when\nnecessary. Note: after <code>persistent!</code> one should never backdoor mutate map or\nset again as this will break the contract of immutability.  Immutable\ndata structures also support conversion to transient via <code>transient</code>.</p>\n<p>Map keysets (<code>.keySet</code>) are full <code>PersistentHashSet</code>s of keys.</p>\n<p>Maps and sets support metadata but setting the metadata on mutable objects\nreturns a new mutable object that shares the backing store leading to possible\nissues. Metadata is transferred to the persistent versions of the\nmutable/transient objects upon <code>persistent!</code>.</p>\n<p>Very fast versions of union, difference and intersection are provided for maps\nand sets with the map version of union and difference requiring an extra\nargument, a <code>java.util.BiFunction</code> or an <code>IFn</code> taking 2 arguments to merge the\nleft and right sides into the final map. These implementations of union,\ndifference, and intersection are the fastest implementation of these\noperations we know of on the JVM.</p>\n<p>Additionally a fast value update pathway is provided, enabling quickly\nupdating all the values in a given map. Additionally, a new map primitive</p>\n<ul>\n<li><a href=\"ham-fisted.api.html#var-mapmap\">mapmap</a> - allows transforming a given map into a new map quickly by\nmapping across all the entries.</li>\n</ul>\n<p>Unlike the standard Java objects, mutation-via-iterator is not supported.</p>\n</div></div><div class=\"public anchor\" id=\"var--.3Ecollection\"><h3>-&gt;collection</h3><div class=\"usage\"><code>(-&gt;collection item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Ensure item is an implementation of java.util.Collection.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L144\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Erandom-access\"><h3>-&gt;random-access</h3><div class=\"usage\"><code>(-&gt;random-access item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Ensure item is derived from java.util.List and java.util.RandomAccess and\nthus supports constant time random addressing.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L150\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ereducible\"><h3>-&gt;reducible</h3><div class=\"usage\"><code>(-&gt;reducible item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Ensure item either implements IReduceInit or java.util.Collection.  For arrays\nthis will return an object that has a much more efficient reduction pathway\nthan the base Clojure reducer.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L157\">view source</a></div></div><div class=\"public anchor\" id=\"var-add-all.21\"><h3>add-all!</h3><div class=\"usage\"><code>(add-all! l1 l2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Add all items from l2 to l1.  l1 is expected to be a java.util.List implementation.\nReturns l1.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L684\">view source</a></div></div><div class=\"public anchor\" id=\"var-add-constant.21\"><h3>add-constant!</h3><div class=\"usage\"><code>(add-constant! l idx v)</code><code>(add-constant! l idx count v)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2152\">view source</a></div></div><div class=\"public anchor\" id=\"var-apply-concat\"><h3>apply-concat</h3><div class=\"usage\"><code>(apply-concat args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster lazy noncaching version of (apply concat)</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1612\">view source</a></div></div><div class=\"public anchor\" id=\"var-apply-concatv\"><h3>apply-concatv</h3><div class=\"usage\"><code>(apply-concatv data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1570\">view source</a></div></div><div class=\"public anchor\" id=\"var-argsort\"><h3>argsort</h3><div class=\"usage\"><code>(argsort comp coll)</code><code>(argsort coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Sort a collection of data returning an array of indexes.  The collection must be\nrandom access and the return value is an integer array of indexes which will read the\ninput data in sorted order.  Faster implementations are provided when the collection\nis an integer, long, or double array.  See also <a href=\"ham-fisted.api.html#var-reindex\">reindex</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1815\">view source</a></div></div><div class=\"public anchor\" id=\"var-array-list\"><h3>array-list</h3><div class=\"usage\"><code>(array-list data)</code><code>(array-list)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.ArrayList.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L633\">view source</a></div></div><div class=\"public anchor\" id=\"var-assoc.21\"><h3>assoc!</h3><div class=\"usage\"><code>(assoc! obj k v)</code></div><div class=\"doc\"><div class=\"markdown\"><p>assoc! that works on transient collections, implementations of java.util.Map and\nRandomAccess java.util.List implementations.  Be sure to keep track of return value\nas some implementations return a different return value than the first argument.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L642\">view source</a></div></div><div class=\"public anchor\" id=\"var-binary-search\"><h3>binary-search</h3><div class=\"usage\"><code>(binary-search coll v)</code><code>(binary-search coll v comp)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Binary search.  Coll must be a sorted random access container.\ncomp must be an implementation of java.lang.Comparator.  If you know your container's\ntype, such as a double array, then comp should be a fastutil DoubleComparator.</p>\n<p>The most efficient method will be to convert coll to random access using\n-&gt;random-access, so for a pure double array it is slightly better to call\n-&gt;random-access outside this function before the function call.</p>\n<p>This search defaults to the slower java.util.Collections search using\nclojure's built in <code>compare</code> - reason being that that allows you to search\nfor a double number in a vector of only longs.  If you want an accelerated search\nyou can explicitly pass in a nil comparator <em>but</em> you need to make sure that\nyou are searching for the rough datatype in the data - e.g. long in a byte array\nor a double in a double for float array.  Searching for doubles in integer arrays\nwith an accelerated search will probably result in confusing results.</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (def data (-&gt;random-access (double-array (range 10))))\n#'ham-fisted.api/data\nham-fisted.api&gt; (binary-search data 0)\n0\nham-fisted.api&gt; (binary-search data -1)\n0\nham-fisted.api&gt; (binary-search data 1)\n1\nham-fisted.api&gt; (binary-search data 1.1)\n2\nham-fisted.api&gt; (binary-search data 10)\n10\nham-fisted.api&gt; (binary-search data 11)\n10\nham-fisted.api&gt; ;;be wary of datatype conversions in typed containers\nham-fisted.api&gt; (def data (-&gt;random-access (int-array (range 10))))\n#'ham-fisted.api/data\nham-fisted.api&gt; (binary-search data 1)\n1\nham-fisted.api&gt; (binary-search data 1.1)\n  2\nham-fisted.api&gt; ;;accelerated search - flattens input to container datatype\nham-fisted.api&gt; (binary-search data 1.1 nil)\n1\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1706\">view source</a></div></div><div class=\"public anchor\" id=\"var-boolean-array\"><h3>boolean-array</h3><div class=\"usage\"><code>(boolean-array)</code><code>(boolean-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1938\">view source</a></div></div><div class=\"public anchor\" id=\"var-boolean-array-list\"><h3>boolean-array-list</h3><div class=\"usage\"><code>(boolean-array-list)</code><code>(boolean-array-list data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1926\">view source</a></div></div><div class=\"public anchor\" id=\"var-byte-array\"><h3>byte-array</h3><div class=\"usage\"><code>(byte-array)</code><code>(byte-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1865\">view source</a></div></div><div class=\"public anchor\" id=\"var-byte-array-list\"><h3>byte-array-list</h3><div class=\"usage\"><code>(byte-array-list)</code><code>(byte-array-list data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1853\">view source</a></div></div><div class=\"public anchor\" id=\"var-char-array\"><h3>char-array</h3><div class=\"usage\"><code>(char-array)</code><code>(char-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1919\">view source</a></div></div><div class=\"public anchor\" id=\"var-char-array-list\"><h3>char-array-list</h3><div class=\"usage\"><code>(char-array-list)</code><code>(char-array-list data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1907\">view source</a></div></div><div class=\"public anchor\" id=\"var-clear.21\"><h3>clear!</h3><div class=\"usage\"><code>(clear! map-or-coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Mutably clear a map, set, list or implementation of java.util.Collection.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L695\">view source</a></div></div><div class=\"public anchor\" id=\"var-clear-memoized-fn.21\"><h3>clear-memoized-fn!</h3><div class=\"usage\"><code>(clear-memoized-fn! memoized-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Clear a memoized function backing store.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1305\">view source</a></div></div><div class=\"public anchor\" id=\"var-complement\"><h3>complement</h3><div class=\"usage\"><code>(complement f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Like clojure core complement but avoids var lookup on 'not'</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L137\">view source</a></div></div><div class=\"public anchor\" id=\"var-concata\"><h3>concata</h3><div class=\"usage\"><code>(concata)</code><code>(concata v1)</code><code>(concata v1 v2)</code><code>(concata v1 v2 &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>non-lazily concat a set of items returning an object array.  This always returns an\nobject array an may return an empty array whereas concat may return nil.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1595\">view source</a></div></div><div class=\"public anchor\" id=\"var-concatv\"><h3>concatv</h3><div class=\"usage\"><code>(concatv)</code><code>(concatv v1)</code><code>(concatv v1 v2)</code><code>(concatv v1 v2 &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>non-lazily concat a set of items returning a persistent vector.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1579\">view source</a></div></div><div class=\"public anchor\" id=\"var-cond\"><h3>cond</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(cond &amp; clauses)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Similar to <code>core/cond</code> except it supports true else clauses as opposed to always\nreturning nil on else.  The last clause of an odd number of clauses will be used as\nthe else branch similar to case.  Additional if the last predicate is the constant\n'true' or ':else' it will be used as the else clause.  If no else is provided then\nreturns nil same as <code>core/cond</code>.</p>\n<p>Important! - in order to get correct type hinting on both branches of the if they\nboth must return an explicit long or double:</p>\n<ul>\n<li>Sill Boxed</li>\n</ul>\n<pre><code class=\"language-clojure\">  (defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (.length ^String a) ;;string.length returns integer not long\n      ))\n\n(defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (alength ^longs a)\n      ))\n</code></pre>\n<ul>\n<li>Correctly Unboxed</li>\n</ul>\n<pre><code class=\"language-clojure\">(defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (long (.length ^String a))\n      ))\n\n(defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (long (alength ^longs a))\n      ))\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L212\">view source</a></div></div><div class=\"public anchor\" id=\"var-conj.21\"><h3>conj!</h3><div class=\"usage\"><code>(conj! obj val)</code></div><div class=\"doc\"><div class=\"markdown\"><p>conj! that works on transient collections, implementations of java.util.Set and\nRandomAccess java.util.List implementations.  Be sure to keep track of return value\nas some implementations return a different return value than the first argument.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L658\">view source</a></div></div><div class=\"public anchor\" id=\"var-constant-count\"><h3>constant-count</h3><div class=\"usage\"><code>(constant-count data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Constant time count.  Returns nil if input doesn't have a constant time count.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L413\">view source</a></div></div><div class=\"public anchor\" id=\"var-constant-countable.3F\"><h3>constant-countable?</h3><div class=\"usage\"><code>(constant-countable? data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return true if data has a constant time count.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L407\">view source</a></div></div><div class=\"public anchor\" id=\"var-constantly\"><h3>constantly</h3><div class=\"usage\"><code>(constantly x)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L126\">view source</a></div></div><div class=\"public anchor\" id=\"var-count\"><h3>count</h3><div class=\"usage\"><code>(count m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>hamf protocol extensible count</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L142\">view source</a></div></div><div class=\"public anchor\" id=\"var-custom-counted-ireduce\"><h3>custom-counted-ireduce</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(custom-counted-ireduce n-elems rfn acc &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Custom implementation of IReduceInit and nothing else.  This can be the most efficient\nway to pass data to other interfaces.  Also see custom-ireduce if the object\ndoes not need to be counted and see <a href=\"ham-fisted.api.html#var-reduced-.3E\">reduced-&gt;</a> for implementation helper.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2651\">view source</a></div></div><div class=\"public anchor\" id=\"var-custom-ireduce\"><h3>custom-ireduce</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(custom-ireduce rfn acc &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Custom implementation of IReduceInit and nothing else.  This can be the most efficient\nway to pass data to other interfaces.  Also see <a href=\"ham-fisted.api.html#var-custom-counted-ireduce\">custom-counted-ireduce</a> if the object\nshould also implement ICounted.  See <a href=\"ham-fisted.api.html#var-reduced-.3E\">reduced-&gt;</a> for implementation helper.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2641\">view source</a></div></div><div class=\"public anchor\" id=\"var-darange\"><h3>darange</h3><div class=\"usage\"><code>(darange end)</code><code>(darange start end)</code><code>(darange start end step)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a double array holding the values of the range.  Use <code>wrap-array</code> to get\nan implementation of java.util.List that supports the normal Clojure interfaces.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1787\">view source</a></div></div><div class=\"public anchor\" id=\"var-dbl-ary-cls\"><h3>dbl-ary-cls</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2089\">view source</a></div></div><div class=\"public anchor\" id=\"var-difference\"><h3>difference</h3><div class=\"usage\"><code>(difference map1 map2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Take the difference of two maps (or sets) returning a new map.  Return value is a map1\n(or set1) without the keys present in map2.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L871\">view source</a></div></div><div class=\"public anchor\" id=\"var-dnth\"><h3>dnth</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dnth obj idx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>nth operation returning a primitive double.  Efficient when obj is a double array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2161\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-array\"><h3>double-array</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-array)</code><code>(double-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2105\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-array-list\"><h3>double-array-list</h3><div class=\"usage\"><code>(double-array-list)</code><code>(double-array-list cap-or-data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>An array list that is as fast as java.util.ArrayList for add,get, etc but includes\nmany accelerated operations such as fill and an accelerated addAll when the src data\nis an array list.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2077\">view source</a></div></div><div class=\"public anchor\" id=\"var-drop\"><h3>drop</h3><div class=\"usage\"><code>(drop n coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Drop the first N items of the collection.  If item is random access, the return\nvalue is random-access.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2553\">view source</a></div></div><div class=\"public anchor\" id=\"var-drop-last\"><h3>drop-last</h3><div class=\"usage\"><code>(drop-last n)</code><code>(drop-last n coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Drop the last N values from a collection.  IF the input is random access,\nthe result will be random access.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2576\">view source</a></div></div><div class=\"public anchor\" id=\"var-drop-min\"><h3>drop-min</h3><div class=\"usage\"><code>(drop-min n comp values)</code><code>(drop-min n values)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Drop the min n values of a collection.  This is not an order-preserving operation.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2564\">view source</a></div></div><div class=\"public anchor\" id=\"var-dsummary\"><h3>dsummary</h3><div class=\"usage\"><code>(dsummary data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Summary statistics {:mean :max :min :n-elems :sum} in double space</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2287\">view source</a></div></div><div class=\"public anchor\" id=\"var-dvec\"><h3>dvec</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dvec)</code><code>(dvec data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a persistent-vector-compatible list backed by a double array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2112\">view source</a></div></div><div class=\"public anchor\" id=\"var-empty-map\"><h3>empty-map</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Constant persistent empty map</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L172\">view source</a></div></div><div class=\"public anchor\" id=\"var-empty-set\"><h3>empty-set</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Constant persistent empty set</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L174\">view source</a></div></div><div class=\"public anchor\" id=\"var-empty-vec\"><h3>empty-vec</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Constant persistent empty vec</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L176\">view source</a></div></div><div class=\"public anchor\" id=\"var-empty.3F\"><h3>empty?</h3><div class=\"usage\"><code>(empty? coll)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1548\">view source</a></div></div><div class=\"public anchor\" id=\"var-evict-memoized-call\"><h3>evict-memoized-call</h3><div class=\"usage\"><code>(evict-memoized-call memo-fn fn-args)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1321\">view source</a></div></div><div class=\"public anchor\" id=\"var-filterv\"><h3>filterv</h3><div class=\"usage\"><code>(filterv pred coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Filter a collection into a vector.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2208\">view source</a></div></div><div class=\"public anchor\" id=\"var-first\"><h3>first</h3><div class=\"usage\"><code>(first coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Get the first item of a collection.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2298\">view source</a></div></div><div class=\"public anchor\" id=\"var-float-array\"><h3>float-array</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(float-array)</code><code>(float-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2065\">view source</a></div></div><div class=\"public anchor\" id=\"var-float-array-list\"><h3>float-array-list</h3><div class=\"usage\"><code>(float-array-list)</code><code>(float-array-list data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2046\">view source</a></div></div><div class=\"public anchor\" id=\"var-fnth\"><h3>fnth</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(fnth obj idx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>nth operation returning a primitive float.  Efficient when obj is a float array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2173\">view source</a></div></div><div class=\"public anchor\" id=\"var-freq-reducer\"><h3>freq-reducer</h3><div class=\"usage\"><code>(freq-reducer options)</code><code>(freq-reducer)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a hamf parallel reducer that performs a frequencies operation.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1152\">view source</a></div></div><div class=\"public anchor\" id=\"var-frequencies\"><h3>frequencies</h3><div class=\"usage\"><code>(frequencies coll)</code><code>(frequencies options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster implementation of clojure.core/frequencies.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1178\">view source</a></div></div><div class=\"public anchor\" id=\"var-fvec\"><h3>fvec</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(fvec)</code><code>(fvec data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a persistent-vector-compatible list backed by a float array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2071\">view source</a></div></div><div class=\"public anchor\" id=\"var-group-by\"><h3>group-by</h3><div class=\"usage\"><code>(group-by f options coll)</code><code>(group-by f coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Group items in collection by the grouping function f.  Returns persistent map of\nkeys to persistent vectors.</p>\n<p>Options are same as <a href=\"ham-fisted.api.html#var-group-by-reduce\">group-by-reduce</a> but this reductions defaults to an\nordered reduction.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1496\">view source</a></div></div><div class=\"public anchor\" id=\"var-group-by-consumer\"><h3>group-by-consumer</h3><div class=\"usage\"><code>(group-by-consumer key-fn reducer coll)</code><code>(group-by-consumer key-fn reducer options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Perform a group-by-reduce passing in a reducer.  Same options as group-by-reduce -\nThis uses a slightly different pathway - computeIfAbsent - in order to preserve order.\nIn this case the return value of the reduce fn is ignored.  This allows things like\nthe linked hash map to preserve initial order of keys.  It map also be slightly\nmore efficient because the map itself does not need to check the return value\nof rfn - something that the <code>.compute</code> primitive <em>does</em> need to do.</p>\n<p>Options:</p>\n<ul>\n<li><code>:skip-finalize?</code> - skip finalization step.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1435\">view source</a></div></div><div class=\"public anchor\" id=\"var-group-by-reduce\"><h3>group-by-reduce</h3><div class=\"usage\"><code>(group-by-reduce key-fn init-val-fn rfn merge-fn options coll)</code><code>(group-by-reduce key-fn init-val-fn rfn merge-fn coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Group by key. Apply the reduce-fn with the new value an the return of init-val-fn.\nMerged maps due to multithreading will be merged with merge-fn in a similar way\nof <a href=\"ham-fisted.protocols.html#var-preduce\">preduce</a>.</p>\n<p>This type of reduction can be both faster and more importantly use\nless memory than a reduction of the forms:</p>\n<pre><code class=\"language-clojure\">  (-&gt;&gt; group-by map into)\n  ;; or\n  (-&gt;&gt; group-by mapmap)\n</code></pre>\n<p>Options (which are passed to <a href=\"ham-fisted.protocols.html#var-preduce\">preduce</a>):</p>\n<ul>\n<li><code>:map-fn</code> Function which takes no arguments and must return an instance of\njava.util.Map that supports <code>computeIfAbsent</code>.  Some examples:\n<ul>\n<li><code>(constantly (java.util.concurrent.ConcurrentHashMap. ...))</code>  Very fast update\nespecially in the case where the keyspace is large.</li>\n<li><code>mut-map</code> - Fast merge, fast update, in-place immutable conversion via <code>persistent!</code>.</li>\n<li><code>java-hashmap</code> - fast merge, fast update, just a simple java.util.HashMap-based reduction.</li>\n<li><code>#(LinkedHashMap.)</code> - When used with options {:ordered? true} the result keys will be\nin order <em>and</em> the result values will be reduced in order.</li>\n</ul>\n</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1348\">view source</a></div></div><div class=\"public anchor\" id=\"var-group-by-reducer\"><h3>group-by-reducer</h3><div class=\"usage\"><code>(group-by-reducer key-fn reducer coll)</code><code>(group-by-reducer key-fn reducer options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Perform a group-by-reduce passing in a reducer.  Same options as group-by-reduce.</p>\n<p>Options:</p>\n<ul>\n<li><code>:skip-finalize?</code> - skip finalization step.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1415\">view source</a></div></div><div class=\"public anchor\" id=\"var-hash-map\"><h3>hash-map</h3><div class=\"usage\"><code>(hash-map)</code><code>(hash-map a b)</code><code>(hash-map a b c d)</code><code>(hash-map a b c d e f)</code><code>(hash-map a b c d e f g h)</code><code>(hash-map a b c d e f g h i j)</code><code>(hash-map a b c d e f g h i j k l)</code><code>(hash-map a b c d e f g h i j k l m n)</code><code>(hash-map a b c d e f g h i j k l m n o p)</code><code>(hash-map a b c d e f g h i j k l m n o p &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Drop-in replacement to Clojure's hash-map function.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L454\">view source</a></div></div><div class=\"public anchor\" id=\"var-iarange\"><h3>iarange</h3><div class=\"usage\"><code>(iarange end)</code><code>(iarange start end)</code><code>(iarange start end step)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an integer array holding the values of the range.  Use <code>-&gt;collection</code> to get a\nlist implementation wrapping for generic access.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1767\">view source</a></div></div><div class=\"public anchor\" id=\"var-immut-list\"><h3>immut-list</h3><div class=\"usage\"><code>(immut-list)</code><code>(immut-list data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a persistent list.  Object arrays will be treated as if this new object owns them.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L624\">view source</a></div></div><div class=\"public anchor\" id=\"var-immut-map\"><h3>immut-map</h3><div class=\"usage\"><code>(immut-map)</code><code>(immut-map data)</code><code>(immut-map options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an immutable map.  This object supports conversion to a transient map via\nClojure's <code>transient</code> function.  Duplicate keys are treated as if by assoc.</p>\n<p>If data is an object array it is treated as a flat key-value list which is distinctly\ndifferent than how conj! treats object arrays.  You have been warned.</p>\n<p>If you know you will have consistently more key/val pairs than 8 you should just\nuse <code>(persistent! (mut-map data))</code> as that avoids the transition from an arraymap\nto a persistent hashmap.</p>\n<p>Examples:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (immut-map (obj-ary :a 1 :b 2 :c 3 :d 4))\n{:a 1, :b 2, :c 3, :d 4}\nham-fisted.api&gt; (type *1)\nham_fisted.PersistentArrayMap\nham-fisted.api&gt; (immut-map (obj-ary :a 1 :b 2 :c 3 :d 4 :e 5))\n{:d 4, :b 2, :c 3, :a 1, :e 5}\nham-fisted.api&gt; (type *1)\nham_fisted.PersistentHashMap\nham-fisted.api&gt; (immut-map [[:a 1][:b 2][:c 3][:d 4][:e 5]])\n{:d 4, :b 2, :c 3, :a 1, :e 5}\nham-fisted.api&gt; (type *1)\nham_fisted.PersistentHashMap\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L419\">view source</a></div></div><div class=\"public anchor\" id=\"var-immut-set\"><h3>immut-set</h3><div class=\"usage\"><code>(immut-set)</code><code>(immut-set data)</code><code>(immut-set options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an immutable hashset based on a hash table.  This object supports conversion\nto transients via <code>transient</code>.</p>\n<p>Options:</p>\n<ul>\n<li><code>:hash-provider</code> - An implementation of <code>BitmapTrieCommon$HashProvider</code>.  Defaults to\nthe <a href=\"default-hash-provider\">default-hash-provider</a>.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L587\">view source</a></div></div><div class=\"public anchor\" id=\"var-in-fork-join-task.3F\"><h3>in-fork-join-task?</h3><div class=\"usage\"><code>(in-fork-join-task?)</code></div><div class=\"doc\"><div class=\"markdown\"><p>True if you are currently running in a fork-join task</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1021\">view source</a></div></div><div class=\"public anchor\" id=\"var-inc-consumer\"><h3>inc-consumer</h3><div class=\"usage\"><code>(inc-consumer)</code><code>(inc-consumer init-value)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a consumer that simply increments a long.  See java/ham_fisted/Consumers.java for definition.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2679\">view source</a></div></div><div class=\"public anchor\" id=\"var-inc-consumer-reducer\"><h3>inc-consumer-reducer</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>A hamf reducer that works with inc-consumers</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1193\">view source</a></div></div><div class=\"public anchor\" id=\"var-int-array\"><h3>int-array</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(int-array)</code><code>(int-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1990\">view source</a></div></div><div class=\"public anchor\" id=\"var-int-array-list\"><h3>int-array-list</h3><div class=\"usage\"><code>(int-array-list)</code><code>(int-array-list cap-or-data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>An array list that is as fast as java.util.ArrayList for add,get, etc but includes\nmany accelerated operations such as fill and an accelerated addAll when the src data\nis an array list.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1962\">view source</a></div></div><div class=\"public anchor\" id=\"var-intersect-sets\"><h3>intersect-sets</h3><div class=\"usage\"><code>(intersect-sets sets)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a sequence of sets, efficiently perform the intersection of them.  This algorithm is usually faster and has a more stable\nruntime than (reduce clojure.set/intersection sets) which degrades depending on the order of the sets and the pairwise\nintersection of the initial sets.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2446\">view source</a></div></div><div class=\"public anchor\" id=\"var-intersection\"><h3>intersection</h3><div class=\"usage\"><code>(intersection s1 s2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Intersect the keyspace of set1 and set2 returning a new set.  Also works if s1 is a\nmap and s2 is a set - the map is trimmed to the intersecting keyspace of s1 and s2.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L931\">view source</a></div></div><div class=\"public anchor\" id=\"var-inth\"><h3>inth</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(inth obj idx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>nth operation returning a primitive int.  Efficient when obj is an int array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2179\">view source</a></div></div><div class=\"public anchor\" id=\"var-into\"><h3>into</h3><div class=\"usage\"><code>(into container data)</code><code>(into container xform data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Like clojure.core/into, but also designed to handle editable collections,\ntransients, and base java.util.Map, List and Set containers.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L259\">view source</a></div></div><div class=\"public anchor\" id=\"var-into-array\"><h3>into-array</h3><div class=\"usage\"><code>(into-array aseq)</code><code>(into-array ary-type aseq)</code><code>(into-array ary-type mapfn aseq)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster version of clojure.core/into-array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1625\">view source</a></div></div><div class=\"public anchor\" id=\"var-ivec\"><h3>ivec</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ivec)</code><code>(ivec data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a persistent-vector-compatible list backed by an int array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2003\">view source</a></div></div><div class=\"public anchor\" id=\"var-java-concurrent-hashmap\"><h3>java-concurrent-hashmap</h3><div class=\"usage\"><code>(java-concurrent-hashmap)</code><code>(java-concurrent-hashmap data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a java concurrent hashmap which is still the fastest possible way to solve a\nfew concurrent problems.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L560\">view source</a></div></div><div class=\"public anchor\" id=\"var-java-hashmap\"><h3>java-hashmap</h3><div class=\"usage\"><code>(java-hashmap)</code><code>(java-hashmap data)</code><code>(java-hashmap xform data)</code><code>(java-hashmap xform options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a java.util.HashMap.  Duplicate keys are treated as if map was created by assoc.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L514\">view source</a></div></div><div class=\"public anchor\" id=\"var-java-hashset\"><h3>java-hashset</h3><div class=\"usage\"><code>(java-hashset)</code><code>(java-hashset data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a java hashset which is still the fastest possible way to solve a few problems.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L600\">view source</a></div></div><div class=\"public anchor\" id=\"var-java-linked-hashmap\"><h3>java-linked-hashmap</h3><div class=\"usage\"><code>(java-linked-hashmap)</code><code>(java-linked-hashmap data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Linked hash maps perform identically or very nearly so to java.util.HashMaps\nbut they retain the order of insertion and modification.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L533\">view source</a></div></div><div class=\"public anchor\" id=\"var-keys\"><h3>keys</h3><div class=\"usage\"><code>(keys m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the keys of a map.  This version allows parallel reduction operations on\nthe returned sequence.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L728\">view source</a></div></div><div class=\"public anchor\" id=\"var-larange\"><h3>larange</h3><div class=\"usage\"><code>(larange end)</code><code>(larange start end)</code><code>(larange start end step)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a long array holding values of the range.  Use <code>-&gt;collection</code> get a list\nimplementation for generic access.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1777\">view source</a></div></div><div class=\"public anchor\" id=\"var-last\"><h3>last</h3><div class=\"usage\"><code>(last coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Get the last item in the collection.  Constant time for\nrandom access lists.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2310\">view source</a></div></div><div class=\"public anchor\" id=\"var-linear-merge-iterable\"><h3>linear-merge-iterable</h3><div class=\"usage\"><code>(linear-merge-iterable cmp pred iterables)</code><code>(linear-merge-iterable cmp iterables)</code><code>(linear-merge-iterable iterables)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an N-way merge iterable using cmp to order the merge of provided iterables.\nIf a predicate pred is provided the iterable itself will filter out values for which\nthe pred returns false.  In this mode it is possible for the iterator to return null\nif the last value is filtered out -- the hasNext method doesn't check if the next value\npasses the predicate.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2734\">view source</a></div></div><div class=\"public anchor\" id=\"var-lines\"><h3>lines</h3><div class=\"usage\"><code>(lines fname)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a closeable iterable that produces an iterator that simply produces lines of the reader.\nIterator does not cache more than 1 line so there is no possibility of holding onto head normal nor\nchunked seq-ing.</p>\n<p>Example:</p>\n<pre><code class=\"language-clojure\">(with-open [ld (hamf/lines fname)]\n  (-&gt;&gt; ld\n       (hamf/pmap (fn [line] ...))\n       (reduce ...)))\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2701\">view source</a></div></div><div class=\"public anchor\" id=\"var-linked-hashmap\"><h3>linked-hashmap</h3><div class=\"usage\"><code>(linked-hashmap)</code><code>(linked-hashmap data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Linked hash map using clojure's equiv pathways.  At this time the node link order reflects\ninsertion order.  Modification and access do not affect the node link order.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L549\">view source</a></div></div><div class=\"public anchor\" id=\"var-lnth\"><h3>lnth</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lnth obj idx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>nth operation returning a primitive long.  Efficient when obj is a long array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2167\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-array\"><h3>long-array</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-array)</code><code>(long-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2034\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-array-list\"><h3>long-array-list</h3><div class=\"usage\"><code>(long-array-list)</code><code>(long-array-list cap-or-data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>An array list that is as fast as java.util.ArrayList for add,get, etc but includes\nmany accelerated operations such as fill and an accelerated addAll when the src data\nis an array list.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2009\">view source</a></div></div><div class=\"public anchor\" id=\"var-lsum\"><h3>lsum</h3><div class=\"usage\"><code>(lsum data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Simple summation that returns a long integer.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2258\">view source</a></div></div><div class=\"public anchor\" id=\"var-lsummary\"><h3>lsummary</h3><div class=\"usage\"><code>(lsummary data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Summary statistics {:mean :max :min :n-elems :sum} in long space</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2267\">view source</a></div></div><div class=\"public anchor\" id=\"var-lvec\"><h3>lvec</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lvec)</code><code>(lvec data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a persistent-vector-compatible list backed by a long array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2040\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-map-entry\"><h3>make-map-entry</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(make-map-entry k-code v-code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a dynamic implementation of clojure's IMapEntry class.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L741\">view source</a></div></div><div class=\"public anchor\" id=\"var-map-intersection\"><h3>map-intersection</h3><div class=\"usage\"><code>(map-intersection bfn map1 map2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Intersect the keyspace of map1 and map2 returning a new map.  Each value is the result\nof bfn applied to the map1-value and map2-value, respectively.  See documentation for\n<a href=\"ham-fisted.api.html#var-map-union\">map-union</a>.</p>\n<p>Clojure's <code>merge</code> functionality can be duplicate via:</p>\n<pre><code class=\"language-clojure\">(map-intersection (fn [lhs rhs] rhs) map1 map2)\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L904\">view source</a></div></div><div class=\"public anchor\" id=\"var-map-union\"><h3>map-union</h3><div class=\"usage\"><code>(map-union bfn map1 map2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Take the union of two maps returning a new map.  bfn is a function that takes 2 arguments,\nmap1-val and map2-val and returns a new value.  Has fallback if map1 and map2 aren't backed\nby bitmap tries.</p>\n<ul>\n<li><code>bfn</code> - A function taking two arguments and returning one.  <code>+</code> is a fine choice.</li>\n<li><code>map1</code> - the lhs of the union.</li>\n<li><code>map2</code> - the rhs of the union.</li>\n</ul>\n<p>Returns a persistent map if input is a persistent map else if map1 is a mutable map\nmap1 is returned with overlapping entries merged.  In this way you can pass in a\nnormal java hashmap, a linked java hashmap, or a persistent map and get back a result that\nmatches the input.</p>\n<p>If map1 and map2 are the same returns map1.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L749\">view source</a></div></div><div class=\"public anchor\" id=\"var-map-union-java-hashmap\"><h3>map-union-java-hashmap</h3><div class=\"usage\"><code>(map-union-java-hashmap bfn lhs rhs)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Take the union of two maps returning a new map.  See documentation for <a href=\"map-union\">map-union</a>.\nReturns a java.util.HashMap.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L783\">view source</a></div></div><div class=\"public anchor\" id=\"var-mapmap\"><h3>mapmap</h3><div class=\"usage\"><code>(mapmap map-fn src-map)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Clojure's missing piece. Map over the data in src-map, which must be a map or\nsequence of pairs, using map-fn. map-fn must return either a new key-value\npair or nil. Then, remove nil pairs, and return a new map. If map-fn returns\nmore than one pair with the same key later pair will overwrite the earlier\npair.</p>\n<p>Logically the same as:</p>\n<pre><code class=\"language-clojure\">(into {} (comp (map map-fn) (remove nil?)) src-map)\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L998\">view source</a></div></div><div class=\"public anchor\" id=\"var-mapv\"><h3>mapv</h3><div class=\"usage\"><code>(mapv map-fn coll)</code><code>(mapv map-fn c1 c2)</code><code>(mapv map-fn c1 c2 c3)</code><code>(mapv map-fn c1 c2 c3 &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Produce a persistent vector from a collection.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2185\">view source</a></div></div><div class=\"public anchor\" id=\"var-mean\"><h3>mean</h3><div class=\"usage\"><code>(mean coll)</code><code>(mean options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the mean of the collection.  Returns double/NaN for empty collections.\nSee options for <a href=\"ham-fisted.api.html#var-sum\">sum</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2277\">view source</a></div></div><div class=\"public anchor\" id=\"var-memoize\"><h3>memoize</h3><div class=\"usage\"><code>(memoize memo-fn)</code><code>(memoize memo-fn {:keys [write-ttl-ms access-ttl-ms soft-values? weak-values? max-size record-stats? eviction-fn], :as options})</code></div><div class=\"doc\"><div class=\"markdown\"><p>Efficient thread-safe version of clojure.core/memoize.</p>\n<p>Also see <a href=\"ham-fisted.api.html#var-clear-memoized-fn.21\">clear-memoized-fn!</a> <a href=\"ham-fisted.api.html#var-evict-memoized-call\">evict-memoized-call</a> and <a href=\"ham-fisted.api.html#var-memoize-cache-as-map\">memoize-cache-as-map</a> to\nmutably clear the backing store, manually evict a value, and get a java.util.Map view of\nthe cache backing store.</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (def m (memoize (fn [&amp; args] (println \"fn called - \" args) args)\n                                {:write-ttl-ms 1000 :eviction-fn (fn [args rv cause]\n                                                                   (println \"evicted - \" args rv cause))}))\n#'ham-fisted.api/m\nham-fisted.api&gt; (m 3)\nfn called -  (3)\n(3)\nham-fisted.api&gt; (m 4)\nfn called -  (4)\n(4)evicted -  [3] (3) :expired\nham-fisted.api&gt; (dotimes [idx 4] (do (m 3) (evict-memoized-call m [3])))\nfn called -  (3)\nfn called -  (3)\nfn called -  (3)\nfn called -  (3)\nnil\nham-fisted.api&gt; (dotimes [idx 4] (do (m 3) #_(evict-memoized-call m [3])))\nfn called -  (3)\nnil\n</code></pre>\n<p>Options:</p>\n<ul>\n<li><code>:write-ttl-ms</code> - Time that values should remain in the cache after write in milliseconds.</li>\n<li><code>:access-ttl-ms</code> - Time that values should remain in the cache after access in milliseconds.</li>\n<li><code>:soft-values?</code> - When true, the cache will store <a href=\"https://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html\">SoftReferences</a> to the data.</li>\n<li><code>:weak-values?</code> - When true, the cache will store <a href=\"https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html\">WeakReferences</a> to the data.</li>\n<li><code>:max-size</code> - When set, the cache will behave like an LRU cache.</li>\n<li><code>:record-stats?</code> - When true, the LoadingCache will record access statistics.  You can\nget those via the undocumented function memo-stats.</li>\n<li><code>:eviction-fn - Function that receives 3 arguments, [args v cause], when a value is evicted. Causes the keywords</code>:collected :expired :explicit :replaced and :size`.  See\n<a href=\"https://www.javadoc.io/static/com.github.ben-manes.caffeine/caffeine/2.9.3/com/github/benmanes/caffeine/cache/RemovalCause.html\">caffeine documentation</a> for cause definitions.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1231\">view source</a></div></div><div class=\"public anchor\" id=\"var-memoize-cache-as-map\"><h3>memoize-cache-as-map</h3><div class=\"usage\"><code>(memoize-cache-as-map memoized-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the memoize backing store as an implementation of java.util.Map.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1314\">view source</a></div></div><div class=\"public anchor\" id=\"var-merge\"><h3>merge</h3><div class=\"usage\"><code>(merge)</code><code>(merge m1)</code><code>(merge m1 m2)</code><code>(merge m1 m2 &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Merge 2 maps with the rhs values winning any intersecting keys.  Uses map-union\nwith <code>BitmapTrieCommon/rhsWins</code>.</p>\n<p>Returns a new persistent map.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1204\">view source</a></div></div><div class=\"public anchor\" id=\"var-merge-iterator\"><h3>merge-iterator</h3><div class=\"usage\"><code>(merge-iterator cmp iterables)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an N-way priority queue iterable using cmp to order the merge of provided iterables.\nIf a predicate pred is provided the iterable itself will filter out values for which\nthe pred returns false.  In this mode it is possible for the iterator to return null\nif the last value is filtered out -- the hasNext method doesn't check if the next value\npasses the predicate.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2748\">view source</a></div></div><div class=\"public anchor\" id=\"var-merge-with\"><h3>merge-with</h3><div class=\"usage\"><code>(merge-with f)</code><code>(merge-with f m1)</code><code>(merge-with f m1 m2)</code><code>(merge-with f m1 m2 &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Merge (union) any number of maps using <code>f</code> as the merge operator.  <code>f</code> gets passed two\narguments, lhs-val and rhs-val and must return a new value.</p>\n<p>Returns a new persistent map.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1219\">view source</a></div></div><div class=\"public anchor\" id=\"var-mmax-idx\"><h3>mmax-idx</h3><div class=\"usage\"><code>(mmax-idx f data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Like <a href=\"ham-fisted.api.html#var-mmin-key\">mmin-key</a> but returns the max index.  F should be a function from obj-&gt;long.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2414\">view source</a></div></div><div class=\"public anchor\" id=\"var-mmax-key\"><h3>mmax-key</h3><div class=\"usage\"><code>(mmax-key f data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster and nil-safe version of #(apply max-key %1 %2)</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2358\">view source</a></div></div><div class=\"public anchor\" id=\"var-mmin-idx\"><h3>mmin-idx</h3><div class=\"usage\"><code>(mmin-idx f data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Like <a href=\"ham-fisted.api.html#var-mmin-key\">mmin-key</a> but returns the min index.  F should be a function from obj-&gt;long.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2439\">view source</a></div></div><div class=\"public anchor\" id=\"var-mmin-key\"><h3>mmin-key</h3><div class=\"usage\"><code>(mmin-key f data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster and nil-safe version of #(apply min-key %1 %2)</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2389\">view source</a></div></div><div class=\"public anchor\" id=\"var-mode\"><h3>mode</h3><div class=\"usage\"><code>(mode data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the most common occurance in the data.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2468\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-hashtable-map\"><h3>mut-hashtable-map</h3><div class=\"usage\"><code>(mut-hashtable-map)</code><code>(mut-hashtable-map data)</code><code>(mut-hashtable-map xform data)</code><code>(mut-hashtable-map xform options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a mutable implementation of java.util.Map.  This object efficiently implements\nITransient map so you can use assoc! and persistent! on it but you can additionally use\nthe various members of the java.util.Map interface such as put, compute, computeIfAbsent,\nreplaceAll and merge.</p>\n<p>If data is an object array it is treated as a flat key-value list which is distinctly\ndifferent than how conj! treats object arrays.  You have been warned.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L323\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-list\"><h3>mut-list</h3><div class=\"usage\"><code>(mut-list)</code><code>(mut-list data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a mutable java list that is in-place convertible to a persistent list</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L606\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-long-hashtable-map\"><h3>mut-long-hashtable-map</h3><div class=\"usage\"><code>(mut-long-hashtable-map)</code><code>(mut-long-hashtable-map data)</code><code>(mut-long-hashtable-map xform data)</code><code>(mut-long-hashtable-map xform options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a mutable implementation of java.util.Map.  This object efficiently implements\nITransient map so you can use assoc! and persistent! on it but you can additionally use\nthe various members of the java.util.Map interface such as put, compute, computeIfAbsent,\nreplaceAll and merge.</p>\n<p>If data is an object array it is treated as a flat key-value list which is distinctly\ndifferent than how conj! treats object arrays.  You have been warned.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L351\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-long-map\"><h3>mut-long-map</h3><div class=\"usage\"><code>(mut-long-map)</code><code>(mut-long-map data)</code><code>(mut-long-map xform data)</code><code>(mut-long-map xform options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a mutable implementation of java.util.Map specialized to long keys.  This object\nefficiently implements ITransient map so you can use assoc! and persistent! on it but you can additionally use\nthe various members of the java.util.Map interface such as put, compute, computeIfAbsent,\nreplaceAll and merge.  Attempting to store any non-numeric value will result in an exception.</p>\n<p>If data is an object array it is treated as a flat key-value list which is distinctly\ndifferent than how conj! treats object arrays.  You have been warned.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L393\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-map\"><h3>mut-map</h3><div class=\"usage\"><code>(mut-map)</code><code>(mut-map data)</code><code>(mut-map xform data)</code><code>(mut-map xform options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a mutable implementation of java.util.Map.  This object efficiently implements\nITransient map so you can use assoc! and persistent! on it but you can additionally use\nthe various members of the java.util.Map interface such as put, compute, computeIfAbsent,\nreplaceAll and merge.</p>\n<p>If data is an object array it is treated as a flat key-value list which is distinctly\ndifferent than how conj! treats object arrays.  You have been warned.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L379\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-map-rf\"><h3>mut-map-rf</h3><div class=\"usage\"><code>(mut-map-rf cons-fn)</code><code>(mut-map-rf cons-fn finalize-fn)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L290\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-map-union.21\"><h3>mut-map-union!</h3><div class=\"usage\"><code>(mut-map-union! merge-bifn l r)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Very fast union that may simply update lhs and return it.  Both lhs and rhs <em>must</em> be\nmutable maps.  See docs for <a href=\"ham-fisted.api.html#var-map-union\">map-union</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1138\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-set\"><h3>mut-set</h3><div class=\"usage\"><code>(mut-set)</code><code>(mut-set data)</code><code>(mut-set options data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a mutable hashset based on the hashtable. You can create a persistent hashset via\nthe clojure <code>persistent!</code> call.</p>\n<p>Options:</p>\n<ul>\n<li><code>:hash-provider</code> - An implementation of <code>BitmapTrieCommon$HashProvider</code>.  Defaults to\nthe <a href=\"default-hash-provider\">default-hash-provider</a>.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L574\">view source</a></div></div><div class=\"public anchor\" id=\"var-mutable-map.3F\"><h3>mutable-map?</h3><div class=\"usage\"><code>(mutable-map? m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L810\">view source</a></div></div><div class=\"public anchor\" id=\"var-not\"><h3>not</h3><div class=\"usage\"><code>(not a)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns boolean opposite of passed in value</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L130\">view source</a></div></div><div class=\"public anchor\" id=\"var-obj-ary\"><h3>obj-ary</h3><div class=\"usage\"><code>(obj-ary)</code><code>(obj-ary v0)</code><code>(obj-ary v0 v1)</code><code>(obj-ary v0 v1 v2)</code><code>(obj-ary v0 v1 v2 v3)</code><code>(obj-ary v0 v1 v2 v3 v4)</code><code>(obj-ary v0 v1 v2 v3 v4 v5)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14)</code><code>(obj-ary v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15)</code></div><div class=\"doc\"><div class=\"markdown\"><p>As quickly as possible, produce an object array from these inputs.  Very fast for arities\n&lt;= 16.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L191\">view source</a></div></div><div class=\"public anchor\" id=\"var-object-array\"><h3>object-array</h3><div class=\"usage\"><code>(object-array item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster version of object-array for java collections and strings.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1620\">view source</a></div></div><div class=\"public anchor\" id=\"var-object-array-list\"><h3>object-array-list</h3><div class=\"usage\"><code>(object-array-list)</code><code>(object-array-list cap-or-data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>An array list that is as fast as java.util.ArrayList for add,get, etc but includes\nmany accelerated operations such as fill and an accelerated addAll when the src data\nis an object array based list.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2119\">view source</a></div></div><div class=\"public anchor\" id=\"var-ovec\"><h3>ovec</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ovec)</code><code>(ovec data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an immutable persistent vector like object backed by a single object array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2139\">view source</a></div></div><div class=\"public anchor\" id=\"var-persistent.21\"><h3>persistent!</h3><div class=\"usage\"><code>(persistent! v)</code></div><div class=\"doc\"><div class=\"markdown\"><p>If object is an ITransientCollection, call clojure.core/persistent!.  Else return\ncollection.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1122\">view source</a></div></div><div class=\"public anchor\" id=\"var-pgroups\"><h3>pgroups</h3><div class=\"usage\"><code>(pgroups n-elems body-fn options)</code><code>(pgroups n-elems body-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Run y index groups across n-elems.   Y is common pool parallelism.</p>\n<p>body-fn gets passed two longs, startidx and endidx.</p>\n<p>Returns a sequence of the results of body-fn applied to each group of indexes.</p>\n<p>Before using this primitive please see if <a href=\"ham-fisted.reduce.html#var-preduce\">ham-fisted.reduce/preduce</a> will work.</p>\n<p>You <em>must</em> wrap this in something that realizes the results if you need the parallelization\nto finish by a particular point in the program - <code>(dorun (hamf/pgroups ...))</code>.</p>\n<p>Options:</p>\n<ul>\n<li><code>:pgroup-min</code> - when provided n-elems must be more than this value for the computation\nto be parallelized.</li>\n<li><code>:batch-size</code> - max batch size.  Defaults to 64000.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1030\">view source</a></div></div><div class=\"public anchor\" id=\"var-pmap\"><h3>pmap</h3><div class=\"usage\"><code>(pmap map-fn &amp; sequences)</code></div><div class=\"doc\"><div class=\"markdown\"><p>pmap using the commonPool.  This is useful for interacting with other primitives, namely\n<a href=\"ham-fisted.api.html#var-pgroups\">pgroups</a> which are also based on this pool.  This is a change from Clojure's base\npmap in that it uses the ForkJoinPool/commonPool for parallelism as opposed to the\nagent pool - this makes it compose with pgroups and dtype-next's parallelism system.</p>\n<p>Before using this primitive please see if <a href=\"ham-fisted.reduce.html#var-preduce\">ham-fisted.reduce/preduce</a> will work.</p>\n<p>Is guaranteed to <em>not</em> trigger the need for <code>shutdown-agents</code>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1079\">view source</a></div></div><div class=\"public anchor\" id=\"var-pmap-io\"><h3>pmap-io</h3><div class=\"usage\"><code>(pmap-io n-lookahead map-fn &amp; sequences)</code></div><div class=\"doc\"><div class=\"markdown\"><p>pmap for io bound tasks where you want to specify how far ahead\nto run - uses the clojure.lang.Agent/soloExecutor for execution of presumably\nio-bound operations.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1113\">view source</a></div></div><div class=\"public anchor\" id=\"var-pmap-opts\"><h3>pmap-opts</h3><div class=\"usage\"><code>(pmap-opts opts map-fn &amp; sequences)</code></div><div class=\"doc\"><div class=\"markdown\"><p><a href=\"ham-fisted.api.html#var-pmap\">pmap</a> but takes an extra option map as the <em>first</em> argument.  This is useful if you,\nfor instance, want to control exactly the parallel options arguments such as\n<code>:n-lookahead</code>.  See docs for <a href=\"ham-fisted.reduce.html#var-options-.3Eparallel-options\">ham-fisted.reduce/options-&gt;parallel-options</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1105\">view source</a></div></div><div class=\"public anchor\" id=\"var-range\"><h3>range</h3><div class=\"usage\"><code>(range)</code><code>(range end)</code><code>(range start end)</code><code>(range start end step)</code></div><div class=\"doc\"><div class=\"markdown\"><p>When given arguments returns a range that implements random access java list\ninterfaces so nth, reverse and friends are efficient.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1803\">view source</a></div></div><div class=\"public anchor\" id=\"var-re-matches\"><h3>re-matches</h3><div class=\"usage\"><code>(re-matches re s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Much faster version of clojure.core/re-matches.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2685\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduced-.3E\"><h3>reduced-&gt;</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(reduced-&gt; rfn acc &amp; data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Helper macro to implement reduce chains checking for if the accumulator\nis reduced before calling the next expression in data.</p>\n<pre><code class=\"language-clojure\">(defrecord YMC [year-month ^long count]\n  clojure.lang.IReduceInit\n  (reduce [this rfn init]\n    (let [init (reduced-&gt; rfn init\n                   (clojure.lang.MapEntry/create :year-month year-month)\n                   (clojure.lang.MapEntry/create :count count))]\n      (if (and __extmap (not (reduced? init)))\n        (reduce rfn init __extmap)\n        init))))\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2616\">view source</a></div></div><div class=\"public anchor\" id=\"var-reindex\"><h3>reindex</h3><div class=\"usage\"><code>(reindex coll indexes)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Permut coll by the given indexes.  Result is random-access and the same length as\nthe index collection.  Indexes are expected to be in the range of [0-&gt;count(coll)).</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1996\">view source</a></div></div><div class=\"public anchor\" id=\"var-repeat\"><h3>repeat</h3><div class=\"usage\"><code>(repeat v)</code><code>(repeat n v)</code></div><div class=\"doc\"><div class=\"markdown\"><p>When called with no arguments, produce an infinite sequence of v.\nWhen called with 2 arguments, produce a random access list that produces v at each\nindex.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2590\">view source</a></div></div><div class=\"public anchor\" id=\"var-rest\"><h3>rest</h3><div class=\"usage\"><code>(rest coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Version of rest that does uses subvec if collection is random access.  This preserves the\nability to reduce in parallel over the collection.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2476\">view source</a></div></div><div class=\"public anchor\" id=\"var-reverse\"><h3>reverse</h3><div class=\"usage\"><code>(reverse coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Reverse a collection or sequence.  Constant time reverse is provided\nfor any random access list.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2489\">view source</a></div></div><div class=\"public anchor\" id=\"var-short-array\"><h3>short-array</h3><div class=\"usage\"><code>(short-array)</code><code>(short-array data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1892\">view source</a></div></div><div class=\"public anchor\" id=\"var-short-array-list\"><h3>short-array-list</h3><div class=\"usage\"><code>(short-array-list)</code><code>(short-array-list data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1880\">view source</a></div></div><div class=\"public anchor\" id=\"var-shuffle\"><h3>shuffle</h3><div class=\"usage\"><code>(shuffle coll)</code><code>(shuffle coll opts)</code></div><div class=\"doc\"><div class=\"markdown\"><p>shuffle values returning random access container.  If you are calling this repeatedly\non the same collection you should call <a href=\"ham-fisted.api.html#var--.3Erandom-access\">-&gt;random-access</a> on the collection <em>before</em>\nyou start as shuffle internally only works on random access collections.</p>\n<p>Options:</p>\n<ul>\n<li><code>:seed</code> - If instance of java.util.Random, use this.  If integer, use as seed.\nIf not provided a new instance of java.util.Random is created.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1693\">view source</a></div></div><div class=\"public anchor\" id=\"var-sort\"><h3>sort</h3><div class=\"usage\"><code>(sort coll)</code><code>(sort comp coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Exact replica of clojure.core/sort but instead of wrapping the final object array in a seq\nwhich loses the fact the result is countable and random access.  Faster implementations\nare provided when the input is an integer, long, or double array.</p>\n<p>The default comparison is nan-last meaning null-last if the input is an undefined\ncontainer and nan-last if the input is a double or float specific container.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1654\">view source</a></div></div><div class=\"public anchor\" id=\"var-sort-by\"><h3>sort-by</h3><div class=\"usage\"><code>(sort-by keyfn coll)</code><code>(sort-by keyfn comp coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Sort a collection by keyfn.  Typehinting the return value of keyfn will somewhat increase\nthe speed of the sort :-).</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1672\">view source</a></div></div><div class=\"public anchor\" id=\"var-sorta\"><h3>sorta</h3><div class=\"usage\"><code>(sorta coll)</code><code>(sorta comp coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Sort returning an object array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1637\">view source</a></div></div><div class=\"public anchor\" id=\"var-splice\"><h3>splice</h3><div class=\"usage\"><code>(splice v1 idx v2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Splice v2 into v1 at idx.  Returns a persistent vector.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1537\">view source</a></div></div><div class=\"public anchor\" id=\"var-subvec\"><h3>subvec</h3><div class=\"usage\"><code>(subvec m sidx eidx)</code><code>(subvec m sidx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>More general version of subvec.  Works for any java list implementation\nincluding persistent vectors and any array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1337\">view source</a></div></div><div class=\"public anchor\" id=\"var-sum\"><h3>sum</h3><div class=\"usage\"><code>(sum coll)</code><code>(sum options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Very stable high performance summation.  Uses both threading and kahans compensated\nsummation.</p>\n<p>Options:</p>\n<ul>\n<li><code>nan-strategy</code> - defaults to <code>:remove</code>.  Options are <code>:keep</code>, <code>:remove</code> and\n<code>:exception</code>.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2242\">view source</a></div></div><div class=\"public anchor\" id=\"var-sum-fast\"><h3>sum-fast</h3><div class=\"usage\"><code>(sum-fast coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Fast simple double summation.  Does not do any nan checking or summation\ncompensation.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2214\">view source</a></div></div><div class=\"public anchor\" id=\"var-sum-stable-nelems\"><h3>sum-stable-nelems</h3><div class=\"usage\"><code>(sum-stable-nelems coll)</code><code>(sum-stable-nelems options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Stable sum returning map of {:sum :n-elems}. See options for <a href=\"ham-fisted.api.html#var-sum\">sum</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2233\">view source</a></div></div><div class=\"public anchor\" id=\"var-take\"><h3>take</h3><div class=\"usage\"><code>(take n)</code><code>(take n coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Take the first N values from a collection.  If the input is\nrandom access, the result will be random access.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2505\">view source</a></div></div><div class=\"public anchor\" id=\"var-take-last\"><h3>take-last</h3><div class=\"usage\"><code>(take-last n coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Take the last N values of the collection.  If the input is random-access,\nthe result will be random-access.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2517\">view source</a></div></div><div class=\"public anchor\" id=\"var-take-min\"><h3>take-min</h3><div class=\"usage\"><code>(take-min n comp values)</code><code>(take-min n values)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Take the min n values of a collection.  This is not an order-preserving operation.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2545\">view source</a></div></div><div class=\"public anchor\" id=\"var-transient\"><h3>transient</h3><div class=\"usage\"><code>(transient v)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1131\">view source</a></div></div><div class=\"public anchor\" id=\"var-transient-map-rf\"><h3>transient-map-rf</h3><div class=\"usage\"><code>(transient-map-rf cons-fn)</code><code>(transient-map-rf cons-fn finalize-fn)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L307\">view source</a></div></div><div class=\"public anchor\" id=\"var-union\"><h3>union</h3><div class=\"usage\"><code>(union s1 s2)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Union of two sets or two maps.  When two maps are provided the right hand side\nwins in the case of an intersection - same as merge.</p>\n<p>Result is either a set or a map, depending on if s1 is a set or map.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L818\">view source</a></div></div><div class=\"public anchor\" id=\"var-union-reduce-maps\"><h3>union-reduce-maps</h3><div class=\"usage\"><code>(union-reduce-maps bfn maps)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Do an efficient union reduction across many maps using bfn to update values.\nIf the first map is mutable the union is done mutably into the first map and it is\nreturned.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L846\">view source</a></div></div><div class=\"public anchor\" id=\"var-update-vals\"><h3>update-vals</h3><div class=\"usage\"><code>(update-vals data f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L993\">view source</a></div></div><div class=\"public anchor\" id=\"var-update-values\"><h3>update-values</h3><div class=\"usage\"><code>(update-values map bfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Immutably (or mutably) update all values in the map returning a new map.\nbfn takes 2 arguments, k,v and returns a new v. Returning nil removes the key from the map.\nWhen passed a vector the keys are indexes and no nil-removal is done.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L958\">view source</a></div></div><div class=\"public anchor\" id=\"var-upgroups\"><h3>upgroups</h3><div class=\"usage\"><code>(upgroups n-elems body-fn options)</code><code>(upgroups n-elems body-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Run y index groups across n-elems.   Y is common pool parallelism.</p>\n<p>body-fn gets passed two longs, startidx and endidx.</p>\n<p>Returns a sequence of the results of body-fn applied to each group of indexes.</p>\n<p>Before using this primitive please see if <a href=\"ham-fisted.reduce.html#var-preduce\">ham-fisted.reduce/preduce</a> will work.</p>\n<p>You <em>must</em> wrap this in something that realizes the results if you need the parallelization\nto finish by a particular point in the program - <code>(dorun (hamf/upgroups ...))</code>.</p>\n<p>Options:</p>\n<ul>\n<li><code>:pgroup-min</code> - when provided n-elems must be more than this value for the computation\nto be parallelized.</li>\n<li><code>:batch-size</code> - max batch size.  Defaults to 64000.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1056\">view source</a></div></div><div class=\"public anchor\" id=\"var-upmap\"><h3>upmap</h3><div class=\"usage\"><code>(upmap map-fn &amp; sequences)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Unordered pmap using the commonPool.  This is useful for interacting with other\nprimitives, namely <a href=\"ham-fisted.api.html#var-pgroups\">pgroups</a> which are also based on this pool.</p>\n<p>Before using this primitive please see if <a href=\"ham-fisted.reduce.html#var-preduce\">ham-fisted.reduce/preduce</a> will work.</p>\n<p>Like pmap this uses the commonPool so it composes with this api's pmap, pgroups, and\ndtype-next's parallelism primitives <em>but</em> it does not impose an ordering constraint on the\nresults and thus may be significantly faster in some cases.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1092\">view source</a></div></div><div class=\"public anchor\" id=\"var-vals\"><h3>vals</h3><div class=\"usage\"><code>(vals m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the values of a map.  This version allows parallel reduction operations on\nthe returned sequence.  Returned sequence is in same order as <code>(keys m)</code>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L735\">view source</a></div></div><div class=\"public anchor\" id=\"var-vec\"><h3>vec</h3><div class=\"usage\"><code>(vec data)</code><code>(vec)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Produce a persistent vector.  Optimized pathways exist for object arrays and\njava List implementations.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1509\">view source</a></div></div><div class=\"public anchor\" id=\"var-vector\"><h3>vector</h3><div class=\"usage\"><code>(vector)</code><code>(vector a)</code><code>(vector a b)</code><code>(vector a b c)</code><code>(vector a b c d)</code><code>(vector a b c d e)</code><code>(vector a b c d e f)</code><code>(vector a b c d e f g)</code><code>(vector a b c d e f g h)</code><code>(vector a b c d e f g h i)</code><code>(vector a b c d e f g h i j)</code><code>(vector a b c d e f g h i j k)</code><code>(vector a b c d e f g h i j k &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L1521\">view source</a></div></div><div class=\"public anchor\" id=\"var-wrap-array\"><h3>wrap-array</h3><div class=\"usage\"><code>(wrap-array ary)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Wrap an array with an implementation of IMutList</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2664\">view source</a></div></div><div class=\"public anchor\" id=\"var-wrap-array-growable\"><h3>wrap-array-growable</h3><div class=\"usage\"><code>(wrap-array-growable ary ptr)</code><code>(wrap-array-growable ary)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Wrap an array with an implementation of IMutList that supports add and addAllReducible.\n'ptr is the numeric put ptr, defaults to the array length.  Pass in zero for a preallocated\nbut empty growable wrapper.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/api.clj#L2669\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.bloom-filter.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.bloom-filter documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-add-uuids.21\"><div class=\"inner\"><span>add-uuids!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-bitset-size\"><div class=\"inner\"><span>bitset-size</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-bloom-filter\"><div class=\"inner\"><span>bloom-filter</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-bloom-filter-.3Ebyte-array\"><div class=\"inner\"><span>bloom-filter-&gt;byte-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-byte-array-.3Ebloom-filter\"><div class=\"inner\"><span>byte-array-&gt;bloom-filter</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-byte-array-cls\"><div class=\"inner\"><span>byte-array-cls</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-contains.3F\"><div class=\"inner\"><span>contains?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-hash-obj\"><div class=\"inner\"><span>hash-obj</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-insert-hash.21\"><div class=\"inner\"><span>insert-hash!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-insert-obj\"><div class=\"inner\"><span>insert-obj</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-make-long-hash-predicate\"><div class=\"inner\"><span>make-long-hash-predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-make-obj-predicate\"><div class=\"inner\"><span>make-obj-predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-make-uuid-hasher\"><div class=\"inner\"><span>make-uuid-hasher</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-make-uuid-pred\"><div class=\"inner\"><span>make-uuid-pred</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.bloom-filter.html#var-serialize-.3Ebytes\"><div class=\"inner\"><span>serialize-&gt;bytes</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.bloom-filter</h1><div class=\"doc\"><div class=\"markdown\"><p>Simple fast bloom filter based on apache parquet BlockSplitBloomFilter.</p>\n</div></div><div class=\"public anchor\" id=\"var-add-uuids.21\"><h3>add-uuids!</h3><div class=\"usage\"><code>(add-uuids! bf val-seq)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L112\">view source</a></div></div><div class=\"public anchor\" id=\"var-bitset-size\"><h3>bitset-size</h3><div class=\"usage\"><code>(bitset-size fb)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the length of the byte array underlying this bitset</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L86\">view source</a></div></div><div class=\"public anchor\" id=\"var-bloom-filter\"><h3>bloom-filter</h3><div class=\"usage\"><code>(bloom-filter n f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a bloom filter.</p>\n<ul>\n<li>'n' - Number of distinct values.</li>\n<li>'f' - Value from 1.0-0.0, defaults to 0.01.  False positive rate.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L56\">view source</a></div></div><div class=\"public anchor\" id=\"var-bloom-filter-.3Ebyte-array\"><h3>bloom-filter-&gt;byte-array</h3><div class=\"usage\"><code>(bloom-filter-&gt;byte-array bf)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L91\">view source</a></div></div><div class=\"public anchor\" id=\"var-byte-array-.3Ebloom-filter\"><h3>byte-array-&gt;bloom-filter</h3><div class=\"usage\"><code>(byte-array-&gt;bloom-filter data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L95\">view source</a></div></div><div class=\"public anchor\" id=\"var-byte-array-cls\"><h3>byte-array-cls</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L14\">view source</a></div></div><div class=\"public anchor\" id=\"var-contains.3F\"><h3>contains?</h3><div class=\"usage\"><code>(contains? bf obj)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L76\">view source</a></div></div><div class=\"public anchor\" id=\"var-hash-obj\"><h3>hash-obj</h3><div class=\"usage\"><code>(hash-obj obj)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Hash an object. If integer - return integer else serialize-&gt;bytes and hash those</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L49\">view source</a></div></div><div class=\"public anchor\" id=\"var-insert-hash.21\"><h3>insert-hash!</h3><div class=\"usage\"><code>(insert-hash! bf hc)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L63\">view source</a></div></div><div class=\"public anchor\" id=\"var-insert-obj\"><h3>insert-obj</h3><div class=\"usage\"><code>(insert-obj bf o)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L80\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-long-hash-predicate\"><h3>make-long-hash-predicate</h3><div class=\"usage\"><code>(make-long-hash-predicate bf)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L68\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-obj-predicate\"><h3>make-obj-predicate</h3><div class=\"usage\"><code>(make-obj-predicate bf)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L72\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-uuid-hasher\"><h3>make-uuid-hasher</h3><div class=\"usage\"><code>(make-uuid-hasher)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L99\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-uuid-pred\"><h3>make-uuid-pred</h3><div class=\"usage\"><code>(make-uuid-pred bf)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L122\">view source</a></div></div><div class=\"public anchor\" id=\"var-serialize-.3Ebytes\"><h3>serialize-&gt;bytes</h3><div class=\"usage\"><code>(serialize-&gt;bytes o)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Serialize an object to a byte array</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/bloom_filter.clj#L42\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.defprotocol.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.defprotocol documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-defprotocol\"><div class=\"inner\"><span>defprotocol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-extend\"><div class=\"inner\"><span>extend</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-extend-protocol\"><div class=\"inner\"><span>extend-protocol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-extend-type\"><div class=\"inner\"><span>extend-type</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-extenders\"><div class=\"inner\"><span>extenders</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-extends.3F\"><div class=\"inner\"><span>extends?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-find-protocol-cache-method\"><div class=\"inner\"><span>find-protocol-cache-method</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-find-protocol-method\"><div class=\"inner\"><span>find-protocol-method</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.defprotocol.html#var-satisfies.3F\"><div class=\"inner\"><span>satisfies?</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.defprotocol</h1><div class=\"doc\"><div class=\"markdown\"><p>Alternative protocol implementation.</p>\n<p>Major features:</p>\n<ul>\n<li>\n<p>Allows subclasses to override only a subset of the methods and if the superclass\nhas overridden the method then the superclasses implementation will be used.</p>\n</li>\n<li>\n<p>Supports primitive typehints on function arguments and return values.</p>\n</li>\n<li>\n<p>Much higher and more predictable multithreaded performance for protocol method invocation due to\nthe fewer number of global variables that are read and written to for a single protocol method\ninvocation.  Does not write to global variables on a per-call basis meaning far less cpu/cache traffic\nin high contention scenarios.</p>\n</li>\n<li>\n<p>Attempting to extend a protocol method that doesn't exist is an error at extension time.</p>\n</li>\n<li>\n<p>Overriding the protocol for the base object array class overrides it for all things convertible\nto object array while still allowing the concrete array type to match a specific override.</p>\n</li>\n</ul>\n<p>Another design decision is to avoid the interface check - this simplifes the hot path a slight bit\nat the cost of slightly slower calltimes in the case the interface is used.  For those cases often\nit is possible to simply typehint the interface and call it directly avoiding any protocol dispatch\noverhead.</p>\n<p>Additional call overhead above and beyond a normal fn invocation in an arm mac is <code>-6ns</code> - the time\nfor <code>.getClass</code> call into single concurrent hash map lookup.</p>\n</div></div><div class=\"public anchor\" id=\"var-defprotocol\"><h3>defprotocol</h3><h4 class=\"type\">macro</h4><h4 class=\"added\">added in 1.2</h4><div class=\"usage\"><code>(defprotocol name &amp; opts+sigs)</code></div><div class=\"doc\"><div class=\"markdown\"><p>A protocol is a named set of named methods and their signatures:</p>\n<pre><code class=\"language-clojure\">  (defprotocol AProtocolName\n\n    ;optional doc string\n    \"A doc string for AProtocol abstraction\"\n\n   ;options\n   :extend-via-metadata true\n\n  ;method signatures\n    (bar [this a b] \"bar docs\")\n    (baz [this a] [this a b] [this a b c] \"baz docs\"))\n</code></pre>\n<p>No implementations are provided. Docs can be specified for the\nprotocol overall and for each method. The above yields a set of\npolymorphic functions and a protocol object. All are\nnamespace-qualified by the ns enclosing the definition The resulting\nfunctions dispatch on the type of their first argument, which is\nrequired and corresponds to the implicit target object ('this' in\nJava parlance). defprotocol is dynamic, has no special compile-time\neffect, and defines no new types or classes. Implementations of\nthe protocol methods can be provided using extend.</p>\n<p>When :extend-via-metadata is true, values can extend protocols by\nadding metadata where keys are fully-qualified protocol function\nsymbols and values are function implementations. Protocol\nimplementations are checked first for direct definitions (defrecord,\ndeftype, reify), then metadata definitions, then external\nextensions (extend, extend-type, extend-protocol)</p>\n<p>defprotocol will automatically generate a corresponding interface,\nwith the same name as the protocol, i.e. given a protocol:\nmy.ns/Protocol, an interface: my.ns.Protocol. The interface will\nhave methods corresponding to the protocol functions, and the\nprotocol will automatically work with instances of the interface.</p>\n<p>Note that you should not use this interface with deftype or\nreify, as they support the protocol directly:</p>\n<pre><code class=\"language-clojure\">\n  (defprotocol P\n    (foo [this])\n    (bar-me [this] [this y]))\n\n  (deftype Foo [a b c]\n   P\n    (foo [this] a)\n    (bar-me [this] b)\n    (bar-me [this y] (+ c y)))\n\n  (bar-me (Foo. 1 2 3) 42)\n  =&gt; 45\n\n  (foo\n    (let [x 42]\n      (reify P\n        (foo [this] 17)\n        (bar-me [this] x)\n        (bar-me [this y] x))))\n  =&gt; 17\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L253\">view source</a></div></div><div class=\"public anchor\" id=\"var-extend\"><h3>extend</h3><h4 class=\"added\">added in 1.2</h4><div class=\"usage\"><code>(extend atype &amp; proto+mmaps)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Implementations of protocol methods can be provided using the extend construct:</p>\n<pre><code class=\"language-clojure\">  (extend AType\n    AProtocol\n     {:foo an-existing-fn\n      :bar (fn [a b] ...)\n      :baz (fn ([a]...) ([a b] ...)...)}\n    BProtocol\n      {...}\n    ...)\n</code></pre>\n<p>extend takes a type/class (or interface, see below), and one or more\nprotocol + method map pairs. It will extend the polymorphism of the\nprotocol's methods to call the supplied methods when an AType is\nprovided as the first argument.</p>\n<p>Method maps are maps of the keyword-ized method names to ordinary\nfns. This facilitates easy reuse of existing fns and fn maps, for\ncode reuse/mixins without derivation or composition. You can extend\nan interface to a protocol. This is primarily to facilitate interop\nwith the host (e.g. Java) but opens the door to incidental multiple\ninheritance of implementation since a class can inherit from more\nthan one interface, both of which extend the protocol. It is TBD how\nto specify which impl to use. You can extend a protocol on nil.</p>\n<p>If you are supplying the definitions explicitly (i.e. not reusing\nexsting functions or mixin maps), you may find it more convenient to\nuse the extend-type or extend-protocol macros.</p>\n<p>Note that multiple independent extend clauses can exist for the same\ntype, not all protocols need be defined in a single extend call.</p>\n<p>See also:\nextends?, satisfies?, extenders</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L350\">view source</a></div></div><div class=\"public anchor\" id=\"var-extend-protocol\"><h3>extend-protocol</h3><h4 class=\"type\">macro</h4><h4 class=\"added\">added in 1.2</h4><div class=\"usage\"><code>(extend-protocol p &amp; specs)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Useful when you want to provide several implementations of the same\nprotocol all at once. Takes a single protocol and the implementation\nof that protocol for one or more types. Expands into calls to\nextend-type:</p>\n<pre><code class=\"language-clojure\">  (extend-protocol Protocol\n    AType\n      (foo [x] ...)\n      (bar [x y] ...)\n    BType\n      (foo [x] ...)\n      (bar [x y] ...)\n    AClass\n      (foo [x] ...)\n      (bar [x y] ...)\n    nil\n      (foo [x] ...)\n      (bar [x y] ...))\n</code></pre>\n<p>expands into:</p>\n<pre><code class=\"language-clojure\">  (do\n   (clojure.core/extend-type AType Protocol\n     (foo [x] ...)\n     (bar [x y] ...))\n   (clojure.core/extend-type BType Protocol\n     (foo [x] ...)\n     (bar [x y] ...))\n   (clojure.core/extend-type AClass Protocol\n     (foo [x] ...)\n     (bar [x y] ...))\n   (clojure.core/extend-type nil Protocol\n     (foo [x] ...)\n     (bar [x y] ...)))\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L519\">view source</a></div></div><div class=\"public anchor\" id=\"var-extend-type\"><h3>extend-type</h3><h4 class=\"type\">macro</h4><h4 class=\"added\">added in 1.2</h4><div class=\"usage\"><code>(extend-type t &amp; specs)</code></div><div class=\"doc\"><div class=\"markdown\"><p>A macro that expands into an extend call. Useful when you are\nsupplying the definitions explicitly inline, extend-type\nautomatically creates the maps required by extend.  Propagates the\nclass as a type hint on the first argument of all fns.</p>\n<pre><code class=\"language-clojure\">  (extend-type MyType\n    Countable\n      (cnt [c] ...)\n    Foo\n      (bar [x y] ...)\n      (baz ([x] ...) ([x y &amp; zs] ...)))\n</code></pre>\n<p>expands into:</p>\n<pre><code class=\"language-clojure\">\n  (extend MyType\n   Countable\n     {:cnt (fn [c] ...)}\n   Foo\n     {:baz (fn ([x] ...) ([x y &amp; zs] ...))\n      :bar (fn [x y] ...)})\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L482\">view source</a></div></div><div class=\"public anchor\" id=\"var-extenders\"><h3>extenders</h3><div class=\"usage\"><code>(extenders protocol)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns a collection of the types explicitly extending protocol</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L65\">view source</a></div></div><div class=\"public anchor\" id=\"var-extends.3F\"><h3>extends?</h3><div class=\"usage\"><code>(extends? protocol atype)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns true if atype extends protocol</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L59\">view source</a></div></div><div class=\"public anchor\" id=\"var-find-protocol-cache-method\"><h3>find-protocol-cache-method</h3><div class=\"usage\"><code>(find-protocol-cache-method protocol cache x)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L35\">view source</a></div></div><div class=\"public anchor\" id=\"var-find-protocol-method\"><h3>find-protocol-method</h3><div class=\"usage\"><code>(find-protocol-method protocol methodk x)</code></div><div class=\"doc\"><div class=\"markdown\"><p>It may be more efficient in a tight loop to bypass the protocol dispatch on a per-call basis.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L46\">view source</a></div></div><div class=\"public anchor\" id=\"var-satisfies.3F\"><h3>satisfies?</h3><div class=\"usage\"><code>(satisfies? protocol x)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns true if x satisfies the protocol</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/defprotocol.clj#L70\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.fjp.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.fjp documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-common-pool\"><div class=\"inner\"><span>common-pool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-common-pool-parallelism\"><div class=\"inner\"><span>common-pool-parallelism</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-compute\"><div class=\"inner\"><span>compute</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-exception-safe\"><div class=\"inner\"><span>exception-safe</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-fork-task\"><div class=\"inner\"><span>fork-task</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-in-fork-join-pool.3F\"><div class=\"inner\"><span>in-fork-join-pool?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-join\"><div class=\"inner\"><span>join</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-managed-block\"><div class=\"inner\"><span>managed-block</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-managed-block-unwrap\"><div class=\"inner\"><span>managed-block-unwrap</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-on-cp\"><div class=\"inner\"><span>on-cp</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-safe-common-pool\"><div class=\"inner\"><span>safe-common-pool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-safe-fork-task\"><div class=\"inner\"><span>safe-fork-task</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-task\"><div class=\"inner\"><span>task</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-unsafe-common-pool\"><div class=\"inner\"><span>unsafe-common-pool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.fjp.html#var-unwrap-safe\"><div class=\"inner\"><span>unwrap-safe</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.fjp</h1><div class=\"doc\"><div class=\"markdown\"><p>Support for java.util.concurrent.ForkJoinPool-specific operations such as managed block and task fork/join.\nAdditionally supports concept of 'exception-safe' via wrapping executing code and unwrapper result post\nexecution in order avoid wrapping exceptions and breaking calling code that may be expecting specific\nexception types.</p>\n<p>Some of the api's fall back to regular executor service code when called.</p>\n<p>Example:</p>\n<pre><code class=\"language-clojure\">(defn split-parallel-reduce\n  \"Perform a parallel reduction of a spliterator using the provided ExecutorService\"\n  [executor-service split ideal-split init-fn rfn merge-fn]\n  (let [n-elems (proto/estimate-count split)\n        pool (or executor-service (ForkJoinPool/commonPool))]\n    (if (or (&lt;= n-elems (long ideal-split)) (= n-elems Long/MAX_VALUE))\n      (split-reduce rfn (init-fn) split)\n      (if-let [[lhs rhs] (proto/split split)]\n        (let [lt (fjp/safe-fork-task pool (split-parallel-reduce pool lhs ideal-split init-fn rfn merge-fn))\n              rt (fjp/safe-fork-task pool (split-parallel-reduce pool rhs ideal-split init-fn rfn merge-fn))]\n          (merge-fn (fjp/managed-block-unwrap lt) (fjp/managed-block-unwrap rt)))))))\n</code></pre>\n</div></div><div class=\"public anchor\" id=\"var-common-pool\"><h3>common-pool</h3><div class=\"usage\"><code>(common-pool)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns  (ForkJoinPool/commonPool)</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L36\">view source</a></div></div><div class=\"public anchor\" id=\"var-common-pool-parallelism\"><h3>common-pool-parallelism</h3><div class=\"usage\"><code>(common-pool-parallelism)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Integer parallelism assigned to the common pool</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L38\">view source</a></div></div><div class=\"public anchor\" id=\"var-compute\"><h3>compute</h3><div class=\"usage\"><code>(compute t)</code></div><div class=\"doc\"><div class=\"markdown\"><p>compute a task in current thread - returns result</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L114\">view source</a></div></div><div class=\"public anchor\" id=\"var-exception-safe\"><h3>exception-safe</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(exception-safe &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Wrap code in an exception-safe wrapper - returns a map with either\n<code>:ham-fisted.fjp/result</code> or <code>:ham-fisted.fjp.error</code>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L92\">view source</a></div></div><div class=\"public anchor\" id=\"var-fork-task\"><h3>fork-task</h3><div class=\"usage\"><code>(fork-task pool f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Begin a separate execution for f.  If already in a fork join pool fork the task else\nsubmit f to passed in pool.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L85\">view source</a></div></div><div class=\"public anchor\" id=\"var-in-fork-join-pool.3F\"><h3>in-fork-join-pool?</h3><div class=\"usage\"><code>(in-fork-join-pool?)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns true if this task is executing in a fork join pool thread</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L40\">view source</a></div></div><div class=\"public anchor\" id=\"var-join\"><h3>join</h3><div class=\"usage\"><code>(join t)</code></div><div class=\"doc\"><div class=\"markdown\"><p>join a previously forked task returning the result</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L110\">view source</a></div></div><div class=\"public anchor\" id=\"var-managed-block\"><h3>managed-block</h3><div class=\"usage\"><code>(managed-block dly)</code><code>(managed-block finished? wait-till-finished get-value)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Block on a delay or future using the fjp system's managed blocking facility.  Safe to call all the time\nwhether the current system is in a forkjoinpool task or not.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L65\">view source</a></div></div><div class=\"public anchor\" id=\"var-managed-block-unwrap\"><h3>managed-block-unwrap</h3><div class=\"usage\"><code>(managed-block-unwrap dly)</code></div><div class=\"doc\"><div class=\"markdown\"><p>managed block then safe unwrap the exception-safe result</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L147\">view source</a></div></div><div class=\"public anchor\" id=\"var-on-cp\"><h3>on-cp</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(on-cp &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Run arbitrary code on the common-pool.  Make sure any blocking operations are wrapped in <a href=\"ham-fisted.fjp.html#var-managed-block\">managed-block</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L142\">view source</a></div></div><div class=\"public anchor\" id=\"var-safe-common-pool\"><h3>safe-common-pool</h3><div class=\"usage\"><code>(safe-common-pool safe-code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Run safe code - see <a href=\"ham-fisted.fjp.html#var-exception-safe\">exception-safe</a> unwrapping the result and re-throwing the wrapped exception.  This allows\nsystems based on typed exceptions to pass error info.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-safe-fork-task\"><h3>safe-fork-task</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(safe-fork-task pool &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Called from within an executing task, fork a executing some code and wrapping it in <a href=\"ham-fisted.fjp.html#var-exception-safe\">exception-safe</a>\nthen calling <a href=\"ham-fisted.fjp.html#var-fork-task\">fork-task</a></p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L102\">view source</a></div></div><div class=\"public anchor\" id=\"var-task\"><h3>task</h3><div class=\"usage\"><code>(task f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a task from a clojure IFn or something that implements IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L82\">view source</a></div></div><div class=\"public anchor\" id=\"var-unsafe-common-pool\"><h3>unsafe-common-pool</h3><div class=\"usage\"><code>(unsafe-common-pool code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Run a callable on the common pool.  If the callable throws you will get a wrapped exception thrown\nwhich may confuse calling code - specifically code that relies on exact exception types or ex-info.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L121\">view source</a></div></div><div class=\"public anchor\" id=\"var-unwrap-safe\"><h3>unwrap-safe</h3><div class=\"usage\"><code>(unwrap-safe m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Unwrap result created via executing code wrapped in <a href=\"ham-fisted.fjp.html#var-exception-safe\">exception-safe</a>.  Throws original exception if found.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/fjp.clj#L128\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.function.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.function documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var--.3Ebi-function\"><div class=\"inner\"><span>-&gt;bi-function</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var--.3Efunction\"><div class=\"inner\"><span>-&gt;function</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var--.3Elong-predicate\"><div class=\"inner\"><span>-&gt;long-predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-bi-consumer\"><div class=\"inner\"><span>bi-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-bi-function\"><div class=\"inner\"><span>bi-function</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-binary-operator\"><div class=\"inner\"><span>binary-operator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-binary-predicate\"><div class=\"inner\"><span>binary-predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-binary-predicate-or-null\"><div class=\"inner\"><span>binary-predicate-or-null</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-comp-nan-first\"><div class=\"inner\"><span>comp-nan-first</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-comp-nan-last\"><div class=\"inner\"><span>comp-nan-last</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-consumer\"><div class=\"inner\"><span>consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-double-.3Elong\"><div class=\"inner\"><span>double-&gt;long</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-double-.3Eobj\"><div class=\"inner\"><span>double-&gt;obj</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-double-binary-operator\"><div class=\"inner\"><span>double-binary-operator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-double-consumer\"><div class=\"inner\"><span>double-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-double-predicate\"><div class=\"inner\"><span>double-predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-double-unary-operator\"><div class=\"inner\"><span>double-unary-operator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-function\"><div class=\"inner\"><span>function</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-long-.3Edouble\"><div class=\"inner\"><span>long-&gt;double</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-long-.3Eobj\"><div class=\"inner\"><span>long-&gt;obj</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-long-binary-operator\"><div class=\"inner\"><span>long-binary-operator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-long-consumer\"><div class=\"inner\"><span>long-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-long-predicate\"><div class=\"inner\"><span>long-predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-long-unary-operator\"><div class=\"inner\"><span>long-unary-operator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-make-comparator\"><div class=\"inner\"><span>make-comparator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-make-double-comparator\"><div class=\"inner\"><span>make-double-comparator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-make-long-comparator\"><div class=\"inner\"><span>make-long-comparator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-obj-.3Edouble\"><div class=\"inner\"><span>obj-&gt;double</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-obj-.3Elong\"><div class=\"inner\"><span>obj-&gt;long</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-predicate\"><div class=\"inner\"><span>predicate</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-rcomp\"><div class=\"inner\"><span>rcomp</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.function.html#var-unary-operator\"><div class=\"inner\"><span>unary-operator</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.function</h1><div class=\"doc\"><div class=\"markdown\"><p>Helpers for working with <a href=\"https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html\">java.util.function</a>\npackage objects.</p>\n</div></div><div class=\"public anchor\" id=\"var--.3Ebi-function\"><h3>-&gt;bi-function</h3><div class=\"usage\"><code>(-&gt;bi-function cljfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Convert an object to a java.util.BiFunction. Object can either already be a\nbi-function or an IFn to be invoked with 2 arguments.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L29\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Efunction\"><h3>-&gt;function</h3><div class=\"usage\"><code>(-&gt;function cljfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Convert an object to a java Function. Object can either already be a\nFunction or an IFn to be invoked.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L96\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elong-predicate\"><h3>-&gt;long-predicate</h3><div class=\"usage\"><code>(-&gt;long-predicate f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L132\">view source</a></div></div><div class=\"public anchor\" id=\"var-bi-consumer\"><h3>bi-consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(bi-consumer arg1 arg2 &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L22\">view source</a></div></div><div class=\"public anchor\" id=\"var-bi-function\"><h3>bi-function</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(bi-function arg1 arg2 &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.function.BiFunction.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L16\">view source</a></div></div><div class=\"public anchor\" id=\"var-binary-operator\"><h3>binary-operator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(binary-operator arg1 arg2 &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.function.BinaryOperator</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L163\">view source</a></div></div><div class=\"public anchor\" id=\"var-binary-predicate\"><h3>binary-predicate</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(binary-predicate xvar yvar code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a java.util.function.BiPredicate</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L336\">view source</a></div></div><div class=\"public anchor\" id=\"var-binary-predicate-or-null\"><h3>binary-predicate-or-null</h3><div class=\"usage\"><code>(binary-predicate-or-null f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>If f is null, return null.  Else return f as a java.util.function.BiPredicate.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L346\">view source</a></div></div><div class=\"public anchor\" id=\"var-comp-nan-first\"><h3>comp-nan-first</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>A comparator that sorts null, NAN first, natural order</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L262\">view source</a></div></div><div class=\"public anchor\" id=\"var-comp-nan-last\"><h3>comp-nan-last</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>A comparator that sorts null, NAN last, natural order</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L286\">view source</a></div></div><div class=\"public anchor\" id=\"var-consumer\"><h3>consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(consumer varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an instance of a java.util.function.Consumer</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L191\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-.3Elong\"><h3>double-&gt;long</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-&gt;long varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a function that receives a double and returns a long</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L76\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-.3Eobj\"><h3>double-&gt;obj</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-&gt;obj varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L90\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-binary-operator\"><h3>double-binary-operator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-binary-operator lvar rvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a binary operator that is specialized for double values.  Useful to speed up\noperations such as sorting or summation.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L310\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-consumer\"><h3>double-consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-consumer varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an instance of a java.util.function.DoubleConsumer</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L169\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-predicate\"><h3>double-predicate</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-predicate varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.Function.DoublePredicate</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L105\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-unary-operator\"><h3>double-unary-operator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-unary-operator varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.function.DoubleUnaryOperator</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L114\">view source</a></div></div><div class=\"public anchor\" id=\"var-function\"><h3>function</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(function arg &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a java.util.function.Function</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L39\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-.3Edouble\"><h3>long-&gt;double</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-&gt;double varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a function that receives a long and returns a double</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L69\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-.3Eobj\"><h3>long-&gt;obj</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-&gt;obj varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a function that receives a primitive long and returns an object.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L83\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-binary-operator\"><h3>long-binary-operator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-binary-operator lvar rvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a binary operator that is specialized for long values.  Useful to speed up\noperations such as sorting or summation.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L323\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-consumer\"><h3>long-consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-consumer varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an instance of a java.util.function.LongConsumer</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L180\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-predicate\"><h3>long-predicate</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-predicate varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.Function.LongPredicate</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L123\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-unary-operator\"><h3>long-unary-operator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-unary-operator varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.function.LongUnaryOperator</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L139\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-comparator\"><h3>make-comparator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(make-comparator lhsvar rhsvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Make a java comparator.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L231\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-double-comparator\"><h3>make-double-comparator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(make-double-comparator lhsvar rhsvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Make a comparator that gets passed two double arguments.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L216\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-long-comparator\"><h3>make-long-comparator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(make-long-comparator lhsvar rhsvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Make a comparator that gets passed two long arguments.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L201\">view source</a></div></div><div class=\"public anchor\" id=\"var-obj-.3Edouble\"><h3>obj-&gt;double</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(obj-&gt;double)</code><code>(obj-&gt;double varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a function that converts objects to doubles</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L57\">view source</a></div></div><div class=\"public anchor\" id=\"var-obj-.3Elong\"><h3>obj-&gt;long</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(obj-&gt;long)</code><code>(obj-&gt;long varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a function that converts objects to longs</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L45\">view source</a></div></div><div class=\"public anchor\" id=\"var-predicate\"><h3>predicate</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(predicate varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.Function.Predicate</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L148\">view source</a></div></div><div class=\"public anchor\" id=\"var-rcomp\"><h3>rcomp</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>A reverse comparator that sorts in descending order</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L245\">view source</a></div></div><div class=\"public anchor\" id=\"var-unary-operator\"><h3>unary-operator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(unary-operator varname &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an implementation of java.util.function.UnaryOperator</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/function.clj#L157\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.hlet.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.hlet documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.hlet.html#var-extend-let\"><div class=\"inner\"><span>extend-let</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.hlet.html#var-let\"><div class=\"inner\"><span>let</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.hlet.html#var-let-extension-names\"><div class=\"inner\"><span>let-extension-names</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.hlet</h1><div class=\"doc\"><div class=\"markdown\"><p>Extensible let to allow efficient typed destructuring.</p>\n<p>Registered Extensions:</p>\n<p><code>dbls</code> and <code>lngs</code> will most efficiently destructure java primitive arrays and fall back to casting the result\nof clojure.lang.RT/nth if input is not a double or long array.</p>\n<p><code>dlb-fns</code> and <code>lng-fns</code> call the object's IFn interface with no interface checking.  This will <em>not</em> work\nwith a raw array but is the fastest way - faster than RT/nth - to get data out of a persistent-vector or map\nlike object.</p>\n<p><code>obj-fns</code> - fast IFn-based destructuring to objects - does not work with object arrays.  Often much faster\nthan RT/nth.</p>\n<p>This can significantly reduce boxing in tight loops without needing to result in really verbose pathways.</p>\n<pre><code class=\"language-clojure\">user&gt; (h/let [[a b] (dbls [1 2])] (+ a b))\n  3.0\nuser&gt; (hamf/sum-fast (lznc/cartesian-map\n                      #(h/let [[a b c d](lng-fns %)]\n                         (-&gt; (+ a b) (+ c) (+ d)))\n                      [1 2 3]\n                      [4 5 6]\n                      [7 8 9]\n                      [10 11 12 13 14]))\n3645.0\n</code></pre>\n<p>See also <a href=\"ham-fisted.primitive-invoke.html\">ham-fisted.primitive-invoke</a>, <a href=\"ham-fisted.api.html#var-dnth\">ham-fisted.api/dnth</a> <a href=\"ham-fisted.api.html#var-lnth\">ham-fisted.api/lnth</a>.</p>\n</div></div><div class=\"public anchor\" id=\"var-extend-let\"><h3>extend-let</h3><div class=\"usage\"><code>(extend-let sym-name code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Code gets a tuple of <a href=\"lhs rhs\">lhs rhs</a> must return\na flattened sequence of left and right hand sides.\nThis uses a special symbol that will look like a function call on the\nright hand side as the dispatch mechanism.</p>\n<p>See source code of this file for example extensions.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/hlet.clj#L43\">view source</a></div></div><div class=\"public anchor\" id=\"var-let\"><h3>let</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(let bindings &amp; body)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Extensible let intended to allow typed destructuring of arbitrary datatypes such as primitive arrays\nor point types.  Falls back to normal let after extension process.  Several extensions are registered by default -</p>\n<ul>\n<li><code>dbls</code> and <code>lngs</code> which destructure into primitive doubles and primitive longs, respectively.</li>\n<li><code>dlb-fns</code> and <code>lng-fns</code> which destructure into primitive doubls and longs but use the often faster IFn overloads\nto get the data - avoiding RT.nth calls.</li>\n<li><code>obj-fns</code> which destructure into objects using the IFn interface.</li>\n</ul>\n<pre><code class=\"language-clojure\">user&gt; (h/let [[x y] (dbls (hamf/double-array [1 2]))]\n        (+ x y))\n3.0\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/hlet.clj#L92\">view source</a></div></div><div class=\"public anchor\" id=\"var-let-extension-names\"><h3>let-extension-names</h3><div class=\"usage\"><code>(let-extension-names)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the current extension names.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/hlet.clj#L161\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.iterator.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.iterator documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var--.3Eiterator\"><div class=\"inner\"><span>-&gt;iterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-ary-iter\"><div class=\"inner\"><span>ary-iter</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-blocking-queue-.3Eiterable\"><div class=\"inner\"><span>blocking-queue-&gt;iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-const-iterable\"><div class=\"inner\"><span>const-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-ctx-iter\"><div class=\"inner\"><span>ctx-iter</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-current-iterator\"><div class=\"inner\"><span>current-iterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-dedup-first-by\"><div class=\"inner\"><span>dedup-first-by</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-doiter\"><div class=\"inner\"><span>doiter</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-has-next.3F\"><div class=\"inner\"><span>has-next?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-iter-cons\"><div class=\"inner\"><span>iter-cons</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-iter-take\"><div class=\"inner\"><span>iter-take</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-iter-take-while\"><div class=\"inner\"><span>iter-take-while</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-iterable\"><div class=\"inner\"><span>iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-linear-merge-iterator\"><div class=\"inner\"><span>linear-merge-iterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-maybe-next\"><div class=\"inner\"><span>maybe-next</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-merge-iterable\"><div class=\"inner\"><span>merge-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-next\"><div class=\"inner\"><span>next</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-non-nil.3F\"><div class=\"inner\"><span>non-nil?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-once-iterable\"><div class=\"inner\"><span>once-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-seq-iterable\"><div class=\"inner\"><span>seq-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-seq-once-iterable\"><div class=\"inner\"><span>seq-once-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-unstable-merge-iterable\"><div class=\"inner\"><span>unstable-merge-iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.iterator.html#var-wrap-iter\"><div class=\"inner\"><span>wrap-iter</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.iterator</h1><div class=\"doc\"><div class=\"markdown\"><p>Generialized efficient pathways involving iterators.</p>\n</div></div><div class=\"public anchor\" id=\"var--.3Eiterator\"><h3>-&gt;iterator</h3><div class=\"usage\"><code>(-&gt;iterator item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Convert a stream, supplier, or an iterable into an iterator.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L69\">view source</a></div></div><div class=\"public anchor\" id=\"var-ary-iter\"><h3>ary-iter</h3><div class=\"usage\"><code>(ary-iter ary-data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an iterator for any primitive or object java array.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L36\">view source</a></div></div><div class=\"public anchor\" id=\"var-blocking-queue-.3Eiterable\"><h3>blocking-queue-&gt;iterable</h3><div class=\"usage\"><code>(blocking-queue-&gt;iterable queue term-symbol)</code><code>(blocking-queue-&gt;iterable queue timeout-us timeout-symbol term-symbol)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a blocking queue return an iterable that iterates until queue returns term-symbol.  Uses\ntake to block indefinitely  --  will throw any throwable that comes out of the queue.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L318\">view source</a></div></div><div class=\"public anchor\" id=\"var-const-iterable\"><h3>const-iterable</h3><div class=\"usage\"><code>(const-iterable arg)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an iterable that always returns a arg.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L337\">view source</a></div></div><div class=\"public anchor\" id=\"var-ctx-iter\"><h3>ctx-iter</h3><div class=\"usage\"><code>(ctx-iter valid? init-fn update-fn val-fn)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L65\">view source</a></div></div><div class=\"public anchor\" id=\"var-current-iterator\"><h3>current-iterator</h3><div class=\"usage\"><code>(current-iterator item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a current iterator - and iterator that retains the current object.\nThis iterator is positioned just before the first object so it's current item\nis nil.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L122\">view source</a></div></div><div class=\"public anchor\" id=\"var-dedup-first-by\"><h3>dedup-first-by</h3><div class=\"usage\"><code>(dedup-first-by key-fn cmp data)</code><code>(dedup-first-by cmp data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a sorted sequence remove duplicates keeping first.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L247\">view source</a></div></div><div class=\"public anchor\" id=\"var-doiter\"><h3>doiter</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doiter varname iterable &amp; body)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Execute body for every item in the iterable.  Expecting side effects, returns nil.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L96\">view source</a></div></div><div class=\"public anchor\" id=\"var-has-next.3F\"><h3>has-next?</h3><div class=\"usage\"><code>(has-next? iter)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given an iterator or nil return true if the iterator has next.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L19\">view source</a></div></div><div class=\"public anchor\" id=\"var-iter-cons\"><h3>iter-cons</h3><div class=\"usage\"><code>(iter-cons vv iter)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Produce a new iterator that points to vv then defers to passed in iterator.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L239\">view source</a></div></div><div class=\"public anchor\" id=\"var-iter-take\"><h3>iter-take</h3><div class=\"usage\"><code>(iter-take n coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>take n from an iterator returning a new iterator</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L354\">view source</a></div></div><div class=\"public anchor\" id=\"var-iter-take-while\"><h3>iter-take-while</h3><div class=\"usage\"><code>(iter-take-while pred iter)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns {:data :rest*} where rest* resolves to an iterator once data has been\ncompletely consumed.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L363\">view source</a></div></div><div class=\"public anchor\" id=\"var-iterable\"><h3>iterable</h3><div class=\"usage\"><code>(iterable valid? init-fn update-fn val-fn)</code><code>(iterable init-fn update-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an iterable.  init-fn is not called until the first has-next call.</p>\n<ul>\n<li>valid? - ctx-&gt;boolean - defaults to non-nil?</li>\n<li>init-fn - creates new ctx</li>\n<li>update-fn - function from ctx-&gt;ctx</li>\n<li>val-fn - function from ctx-&gt;val - defaults to deref</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-linear-merge-iterator\"><h3>linear-merge-iterator</h3><div class=\"usage\"><code>(linear-merge-iterator cmp p iterators)</code><code>(linear-merge-iterator cmp iterators)</code><code>(linear-merge-iterator iterators)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a merging iterator - fast for N &lt; 8.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L107\">view source</a></div></div><div class=\"public anchor\" id=\"var-maybe-next\"><h3>maybe-next</h3><div class=\"usage\"><code>(maybe-next iter)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given an iterator or nil return the next element if the iterator hasNext.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L25\">view source</a></div></div><div class=\"public anchor\" id=\"var-merge-iterable\"><h3>merge-iterable</h3><div class=\"usage\"><code>(merge-iterable cmp iterables)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an efficient stable n-way merge between a sequence of iterables using comparator.  If iterables themselves\nare sorted result will be sorted.  If two items tie then the one from the leftmost iterable wins.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L266\">view source</a></div></div><div class=\"public anchor\" id=\"var-next\"><h3>next</h3><div class=\"usage\"><code>(next iter)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given an iterator call next.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L22\">view source</a></div></div><div class=\"public anchor\" id=\"var-non-nil.3F\"><h3>non-nil?</h3><div class=\"usage\"><code>(non-nil? a)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L28\">view source</a></div></div><div class=\"public anchor\" id=\"var-once-iterable\"><h3>once-iterable</h3><div class=\"usage\"><code>(once-iterable valid? init-fn update-fn val-fn)</code><code>(once-iterable valid? init-fn)</code><code>(once-iterable init-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an iterable that can only be iterated once - it always returns the same (non threadsafe) iterator\nevery <code>iterator</code> call.  init-fn is not called until the first has-next call - also see <a href=\"ham-fisted.iterator.html#var-iterable\">iterable</a>.</p>\n<p>The arguments have different defaults as once-iterables can close over global context on construction\nas they can only be iterated once.</p>\n<ul>\n<li>valid? - ctx-&gt;boolean - defaults to non-nil?</li>\n<li>init-fn - creates new ctx</li>\n<li>update-fn - function from ctx-&gt;ctx - defaults to init-fn ignoring argument.</li>\n<li>val-fn - function from ctx-&gt;val - defaults to identity</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L150\">view source</a></div></div><div class=\"public anchor\" id=\"var-seq-iterable\"><h3>seq-iterable</h3><div class=\"usage\"><code>(seq-iterable iterable)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Iterable with efficient reduce but also contains a cached seq conversion so patterns like:\n(when (seq v) ...) still work without needing to dereference the iterable twice.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L206\">view source</a></div></div><div class=\"public anchor\" id=\"var-seq-once-iterable\"><h3>seq-once-iterable</h3><div class=\"usage\"><code>(seq-once-iterable valid? init update val-fn)</code><code>(seq-once-iterable valid? init)</code><code>(seq-once-iterable init)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L212\">view source</a></div></div><div class=\"public anchor\" id=\"var-unstable-merge-iterable\"><h3>unstable-merge-iterable</h3><div class=\"usage\"><code>(unstable-merge-iterable cmp iterables)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an efficient n-way merge between a sequence of iterables using comparator.  If iterables themselves\nare sorted result will be sorted.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L295\">view source</a></div></div><div class=\"public anchor\" id=\"var-wrap-iter\"><h3>wrap-iter</h3><div class=\"usage\"><code>(wrap-iter iter)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Wrap an iterator returning an iterable.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/iterator.clj#L357\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.lazy-noncaching.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.lazy-noncaching documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var--.3Ecollection\"><div class=\"inner\"><span>-&gt;collection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var--.3Eiterable\"><div class=\"inner\"><span>-&gt;iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var--.3Erandom-access\"><div class=\"inner\"><span>-&gt;random-access</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var--.3Ereducible\"><div class=\"inner\"><span>-&gt;reducible</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-apply-concat\"><div class=\"inner\"><span>apply-concat</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-as-random-access\"><div class=\"inner\"><span>as-random-access</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-boolean-alength\"><div class=\"inner\"><span>boolean-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-byte-alength\"><div class=\"inner\"><span>byte-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-cartesian-map\"><div class=\"inner\"><span>cartesian-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-char-alength\"><div class=\"inner\"><span>char-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-complement\"><div class=\"inner\"><span>complement</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-concat\"><div class=\"inner\"><span>concat</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-concat-opts\"><div class=\"inner\"><span>concat-opts</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-cond\"><div class=\"inner\"><span>cond</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-constant-count\"><div class=\"inner\"><span>constant-count</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-constant-countable.3F\"><div class=\"inner\"><span>constant-countable?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-count\"><div class=\"inner\"><span>count</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-countable-arrays\"><div class=\"inner\"><span>countable-arrays</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-define-drop-tducer\"><div class=\"inner\"><span>define-drop-tducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-define-take-tducer\"><div class=\"inner\"><span>define-take-tducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-double-alength\"><div class=\"inner\"><span>double-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-drop\"><div class=\"inner\"><span>drop</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-empty-vec\"><div class=\"inner\"><span>empty-vec</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-every.3F\"><div class=\"inner\"><span>every?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-filter\"><div class=\"inner\"><span>filter</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-float-alength\"><div class=\"inner\"><span>float-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-int-alength\"><div class=\"inner\"><span>int-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-into-array\"><div class=\"inner\"><span>into-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-long-alength\"><div class=\"inner\"><span>long-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-make-readonly-list\"><div class=\"inner\"><span>make-readonly-list</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-map\"><div class=\"inner\"><span>map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-map-indexed\"><div class=\"inner\"><span>map-indexed</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-map-reducible\"><div class=\"inner\"><span>map-reducible</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-object-alength\"><div class=\"inner\"><span>object-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-object-array\"><div class=\"inner\"><span>object-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-partition-all\"><div class=\"inner\"><span>partition-all</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-partition-by\"><div class=\"inner\"><span>partition-by</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-partition-by-comparator\"><div class=\"inner\"><span>partition-by-comparator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-partition-by-cost\"><div class=\"inner\"><span>partition-by-cost</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-reindex\"><div class=\"inner\"><span>reindex</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-remove\"><div class=\"inner\"><span>remove</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-repeatedly\"><div class=\"inner\"><span>repeatedly</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-seed-.3Erandom\"><div class=\"inner\"><span>seed-&gt;random</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-shift\"><div class=\"inner\"><span>shift</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-short-alength\"><div class=\"inner\"><span>short-alength</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-shuffle\"><div class=\"inner\"><span>shuffle</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-take\"><div class=\"inner\"><span>take</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-tuple-map\"><div class=\"inner\"><span>tuple-map</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-type-single-arg-ifn\"><div class=\"inner\"><span>type-single-arg-ifn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.lazy-noncaching.html#var-type-zero-arg-ifn\"><div class=\"inner\"><span>type-zero-arg-ifn</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.lazy-noncaching</h1><div class=\"doc\"><div class=\"markdown\"><p>Lazy, noncaching implementation of many clojure.core functions.  There are several benefits of carefully\nconstructed lazy noncaching versions:</p>\n<ol>\n<li>No locking - better multithreading/green thread performance.</li>\n<li>Higher performance generally.</li>\n<li>More datatype flexibility - if map is passed a single randomly addressible or generically\nparallelizable container the result is still randomly addressible or generically perallelizable.\nFor instance (map key {:a 1 :b 2}) returns in the generic case something that can still be parallelizable\nas the entry set of a map implements spliterator.</li>\n</ol>\n</div></div><div class=\"public anchor\" id=\"var--.3Ecollection\"><h3>-&gt;collection</h3><div class=\"usage\"><code>(-&gt;collection item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Ensure an item implements java.util.Collection.  This is inherently true for seqs and any\nimplementation of java.util.List but not true for object arrays.  For maps this returns\nthe entry set.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L99\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eiterable\"><h3>-&gt;iterable</h3><div class=\"usage\"><code>(-&gt;iterable a)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L122\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Erandom-access\"><h3>-&gt;random-access</h3><div class=\"usage\"><code>(-&gt;random-access item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L183\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ereducible\"><h3>-&gt;reducible</h3><div class=\"usage\"><code>(-&gt;reducible item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L112\">view source</a></div></div><div class=\"public anchor\" id=\"var-apply-concat\"><h3>apply-concat</h3><div class=\"usage\"><code>(apply-concat)</code><code>(apply-concat data)</code><code>(apply-concat opts data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>A more efficient form of (apply concat ...) that doesn't force data to be a clojure seq.\nSee <a href=\"ham-fisted.lazy-noncaching.html#var-concat-opts\">concat-opts</a> for opts definition.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L419\">view source</a></div></div><div class=\"public anchor\" id=\"var-as-random-access\"><h3>as-random-access</h3><div class=\"usage\"><code>(as-random-access item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>If item implements RandomAccess, return List interface.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L174\">view source</a></div></div><div class=\"public anchor\" id=\"var-boolean-alength\"><h3>boolean-alength</h3><div class=\"usage\"><code>(boolean-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-byte-alength\"><h3>byte-alength</h3><div class=\"usage\"><code>(byte-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-cartesian-map\"><h3>cartesian-map</h3><div class=\"usage\"><code>(cartesian-map f)</code><code>(cartesian-map f a)</code><code>(cartesian-map f a b)</code><code>(cartesian-map f a b &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a new sequence that is the cartesian join of the input sequence passed through f.\nUnlike map, f is passed the arguments as a single persistent vector.  This is to enable much\nhigher efficiency in the higher-arity applications.  For tight numeric loops, see <a href=\"ham-fisted.hlet.html#var-let\">ham-fisted.hlet/let</a>.</p>\n<p>The argument vector is mutably updated between function calls so you can't cache it.  Use <code>(into [] args)</code>\nor some variation thereof to cache the arguments as is.</p>\n<pre><code class=\"language-clojure\">user&gt; (hamf/sum-fast (lznc/cartesian-map\n                      #(h/let [[a b c d](lng-fns %)]\n                         (-&gt; (+ a b) (+ c) (+ d)))\n                      [1 2 3]\n                      [4 5 6]\n                      [7 8 9]\n                      [10 11 12 13 14]))\n3645.0\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L1151\">view source</a></div></div><div class=\"public anchor\" id=\"var-char-alength\"><h3>char-alength</h3><div class=\"usage\"><code>(char-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-complement\"><h3>complement</h3><div class=\"usage\"><code>(complement f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Like clojure core complement but avoids var lookup on 'not'</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L474\">view source</a></div></div><div class=\"public anchor\" id=\"var-concat\"><h3>concat</h3><div class=\"usage\"><code>(concat)</code><code>(concat a)</code><code>(concat a &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L433\">view source</a></div></div><div class=\"public anchor\" id=\"var-concat-opts\"><h3>concat-opts</h3><div class=\"usage\"><code>(concat-opts opts a)</code><code>(concat-opts opts a &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Concat where the first argument is an options map.  This variation allows you to set the <code>:cat-parallelism</code>\nas you may have an idea the best way to parallelism this concatenation at time of the concatenation creation.</p>\n<p>Options:</p>\n<p><code>:cat-parallelism</code> - Set the type of parallelism - either <code>:elem-wise</code> or <code>:seq-wise</code>  - this overrides\nsettings later passed into calls such as <a href=\"reduce.preduce\">reduce.preduce</a> - see <a href=\"ham-fisted.reduce.html#var-options-.3Eparallel-options\">reduce/options-&gt;parallel-options</a>\nfor definition.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L442\">view source</a></div></div><div class=\"public anchor\" id=\"var-cond\"><h3>cond</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(cond &amp; clauses)</code></div><div class=\"doc\"><div class=\"markdown\"><p>See documentation for <a href=\"ham-fisted.api.html#var-cond\">ham-fisted.api/cond</a></p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L50\">view source</a></div></div><div class=\"public anchor\" id=\"var-constant-count\"><h3>constant-count</h3><div class=\"usage\"><code>(constant-count data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Constant time count.  Returns nil if input doesn't have a constant time count.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L204\">view source</a></div></div><div class=\"public anchor\" id=\"var-constant-countable.3F\"><h3>constant-countable?</h3><div class=\"usage\"><code>(constant-countable? data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L194\">view source</a></div></div><div class=\"public anchor\" id=\"var-count\"><h3>count</h3><div class=\"usage\"><code>(count m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L55\">view source</a></div></div><div class=\"public anchor\" id=\"var-countable-arrays\"><h3>countable-arrays</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(countable-arrays)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L62\">view source</a></div></div><div class=\"public anchor\" id=\"var-define-drop-tducer\"><h3>define-drop-tducer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(define-drop-tducer nm iface rf-tag)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L514\">view source</a></div></div><div class=\"public anchor\" id=\"var-define-take-tducer\"><h3>define-take-tducer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(define-take-tducer nm invoke-nm iface rf-tag)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L557\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-alength\"><h3>double-alength</h3><div class=\"usage\"><code>(double-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-drop\"><h3>drop</h3><div class=\"usage\"><code>(drop n)</code><code>(drop n data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L537\">view source</a></div></div><div class=\"public anchor\" id=\"var-empty-vec\"><h3>empty-vec</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L46\">view source</a></div></div><div class=\"public anchor\" id=\"var-every.3F\"><h3>every?</h3><div class=\"usage\"><code>(every? pred coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster (in most circumstances) implementation of clojure.core/every?.  This can be much faster in the case\nof primitive arrays of values.  Type-hinted functions are best if coll is primitive array - see example.</p>\n<pre><code class=\"language-clojure\">user&gt; (type data)\n[J\nuser&gt; (count data)\n100\nuser&gt; (def vdata (vec data))\n#'user/vdata\nuser&gt; (crit/quick-bench (every? (fn [^long v] (&gt; v 80)) data))\n             Execution time mean : 40.248868 ns\nnil\nuser&gt; (crit/quick-bench (lznc/every? (fn [^long v] (&gt; v 80)) data))\n             Execution time mean : 7.601190 ns\nnil\nuser&gt; (crit/quick-bench (every? (fn [^long v] (&lt; v 80)) vdata))\n             Execution time mean : 1.269582 µs\nnil\nuser&gt; (crit/quick-bench (lznc/every? (fn [^long v] (&lt; v 80)) vdata))\n             Execution time mean : 211.645613 ns\nnil\nuser&gt;\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L1072\">view source</a></div></div><div class=\"public anchor\" id=\"var-filter\"><h3>filter</h3><div class=\"usage\"><code>(filter pred)</code><code>(filter pred coll)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L458\">view source</a></div></div><div class=\"public anchor\" id=\"var-float-alength\"><h3>float-alength</h3><div class=\"usage\"><code>(float-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-int-alength\"><h3>int-alength</h3><div class=\"usage\"><code>(int-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-into-array\"><h3>into-array</h3><div class=\"usage\"><code>(into-array aseq)</code><code>(into-array ary-type aseq)</code><code>(into-array ary-type mapfn aseq)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L216\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-alength\"><h3>long-alength</h3><div class=\"usage\"><code>(long-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-make-readonly-list\"><h3>make-readonly-list</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(make-readonly-list n idxvar read-code)</code><code>(make-readonly-list cls-type-kwd n idxvar read-code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Implement a readonly list.  If cls-type-kwd is provided it must be, at compile time,\neither :int64, :float64 or :object and the getLong, getDouble or get interface methods\nwill be filled in, respectively.  In those cases read-code must return the appropriate\ntype.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L622\">view source</a></div></div><div class=\"public anchor\" id=\"var-map\"><h3>map</h3><div class=\"usage\"><code>(map f)</code><code>(map f arg)</code><code>(map f arg &amp; args)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L234\">view source</a></div></div><div class=\"public anchor\" id=\"var-map-indexed\"><h3>map-indexed</h3><div class=\"usage\"><code>(map-indexed map-fn coll)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L282\">view source</a></div></div><div class=\"public anchor\" id=\"var-map-reducible\"><h3>map-reducible</h3><div class=\"usage\"><code>(map-reducible f r)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Map a function over r - r need only be reducible.  Returned value does not implement\nseq but is countable when r is countable.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L313\">view source</a></div></div><div class=\"public anchor\" id=\"var-object-alength\"><h3>object-alength</h3><div class=\"usage\"><code>(object-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-object-array\"><h3>object-array</h3><div class=\"usage\"><code>(object-array item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Faster version of object-array for eductions, java collections and strings.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L131\">view source</a></div></div><div class=\"public anchor\" id=\"var-partition-all\"><h3>partition-all</h3><div class=\"usage\"><code>(partition-all n)</code><code>(partition-all n coll)</code><code>(partition-all n step coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Lazy noncaching version of partition-all.  When input is random access returns random access result.</p>\n<p>If input is not random access then similar to <a href=\"ham-fisted.lazy-noncaching.html#var-partition-by\">partition-by</a> each sub-collection must be entirely\niterated through before requesting the next sub-collection.</p>\n<pre><code class=\"language-clojure\">user&gt; (crit/quick-bench (mapv hamf/sum-fast (lznc/partition-all 100 (range 100000))))\n             Execution time mean : 335.821098 µs\nnil\nuser&gt; (crit/quick-bench (mapv hamf/sum-fast (partition-all 100 (range 100000))))\n             Execution time mean : 6.831242 ms\nnil\nuser&gt; (crit/quick-bench (into [] (comp (partition-all 100)\n                                       (map hamf/sum-fast))\n                              (range 100000)))\n             Execution time mean : 1.645954 ms\nnil\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L1007\">view source</a></div></div><div class=\"public anchor\" id=\"var-partition-by\"><h3>partition-by</h3><div class=\"usage\"><code>(partition-by f)</code><code>(partition-by f coll)</code><code>(partition-by f options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Lazy noncaching version of partition-by.  For reducing partitions into a singular value please see\n<a href=\"ham-fisted.api.html#var-apply-concat\">apply-concat</a>.  Return value most efficiently implements reduce with a slightly less efficient\nimplementation of Iterable.</p>\n<p>Unlike clojure.core/partition-by this does not store intermediate elements nor does it build\nup intermediate containers.  This makes it somewhat faster in most contexts.</p>\n<p>Each sub-collection must be iterated through entirely before the next method of the parent iterator\nelse the result will not be correct.</p>\n<p>Options:</p>\n<ul>\n<li><code>:ignore-leftover?</code> - When true leftover items in the previous iteration do not cause an exception.\nDefaults to false.</li>\n<li><code>:binary-predicate</code> - When provided, use this for equality semantics.  Defaults to equiv semantics\nbut in a numeric context it may be useful to have <code>(== ##NaN ##Nan)</code>.</li>\n</ul>\n<pre><code class=\"language-clojure\">user&gt; ;;incorrect - inner items not iterated and non-caching!\nuser&gt; (into [] (lznc/partition-by identity [1 1 1 2 2 2 3 3 3]))\nExecution error at ham_fisted.lazy_noncaching.PartitionBy/reduce (lazy_noncaching.clj:514).\nSub-collection was not entirely consumed.\n\nuser&gt; ;;correct - transducing form of into calls vec on each sub-collection\nuser&gt; ;;thus iterating through it entirely.\nuser&gt; (into [] (map vec) (lznc/partition-by identity [1 1 1 2 2 2 3 3 3]))\n[[1 1 1] [2 2 2] [3 3 3]]\nuser&gt; ;;filter,collect NaN out of sequence\nuser&gt; (lznc/map hamf/vec (lznc/partition-by identity {:binary-predicate (hamf-fn/binary-predicate\n                                                                         x y (let [x (double x)\n                                                                                   y (double y)]\n                                                                               (cond\n                                                                                 (Double/isNaN x)\n                                                                                 (if (Double/isNaN y)\n                                                                                   true\n                                                                                   false)\n                                                                                 (Double/isNaN y) false\n                                                                                 :else true))) }\n                                            [1 2 3 ##NaN ##NaN 3 4 5]))\n([1 2 3] [NaN NaN] [3 4 5])\n\nuser&gt; (def init-data (vec (lznc/apply-concat (lznc/map #(repeat 100 %) (range 1000)))))\n#'user/init-data\nuser&gt; (crit/quick-bench (mapv hamf/sum-fast (lznc/partition-by identity init-data)))\n             Execution time mean : 366.915796 µs\n  ...\nnil\nuser&gt; (crit/quick-bench (mapv hamf/sum-fast (clojure.core/partition-by identity init-data)))\n             Execution time mean : 6.699424 ms\n  ...\nnil\nuser&gt; (crit/quick-bench (into [] (comp (clojure.core/partition-by identity)\n                                       (map hamf/sum-fast)) init-data))\n             Execution time mean : 1.705864 ms\n  ...\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L876\">view source</a></div></div><div class=\"public anchor\" id=\"var-partition-by-comparator\"><h3>partition-by-comparator</h3><div class=\"usage\"><code>(partition-by-comparator cmp coll)</code><code>(partition-by-comparator cmp options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Partition by a comparator.  Sub partitions must be fully consumed before parent is called.  An optional\ntimeout can be used if sub partitions are being consumed in a future - the parent iteration will block\nuntil the sub partition is fully consumed.</p>\n<p>Options:</p>\n<ul>\n<li><code>:timeout-ms</code> - Timeout in milliseconds - if the sub partition isn't consumed by this time an exception\nis thrown.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L941\">view source</a></div></div><div class=\"public anchor\" id=\"var-partition-by-cost\"><h3>partition-by-cost</h3><div class=\"usage\"><code>(partition-by-cost cost-fn max-cost coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Partition a sequence by integer cost.  Will produce partitions of average cost '(quot max-cost 2)\nwith some partitions being larger or smaller if the input sequence ends.  This function not very lazy\nwith each new partition greedily calculated.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L968\">view source</a></div></div><div class=\"public anchor\" id=\"var-reindex\"><h3>reindex</h3><div class=\"usage\"><code>(reindex coll indexes)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Permut coll by the given indexes.  Result is random-access and the same length as\nthe index collection.  Indexes are expected to be in the range of [0-&gt;count(coll)).</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L754\">view source</a></div></div><div class=\"public anchor\" id=\"var-remove\"><h3>remove</h3><h4 class=\"added\">added in 1.0</h4><div class=\"usage\"><code>(remove pred coll)</code><code>(remove pred)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns a lazy sequence of the items in coll for which\n(pred item) returns logical false. pred must be free of side-effects.\nReturns a transducer when no collection is provided.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L484\">view source</a></div></div><div class=\"public anchor\" id=\"var-repeatedly\"><h3>repeatedly</h3><div class=\"usage\"><code>(repeatedly f)</code><code>(repeatedly n f)</code></div><div class=\"doc\"><div class=\"markdown\"><p>When called with one argument, produce infinite list of calls to v.\nWhen called with two arguments, produce a non-caching random access list of length n of calls to v.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L663\">view source</a></div></div><div class=\"public anchor\" id=\"var-seed-.3Erandom\"><h3>seed-&gt;random</h3><div class=\"usage\"><code>(seed-&gt;random seed)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L741\">view source</a></div></div><div class=\"public anchor\" id=\"var-shift\"><h3>shift</h3><div class=\"usage\"><code>(shift n coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Shift a collection forward or backward repeating either the first or the last entries.\nReturns a random access list with the same elements as coll.</p>\n<p>Example:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (shift 2 (range 10))\n[0 0 0 1 2 3 4 5 6 7]\nham-fisted.api&gt; (shift -2 (range 10))\n[2 3 4 5 6 7 8 9 9 9]\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L713\">view source</a></div></div><div class=\"public anchor\" id=\"var-short-alength\"><h3>short-alength</h3><div class=\"usage\"><code>(short-alength m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-shuffle\"><h3>shuffle</h3><div class=\"usage\"><code>(shuffle coll)</code><code>(shuffle coll opts)</code></div><div class=\"doc\"><div class=\"markdown\"><p>shuffle values returning random access container.</p>\n<p>Options:</p>\n<ul>\n<li><code>:seed</code> - If instance of java.util.Random, use this.  If integer, use as seed.\nIf not provided a new instance of java.util.Random is created.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L769\">view source</a></div></div><div class=\"public anchor\" id=\"var-take\"><h3>take</h3><div class=\"usage\"><code>(take n)</code><code>(take n data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L605\">view source</a></div></div><div class=\"public anchor\" id=\"var-tuple-map\"><h3>tuple-map</h3><div class=\"usage\"><code>(tuple-map f c1)</code><code>(tuple-map f c1 c2)</code><code>(tuple-map f c1 c2 &amp; cs)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Lazy nonaching map but f simply gets a single random-access list of arguments.\nThe argument list may be mutably updated between calls.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L330\">view source</a></div></div><div class=\"public anchor\" id=\"var-type-single-arg-ifn\"><h3>type-single-arg-ifn</h3><div class=\"usage\"><code>(type-single-arg-ifn ifn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Categorize the return type of a single argument ifn.  May be :float64, :int64, or :object.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L652\">view source</a></div></div><div class=\"public anchor\" id=\"var-type-zero-arg-ifn\"><h3>type-zero-arg-ifn</h3><div class=\"usage\"><code>(type-zero-arg-ifn ifn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Categorize the return type of a single argument ifn.  May be :float64, :int64, or :object.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/lazy_noncaching.clj#L658\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.mut-map.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.mut-map documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.mut-map.html#var-compute.21\"><div class=\"inner\"><span>compute!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.mut-map.html#var-compute-if-absent.21\"><div class=\"inner\"><span>compute-if-absent!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.mut-map.html#var-compute-if-present.21\"><div class=\"inner\"><span>compute-if-present!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.mut-map.html#var-keyset\"><div class=\"inner\"><span>keyset</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.mut-map.html#var-values\"><div class=\"inner\"><span>values</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.mut-map</h1><div class=\"doc\"><div class=\"markdown\"><p>Functions for working with java's mutable map interface</p>\n</div></div><div class=\"public anchor\" id=\"var-compute.21\"><h3>compute!</h3><div class=\"usage\"><code>(compute! m k bfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Compute a new value in a map derived from an existing value.  bfn gets passed k, v where k\nmay be nil.  If the function returns nil the corresponding key is removed from the map.</p>\n<p>See <a href=\"https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#compute-K-java.util.function.BiFunction-\">Map.compute</a></p>\n<p>An example <code>bfn</code> for counting occurrences would be <code>#(if % (inc (long %)) 1)</code>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/mut_map.clj#L7\">view source</a></div></div><div class=\"public anchor\" id=\"var-compute-if-absent.21\"><h3>compute-if-absent!</h3><div class=\"usage\"><code>(compute-if-absent! m k bfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Compute a value if absent from the map.  Useful for memoize-type operations.  Must use\nmutable maps.  bfn gets passed k.</p>\n<p>See <a href=\"https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-\">map.computeIfAbsent</a></p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/mut_map.clj#L27\">view source</a></div></div><div class=\"public anchor\" id=\"var-compute-if-present.21\"><h3>compute-if-present!</h3><div class=\"usage\"><code>(compute-if-present! m k bfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Compute a new value if the value already exists and is non-nil in the hashmap.  Must use\nmutable maps.  bfn gets passed k, v where v is non-nil.</p>\n<p>See <a href=\"https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfPresent-K-java.util.function.BiFunction-\">Map.computeIfPresent</a></p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/mut_map.clj#L18\">view source</a></div></div><div class=\"public anchor\" id=\"var-keyset\"><h3>keyset</h3><div class=\"usage\"><code>(keyset m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the keyset of the map.  This may not be in the same order as (keys m) or (vals\nm).  For hamf maps, this has the same ordering as (keys m).  For both hamf and java\nhashmaps, the returned implementation of java.util.Set has both more utility and better\nperformance than (keys m).</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/mut_map.clj#L36\">view source</a></div></div><div class=\"public anchor\" id=\"var-values\"><h3>values</h3><div class=\"usage\"><code>(values m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the values collection of the map.  This may not be in the same order as (keys m)\nor (vals m).  For hamf hashmaps, this does have the same order as (vals m).</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/mut_map.clj#L44\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.primitive-invoke.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.primitive-invoke documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ed\"><div class=\"inner\"><span>-&gt;d</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edd\"><div class=\"inner\"><span>-&gt;dd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddd\"><div class=\"inner\"><span>-&gt;ddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddd\"><div class=\"inner\"><span>-&gt;dddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddddd\"><div class=\"inner\"><span>-&gt;ddddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddddl\"><div class=\"inner\"><span>-&gt;ddddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddddo\"><div class=\"inner\"><span>-&gt;ddddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddl\"><div class=\"inner\"><span>-&gt;dddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddld\"><div class=\"inner\"><span>-&gt;dddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddll\"><div class=\"inner\"><span>-&gt;dddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddlo\"><div class=\"inner\"><span>-&gt;dddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddo\"><div class=\"inner\"><span>-&gt;dddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddod\"><div class=\"inner\"><span>-&gt;dddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddol\"><div class=\"inner\"><span>-&gt;dddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edddoo\"><div class=\"inner\"><span>-&gt;dddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddl\"><div class=\"inner\"><span>-&gt;ddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddld\"><div class=\"inner\"><span>-&gt;ddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddldd\"><div class=\"inner\"><span>-&gt;ddldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddldl\"><div class=\"inner\"><span>-&gt;ddldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddldo\"><div class=\"inner\"><span>-&gt;ddldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddll\"><div class=\"inner\"><span>-&gt;ddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlld\"><div class=\"inner\"><span>-&gt;ddlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlll\"><div class=\"inner\"><span>-&gt;ddlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddllo\"><div class=\"inner\"><span>-&gt;ddllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlo\"><div class=\"inner\"><span>-&gt;ddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlod\"><div class=\"inner\"><span>-&gt;ddlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlol\"><div class=\"inner\"><span>-&gt;ddlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddloo\"><div class=\"inner\"><span>-&gt;ddloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddo\"><div class=\"inner\"><span>-&gt;ddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddod\"><div class=\"inner\"><span>-&gt;ddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddodd\"><div class=\"inner\"><span>-&gt;ddodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddodl\"><div class=\"inner\"><span>-&gt;ddodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddodo\"><div class=\"inner\"><span>-&gt;ddodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddol\"><div class=\"inner\"><span>-&gt;ddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddold\"><div class=\"inner\"><span>-&gt;ddold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddoll\"><div class=\"inner\"><span>-&gt;ddoll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddolo\"><div class=\"inner\"><span>-&gt;ddolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddoo\"><div class=\"inner\"><span>-&gt;ddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddood\"><div class=\"inner\"><span>-&gt;ddood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddool\"><div class=\"inner\"><span>-&gt;ddool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eddooo\"><div class=\"inner\"><span>-&gt;ddooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edl\"><div class=\"inner\"><span>-&gt;dl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edld\"><div class=\"inner\"><span>-&gt;dld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldd\"><div class=\"inner\"><span>-&gt;dldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlddd\"><div class=\"inner\"><span>-&gt;dlddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlddl\"><div class=\"inner\"><span>-&gt;dlddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlddo\"><div class=\"inner\"><span>-&gt;dlddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldl\"><div class=\"inner\"><span>-&gt;dldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldld\"><div class=\"inner\"><span>-&gt;dldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldll\"><div class=\"inner\"><span>-&gt;dldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldlo\"><div class=\"inner\"><span>-&gt;dldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldo\"><div class=\"inner\"><span>-&gt;dldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldod\"><div class=\"inner\"><span>-&gt;dldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldol\"><div class=\"inner\"><span>-&gt;dldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edldoo\"><div class=\"inner\"><span>-&gt;dldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edll\"><div class=\"inner\"><span>-&gt;dll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlld\"><div class=\"inner\"><span>-&gt;dlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlldd\"><div class=\"inner\"><span>-&gt;dlldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlldl\"><div class=\"inner\"><span>-&gt;dlldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlldo\"><div class=\"inner\"><span>-&gt;dlldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlll\"><div class=\"inner\"><span>-&gt;dlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edllld\"><div class=\"inner\"><span>-&gt;dllld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edllll\"><div class=\"inner\"><span>-&gt;dllll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlllo\"><div class=\"inner\"><span>-&gt;dlllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edllo\"><div class=\"inner\"><span>-&gt;dllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edllod\"><div class=\"inner\"><span>-&gt;dllod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edllol\"><div class=\"inner\"><span>-&gt;dllol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlloo\"><div class=\"inner\"><span>-&gt;dlloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlo\"><div class=\"inner\"><span>-&gt;dlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlod\"><div class=\"inner\"><span>-&gt;dlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlodd\"><div class=\"inner\"><span>-&gt;dlodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlodl\"><div class=\"inner\"><span>-&gt;dlodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlodo\"><div class=\"inner\"><span>-&gt;dlodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlol\"><div class=\"inner\"><span>-&gt;dlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlold\"><div class=\"inner\"><span>-&gt;dlold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edloll\"><div class=\"inner\"><span>-&gt;dloll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlolo\"><div class=\"inner\"><span>-&gt;dlolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edloo\"><div class=\"inner\"><span>-&gt;dloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlood\"><div class=\"inner\"><span>-&gt;dlood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlool\"><div class=\"inner\"><span>-&gt;dlool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edlooo\"><div class=\"inner\"><span>-&gt;dlooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edo\"><div class=\"inner\"><span>-&gt;do</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edod\"><div class=\"inner\"><span>-&gt;dod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodd\"><div class=\"inner\"><span>-&gt;dodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoddd\"><div class=\"inner\"><span>-&gt;doddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoddl\"><div class=\"inner\"><span>-&gt;doddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoddo\"><div class=\"inner\"><span>-&gt;doddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodl\"><div class=\"inner\"><span>-&gt;dodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodld\"><div class=\"inner\"><span>-&gt;dodld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodll\"><div class=\"inner\"><span>-&gt;dodll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodlo\"><div class=\"inner\"><span>-&gt;dodlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodo\"><div class=\"inner\"><span>-&gt;dodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodod\"><div class=\"inner\"><span>-&gt;dodod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodol\"><div class=\"inner\"><span>-&gt;dodol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edodoo\"><div class=\"inner\"><span>-&gt;dodoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edol\"><div class=\"inner\"><span>-&gt;dol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edold\"><div class=\"inner\"><span>-&gt;dold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoldd\"><div class=\"inner\"><span>-&gt;doldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoldl\"><div class=\"inner\"><span>-&gt;doldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoldo\"><div class=\"inner\"><span>-&gt;doldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoll\"><div class=\"inner\"><span>-&gt;doll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edolld\"><div class=\"inner\"><span>-&gt;dolld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edolll\"><div class=\"inner\"><span>-&gt;dolll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edollo\"><div class=\"inner\"><span>-&gt;dollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edolo\"><div class=\"inner\"><span>-&gt;dolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edolod\"><div class=\"inner\"><span>-&gt;dolod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edolol\"><div class=\"inner\"><span>-&gt;dolol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoloo\"><div class=\"inner\"><span>-&gt;doloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoo\"><div class=\"inner\"><span>-&gt;doo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edood\"><div class=\"inner\"><span>-&gt;dood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoodd\"><div class=\"inner\"><span>-&gt;doodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoodl\"><div class=\"inner\"><span>-&gt;doodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoodo\"><div class=\"inner\"><span>-&gt;doodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edool\"><div class=\"inner\"><span>-&gt;dool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoold\"><div class=\"inner\"><span>-&gt;doold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edooll\"><div class=\"inner\"><span>-&gt;dooll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoolo\"><div class=\"inner\"><span>-&gt;doolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edooo\"><div class=\"inner\"><span>-&gt;dooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoood\"><div class=\"inner\"><span>-&gt;doood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoool\"><div class=\"inner\"><span>-&gt;doool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Edoooo\"><div class=\"inner\"><span>-&gt;doooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3El\"><div class=\"inner\"><span>-&gt;l</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eld\"><div class=\"inner\"><span>-&gt;ld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldd\"><div class=\"inner\"><span>-&gt;ldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddd\"><div class=\"inner\"><span>-&gt;lddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldddd\"><div class=\"inner\"><span>-&gt;ldddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldddl\"><div class=\"inner\"><span>-&gt;ldddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldddo\"><div class=\"inner\"><span>-&gt;ldddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddl\"><div class=\"inner\"><span>-&gt;lddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddld\"><div class=\"inner\"><span>-&gt;lddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddll\"><div class=\"inner\"><span>-&gt;lddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddlo\"><div class=\"inner\"><span>-&gt;lddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddo\"><div class=\"inner\"><span>-&gt;lddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddod\"><div class=\"inner\"><span>-&gt;lddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddol\"><div class=\"inner\"><span>-&gt;lddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elddoo\"><div class=\"inner\"><span>-&gt;lddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldl\"><div class=\"inner\"><span>-&gt;ldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldld\"><div class=\"inner\"><span>-&gt;ldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldldd\"><div class=\"inner\"><span>-&gt;ldldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldldl\"><div class=\"inner\"><span>-&gt;ldldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldldo\"><div class=\"inner\"><span>-&gt;ldldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldll\"><div class=\"inner\"><span>-&gt;ldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlld\"><div class=\"inner\"><span>-&gt;ldlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlll\"><div class=\"inner\"><span>-&gt;ldlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldllo\"><div class=\"inner\"><span>-&gt;ldllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlo\"><div class=\"inner\"><span>-&gt;ldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlod\"><div class=\"inner\"><span>-&gt;ldlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlol\"><div class=\"inner\"><span>-&gt;ldlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldloo\"><div class=\"inner\"><span>-&gt;ldloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldo\"><div class=\"inner\"><span>-&gt;ldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldod\"><div class=\"inner\"><span>-&gt;ldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldodd\"><div class=\"inner\"><span>-&gt;ldodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldodl\"><div class=\"inner\"><span>-&gt;ldodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldodo\"><div class=\"inner\"><span>-&gt;ldodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldol\"><div class=\"inner\"><span>-&gt;ldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldold\"><div class=\"inner\"><span>-&gt;ldold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldoll\"><div class=\"inner\"><span>-&gt;ldoll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldolo\"><div class=\"inner\"><span>-&gt;ldolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldoo\"><div class=\"inner\"><span>-&gt;ldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldood\"><div class=\"inner\"><span>-&gt;ldood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldool\"><div class=\"inner\"><span>-&gt;ldool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eldooo\"><div class=\"inner\"><span>-&gt;ldooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ell\"><div class=\"inner\"><span>-&gt;ll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elld\"><div class=\"inner\"><span>-&gt;lld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldd\"><div class=\"inner\"><span>-&gt;lldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellddd\"><div class=\"inner\"><span>-&gt;llddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellddl\"><div class=\"inner\"><span>-&gt;llddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellddo\"><div class=\"inner\"><span>-&gt;llddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldl\"><div class=\"inner\"><span>-&gt;lldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldld\"><div class=\"inner\"><span>-&gt;lldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldll\"><div class=\"inner\"><span>-&gt;lldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldlo\"><div class=\"inner\"><span>-&gt;lldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldo\"><div class=\"inner\"><span>-&gt;lldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldod\"><div class=\"inner\"><span>-&gt;lldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldol\"><div class=\"inner\"><span>-&gt;lldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elldoo\"><div class=\"inner\"><span>-&gt;lldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elll\"><div class=\"inner\"><span>-&gt;lll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellld\"><div class=\"inner\"><span>-&gt;llld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellldd\"><div class=\"inner\"><span>-&gt;llldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellldl\"><div class=\"inner\"><span>-&gt;llldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellldo\"><div class=\"inner\"><span>-&gt;llldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellll\"><div class=\"inner\"><span>-&gt;llll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elllld\"><div class=\"inner\"><span>-&gt;lllld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elllll\"><div class=\"inner\"><span>-&gt;lllll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellllo\"><div class=\"inner\"><span>-&gt;llllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elllo\"><div class=\"inner\"><span>-&gt;lllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elllod\"><div class=\"inner\"><span>-&gt;lllod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elllol\"><div class=\"inner\"><span>-&gt;lllol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellloo\"><div class=\"inner\"><span>-&gt;llloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ello\"><div class=\"inner\"><span>-&gt;llo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellod\"><div class=\"inner\"><span>-&gt;llod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellodd\"><div class=\"inner\"><span>-&gt;llodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellodl\"><div class=\"inner\"><span>-&gt;llodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellodo\"><div class=\"inner\"><span>-&gt;llodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellol\"><div class=\"inner\"><span>-&gt;llol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellold\"><div class=\"inner\"><span>-&gt;llold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elloll\"><div class=\"inner\"><span>-&gt;lloll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellolo\"><div class=\"inner\"><span>-&gt;llolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elloo\"><div class=\"inner\"><span>-&gt;lloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellood\"><div class=\"inner\"><span>-&gt;llood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellool\"><div class=\"inner\"><span>-&gt;llool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Ellooo\"><div class=\"inner\"><span>-&gt;llooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elo\"><div class=\"inner\"><span>-&gt;lo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elod\"><div class=\"inner\"><span>-&gt;lod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodd\"><div class=\"inner\"><span>-&gt;lodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloddd\"><div class=\"inner\"><span>-&gt;loddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloddl\"><div class=\"inner\"><span>-&gt;loddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloddo\"><div class=\"inner\"><span>-&gt;loddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodl\"><div class=\"inner\"><span>-&gt;lodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodld\"><div class=\"inner\"><span>-&gt;lodld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodll\"><div class=\"inner\"><span>-&gt;lodll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodlo\"><div class=\"inner\"><span>-&gt;lodlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodo\"><div class=\"inner\"><span>-&gt;lodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodod\"><div class=\"inner\"><span>-&gt;lodod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodol\"><div class=\"inner\"><span>-&gt;lodol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elodoo\"><div class=\"inner\"><span>-&gt;lodoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elol\"><div class=\"inner\"><span>-&gt;lol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elold\"><div class=\"inner\"><span>-&gt;lold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloldd\"><div class=\"inner\"><span>-&gt;loldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloldl\"><div class=\"inner\"><span>-&gt;loldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloldo\"><div class=\"inner\"><span>-&gt;loldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloll\"><div class=\"inner\"><span>-&gt;loll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elolld\"><div class=\"inner\"><span>-&gt;lolld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elolll\"><div class=\"inner\"><span>-&gt;lolll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elollo\"><div class=\"inner\"><span>-&gt;lollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elolo\"><div class=\"inner\"><span>-&gt;lolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elolod\"><div class=\"inner\"><span>-&gt;lolod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elolol\"><div class=\"inner\"><span>-&gt;lolol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloloo\"><div class=\"inner\"><span>-&gt;loloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloo\"><div class=\"inner\"><span>-&gt;loo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elood\"><div class=\"inner\"><span>-&gt;lood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloodd\"><div class=\"inner\"><span>-&gt;loodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloodl\"><div class=\"inner\"><span>-&gt;loodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloodo\"><div class=\"inner\"><span>-&gt;loodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elool\"><div class=\"inner\"><span>-&gt;lool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloold\"><div class=\"inner\"><span>-&gt;loold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elooll\"><div class=\"inner\"><span>-&gt;looll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloolo\"><div class=\"inner\"><span>-&gt;loolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Elooo\"><div class=\"inner\"><span>-&gt;looo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloood\"><div class=\"inner\"><span>-&gt;loood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloool\"><div class=\"inner\"><span>-&gt;loool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eloooo\"><div class=\"inner\"><span>-&gt;loooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eod\"><div class=\"inner\"><span>-&gt;od</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodd\"><div class=\"inner\"><span>-&gt;odd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddd\"><div class=\"inner\"><span>-&gt;oddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodddd\"><div class=\"inner\"><span>-&gt;odddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodddl\"><div class=\"inner\"><span>-&gt;odddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodddo\"><div class=\"inner\"><span>-&gt;odddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddl\"><div class=\"inner\"><span>-&gt;oddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddld\"><div class=\"inner\"><span>-&gt;oddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddll\"><div class=\"inner\"><span>-&gt;oddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddlo\"><div class=\"inner\"><span>-&gt;oddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddo\"><div class=\"inner\"><span>-&gt;oddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddod\"><div class=\"inner\"><span>-&gt;oddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddol\"><div class=\"inner\"><span>-&gt;oddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddoo\"><div class=\"inner\"><span>-&gt;oddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodl\"><div class=\"inner\"><span>-&gt;odl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodld\"><div class=\"inner\"><span>-&gt;odld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodldd\"><div class=\"inner\"><span>-&gt;odldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodldl\"><div class=\"inner\"><span>-&gt;odldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodldo\"><div class=\"inner\"><span>-&gt;odldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodll\"><div class=\"inner\"><span>-&gt;odll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlld\"><div class=\"inner\"><span>-&gt;odlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlll\"><div class=\"inner\"><span>-&gt;odlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodllo\"><div class=\"inner\"><span>-&gt;odllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlo\"><div class=\"inner\"><span>-&gt;odlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlod\"><div class=\"inner\"><span>-&gt;odlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlol\"><div class=\"inner\"><span>-&gt;odlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodloo\"><div class=\"inner\"><span>-&gt;odloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodo\"><div class=\"inner\"><span>-&gt;odo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodod\"><div class=\"inner\"><span>-&gt;odod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eododd\"><div class=\"inner\"><span>-&gt;ododd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eododl\"><div class=\"inner\"><span>-&gt;ododl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eododo\"><div class=\"inner\"><span>-&gt;ododo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodol\"><div class=\"inner\"><span>-&gt;odol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodold\"><div class=\"inner\"><span>-&gt;odold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodoll\"><div class=\"inner\"><span>-&gt;odoll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodolo\"><div class=\"inner\"><span>-&gt;odolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodoo\"><div class=\"inner\"><span>-&gt;odoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodood\"><div class=\"inner\"><span>-&gt;odood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodool\"><div class=\"inner\"><span>-&gt;odool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eodooo\"><div class=\"inner\"><span>-&gt;odooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eol\"><div class=\"inner\"><span>-&gt;ol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eold\"><div class=\"inner\"><span>-&gt;old</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldd\"><div class=\"inner\"><span>-&gt;oldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolddd\"><div class=\"inner\"><span>-&gt;olddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolddl\"><div class=\"inner\"><span>-&gt;olddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolddo\"><div class=\"inner\"><span>-&gt;olddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldl\"><div class=\"inner\"><span>-&gt;oldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldld\"><div class=\"inner\"><span>-&gt;oldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldll\"><div class=\"inner\"><span>-&gt;oldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldlo\"><div class=\"inner\"><span>-&gt;oldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldo\"><div class=\"inner\"><span>-&gt;oldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldod\"><div class=\"inner\"><span>-&gt;oldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldol\"><div class=\"inner\"><span>-&gt;oldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldoo\"><div class=\"inner\"><span>-&gt;oldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoll\"><div class=\"inner\"><span>-&gt;oll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolld\"><div class=\"inner\"><span>-&gt;olld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolldd\"><div class=\"inner\"><span>-&gt;olldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolldl\"><div class=\"inner\"><span>-&gt;olldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolldo\"><div class=\"inner\"><span>-&gt;olldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolll\"><div class=\"inner\"><span>-&gt;olll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eollld\"><div class=\"inner\"><span>-&gt;ollld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eollll\"><div class=\"inner\"><span>-&gt;ollll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolllo\"><div class=\"inner\"><span>-&gt;olllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eollo\"><div class=\"inner\"><span>-&gt;ollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eollod\"><div class=\"inner\"><span>-&gt;ollod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eollol\"><div class=\"inner\"><span>-&gt;ollol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolloo\"><div class=\"inner\"><span>-&gt;olloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolo\"><div class=\"inner\"><span>-&gt;olo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolod\"><div class=\"inner\"><span>-&gt;olod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolodd\"><div class=\"inner\"><span>-&gt;olodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolodl\"><div class=\"inner\"><span>-&gt;olodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolodo\"><div class=\"inner\"><span>-&gt;olodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolol\"><div class=\"inner\"><span>-&gt;olol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolold\"><div class=\"inner\"><span>-&gt;olold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eololl\"><div class=\"inner\"><span>-&gt;ololl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eololo\"><div class=\"inner\"><span>-&gt;ololo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoloo\"><div class=\"inner\"><span>-&gt;oloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolood\"><div class=\"inner\"><span>-&gt;olood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolool\"><div class=\"inner\"><span>-&gt;olool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eolooo\"><div class=\"inner\"><span>-&gt;olooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eood\"><div class=\"inner\"><span>-&gt;ood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodd\"><div class=\"inner\"><span>-&gt;oodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooddd\"><div class=\"inner\"><span>-&gt;ooddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooddl\"><div class=\"inner\"><span>-&gt;ooddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooddo\"><div class=\"inner\"><span>-&gt;ooddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodl\"><div class=\"inner\"><span>-&gt;oodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodld\"><div class=\"inner\"><span>-&gt;oodld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodll\"><div class=\"inner\"><span>-&gt;oodll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodlo\"><div class=\"inner\"><span>-&gt;oodlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodo\"><div class=\"inner\"><span>-&gt;oodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodod\"><div class=\"inner\"><span>-&gt;oodod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodol\"><div class=\"inner\"><span>-&gt;oodol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodoo\"><div class=\"inner\"><span>-&gt;oodoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eool\"><div class=\"inner\"><span>-&gt;ool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoold\"><div class=\"inner\"><span>-&gt;oold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooldd\"><div class=\"inner\"><span>-&gt;ooldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooldl\"><div class=\"inner\"><span>-&gt;ooldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooldo\"><div class=\"inner\"><span>-&gt;ooldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooll\"><div class=\"inner\"><span>-&gt;ooll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolld\"><div class=\"inner\"><span>-&gt;oolld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolll\"><div class=\"inner\"><span>-&gt;oolll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoollo\"><div class=\"inner\"><span>-&gt;oollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolo\"><div class=\"inner\"><span>-&gt;oolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolod\"><div class=\"inner\"><span>-&gt;oolod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolol\"><div class=\"inner\"><span>-&gt;oolol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooloo\"><div class=\"inner\"><span>-&gt;ooloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoood\"><div class=\"inner\"><span>-&gt;oood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooodd\"><div class=\"inner\"><span>-&gt;ooodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooodl\"><div class=\"inner\"><span>-&gt;ooodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooodo\"><div class=\"inner\"><span>-&gt;ooodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoool\"><div class=\"inner\"><span>-&gt;oool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooold\"><div class=\"inner\"><span>-&gt;ooold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eoooll\"><div class=\"inner\"><span>-&gt;oooll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooolo\"><div class=\"inner\"><span>-&gt;ooolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooood\"><div class=\"inner\"><span>-&gt;ooood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var--.3Eooool\"><div class=\"inner\"><span>-&gt;ooool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-d\"><div class=\"inner\"><span>d</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dd\"><div class=\"inner\"><span>dd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddd\"><div class=\"inner\"><span>ddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddd\"><div class=\"inner\"><span>dddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddddd\"><div class=\"inner\"><span>ddddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddddl\"><div class=\"inner\"><span>ddddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddddo\"><div class=\"inner\"><span>ddddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddl\"><div class=\"inner\"><span>dddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddld\"><div class=\"inner\"><span>dddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddll\"><div class=\"inner\"><span>dddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddlo\"><div class=\"inner\"><span>dddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddo\"><div class=\"inner\"><span>dddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddod\"><div class=\"inner\"><span>dddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddol\"><div class=\"inner\"><span>dddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dddoo\"><div class=\"inner\"><span>dddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddl\"><div class=\"inner\"><span>ddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddld\"><div class=\"inner\"><span>ddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddldd\"><div class=\"inner\"><span>ddldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddldl\"><div class=\"inner\"><span>ddldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddldo\"><div class=\"inner\"><span>ddldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddll\"><div class=\"inner\"><span>ddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddlld\"><div class=\"inner\"><span>ddlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddlll\"><div class=\"inner\"><span>ddlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddllo\"><div class=\"inner\"><span>ddllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddlo\"><div class=\"inner\"><span>ddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddlod\"><div class=\"inner\"><span>ddlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddlol\"><div class=\"inner\"><span>ddlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddloo\"><div class=\"inner\"><span>ddloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddo\"><div class=\"inner\"><span>ddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddod\"><div class=\"inner\"><span>ddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddodd\"><div class=\"inner\"><span>ddodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddodl\"><div class=\"inner\"><span>ddodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddodo\"><div class=\"inner\"><span>ddodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddol\"><div class=\"inner\"><span>ddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddold\"><div class=\"inner\"><span>ddold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddoll\"><div class=\"inner\"><span>ddoll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddolo\"><div class=\"inner\"><span>ddolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddoo\"><div class=\"inner\"><span>ddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddood\"><div class=\"inner\"><span>ddood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddool\"><div class=\"inner\"><span>ddool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ddooo\"><div class=\"inner\"><span>ddooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dl\"><div class=\"inner\"><span>dl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dld\"><div class=\"inner\"><span>dld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldd\"><div class=\"inner\"><span>dldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlddd\"><div class=\"inner\"><span>dlddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlddl\"><div class=\"inner\"><span>dlddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlddo\"><div class=\"inner\"><span>dlddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldl\"><div class=\"inner\"><span>dldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldld\"><div class=\"inner\"><span>dldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldll\"><div class=\"inner\"><span>dldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldlo\"><div class=\"inner\"><span>dldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldo\"><div class=\"inner\"><span>dldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldod\"><div class=\"inner\"><span>dldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldol\"><div class=\"inner\"><span>dldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dldoo\"><div class=\"inner\"><span>dldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dll\"><div class=\"inner\"><span>dll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlld\"><div class=\"inner\"><span>dlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlldd\"><div class=\"inner\"><span>dlldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlldl\"><div class=\"inner\"><span>dlldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlldo\"><div class=\"inner\"><span>dlldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlll\"><div class=\"inner\"><span>dlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dllld\"><div class=\"inner\"><span>dllld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dllll\"><div class=\"inner\"><span>dllll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlllo\"><div class=\"inner\"><span>dlllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dllo\"><div class=\"inner\"><span>dllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dllod\"><div class=\"inner\"><span>dllod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dllol\"><div class=\"inner\"><span>dllol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlloo\"><div class=\"inner\"><span>dlloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlo\"><div class=\"inner\"><span>dlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlod\"><div class=\"inner\"><span>dlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlodd\"><div class=\"inner\"><span>dlodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlodl\"><div class=\"inner\"><span>dlodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlodo\"><div class=\"inner\"><span>dlodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlol\"><div class=\"inner\"><span>dlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlold\"><div class=\"inner\"><span>dlold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dloll\"><div class=\"inner\"><span>dloll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlolo\"><div class=\"inner\"><span>dlolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dloo\"><div class=\"inner\"><span>dloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlood\"><div class=\"inner\"><span>dlood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlool\"><div class=\"inner\"><span>dlool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dlooo\"><div class=\"inner\"><span>dlooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-do\"><div class=\"inner\"><span>do</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dod\"><div class=\"inner\"><span>dod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodd\"><div class=\"inner\"><span>dodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doddd\"><div class=\"inner\"><span>doddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doddl\"><div class=\"inner\"><span>doddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doddo\"><div class=\"inner\"><span>doddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodl\"><div class=\"inner\"><span>dodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodld\"><div class=\"inner\"><span>dodld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodll\"><div class=\"inner\"><span>dodll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodlo\"><div class=\"inner\"><span>dodlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodo\"><div class=\"inner\"><span>dodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodod\"><div class=\"inner\"><span>dodod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodol\"><div class=\"inner\"><span>dodol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dodoo\"><div class=\"inner\"><span>dodoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dol\"><div class=\"inner\"><span>dol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dold\"><div class=\"inner\"><span>dold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doldd\"><div class=\"inner\"><span>doldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doldl\"><div class=\"inner\"><span>doldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doldo\"><div class=\"inner\"><span>doldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doll\"><div class=\"inner\"><span>doll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dolld\"><div class=\"inner\"><span>dolld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dolll\"><div class=\"inner\"><span>dolll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dollo\"><div class=\"inner\"><span>dollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dolo\"><div class=\"inner\"><span>dolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dolod\"><div class=\"inner\"><span>dolod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dolol\"><div class=\"inner\"><span>dolol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doloo\"><div class=\"inner\"><span>doloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doo\"><div class=\"inner\"><span>doo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dood\"><div class=\"inner\"><span>dood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doodd\"><div class=\"inner\"><span>doodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doodl\"><div class=\"inner\"><span>doodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doodo\"><div class=\"inner\"><span>doodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dool\"><div class=\"inner\"><span>dool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doold\"><div class=\"inner\"><span>doold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dooll\"><div class=\"inner\"><span>dooll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doolo\"><div class=\"inner\"><span>doolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-dooo\"><div class=\"inner\"><span>dooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doood\"><div class=\"inner\"><span>doood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doool\"><div class=\"inner\"><span>doool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-doooo\"><div class=\"inner\"><span>doooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-l\"><div class=\"inner\"><span>l</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ld\"><div class=\"inner\"><span>ld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldd\"><div class=\"inner\"><span>ldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddd\"><div class=\"inner\"><span>lddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldddd\"><div class=\"inner\"><span>ldddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldddl\"><div class=\"inner\"><span>ldddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldddo\"><div class=\"inner\"><span>ldddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddl\"><div class=\"inner\"><span>lddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddld\"><div class=\"inner\"><span>lddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddll\"><div class=\"inner\"><span>lddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddlo\"><div class=\"inner\"><span>lddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddo\"><div class=\"inner\"><span>lddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddod\"><div class=\"inner\"><span>lddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddol\"><div class=\"inner\"><span>lddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lddoo\"><div class=\"inner\"><span>lddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldl\"><div class=\"inner\"><span>ldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldld\"><div class=\"inner\"><span>ldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldldd\"><div class=\"inner\"><span>ldldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldldl\"><div class=\"inner\"><span>ldldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldldo\"><div class=\"inner\"><span>ldldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldll\"><div class=\"inner\"><span>ldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldlld\"><div class=\"inner\"><span>ldlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldlll\"><div class=\"inner\"><span>ldlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldllo\"><div class=\"inner\"><span>ldllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldlo\"><div class=\"inner\"><span>ldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldlod\"><div class=\"inner\"><span>ldlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldlol\"><div class=\"inner\"><span>ldlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldloo\"><div class=\"inner\"><span>ldloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldo\"><div class=\"inner\"><span>ldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldod\"><div class=\"inner\"><span>ldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldodd\"><div class=\"inner\"><span>ldodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldodl\"><div class=\"inner\"><span>ldodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldodo\"><div class=\"inner\"><span>ldodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldol\"><div class=\"inner\"><span>ldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldold\"><div class=\"inner\"><span>ldold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldoll\"><div class=\"inner\"><span>ldoll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldolo\"><div class=\"inner\"><span>ldolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldoo\"><div class=\"inner\"><span>ldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldood\"><div class=\"inner\"><span>ldood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldool\"><div class=\"inner\"><span>ldool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ldooo\"><div class=\"inner\"><span>ldooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ll\"><div class=\"inner\"><span>ll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lld\"><div class=\"inner\"><span>lld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldd\"><div class=\"inner\"><span>lldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llddd\"><div class=\"inner\"><span>llddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llddl\"><div class=\"inner\"><span>llddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llddo\"><div class=\"inner\"><span>llddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldl\"><div class=\"inner\"><span>lldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldld\"><div class=\"inner\"><span>lldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldll\"><div class=\"inner\"><span>lldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldlo\"><div class=\"inner\"><span>lldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldo\"><div class=\"inner\"><span>lldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldod\"><div class=\"inner\"><span>lldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldol\"><div class=\"inner\"><span>lldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lldoo\"><div class=\"inner\"><span>lldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lll\"><div class=\"inner\"><span>lll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llld\"><div class=\"inner\"><span>llld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llldd\"><div class=\"inner\"><span>llldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llldl\"><div class=\"inner\"><span>llldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llldo\"><div class=\"inner\"><span>llldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llll\"><div class=\"inner\"><span>llll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lllld\"><div class=\"inner\"><span>lllld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lllll\"><div class=\"inner\"><span>lllll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llllo\"><div class=\"inner\"><span>llllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lllo\"><div class=\"inner\"><span>lllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lllod\"><div class=\"inner\"><span>lllod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lllol\"><div class=\"inner\"><span>lllol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llloo\"><div class=\"inner\"><span>llloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llo\"><div class=\"inner\"><span>llo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llod\"><div class=\"inner\"><span>llod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llodd\"><div class=\"inner\"><span>llodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llodl\"><div class=\"inner\"><span>llodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llodo\"><div class=\"inner\"><span>llodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llol\"><div class=\"inner\"><span>llol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llold\"><div class=\"inner\"><span>llold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lloll\"><div class=\"inner\"><span>lloll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llolo\"><div class=\"inner\"><span>llolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lloo\"><div class=\"inner\"><span>lloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llood\"><div class=\"inner\"><span>llood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llool\"><div class=\"inner\"><span>llool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-llooo\"><div class=\"inner\"><span>llooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lo\"><div class=\"inner\"><span>lo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lod\"><div class=\"inner\"><span>lod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodd\"><div class=\"inner\"><span>lodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loddd\"><div class=\"inner\"><span>loddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loddl\"><div class=\"inner\"><span>loddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loddo\"><div class=\"inner\"><span>loddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodl\"><div class=\"inner\"><span>lodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodld\"><div class=\"inner\"><span>lodld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodll\"><div class=\"inner\"><span>lodll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodlo\"><div class=\"inner\"><span>lodlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodo\"><div class=\"inner\"><span>lodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodod\"><div class=\"inner\"><span>lodod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodol\"><div class=\"inner\"><span>lodol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lodoo\"><div class=\"inner\"><span>lodoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lol\"><div class=\"inner\"><span>lol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lold\"><div class=\"inner\"><span>lold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loldd\"><div class=\"inner\"><span>loldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loldl\"><div class=\"inner\"><span>loldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loldo\"><div class=\"inner\"><span>loldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loll\"><div class=\"inner\"><span>loll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lolld\"><div class=\"inner\"><span>lolld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lolll\"><div class=\"inner\"><span>lolll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lollo\"><div class=\"inner\"><span>lollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lolo\"><div class=\"inner\"><span>lolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lolod\"><div class=\"inner\"><span>lolod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lolol\"><div class=\"inner\"><span>lolol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loloo\"><div class=\"inner\"><span>loloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loo\"><div class=\"inner\"><span>loo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lood\"><div class=\"inner\"><span>lood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loodd\"><div class=\"inner\"><span>loodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loodl\"><div class=\"inner\"><span>loodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loodo\"><div class=\"inner\"><span>loodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-lool\"><div class=\"inner\"><span>lool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loold\"><div class=\"inner\"><span>loold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-looll\"><div class=\"inner\"><span>looll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loolo\"><div class=\"inner\"><span>loolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-looo\"><div class=\"inner\"><span>looo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loood\"><div class=\"inner\"><span>loood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loool\"><div class=\"inner\"><span>loool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-loooo\"><div class=\"inner\"><span>loooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-od\"><div class=\"inner\"><span>od</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odd\"><div class=\"inner\"><span>odd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddd\"><div class=\"inner\"><span>oddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odddd\"><div class=\"inner\"><span>odddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odddl\"><div class=\"inner\"><span>odddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odddo\"><div class=\"inner\"><span>odddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddl\"><div class=\"inner\"><span>oddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddld\"><div class=\"inner\"><span>oddld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddll\"><div class=\"inner\"><span>oddll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddlo\"><div class=\"inner\"><span>oddlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddo\"><div class=\"inner\"><span>oddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddod\"><div class=\"inner\"><span>oddod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddol\"><div class=\"inner\"><span>oddol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oddoo\"><div class=\"inner\"><span>oddoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odl\"><div class=\"inner\"><span>odl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odld\"><div class=\"inner\"><span>odld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odldd\"><div class=\"inner\"><span>odldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odldl\"><div class=\"inner\"><span>odldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odldo\"><div class=\"inner\"><span>odldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odll\"><div class=\"inner\"><span>odll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odlld\"><div class=\"inner\"><span>odlld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odlll\"><div class=\"inner\"><span>odlll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odllo\"><div class=\"inner\"><span>odllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odlo\"><div class=\"inner\"><span>odlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odlod\"><div class=\"inner\"><span>odlod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odlol\"><div class=\"inner\"><span>odlol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odloo\"><div class=\"inner\"><span>odloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odo\"><div class=\"inner\"><span>odo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odod\"><div class=\"inner\"><span>odod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ododd\"><div class=\"inner\"><span>ododd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ododl\"><div class=\"inner\"><span>ododl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ododo\"><div class=\"inner\"><span>ododo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odol\"><div class=\"inner\"><span>odol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odold\"><div class=\"inner\"><span>odold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odoll\"><div class=\"inner\"><span>odoll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odolo\"><div class=\"inner\"><span>odolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odoo\"><div class=\"inner\"><span>odoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odood\"><div class=\"inner\"><span>odood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odool\"><div class=\"inner\"><span>odool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-odooo\"><div class=\"inner\"><span>odooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ol\"><div class=\"inner\"><span>ol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-old\"><div class=\"inner\"><span>old</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldd\"><div class=\"inner\"><span>oldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olddd\"><div class=\"inner\"><span>olddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olddl\"><div class=\"inner\"><span>olddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olddo\"><div class=\"inner\"><span>olddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldl\"><div class=\"inner\"><span>oldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldld\"><div class=\"inner\"><span>oldld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldll\"><div class=\"inner\"><span>oldll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldlo\"><div class=\"inner\"><span>oldlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldo\"><div class=\"inner\"><span>oldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldod\"><div class=\"inner\"><span>oldod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldol\"><div class=\"inner\"><span>oldol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oldoo\"><div class=\"inner\"><span>oldoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oll\"><div class=\"inner\"><span>oll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olld\"><div class=\"inner\"><span>olld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olldd\"><div class=\"inner\"><span>olldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olldl\"><div class=\"inner\"><span>olldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olldo\"><div class=\"inner\"><span>olldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olll\"><div class=\"inner\"><span>olll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ollld\"><div class=\"inner\"><span>ollld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ollll\"><div class=\"inner\"><span>ollll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olllo\"><div class=\"inner\"><span>olllo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ollo\"><div class=\"inner\"><span>ollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ollod\"><div class=\"inner\"><span>ollod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ollol\"><div class=\"inner\"><span>ollol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olloo\"><div class=\"inner\"><span>olloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olo\"><div class=\"inner\"><span>olo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olod\"><div class=\"inner\"><span>olod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olodd\"><div class=\"inner\"><span>olodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olodl\"><div class=\"inner\"><span>olodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olodo\"><div class=\"inner\"><span>olodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olol\"><div class=\"inner\"><span>olol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olold\"><div class=\"inner\"><span>olold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ololl\"><div class=\"inner\"><span>ololl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ololo\"><div class=\"inner\"><span>ololo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oloo\"><div class=\"inner\"><span>oloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olood\"><div class=\"inner\"><span>olood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olool\"><div class=\"inner\"><span>olool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-olooo\"><div class=\"inner\"><span>olooo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ood\"><div class=\"inner\"><span>ood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodd\"><div class=\"inner\"><span>oodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooddd\"><div class=\"inner\"><span>ooddd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooddl\"><div class=\"inner\"><span>ooddl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooddo\"><div class=\"inner\"><span>ooddo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodl\"><div class=\"inner\"><span>oodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodld\"><div class=\"inner\"><span>oodld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodll\"><div class=\"inner\"><span>oodll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodlo\"><div class=\"inner\"><span>oodlo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodo\"><div class=\"inner\"><span>oodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodod\"><div class=\"inner\"><span>oodod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodol\"><div class=\"inner\"><span>oodol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oodoo\"><div class=\"inner\"><span>oodoo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ool\"><div class=\"inner\"><span>ool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oold\"><div class=\"inner\"><span>oold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooldd\"><div class=\"inner\"><span>ooldd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooldl\"><div class=\"inner\"><span>ooldl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooldo\"><div class=\"inner\"><span>ooldo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooll\"><div class=\"inner\"><span>ooll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oolld\"><div class=\"inner\"><span>oolld</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oolll\"><div class=\"inner\"><span>oolll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oollo\"><div class=\"inner\"><span>oollo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oolo\"><div class=\"inner\"><span>oolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oolod\"><div class=\"inner\"><span>oolod</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oolol\"><div class=\"inner\"><span>oolol</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooloo\"><div class=\"inner\"><span>ooloo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oood\"><div class=\"inner\"><span>oood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooodd\"><div class=\"inner\"><span>ooodd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooodl\"><div class=\"inner\"><span>ooodl</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooodo\"><div class=\"inner\"><span>ooodo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oool\"><div class=\"inner\"><span>oool</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooold\"><div class=\"inner\"><span>ooold</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-oooll\"><div class=\"inner\"><span>oooll</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooolo\"><div class=\"inner\"><span>ooolo</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooood\"><div class=\"inner\"><span>ooood</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.primitive-invoke.html#var-ooool\"><div class=\"inner\"><span>ooool</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.primitive-invoke</h1><div class=\"doc\"><div class=\"markdown\"><p>For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions\nand this makes quite a difference in tight loops.  Often times, however, functions are passed by values\nor returned from if-statements and then you need to explicitly call the primitive overload - this makes\nthat pathway less verbose.  Functions must first be check-casted to their primitive types and then\ncalling them will use their primitive overloads avoiding all casting.</p>\n<pre><code class=\"language-clojure\">(defn doit [f x y]\n   (let [f (pi/-&gt;ddd f)]\n     (loop [x x y y]\n      (if (&lt; x y)\n        (recur (pi/ddd f x y) y)\n        x))))\n</code></pre>\n</div></div><div class=\"public anchor\" id=\"var--.3Ed\"><h3>-&gt;d</h3><div class=\"usage\"><code>(-&gt;d f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L23\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edd\"><h3>-&gt;dd</h3><div class=\"usage\"><code>(-&gt;dd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L71\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddd\"><h3>-&gt;ddd</h3><div class=\"usage\"><code>(-&gt;ddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L227\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddd\"><h3>-&gt;dddd</h3><div class=\"usage\"><code>(-&gt;dddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L707\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddddd\"><h3>-&gt;ddddd</h3><div class=\"usage\"><code>(-&gt;ddddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2159\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddddl\"><h3>-&gt;ddddl</h3><div class=\"usage\"><code>(-&gt;ddddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1673\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddddo\"><h3>-&gt;ddddo</h3><div class=\"usage\"><code>(-&gt;ddddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1187\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddl\"><h3>-&gt;dddl</h3><div class=\"usage\"><code>(-&gt;dddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L545\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddld\"><h3>-&gt;dddld</h3><div class=\"usage\"><code>(-&gt;dddld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2153\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddll\"><h3>-&gt;dddll</h3><div class=\"usage\"><code>(-&gt;dddll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1667\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddlo\"><h3>-&gt;dddlo</h3><div class=\"usage\"><code>(-&gt;dddlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1181\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddo\"><h3>-&gt;dddo</h3><div class=\"usage\"><code>(-&gt;dddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L383\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddod\"><h3>-&gt;dddod</h3><div class=\"usage\"><code>(-&gt;dddod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2147\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddol\"><h3>-&gt;dddol</h3><div class=\"usage\"><code>(-&gt;dddol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1661\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edddoo\"><h3>-&gt;dddoo</h3><div class=\"usage\"><code>(-&gt;dddoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1175\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddl\"><h3>-&gt;ddl</h3><div class=\"usage\"><code>(-&gt;ddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L173\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddld\"><h3>-&gt;ddld</h3><div class=\"usage\"><code>(-&gt;ddld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L701\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddldd\"><h3>-&gt;ddldd</h3><div class=\"usage\"><code>(-&gt;ddldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2141\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddldl\"><h3>-&gt;ddldl</h3><div class=\"usage\"><code>(-&gt;ddldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1655\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddldo\"><h3>-&gt;ddldo</h3><div class=\"usage\"><code>(-&gt;ddldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1169\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddll\"><h3>-&gt;ddll</h3><div class=\"usage\"><code>(-&gt;ddll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L539\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddlld\"><h3>-&gt;ddlld</h3><div class=\"usage\"><code>(-&gt;ddlld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2135\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddlll\"><h3>-&gt;ddlll</h3><div class=\"usage\"><code>(-&gt;ddlll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1649\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddllo\"><h3>-&gt;ddllo</h3><div class=\"usage\"><code>(-&gt;ddllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1163\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddlo\"><h3>-&gt;ddlo</h3><div class=\"usage\"><code>(-&gt;ddlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L377\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddlod\"><h3>-&gt;ddlod</h3><div class=\"usage\"><code>(-&gt;ddlod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2129\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddlol\"><h3>-&gt;ddlol</h3><div class=\"usage\"><code>(-&gt;ddlol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1643\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddloo\"><h3>-&gt;ddloo</h3><div class=\"usage\"><code>(-&gt;ddloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1157\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddo\"><h3>-&gt;ddo</h3><div class=\"usage\"><code>(-&gt;ddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L119\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddod\"><h3>-&gt;ddod</h3><div class=\"usage\"><code>(-&gt;ddod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L695\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddodd\"><h3>-&gt;ddodd</h3><div class=\"usage\"><code>(-&gt;ddodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2123\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddodl\"><h3>-&gt;ddodl</h3><div class=\"usage\"><code>(-&gt;ddodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1637\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddodo\"><h3>-&gt;ddodo</h3><div class=\"usage\"><code>(-&gt;ddodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1151\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddol\"><h3>-&gt;ddol</h3><div class=\"usage\"><code>(-&gt;ddol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L533\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddold\"><h3>-&gt;ddold</h3><div class=\"usage\"><code>(-&gt;ddold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2117\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddoll\"><h3>-&gt;ddoll</h3><div class=\"usage\"><code>(-&gt;ddoll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1631\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddolo\"><h3>-&gt;ddolo</h3><div class=\"usage\"><code>(-&gt;ddolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1145\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddoo\"><h3>-&gt;ddoo</h3><div class=\"usage\"><code>(-&gt;ddoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L371\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddood\"><h3>-&gt;ddood</h3><div class=\"usage\"><code>(-&gt;ddood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2111\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddool\"><h3>-&gt;ddool</h3><div class=\"usage\"><code>(-&gt;ddool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1625\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eddooo\"><h3>-&gt;ddooo</h3><div class=\"usage\"><code>(-&gt;ddooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1139\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edl\"><h3>-&gt;dl</h3><div class=\"usage\"><code>(-&gt;dl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L53\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edld\"><h3>-&gt;dld</h3><div class=\"usage\"><code>(-&gt;dld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L221\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldd\"><h3>-&gt;dldd</h3><div class=\"usage\"><code>(-&gt;dldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L689\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlddd\"><h3>-&gt;dlddd</h3><div class=\"usage\"><code>(-&gt;dlddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2105\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlddl\"><h3>-&gt;dlddl</h3><div class=\"usage\"><code>(-&gt;dlddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1619\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlddo\"><h3>-&gt;dlddo</h3><div class=\"usage\"><code>(-&gt;dlddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1133\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldl\"><h3>-&gt;dldl</h3><div class=\"usage\"><code>(-&gt;dldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L527\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldld\"><h3>-&gt;dldld</h3><div class=\"usage\"><code>(-&gt;dldld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2099\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldll\"><h3>-&gt;dldll</h3><div class=\"usage\"><code>(-&gt;dldll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1613\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldlo\"><h3>-&gt;dldlo</h3><div class=\"usage\"><code>(-&gt;dldlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1127\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldo\"><h3>-&gt;dldo</h3><div class=\"usage\"><code>(-&gt;dldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L365\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldod\"><h3>-&gt;dldod</h3><div class=\"usage\"><code>(-&gt;dldod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2093\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldol\"><h3>-&gt;dldol</h3><div class=\"usage\"><code>(-&gt;dldol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1607\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edldoo\"><h3>-&gt;dldoo</h3><div class=\"usage\"><code>(-&gt;dldoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1121\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edll\"><h3>-&gt;dll</h3><div class=\"usage\"><code>(-&gt;dll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L167\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlld\"><h3>-&gt;dlld</h3><div class=\"usage\"><code>(-&gt;dlld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L683\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlldd\"><h3>-&gt;dlldd</h3><div class=\"usage\"><code>(-&gt;dlldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2087\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlldl\"><h3>-&gt;dlldl</h3><div class=\"usage\"><code>(-&gt;dlldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1601\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlldo\"><h3>-&gt;dlldo</h3><div class=\"usage\"><code>(-&gt;dlldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1115\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlll\"><h3>-&gt;dlll</h3><div class=\"usage\"><code>(-&gt;dlll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L521\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edllld\"><h3>-&gt;dllld</h3><div class=\"usage\"><code>(-&gt;dllld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2081\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edllll\"><h3>-&gt;dllll</h3><div class=\"usage\"><code>(-&gt;dllll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1595\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlllo\"><h3>-&gt;dlllo</h3><div class=\"usage\"><code>(-&gt;dlllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1109\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edllo\"><h3>-&gt;dllo</h3><div class=\"usage\"><code>(-&gt;dllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L359\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edllod\"><h3>-&gt;dllod</h3><div class=\"usage\"><code>(-&gt;dllod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2075\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edllol\"><h3>-&gt;dllol</h3><div class=\"usage\"><code>(-&gt;dllol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1589\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlloo\"><h3>-&gt;dlloo</h3><div class=\"usage\"><code>(-&gt;dlloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1103\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlo\"><h3>-&gt;dlo</h3><div class=\"usage\"><code>(-&gt;dlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L113\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlod\"><h3>-&gt;dlod</h3><div class=\"usage\"><code>(-&gt;dlod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L677\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlodd\"><h3>-&gt;dlodd</h3><div class=\"usage\"><code>(-&gt;dlodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2069\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlodl\"><h3>-&gt;dlodl</h3><div class=\"usage\"><code>(-&gt;dlodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1583\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlodo\"><h3>-&gt;dlodo</h3><div class=\"usage\"><code>(-&gt;dlodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1097\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlol\"><h3>-&gt;dlol</h3><div class=\"usage\"><code>(-&gt;dlol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L515\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlold\"><h3>-&gt;dlold</h3><div class=\"usage\"><code>(-&gt;dlold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2063\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edloll\"><h3>-&gt;dloll</h3><div class=\"usage\"><code>(-&gt;dloll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1577\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlolo\"><h3>-&gt;dlolo</h3><div class=\"usage\"><code>(-&gt;dlolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1091\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edloo\"><h3>-&gt;dloo</h3><div class=\"usage\"><code>(-&gt;dloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L353\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlood\"><h3>-&gt;dlood</h3><div class=\"usage\"><code>(-&gt;dlood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2057\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlool\"><h3>-&gt;dlool</h3><div class=\"usage\"><code>(-&gt;dlool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1571\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edlooo\"><h3>-&gt;dlooo</h3><div class=\"usage\"><code>(-&gt;dlooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1085\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edo\"><h3>-&gt;do</h3><div class=\"usage\"><code>(-&gt;do f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L35\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edod\"><h3>-&gt;dod</h3><div class=\"usage\"><code>(-&gt;dod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L215\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodd\"><h3>-&gt;dodd</h3><div class=\"usage\"><code>(-&gt;dodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L671\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoddd\"><h3>-&gt;doddd</h3><div class=\"usage\"><code>(-&gt;doddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2051\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoddl\"><h3>-&gt;doddl</h3><div class=\"usage\"><code>(-&gt;doddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1565\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoddo\"><h3>-&gt;doddo</h3><div class=\"usage\"><code>(-&gt;doddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1079\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodl\"><h3>-&gt;dodl</h3><div class=\"usage\"><code>(-&gt;dodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L509\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodld\"><h3>-&gt;dodld</h3><div class=\"usage\"><code>(-&gt;dodld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2045\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodll\"><h3>-&gt;dodll</h3><div class=\"usage\"><code>(-&gt;dodll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1559\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodlo\"><h3>-&gt;dodlo</h3><div class=\"usage\"><code>(-&gt;dodlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1073\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodo\"><h3>-&gt;dodo</h3><div class=\"usage\"><code>(-&gt;dodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L347\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodod\"><h3>-&gt;dodod</h3><div class=\"usage\"><code>(-&gt;dodod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2039\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodol\"><h3>-&gt;dodol</h3><div class=\"usage\"><code>(-&gt;dodol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1553\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edodoo\"><h3>-&gt;dodoo</h3><div class=\"usage\"><code>(-&gt;dodoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1067\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edol\"><h3>-&gt;dol</h3><div class=\"usage\"><code>(-&gt;dol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L161\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edold\"><h3>-&gt;dold</h3><div class=\"usage\"><code>(-&gt;dold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L665\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoldd\"><h3>-&gt;doldd</h3><div class=\"usage\"><code>(-&gt;doldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2033\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoldl\"><h3>-&gt;doldl</h3><div class=\"usage\"><code>(-&gt;doldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1547\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoldo\"><h3>-&gt;doldo</h3><div class=\"usage\"><code>(-&gt;doldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1061\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoll\"><h3>-&gt;doll</h3><div class=\"usage\"><code>(-&gt;doll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L503\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edolld\"><h3>-&gt;dolld</h3><div class=\"usage\"><code>(-&gt;dolld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2027\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edolll\"><h3>-&gt;dolll</h3><div class=\"usage\"><code>(-&gt;dolll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1541\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edollo\"><h3>-&gt;dollo</h3><div class=\"usage\"><code>(-&gt;dollo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1055\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edolo\"><h3>-&gt;dolo</h3><div class=\"usage\"><code>(-&gt;dolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L341\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edolod\"><h3>-&gt;dolod</h3><div class=\"usage\"><code>(-&gt;dolod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2021\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edolol\"><h3>-&gt;dolol</h3><div class=\"usage\"><code>(-&gt;dolol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1535\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoloo\"><h3>-&gt;doloo</h3><div class=\"usage\"><code>(-&gt;doloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1049\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoo\"><h3>-&gt;doo</h3><div class=\"usage\"><code>(-&gt;doo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L107\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edood\"><h3>-&gt;dood</h3><div class=\"usage\"><code>(-&gt;dood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L659\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoodd\"><h3>-&gt;doodd</h3><div class=\"usage\"><code>(-&gt;doodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2015\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoodl\"><h3>-&gt;doodl</h3><div class=\"usage\"><code>(-&gt;doodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1529\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoodo\"><h3>-&gt;doodo</h3><div class=\"usage\"><code>(-&gt;doodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1043\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edool\"><h3>-&gt;dool</h3><div class=\"usage\"><code>(-&gt;dool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L497\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoold\"><h3>-&gt;doold</h3><div class=\"usage\"><code>(-&gt;doold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2009\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edooll\"><h3>-&gt;dooll</h3><div class=\"usage\"><code>(-&gt;dooll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1523\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoolo\"><h3>-&gt;doolo</h3><div class=\"usage\"><code>(-&gt;doolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1037\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edooo\"><h3>-&gt;dooo</h3><div class=\"usage\"><code>(-&gt;dooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L335\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoood\"><h3>-&gt;doood</h3><div class=\"usage\"><code>(-&gt;doood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2003\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoool\"><h3>-&gt;doool</h3><div class=\"usage\"><code>(-&gt;doool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1517\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Edoooo\"><h3>-&gt;doooo</h3><div class=\"usage\"><code>(-&gt;doooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1031\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3El\"><h3>-&gt;l</h3><div class=\"usage\"><code>(-&gt;l f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L17\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eld\"><h3>-&gt;ld</h3><div class=\"usage\"><code>(-&gt;ld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L65\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldd\"><h3>-&gt;ldd</h3><div class=\"usage\"><code>(-&gt;ldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L209\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddd\"><h3>-&gt;lddd</h3><div class=\"usage\"><code>(-&gt;lddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L653\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldddd\"><h3>-&gt;ldddd</h3><div class=\"usage\"><code>(-&gt;ldddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1997\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldddl\"><h3>-&gt;ldddl</h3><div class=\"usage\"><code>(-&gt;ldddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1511\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldddo\"><h3>-&gt;ldddo</h3><div class=\"usage\"><code>(-&gt;ldddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1025\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddl\"><h3>-&gt;lddl</h3><div class=\"usage\"><code>(-&gt;lddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L491\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddld\"><h3>-&gt;lddld</h3><div class=\"usage\"><code>(-&gt;lddld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1991\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddll\"><h3>-&gt;lddll</h3><div class=\"usage\"><code>(-&gt;lddll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1505\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddlo\"><h3>-&gt;lddlo</h3><div class=\"usage\"><code>(-&gt;lddlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1019\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddo\"><h3>-&gt;lddo</h3><div class=\"usage\"><code>(-&gt;lddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L329\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddod\"><h3>-&gt;lddod</h3><div class=\"usage\"><code>(-&gt;lddod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1985\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddol\"><h3>-&gt;lddol</h3><div class=\"usage\"><code>(-&gt;lddol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1499\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elddoo\"><h3>-&gt;lddoo</h3><div class=\"usage\"><code>(-&gt;lddoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1013\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldl\"><h3>-&gt;ldl</h3><div class=\"usage\"><code>(-&gt;ldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L155\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldld\"><h3>-&gt;ldld</h3><div class=\"usage\"><code>(-&gt;ldld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L647\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldldd\"><h3>-&gt;ldldd</h3><div class=\"usage\"><code>(-&gt;ldldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1979\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldldl\"><h3>-&gt;ldldl</h3><div class=\"usage\"><code>(-&gt;ldldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1493\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldldo\"><h3>-&gt;ldldo</h3><div class=\"usage\"><code>(-&gt;ldldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1007\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldll\"><h3>-&gt;ldll</h3><div class=\"usage\"><code>(-&gt;ldll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L485\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldlld\"><h3>-&gt;ldlld</h3><div class=\"usage\"><code>(-&gt;ldlld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1973\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldlll\"><h3>-&gt;ldlll</h3><div class=\"usage\"><code>(-&gt;ldlll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1487\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldllo\"><h3>-&gt;ldllo</h3><div class=\"usage\"><code>(-&gt;ldllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1001\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldlo\"><h3>-&gt;ldlo</h3><div class=\"usage\"><code>(-&gt;ldlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L323\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldlod\"><h3>-&gt;ldlod</h3><div class=\"usage\"><code>(-&gt;ldlod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1967\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldlol\"><h3>-&gt;ldlol</h3><div class=\"usage\"><code>(-&gt;ldlol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1481\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldloo\"><h3>-&gt;ldloo</h3><div class=\"usage\"><code>(-&gt;ldloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L995\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldo\"><h3>-&gt;ldo</h3><div class=\"usage\"><code>(-&gt;ldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L101\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldod\"><h3>-&gt;ldod</h3><div class=\"usage\"><code>(-&gt;ldod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L641\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldodd\"><h3>-&gt;ldodd</h3><div class=\"usage\"><code>(-&gt;ldodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1961\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldodl\"><h3>-&gt;ldodl</h3><div class=\"usage\"><code>(-&gt;ldodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1475\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldodo\"><h3>-&gt;ldodo</h3><div class=\"usage\"><code>(-&gt;ldodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L989\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldol\"><h3>-&gt;ldol</h3><div class=\"usage\"><code>(-&gt;ldol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L479\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldold\"><h3>-&gt;ldold</h3><div class=\"usage\"><code>(-&gt;ldold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1955\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldoll\"><h3>-&gt;ldoll</h3><div class=\"usage\"><code>(-&gt;ldoll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1469\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldolo\"><h3>-&gt;ldolo</h3><div class=\"usage\"><code>(-&gt;ldolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L983\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldoo\"><h3>-&gt;ldoo</h3><div class=\"usage\"><code>(-&gt;ldoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L317\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldood\"><h3>-&gt;ldood</h3><div class=\"usage\"><code>(-&gt;ldood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1949\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldool\"><h3>-&gt;ldool</h3><div class=\"usage\"><code>(-&gt;ldool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1463\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eldooo\"><h3>-&gt;ldooo</h3><div class=\"usage\"><code>(-&gt;ldooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L977\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ell\"><h3>-&gt;ll</h3><div class=\"usage\"><code>(-&gt;ll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L47\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elld\"><h3>-&gt;lld</h3><div class=\"usage\"><code>(-&gt;lld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L203\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldd\"><h3>-&gt;lldd</h3><div class=\"usage\"><code>(-&gt;lldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L635\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellddd\"><h3>-&gt;llddd</h3><div class=\"usage\"><code>(-&gt;llddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1943\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellddl\"><h3>-&gt;llddl</h3><div class=\"usage\"><code>(-&gt;llddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1457\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellddo\"><h3>-&gt;llddo</h3><div class=\"usage\"><code>(-&gt;llddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L971\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldl\"><h3>-&gt;lldl</h3><div class=\"usage\"><code>(-&gt;lldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L473\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldld\"><h3>-&gt;lldld</h3><div class=\"usage\"><code>(-&gt;lldld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1937\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldll\"><h3>-&gt;lldll</h3><div class=\"usage\"><code>(-&gt;lldll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1451\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldlo\"><h3>-&gt;lldlo</h3><div class=\"usage\"><code>(-&gt;lldlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L965\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldo\"><h3>-&gt;lldo</h3><div class=\"usage\"><code>(-&gt;lldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L311\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldod\"><h3>-&gt;lldod</h3><div class=\"usage\"><code>(-&gt;lldod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1931\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldol\"><h3>-&gt;lldol</h3><div class=\"usage\"><code>(-&gt;lldol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1445\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elldoo\"><h3>-&gt;lldoo</h3><div class=\"usage\"><code>(-&gt;lldoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L959\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elll\"><h3>-&gt;lll</h3><div class=\"usage\"><code>(-&gt;lll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L149\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellld\"><h3>-&gt;llld</h3><div class=\"usage\"><code>(-&gt;llld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L629\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellldd\"><h3>-&gt;llldd</h3><div class=\"usage\"><code>(-&gt;llldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1925\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellldl\"><h3>-&gt;llldl</h3><div class=\"usage\"><code>(-&gt;llldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1439\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellldo\"><h3>-&gt;llldo</h3><div class=\"usage\"><code>(-&gt;llldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L953\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellll\"><h3>-&gt;llll</h3><div class=\"usage\"><code>(-&gt;llll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L467\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elllld\"><h3>-&gt;lllld</h3><div class=\"usage\"><code>(-&gt;lllld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1919\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elllll\"><h3>-&gt;lllll</h3><div class=\"usage\"><code>(-&gt;lllll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1433\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellllo\"><h3>-&gt;llllo</h3><div class=\"usage\"><code>(-&gt;llllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L947\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elllo\"><h3>-&gt;lllo</h3><div class=\"usage\"><code>(-&gt;lllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L305\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elllod\"><h3>-&gt;lllod</h3><div class=\"usage\"><code>(-&gt;lllod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1913\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elllol\"><h3>-&gt;lllol</h3><div class=\"usage\"><code>(-&gt;lllol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1427\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellloo\"><h3>-&gt;llloo</h3><div class=\"usage\"><code>(-&gt;llloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L941\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ello\"><h3>-&gt;llo</h3><div class=\"usage\"><code>(-&gt;llo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L95\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellod\"><h3>-&gt;llod</h3><div class=\"usage\"><code>(-&gt;llod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L623\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellodd\"><h3>-&gt;llodd</h3><div class=\"usage\"><code>(-&gt;llodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1907\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellodl\"><h3>-&gt;llodl</h3><div class=\"usage\"><code>(-&gt;llodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1421\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellodo\"><h3>-&gt;llodo</h3><div class=\"usage\"><code>(-&gt;llodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L935\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellol\"><h3>-&gt;llol</h3><div class=\"usage\"><code>(-&gt;llol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L461\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellold\"><h3>-&gt;llold</h3><div class=\"usage\"><code>(-&gt;llold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1901\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elloll\"><h3>-&gt;lloll</h3><div class=\"usage\"><code>(-&gt;lloll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1415\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellolo\"><h3>-&gt;llolo</h3><div class=\"usage\"><code>(-&gt;llolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L929\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elloo\"><h3>-&gt;lloo</h3><div class=\"usage\"><code>(-&gt;lloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L299\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellood\"><h3>-&gt;llood</h3><div class=\"usage\"><code>(-&gt;llood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1895\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellool\"><h3>-&gt;llool</h3><div class=\"usage\"><code>(-&gt;llool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1409\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Ellooo\"><h3>-&gt;llooo</h3><div class=\"usage\"><code>(-&gt;llooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L923\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elo\"><h3>-&gt;lo</h3><div class=\"usage\"><code>(-&gt;lo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L29\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elod\"><h3>-&gt;lod</h3><div class=\"usage\"><code>(-&gt;lod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L197\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodd\"><h3>-&gt;lodd</h3><div class=\"usage\"><code>(-&gt;lodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L617\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloddd\"><h3>-&gt;loddd</h3><div class=\"usage\"><code>(-&gt;loddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1889\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloddl\"><h3>-&gt;loddl</h3><div class=\"usage\"><code>(-&gt;loddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1403\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloddo\"><h3>-&gt;loddo</h3><div class=\"usage\"><code>(-&gt;loddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L917\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodl\"><h3>-&gt;lodl</h3><div class=\"usage\"><code>(-&gt;lodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L455\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodld\"><h3>-&gt;lodld</h3><div class=\"usage\"><code>(-&gt;lodld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1883\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodll\"><h3>-&gt;lodll</h3><div class=\"usage\"><code>(-&gt;lodll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1397\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodlo\"><h3>-&gt;lodlo</h3><div class=\"usage\"><code>(-&gt;lodlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L911\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodo\"><h3>-&gt;lodo</h3><div class=\"usage\"><code>(-&gt;lodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L293\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodod\"><h3>-&gt;lodod</h3><div class=\"usage\"><code>(-&gt;lodod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1877\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodol\"><h3>-&gt;lodol</h3><div class=\"usage\"><code>(-&gt;lodol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1391\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elodoo\"><h3>-&gt;lodoo</h3><div class=\"usage\"><code>(-&gt;lodoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L905\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elol\"><h3>-&gt;lol</h3><div class=\"usage\"><code>(-&gt;lol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L143\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elold\"><h3>-&gt;lold</h3><div class=\"usage\"><code>(-&gt;lold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L611\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloldd\"><h3>-&gt;loldd</h3><div class=\"usage\"><code>(-&gt;loldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1871\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloldl\"><h3>-&gt;loldl</h3><div class=\"usage\"><code>(-&gt;loldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1385\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloldo\"><h3>-&gt;loldo</h3><div class=\"usage\"><code>(-&gt;loldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L899\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloll\"><h3>-&gt;loll</h3><div class=\"usage\"><code>(-&gt;loll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L449\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elolld\"><h3>-&gt;lolld</h3><div class=\"usage\"><code>(-&gt;lolld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1865\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elolll\"><h3>-&gt;lolll</h3><div class=\"usage\"><code>(-&gt;lolll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1379\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elollo\"><h3>-&gt;lollo</h3><div class=\"usage\"><code>(-&gt;lollo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L893\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elolo\"><h3>-&gt;lolo</h3><div class=\"usage\"><code>(-&gt;lolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L287\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elolod\"><h3>-&gt;lolod</h3><div class=\"usage\"><code>(-&gt;lolod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1859\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elolol\"><h3>-&gt;lolol</h3><div class=\"usage\"><code>(-&gt;lolol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1373\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloloo\"><h3>-&gt;loloo</h3><div class=\"usage\"><code>(-&gt;loloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L887\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloo\"><h3>-&gt;loo</h3><div class=\"usage\"><code>(-&gt;loo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L89\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elood\"><h3>-&gt;lood</h3><div class=\"usage\"><code>(-&gt;lood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L605\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloodd\"><h3>-&gt;loodd</h3><div class=\"usage\"><code>(-&gt;loodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1853\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloodl\"><h3>-&gt;loodl</h3><div class=\"usage\"><code>(-&gt;loodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1367\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloodo\"><h3>-&gt;loodo</h3><div class=\"usage\"><code>(-&gt;loodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L881\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elool\"><h3>-&gt;lool</h3><div class=\"usage\"><code>(-&gt;lool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L443\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloold\"><h3>-&gt;loold</h3><div class=\"usage\"><code>(-&gt;loold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1847\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elooll\"><h3>-&gt;looll</h3><div class=\"usage\"><code>(-&gt;looll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1361\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloolo\"><h3>-&gt;loolo</h3><div class=\"usage\"><code>(-&gt;loolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L875\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Elooo\"><h3>-&gt;looo</h3><div class=\"usage\"><code>(-&gt;looo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L281\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloood\"><h3>-&gt;loood</h3><div class=\"usage\"><code>(-&gt;loood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1841\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloool\"><h3>-&gt;loool</h3><div class=\"usage\"><code>(-&gt;loool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1355\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eloooo\"><h3>-&gt;loooo</h3><div class=\"usage\"><code>(-&gt;loooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L869\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eod\"><h3>-&gt;od</h3><div class=\"usage\"><code>(-&gt;od f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L59\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodd\"><h3>-&gt;odd</h3><div class=\"usage\"><code>(-&gt;odd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L191\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddd\"><h3>-&gt;oddd</h3><div class=\"usage\"><code>(-&gt;oddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L599\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodddd\"><h3>-&gt;odddd</h3><div class=\"usage\"><code>(-&gt;odddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1835\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodddl\"><h3>-&gt;odddl</h3><div class=\"usage\"><code>(-&gt;odddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1349\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodddo\"><h3>-&gt;odddo</h3><div class=\"usage\"><code>(-&gt;odddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L863\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddl\"><h3>-&gt;oddl</h3><div class=\"usage\"><code>(-&gt;oddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L437\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddld\"><h3>-&gt;oddld</h3><div class=\"usage\"><code>(-&gt;oddld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1829\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddll\"><h3>-&gt;oddll</h3><div class=\"usage\"><code>(-&gt;oddll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1343\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddlo\"><h3>-&gt;oddlo</h3><div class=\"usage\"><code>(-&gt;oddlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L857\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddo\"><h3>-&gt;oddo</h3><div class=\"usage\"><code>(-&gt;oddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L275\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddod\"><h3>-&gt;oddod</h3><div class=\"usage\"><code>(-&gt;oddod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1823\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddol\"><h3>-&gt;oddol</h3><div class=\"usage\"><code>(-&gt;oddol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1337\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoddoo\"><h3>-&gt;oddoo</h3><div class=\"usage\"><code>(-&gt;oddoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L851\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodl\"><h3>-&gt;odl</h3><div class=\"usage\"><code>(-&gt;odl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L137\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodld\"><h3>-&gt;odld</h3><div class=\"usage\"><code>(-&gt;odld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L593\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodldd\"><h3>-&gt;odldd</h3><div class=\"usage\"><code>(-&gt;odldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1817\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodldl\"><h3>-&gt;odldl</h3><div class=\"usage\"><code>(-&gt;odldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1331\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodldo\"><h3>-&gt;odldo</h3><div class=\"usage\"><code>(-&gt;odldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L845\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodll\"><h3>-&gt;odll</h3><div class=\"usage\"><code>(-&gt;odll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L431\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodlld\"><h3>-&gt;odlld</h3><div class=\"usage\"><code>(-&gt;odlld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1811\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodlll\"><h3>-&gt;odlll</h3><div class=\"usage\"><code>(-&gt;odlll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1325\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodllo\"><h3>-&gt;odllo</h3><div class=\"usage\"><code>(-&gt;odllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L839\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodlo\"><h3>-&gt;odlo</h3><div class=\"usage\"><code>(-&gt;odlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L269\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodlod\"><h3>-&gt;odlod</h3><div class=\"usage\"><code>(-&gt;odlod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1805\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodlol\"><h3>-&gt;odlol</h3><div class=\"usage\"><code>(-&gt;odlol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1319\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodloo\"><h3>-&gt;odloo</h3><div class=\"usage\"><code>(-&gt;odloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L833\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodo\"><h3>-&gt;odo</h3><div class=\"usage\"><code>(-&gt;odo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L83\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodod\"><h3>-&gt;odod</h3><div class=\"usage\"><code>(-&gt;odod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L587\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eododd\"><h3>-&gt;ododd</h3><div class=\"usage\"><code>(-&gt;ododd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1799\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eododl\"><h3>-&gt;ododl</h3><div class=\"usage\"><code>(-&gt;ododl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1313\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eododo\"><h3>-&gt;ododo</h3><div class=\"usage\"><code>(-&gt;ododo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L827\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodol\"><h3>-&gt;odol</h3><div class=\"usage\"><code>(-&gt;odol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L425\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodold\"><h3>-&gt;odold</h3><div class=\"usage\"><code>(-&gt;odold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1793\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodoll\"><h3>-&gt;odoll</h3><div class=\"usage\"><code>(-&gt;odoll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1307\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodolo\"><h3>-&gt;odolo</h3><div class=\"usage\"><code>(-&gt;odolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L821\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodoo\"><h3>-&gt;odoo</h3><div class=\"usage\"><code>(-&gt;odoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L263\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodood\"><h3>-&gt;odood</h3><div class=\"usage\"><code>(-&gt;odood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1787\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodool\"><h3>-&gt;odool</h3><div class=\"usage\"><code>(-&gt;odool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1301\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eodooo\"><h3>-&gt;odooo</h3><div class=\"usage\"><code>(-&gt;odooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L815\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eol\"><h3>-&gt;ol</h3><div class=\"usage\"><code>(-&gt;ol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L41\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eold\"><h3>-&gt;old</h3><div class=\"usage\"><code>(-&gt;old f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L185\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldd\"><h3>-&gt;oldd</h3><div class=\"usage\"><code>(-&gt;oldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L581\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolddd\"><h3>-&gt;olddd</h3><div class=\"usage\"><code>(-&gt;olddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1781\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolddl\"><h3>-&gt;olddl</h3><div class=\"usage\"><code>(-&gt;olddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1295\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolddo\"><h3>-&gt;olddo</h3><div class=\"usage\"><code>(-&gt;olddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L809\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldl\"><h3>-&gt;oldl</h3><div class=\"usage\"><code>(-&gt;oldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L419\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldld\"><h3>-&gt;oldld</h3><div class=\"usage\"><code>(-&gt;oldld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1775\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldll\"><h3>-&gt;oldll</h3><div class=\"usage\"><code>(-&gt;oldll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1289\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldlo\"><h3>-&gt;oldlo</h3><div class=\"usage\"><code>(-&gt;oldlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L803\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldo\"><h3>-&gt;oldo</h3><div class=\"usage\"><code>(-&gt;oldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L257\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldod\"><h3>-&gt;oldod</h3><div class=\"usage\"><code>(-&gt;oldod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1769\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldol\"><h3>-&gt;oldol</h3><div class=\"usage\"><code>(-&gt;oldol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1283\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoldoo\"><h3>-&gt;oldoo</h3><div class=\"usage\"><code>(-&gt;oldoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L797\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoll\"><h3>-&gt;oll</h3><div class=\"usage\"><code>(-&gt;oll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L131\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolld\"><h3>-&gt;olld</h3><div class=\"usage\"><code>(-&gt;olld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L575\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolldd\"><h3>-&gt;olldd</h3><div class=\"usage\"><code>(-&gt;olldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1763\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolldl\"><h3>-&gt;olldl</h3><div class=\"usage\"><code>(-&gt;olldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1277\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolldo\"><h3>-&gt;olldo</h3><div class=\"usage\"><code>(-&gt;olldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L791\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolll\"><h3>-&gt;olll</h3><div class=\"usage\"><code>(-&gt;olll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L413\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eollld\"><h3>-&gt;ollld</h3><div class=\"usage\"><code>(-&gt;ollld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1757\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eollll\"><h3>-&gt;ollll</h3><div class=\"usage\"><code>(-&gt;ollll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1271\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolllo\"><h3>-&gt;olllo</h3><div class=\"usage\"><code>(-&gt;olllo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L785\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eollo\"><h3>-&gt;ollo</h3><div class=\"usage\"><code>(-&gt;ollo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L251\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eollod\"><h3>-&gt;ollod</h3><div class=\"usage\"><code>(-&gt;ollod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1751\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eollol\"><h3>-&gt;ollol</h3><div class=\"usage\"><code>(-&gt;ollol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1265\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolloo\"><h3>-&gt;olloo</h3><div class=\"usage\"><code>(-&gt;olloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L779\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolo\"><h3>-&gt;olo</h3><div class=\"usage\"><code>(-&gt;olo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L77\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolod\"><h3>-&gt;olod</h3><div class=\"usage\"><code>(-&gt;olod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L569\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolodd\"><h3>-&gt;olodd</h3><div class=\"usage\"><code>(-&gt;olodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1745\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolodl\"><h3>-&gt;olodl</h3><div class=\"usage\"><code>(-&gt;olodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1259\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolodo\"><h3>-&gt;olodo</h3><div class=\"usage\"><code>(-&gt;olodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L773\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolol\"><h3>-&gt;olol</h3><div class=\"usage\"><code>(-&gt;olol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L407\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolold\"><h3>-&gt;olold</h3><div class=\"usage\"><code>(-&gt;olold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1739\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eololl\"><h3>-&gt;ololl</h3><div class=\"usage\"><code>(-&gt;ololl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1253\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eololo\"><h3>-&gt;ololo</h3><div class=\"usage\"><code>(-&gt;ololo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L767\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoloo\"><h3>-&gt;oloo</h3><div class=\"usage\"><code>(-&gt;oloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L245\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolood\"><h3>-&gt;olood</h3><div class=\"usage\"><code>(-&gt;olood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1733\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolool\"><h3>-&gt;olool</h3><div class=\"usage\"><code>(-&gt;olool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1247\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eolooo\"><h3>-&gt;olooo</h3><div class=\"usage\"><code>(-&gt;olooo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L761\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eood\"><h3>-&gt;ood</h3><div class=\"usage\"><code>(-&gt;ood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L179\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodd\"><h3>-&gt;oodd</h3><div class=\"usage\"><code>(-&gt;oodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L563\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooddd\"><h3>-&gt;ooddd</h3><div class=\"usage\"><code>(-&gt;ooddd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1727\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooddl\"><h3>-&gt;ooddl</h3><div class=\"usage\"><code>(-&gt;ooddl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1241\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooddo\"><h3>-&gt;ooddo</h3><div class=\"usage\"><code>(-&gt;ooddo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L755\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodl\"><h3>-&gt;oodl</h3><div class=\"usage\"><code>(-&gt;oodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L401\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodld\"><h3>-&gt;oodld</h3><div class=\"usage\"><code>(-&gt;oodld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1721\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodll\"><h3>-&gt;oodll</h3><div class=\"usage\"><code>(-&gt;oodll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1235\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodlo\"><h3>-&gt;oodlo</h3><div class=\"usage\"><code>(-&gt;oodlo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L749\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodo\"><h3>-&gt;oodo</h3><div class=\"usage\"><code>(-&gt;oodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L239\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodod\"><h3>-&gt;oodod</h3><div class=\"usage\"><code>(-&gt;oodod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1715\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodol\"><h3>-&gt;oodol</h3><div class=\"usage\"><code>(-&gt;oodol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1229\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoodoo\"><h3>-&gt;oodoo</h3><div class=\"usage\"><code>(-&gt;oodoo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L743\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eool\"><h3>-&gt;ool</h3><div class=\"usage\"><code>(-&gt;ool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L125\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoold\"><h3>-&gt;oold</h3><div class=\"usage\"><code>(-&gt;oold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L557\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooldd\"><h3>-&gt;ooldd</h3><div class=\"usage\"><code>(-&gt;ooldd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1709\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooldl\"><h3>-&gt;ooldl</h3><div class=\"usage\"><code>(-&gt;ooldl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1223\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooldo\"><h3>-&gt;ooldo</h3><div class=\"usage\"><code>(-&gt;ooldo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L737\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooll\"><h3>-&gt;ooll</h3><div class=\"usage\"><code>(-&gt;ooll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L395\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoolld\"><h3>-&gt;oolld</h3><div class=\"usage\"><code>(-&gt;oolld f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1703\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoolll\"><h3>-&gt;oolll</h3><div class=\"usage\"><code>(-&gt;oolll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1217\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoollo\"><h3>-&gt;oollo</h3><div class=\"usage\"><code>(-&gt;oollo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L731\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoolo\"><h3>-&gt;oolo</h3><div class=\"usage\"><code>(-&gt;oolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L233\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoolod\"><h3>-&gt;oolod</h3><div class=\"usage\"><code>(-&gt;oolod f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1697\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoolol\"><h3>-&gt;oolol</h3><div class=\"usage\"><code>(-&gt;oolol f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1211\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooloo\"><h3>-&gt;ooloo</h3><div class=\"usage\"><code>(-&gt;ooloo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L725\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoood\"><h3>-&gt;oood</h3><div class=\"usage\"><code>(-&gt;oood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L551\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooodd\"><h3>-&gt;ooodd</h3><div class=\"usage\"><code>(-&gt;ooodd f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1691\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooodl\"><h3>-&gt;ooodl</h3><div class=\"usage\"><code>(-&gt;ooodl f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1205\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooodo\"><h3>-&gt;ooodo</h3><div class=\"usage\"><code>(-&gt;ooodo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L719\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoool\"><h3>-&gt;oool</h3><div class=\"usage\"><code>(-&gt;oool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L389\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooold\"><h3>-&gt;ooold</h3><div class=\"usage\"><code>(-&gt;ooold f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1685\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eoooll\"><h3>-&gt;oooll</h3><div class=\"usage\"><code>(-&gt;oooll f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1199\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooolo\"><h3>-&gt;ooolo</h3><div class=\"usage\"><code>(-&gt;ooolo f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L713\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooood\"><h3>-&gt;ooood</h3><div class=\"usage\"><code>(-&gt;ooood f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1679\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eooool\"><h3>-&gt;ooool</h3><div class=\"usage\"><code>(-&gt;ooool f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1193\">view source</a></div></div><div class=\"public anchor\" id=\"var-d\"><h3>d</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(d f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L27\">view source</a></div></div><div class=\"public anchor\" id=\"var-dd\"><h3>dd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dd f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L75\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddd\"><h3>ddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddd f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L231\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddd\"><h3>dddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L711\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddddd\"><h3>ddddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2163\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddddl\"><h3>ddddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1677\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddddo\"><h3>ddddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1191\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddl\"><h3>dddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L549\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddld\"><h3>dddld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2157\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddll\"><h3>dddll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1671\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddlo\"><h3>dddlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1185\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddo\"><h3>dddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L387\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddod\"><h3>dddod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2151\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddol\"><h3>dddol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1665\">view source</a></div></div><div class=\"public anchor\" id=\"var-dddoo\"><h3>dddoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dddoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1179\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddl\"><h3>ddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddl f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L177\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddld\"><h3>ddld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddld f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L705\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddldd\"><h3>ddldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2145\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddldl\"><h3>ddldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1659\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddldo\"><h3>ddldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1173\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddll\"><h3>ddll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L543\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddlld\"><h3>ddlld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddlld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2139\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddlll\"><h3>ddlll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddlll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1653\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddllo\"><h3>ddllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddllo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1167\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddlo\"><h3>ddlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddlo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L381\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddlod\"><h3>ddlod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddlod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2133\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddlol\"><h3>ddlol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddlol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1647\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddloo\"><h3>ddloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1161\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddo\"><h3>ddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L123\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddod\"><h3>ddod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddod f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L699\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddodd\"><h3>ddodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2127\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddodl\"><h3>ddodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1641\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddodo\"><h3>ddodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1155\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddol\"><h3>ddol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddol f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L537\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddold\"><h3>ddold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2121\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddoll\"><h3>ddoll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddoll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1635\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddolo\"><h3>ddolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1149\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddoo\"><h3>ddoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddoo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L375\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddood\"><h3>ddood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2115\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddool\"><h3>ddool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1629\">view source</a></div></div><div class=\"public anchor\" id=\"var-ddooo\"><h3>ddooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ddooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1143\">view source</a></div></div><div class=\"public anchor\" id=\"var-dl\"><h3>dl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dl f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L57\">view source</a></div></div><div class=\"public anchor\" id=\"var-dld\"><h3>dld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dld f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L225\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldd\"><h3>dldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L693\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlddd\"><h3>dlddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2109\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlddl\"><h3>dlddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1623\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlddo\"><h3>dlddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1137\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldl\"><h3>dldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L531\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldld\"><h3>dldld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2103\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldll\"><h3>dldll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1617\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldlo\"><h3>dldlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1131\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldo\"><h3>dldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L369\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldod\"><h3>dldod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2097\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldol\"><h3>dldol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1611\">view source</a></div></div><div class=\"public anchor\" id=\"var-dldoo\"><h3>dldoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dldoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1125\">view source</a></div></div><div class=\"public anchor\" id=\"var-dll\"><h3>dll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dll f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L171\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlld\"><h3>dlld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlld f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L687\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlldd\"><h3>dlldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2091\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlldl\"><h3>dlldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1605\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlldo\"><h3>dlldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1119\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlll\"><h3>dlll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L525\">view source</a></div></div><div class=\"public anchor\" id=\"var-dllld\"><h3>dllld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dllld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2085\">view source</a></div></div><div class=\"public anchor\" id=\"var-dllll\"><h3>dllll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dllll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1599\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlllo\"><h3>dlllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlllo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1113\">view source</a></div></div><div class=\"public anchor\" id=\"var-dllo\"><h3>dllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dllo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L363\">view source</a></div></div><div class=\"public anchor\" id=\"var-dllod\"><h3>dllod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dllod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2079\">view source</a></div></div><div class=\"public anchor\" id=\"var-dllol\"><h3>dllol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dllol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1593\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlloo\"><h3>dlloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1107\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlo\"><h3>dlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L117\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlod\"><h3>dlod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlod f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L681\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlodd\"><h3>dlodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2073\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlodl\"><h3>dlodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1587\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlodo\"><h3>dlodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1101\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlol\"><h3>dlol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlol f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L519\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlold\"><h3>dlold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2067\">view source</a></div></div><div class=\"public anchor\" id=\"var-dloll\"><h3>dloll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dloll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1581\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlolo\"><h3>dlolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1095\">view source</a></div></div><div class=\"public anchor\" id=\"var-dloo\"><h3>dloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dloo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L357\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlood\"><h3>dlood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2061\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlool\"><h3>dlool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1575\">view source</a></div></div><div class=\"public anchor\" id=\"var-dlooo\"><h3>dlooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dlooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1089\">view source</a></div></div><div class=\"public anchor\" id=\"var-do\"><h3>do</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(do f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L39\">view source</a></div></div><div class=\"public anchor\" id=\"var-dod\"><h3>dod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dod f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L219\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodd\"><h3>dodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L675\">view source</a></div></div><div class=\"public anchor\" id=\"var-doddd\"><h3>doddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2055\">view source</a></div></div><div class=\"public anchor\" id=\"var-doddl\"><h3>doddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1569\">view source</a></div></div><div class=\"public anchor\" id=\"var-doddo\"><h3>doddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1083\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodl\"><h3>dodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L513\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodld\"><h3>dodld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2049\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodll\"><h3>dodll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1563\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodlo\"><h3>dodlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1077\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodo\"><h3>dodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L351\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodod\"><h3>dodod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2043\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodol\"><h3>dodol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1557\">view source</a></div></div><div class=\"public anchor\" id=\"var-dodoo\"><h3>dodoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dodoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1071\">view source</a></div></div><div class=\"public anchor\" id=\"var-dol\"><h3>dol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dol f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L165\">view source</a></div></div><div class=\"public anchor\" id=\"var-dold\"><h3>dold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dold f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L669\">view source</a></div></div><div class=\"public anchor\" id=\"var-doldd\"><h3>doldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2037\">view source</a></div></div><div class=\"public anchor\" id=\"var-doldl\"><h3>doldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1551\">view source</a></div></div><div class=\"public anchor\" id=\"var-doldo\"><h3>doldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1065\">view source</a></div></div><div class=\"public anchor\" id=\"var-doll\"><h3>doll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L507\">view source</a></div></div><div class=\"public anchor\" id=\"var-dolld\"><h3>dolld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dolld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2031\">view source</a></div></div><div class=\"public anchor\" id=\"var-dolll\"><h3>dolll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dolll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1545\">view source</a></div></div><div class=\"public anchor\" id=\"var-dollo\"><h3>dollo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dollo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1059\">view source</a></div></div><div class=\"public anchor\" id=\"var-dolo\"><h3>dolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dolo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L345\">view source</a></div></div><div class=\"public anchor\" id=\"var-dolod\"><h3>dolod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dolod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2025\">view source</a></div></div><div class=\"public anchor\" id=\"var-dolol\"><h3>dolol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dolol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1539\">view source</a></div></div><div class=\"public anchor\" id=\"var-doloo\"><h3>doloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1053\">view source</a></div></div><div class=\"public anchor\" id=\"var-doo\"><h3>doo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L111\">view source</a></div></div><div class=\"public anchor\" id=\"var-dood\"><h3>dood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dood f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L663\">view source</a></div></div><div class=\"public anchor\" id=\"var-doodd\"><h3>doodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2019\">view source</a></div></div><div class=\"public anchor\" id=\"var-doodl\"><h3>doodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1533\">view source</a></div></div><div class=\"public anchor\" id=\"var-doodo\"><h3>doodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1047\">view source</a></div></div><div class=\"public anchor\" id=\"var-dool\"><h3>dool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dool f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L501\">view source</a></div></div><div class=\"public anchor\" id=\"var-doold\"><h3>doold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2013\">view source</a></div></div><div class=\"public anchor\" id=\"var-dooll\"><h3>dooll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dooll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1527\">view source</a></div></div><div class=\"public anchor\" id=\"var-doolo\"><h3>doolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1041\">view source</a></div></div><div class=\"public anchor\" id=\"var-dooo\"><h3>dooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(dooo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L339\">view source</a></div></div><div class=\"public anchor\" id=\"var-doood\"><h3>doood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2007\">view source</a></div></div><div class=\"public anchor\" id=\"var-doool\"><h3>doool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1521\">view source</a></div></div><div class=\"public anchor\" id=\"var-doooo\"><h3>doooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(doooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1035\">view source</a></div></div><div class=\"public anchor\" id=\"var-l\"><h3>l</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(l f)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L21\">view source</a></div></div><div class=\"public anchor\" id=\"var-ld\"><h3>ld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ld f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L69\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldd\"><h3>ldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldd f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L213\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddd\"><h3>lddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L657\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldddd\"><h3>ldddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L2001\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldddl\"><h3>ldddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1515\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldddo\"><h3>ldddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1029\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddl\"><h3>lddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L495\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddld\"><h3>lddld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1995\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddll\"><h3>lddll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1509\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddlo\"><h3>lddlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1023\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddo\"><h3>lddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L333\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddod\"><h3>lddod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1989\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddol\"><h3>lddol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1503\">view source</a></div></div><div class=\"public anchor\" id=\"var-lddoo\"><h3>lddoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lddoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1017\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldl\"><h3>ldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldl f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L159\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldld\"><h3>ldld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldld f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L651\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldldd\"><h3>ldldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1983\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldldl\"><h3>ldldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1497\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldldo\"><h3>ldldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1011\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldll\"><h3>ldll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L489\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldlld\"><h3>ldlld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldlld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1977\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldlll\"><h3>ldlll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldlll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1491\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldllo\"><h3>ldllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldllo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1005\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldlo\"><h3>ldlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldlo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L327\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldlod\"><h3>ldlod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldlod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1971\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldlol\"><h3>ldlol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldlol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1485\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldloo\"><h3>ldloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L999\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldo\"><h3>ldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L105\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldod\"><h3>ldod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldod f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L645\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldodd\"><h3>ldodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1965\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldodl\"><h3>ldodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1479\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldodo\"><h3>ldodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L993\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldol\"><h3>ldol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldol f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L483\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldold\"><h3>ldold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1959\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldoll\"><h3>ldoll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldoll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1473\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldolo\"><h3>ldolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L987\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldoo\"><h3>ldoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldoo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L321\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldood\"><h3>ldood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1953\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldool\"><h3>ldool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1467\">view source</a></div></div><div class=\"public anchor\" id=\"var-ldooo\"><h3>ldooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ldooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L981\">view source</a></div></div><div class=\"public anchor\" id=\"var-ll\"><h3>ll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ll f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L51\">view source</a></div></div><div class=\"public anchor\" id=\"var-lld\"><h3>lld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lld f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L207\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldd\"><h3>lldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L639\">view source</a></div></div><div class=\"public anchor\" id=\"var-llddd\"><h3>llddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1947\">view source</a></div></div><div class=\"public anchor\" id=\"var-llddl\"><h3>llddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1461\">view source</a></div></div><div class=\"public anchor\" id=\"var-llddo\"><h3>llddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L975\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldl\"><h3>lldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L477\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldld\"><h3>lldld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1941\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldll\"><h3>lldll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1455\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldlo\"><h3>lldlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L969\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldo\"><h3>lldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L315\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldod\"><h3>lldod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1935\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldol\"><h3>lldol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1449\">view source</a></div></div><div class=\"public anchor\" id=\"var-lldoo\"><h3>lldoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lldoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L963\">view source</a></div></div><div class=\"public anchor\" id=\"var-lll\"><h3>lll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lll f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L153\">view source</a></div></div><div class=\"public anchor\" id=\"var-llld\"><h3>llld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llld f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L633\">view source</a></div></div><div class=\"public anchor\" id=\"var-llldd\"><h3>llldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1929\">view source</a></div></div><div class=\"public anchor\" id=\"var-llldl\"><h3>llldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1443\">view source</a></div></div><div class=\"public anchor\" id=\"var-llldo\"><h3>llldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L957\">view source</a></div></div><div class=\"public anchor\" id=\"var-llll\"><h3>llll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L471\">view source</a></div></div><div class=\"public anchor\" id=\"var-lllld\"><h3>lllld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lllld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1923\">view source</a></div></div><div class=\"public anchor\" id=\"var-lllll\"><h3>lllll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lllll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1437\">view source</a></div></div><div class=\"public anchor\" id=\"var-llllo\"><h3>llllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llllo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L951\">view source</a></div></div><div class=\"public anchor\" id=\"var-lllo\"><h3>lllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lllo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L309\">view source</a></div></div><div class=\"public anchor\" id=\"var-lllod\"><h3>lllod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lllod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1917\">view source</a></div></div><div class=\"public anchor\" id=\"var-lllol\"><h3>lllol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lllol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1431\">view source</a></div></div><div class=\"public anchor\" id=\"var-llloo\"><h3>llloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L945\">view source</a></div></div><div class=\"public anchor\" id=\"var-llo\"><h3>llo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L99\">view source</a></div></div><div class=\"public anchor\" id=\"var-llod\"><h3>llod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llod f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L627\">view source</a></div></div><div class=\"public anchor\" id=\"var-llodd\"><h3>llodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1911\">view source</a></div></div><div class=\"public anchor\" id=\"var-llodl\"><h3>llodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1425\">view source</a></div></div><div class=\"public anchor\" id=\"var-llodo\"><h3>llodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L939\">view source</a></div></div><div class=\"public anchor\" id=\"var-llol\"><h3>llol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llol f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L465\">view source</a></div></div><div class=\"public anchor\" id=\"var-llold\"><h3>llold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1905\">view source</a></div></div><div class=\"public anchor\" id=\"var-lloll\"><h3>lloll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lloll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1419\">view source</a></div></div><div class=\"public anchor\" id=\"var-llolo\"><h3>llolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L933\">view source</a></div></div><div class=\"public anchor\" id=\"var-lloo\"><h3>lloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lloo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L303\">view source</a></div></div><div class=\"public anchor\" id=\"var-llood\"><h3>llood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1899\">view source</a></div></div><div class=\"public anchor\" id=\"var-llool\"><h3>llool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1413\">view source</a></div></div><div class=\"public anchor\" id=\"var-llooo\"><h3>llooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(llooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L927\">view source</a></div></div><div class=\"public anchor\" id=\"var-lo\"><h3>lo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lo f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L33\">view source</a></div></div><div class=\"public anchor\" id=\"var-lod\"><h3>lod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lod f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L201\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodd\"><h3>lodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L621\">view source</a></div></div><div class=\"public anchor\" id=\"var-loddd\"><h3>loddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1893\">view source</a></div></div><div class=\"public anchor\" id=\"var-loddl\"><h3>loddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1407\">view source</a></div></div><div class=\"public anchor\" id=\"var-loddo\"><h3>loddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L921\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodl\"><h3>lodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L459\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodld\"><h3>lodld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1887\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodll\"><h3>lodll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1401\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodlo\"><h3>lodlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L915\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodo\"><h3>lodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L297\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodod\"><h3>lodod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1881\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodol\"><h3>lodol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1395\">view source</a></div></div><div class=\"public anchor\" id=\"var-lodoo\"><h3>lodoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lodoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L909\">view source</a></div></div><div class=\"public anchor\" id=\"var-lol\"><h3>lol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lol f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L147\">view source</a></div></div><div class=\"public anchor\" id=\"var-lold\"><h3>lold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lold f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L615\">view source</a></div></div><div class=\"public anchor\" id=\"var-loldd\"><h3>loldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1875\">view source</a></div></div><div class=\"public anchor\" id=\"var-loldl\"><h3>loldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1389\">view source</a></div></div><div class=\"public anchor\" id=\"var-loldo\"><h3>loldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L903\">view source</a></div></div><div class=\"public anchor\" id=\"var-loll\"><h3>loll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L453\">view source</a></div></div><div class=\"public anchor\" id=\"var-lolld\"><h3>lolld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lolld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1869\">view source</a></div></div><div class=\"public anchor\" id=\"var-lolll\"><h3>lolll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lolll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1383\">view source</a></div></div><div class=\"public anchor\" id=\"var-lollo\"><h3>lollo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lollo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L897\">view source</a></div></div><div class=\"public anchor\" id=\"var-lolo\"><h3>lolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lolo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L291\">view source</a></div></div><div class=\"public anchor\" id=\"var-lolod\"><h3>lolod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lolod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1863\">view source</a></div></div><div class=\"public anchor\" id=\"var-lolol\"><h3>lolol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lolol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1377\">view source</a></div></div><div class=\"public anchor\" id=\"var-loloo\"><h3>loloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L891\">view source</a></div></div><div class=\"public anchor\" id=\"var-loo\"><h3>loo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L93\">view source</a></div></div><div class=\"public anchor\" id=\"var-lood\"><h3>lood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lood f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L609\">view source</a></div></div><div class=\"public anchor\" id=\"var-loodd\"><h3>loodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1857\">view source</a></div></div><div class=\"public anchor\" id=\"var-loodl\"><h3>loodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1371\">view source</a></div></div><div class=\"public anchor\" id=\"var-loodo\"><h3>loodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L885\">view source</a></div></div><div class=\"public anchor\" id=\"var-lool\"><h3>lool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(lool f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L447\">view source</a></div></div><div class=\"public anchor\" id=\"var-loold\"><h3>loold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1851\">view source</a></div></div><div class=\"public anchor\" id=\"var-looll\"><h3>looll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(looll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1365\">view source</a></div></div><div class=\"public anchor\" id=\"var-loolo\"><h3>loolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L879\">view source</a></div></div><div class=\"public anchor\" id=\"var-looo\"><h3>looo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(looo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L285\">view source</a></div></div><div class=\"public anchor\" id=\"var-loood\"><h3>loood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1845\">view source</a></div></div><div class=\"public anchor\" id=\"var-loool\"><h3>loool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1359\">view source</a></div></div><div class=\"public anchor\" id=\"var-loooo\"><h3>loooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(loooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L873\">view source</a></div></div><div class=\"public anchor\" id=\"var-od\"><h3>od</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(od f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L63\">view source</a></div></div><div class=\"public anchor\" id=\"var-odd\"><h3>odd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odd f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L195\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddd\"><h3>oddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L603\">view source</a></div></div><div class=\"public anchor\" id=\"var-odddd\"><h3>odddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1839\">view source</a></div></div><div class=\"public anchor\" id=\"var-odddl\"><h3>odddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1353\">view source</a></div></div><div class=\"public anchor\" id=\"var-odddo\"><h3>odddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L867\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddl\"><h3>oddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L441\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddld\"><h3>oddld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1833\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddll\"><h3>oddll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1347\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddlo\"><h3>oddlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L861\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddo\"><h3>oddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L279\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddod\"><h3>oddod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1827\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddol\"><h3>oddol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1341\">view source</a></div></div><div class=\"public anchor\" id=\"var-oddoo\"><h3>oddoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oddoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L855\">view source</a></div></div><div class=\"public anchor\" id=\"var-odl\"><h3>odl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odl f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L141\">view source</a></div></div><div class=\"public anchor\" id=\"var-odld\"><h3>odld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odld f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L597\">view source</a></div></div><div class=\"public anchor\" id=\"var-odldd\"><h3>odldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1821\">view source</a></div></div><div class=\"public anchor\" id=\"var-odldl\"><h3>odldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1335\">view source</a></div></div><div class=\"public anchor\" id=\"var-odldo\"><h3>odldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L849\">view source</a></div></div><div class=\"public anchor\" id=\"var-odll\"><h3>odll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L435\">view source</a></div></div><div class=\"public anchor\" id=\"var-odlld\"><h3>odlld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odlld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1815\">view source</a></div></div><div class=\"public anchor\" id=\"var-odlll\"><h3>odlll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odlll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1329\">view source</a></div></div><div class=\"public anchor\" id=\"var-odllo\"><h3>odllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odllo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L843\">view source</a></div></div><div class=\"public anchor\" id=\"var-odlo\"><h3>odlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odlo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L273\">view source</a></div></div><div class=\"public anchor\" id=\"var-odlod\"><h3>odlod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odlod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1809\">view source</a></div></div><div class=\"public anchor\" id=\"var-odlol\"><h3>odlol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odlol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1323\">view source</a></div></div><div class=\"public anchor\" id=\"var-odloo\"><h3>odloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L837\">view source</a></div></div><div class=\"public anchor\" id=\"var-odo\"><h3>odo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L87\">view source</a></div></div><div class=\"public anchor\" id=\"var-odod\"><h3>odod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odod f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L591\">view source</a></div></div><div class=\"public anchor\" id=\"var-ododd\"><h3>ododd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ododd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1803\">view source</a></div></div><div class=\"public anchor\" id=\"var-ododl\"><h3>ododl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ododl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1317\">view source</a></div></div><div class=\"public anchor\" id=\"var-ododo\"><h3>ododo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ododo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L831\">view source</a></div></div><div class=\"public anchor\" id=\"var-odol\"><h3>odol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odol f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L429\">view source</a></div></div><div class=\"public anchor\" id=\"var-odold\"><h3>odold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1797\">view source</a></div></div><div class=\"public anchor\" id=\"var-odoll\"><h3>odoll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odoll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1311\">view source</a></div></div><div class=\"public anchor\" id=\"var-odolo\"><h3>odolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L825\">view source</a></div></div><div class=\"public anchor\" id=\"var-odoo\"><h3>odoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odoo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L267\">view source</a></div></div><div class=\"public anchor\" id=\"var-odood\"><h3>odood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1791\">view source</a></div></div><div class=\"public anchor\" id=\"var-odool\"><h3>odool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1305\">view source</a></div></div><div class=\"public anchor\" id=\"var-odooo\"><h3>odooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(odooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L819\">view source</a></div></div><div class=\"public anchor\" id=\"var-ol\"><h3>ol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ol f arg0)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L45\">view source</a></div></div><div class=\"public anchor\" id=\"var-old\"><h3>old</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(old f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L189\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldd\"><h3>oldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L585\">view source</a></div></div><div class=\"public anchor\" id=\"var-olddd\"><h3>olddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1785\">view source</a></div></div><div class=\"public anchor\" id=\"var-olddl\"><h3>olddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1299\">view source</a></div></div><div class=\"public anchor\" id=\"var-olddo\"><h3>olddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L813\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldl\"><h3>oldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L423\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldld\"><h3>oldld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1779\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldll\"><h3>oldll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1293\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldlo\"><h3>oldlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L807\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldo\"><h3>oldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L261\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldod\"><h3>oldod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1773\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldol\"><h3>oldol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1287\">view source</a></div></div><div class=\"public anchor\" id=\"var-oldoo\"><h3>oldoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oldoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L801\">view source</a></div></div><div class=\"public anchor\" id=\"var-oll\"><h3>oll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oll f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L135\">view source</a></div></div><div class=\"public anchor\" id=\"var-olld\"><h3>olld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olld f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L579\">view source</a></div></div><div class=\"public anchor\" id=\"var-olldd\"><h3>olldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1767\">view source</a></div></div><div class=\"public anchor\" id=\"var-olldl\"><h3>olldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1281\">view source</a></div></div><div class=\"public anchor\" id=\"var-olldo\"><h3>olldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L795\">view source</a></div></div><div class=\"public anchor\" id=\"var-olll\"><h3>olll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L417\">view source</a></div></div><div class=\"public anchor\" id=\"var-ollld\"><h3>ollld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ollld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1761\">view source</a></div></div><div class=\"public anchor\" id=\"var-ollll\"><h3>ollll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ollll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1275\">view source</a></div></div><div class=\"public anchor\" id=\"var-olllo\"><h3>olllo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olllo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L789\">view source</a></div></div><div class=\"public anchor\" id=\"var-ollo\"><h3>ollo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ollo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L255\">view source</a></div></div><div class=\"public anchor\" id=\"var-ollod\"><h3>ollod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ollod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1755\">view source</a></div></div><div class=\"public anchor\" id=\"var-ollol\"><h3>ollol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ollol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1269\">view source</a></div></div><div class=\"public anchor\" id=\"var-olloo\"><h3>olloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L783\">view source</a></div></div><div class=\"public anchor\" id=\"var-olo\"><h3>olo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olo f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L81\">view source</a></div></div><div class=\"public anchor\" id=\"var-olod\"><h3>olod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olod f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L573\">view source</a></div></div><div class=\"public anchor\" id=\"var-olodd\"><h3>olodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1749\">view source</a></div></div><div class=\"public anchor\" id=\"var-olodl\"><h3>olodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1263\">view source</a></div></div><div class=\"public anchor\" id=\"var-olodo\"><h3>olodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L777\">view source</a></div></div><div class=\"public anchor\" id=\"var-olol\"><h3>olol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olol f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L411\">view source</a></div></div><div class=\"public anchor\" id=\"var-olold\"><h3>olold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1743\">view source</a></div></div><div class=\"public anchor\" id=\"var-ololl\"><h3>ololl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ololl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1257\">view source</a></div></div><div class=\"public anchor\" id=\"var-ololo\"><h3>ololo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ololo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L771\">view source</a></div></div><div class=\"public anchor\" id=\"var-oloo\"><h3>oloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oloo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L249\">view source</a></div></div><div class=\"public anchor\" id=\"var-olood\"><h3>olood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1737\">view source</a></div></div><div class=\"public anchor\" id=\"var-olool\"><h3>olool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1251\">view source</a></div></div><div class=\"public anchor\" id=\"var-olooo\"><h3>olooo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(olooo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L765\">view source</a></div></div><div class=\"public anchor\" id=\"var-ood\"><h3>ood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ood f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L183\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodd\"><h3>oodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodd f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L567\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooddd\"><h3>ooddd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooddd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1731\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooddl\"><h3>ooddl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooddl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1245\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooddo\"><h3>ooddo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooddo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L759\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodl\"><h3>oodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodl f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L405\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodld\"><h3>oodld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1725\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodll\"><h3>oodll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1239\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodlo\"><h3>oodlo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodlo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L753\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodo\"><h3>oodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L243\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodod\"><h3>oodod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1719\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodol\"><h3>oodol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1233\">view source</a></div></div><div class=\"public anchor\" id=\"var-oodoo\"><h3>oodoo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oodoo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L747\">view source</a></div></div><div class=\"public anchor\" id=\"var-ool\"><h3>ool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ool f arg0 arg1)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L129\">view source</a></div></div><div class=\"public anchor\" id=\"var-oold\"><h3>oold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oold f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L561\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooldd\"><h3>ooldd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooldd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1713\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooldl\"><h3>ooldl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooldl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1227\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooldo\"><h3>ooldo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooldo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L741\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooll\"><h3>ooll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooll f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L399\">view source</a></div></div><div class=\"public anchor\" id=\"var-oolld\"><h3>oolld</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oolld f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1707\">view source</a></div></div><div class=\"public anchor\" id=\"var-oolll\"><h3>oolll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oolll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1221\">view source</a></div></div><div class=\"public anchor\" id=\"var-oollo\"><h3>oollo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oollo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L735\">view source</a></div></div><div class=\"public anchor\" id=\"var-oolo\"><h3>oolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oolo f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L237\">view source</a></div></div><div class=\"public anchor\" id=\"var-oolod\"><h3>oolod</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oolod f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1701\">view source</a></div></div><div class=\"public anchor\" id=\"var-oolol\"><h3>oolol</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oolol f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1215\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooloo\"><h3>ooloo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooloo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L729\">view source</a></div></div><div class=\"public anchor\" id=\"var-oood\"><h3>oood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oood f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L555\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooodd\"><h3>ooodd</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooodd f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1695\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooodl\"><h3>ooodl</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooodl f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1209\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooodo\"><h3>ooodo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooodo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L723\">view source</a></div></div><div class=\"public anchor\" id=\"var-oool\"><h3>oool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oool f arg0 arg1 arg2)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L393\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooold\"><h3>ooold</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooold f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1689\">view source</a></div></div><div class=\"public anchor\" id=\"var-oooll\"><h3>oooll</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(oooll f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1203\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooolo\"><h3>ooolo</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooolo f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L717\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooood\"><h3>ooood</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooood f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1683\">view source</a></div></div><div class=\"public anchor\" id=\"var-ooool\"><h3>ooool</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(ooool f arg0 arg1 arg2 arg3)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/primitive_invoke.clj#L1197\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.process.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.process documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-destroy-forcibly.21\"><div class=\"inner\"><span>destroy-forcibly!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-launch\"><div class=\"inner\"><span>launch</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-launch-jvm\"><div class=\"inner\"><span>launch-jvm</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-out-rf\"><div class=\"inner\"><span>out-rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-println-rf\"><div class=\"inner\"><span>println-rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-process-descendants\"><div class=\"inner\"><span>process-descendants</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-quiet-rf\"><div class=\"inner\"><span>quiet-rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-record-rf\"><div class=\"inner\"><span>record-rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-sh\"><div class=\"inner\"><span>sh</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.process.html#var-stream-.3Estrings\"><div class=\"inner\"><span>stream-&gt;strings</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.process</h1><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"public anchor\" id=\"var-destroy-forcibly.21\"><h3>destroy-forcibly!</h3><div class=\"usage\"><code>(destroy-forcibly! proc-hdl)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Destroy the process handle's process forcibly.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L61\">view source</a></div></div><div class=\"public anchor\" id=\"var-launch\"><h3>launch</h3><div class=\"usage\"><code>(launch cmd-line)</code><code>(launch cmd-line {:keys [stdout-hdlr stderr-hdlr print-cmd-line?], :or {print-cmd-line? true}})</code></div><div class=\"doc\"><div class=\"markdown\"><p>Launch a proccess.</p>\n<ul>\n<li>cmd-line string command line.</li>\n<li>stdout-hdrl, stderr-hdlr - transduce-style rf functions that receive each string read from stdout\nand stderr respectively.</li>\n</ul>\n<p>Returns <code>{:keys [^java.lang.ProcessHandle proc-hdl wait-or-kill]}</code>:</p>\n<ul>\n<li><code>proc-hdl</code> -  java.lang.ProcessHandle</li>\n<li><code>wait-or-kill</code> - function that has two arities:\n<ol>\n<li>(proc) - kill the process returning any output as {:out :err}.</li>\n<li>(proc time-ms timeout-symbol) - wait specified time for process to terminate returning either\nthe timeout symbol or {:out :err}.</li>\n</ol>\n</li>\n</ul>\n<p>Example:</p>\n<pre><code class=\"language-clojure\">ham-fisted.process&gt; (launch \"ls -al\" {:print-cmd-line? false})\n  {:proc-hdl #object[java.lang.ProcessHandleImpl 0x7f8e8742 \"31019\"],\n  :wait-or-kill #function[ham-fisted.process/launch/wait-or-kill--65545]}\n  ...\n\nham-fisted.process&gt; (def result ((:wait-or-kill *1)))\n#'ham-fisted.process/result\nham-fisted.process&gt; (keys result)\n(:out :err)\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L74\">view source</a></div></div><div class=\"public anchor\" id=\"var-launch-jvm\"><h3>launch-jvm</h3><div class=\"usage\"><code>(launch-jvm cmd-name {:keys [xmx jvm-opts], :as args})</code></div><div class=\"doc\"><div class=\"markdown\"><p>Assumes a jvm process launched from a shell command.  Will hang looking for first process descendant.</p>\n<p>If shell command then arguments other than :xmx :jvm-opts may need to have quoted strings if they are\nbeing passed the clojure process.</p>\n<p>Example:</p>\n<pre><code class=\"language-clojure\">ham-fisted.process&gt; (launch-jvm \"clojure\" {:jvm-opts [\"-A:dev\" \"-X\" \"ham-fisted.protocol-perf/-main\"]})\nlaunch-process: clojure -A:dev -X ham-fisted.protocol-perf/-main\n{:proc-hdl #object[java.lang.ProcessHandleImpl 0x4f4a8dc7 \"31194\"],\n :wait-or-kill #function[ham-fisted.process/launch/wait-or-kill--10016],\n :jvm-pid 31199,\n  :jvm-proc #object[java.lang.ProcessHandleImpl 0x2e52e7c8 \"31199\"]}\n...\nham-fisted.process&gt; (def result ((:wait-or-kill *1)))\n#'ham-fisted.process/result\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L151\">view source</a></div></div><div class=\"public anchor\" id=\"var-out-rf\"><h3>out-rf</h3><div class=\"usage\"><code>(out-rf print?)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L31\">view source</a></div></div><div class=\"public anchor\" id=\"var-println-rf\"><h3>println-rf</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Print process output using println.  Example process output handler.\nReturns total output as a string to when finalized.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L48\">view source</a></div></div><div class=\"public anchor\" id=\"var-process-descendants\"><h3>process-descendants</h3><div class=\"usage\"><code>(process-descendants proc-hdl)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Get the first descendants of a process handle.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L66\">view source</a></div></div><div class=\"public anchor\" id=\"var-quiet-rf\"><h3>quiet-rf</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Returns total output as a string to when finalized.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L52\">view source</a></div></div><div class=\"public anchor\" id=\"var-record-rf\"><h3>record-rf</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Record all the strings and save them to a vector</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L54\">view source</a></div></div><div class=\"public anchor\" id=\"var-sh\"><h3>sh</h3><div class=\"usage\"><code>(sh cmd-line)</code><code>(sh cmd-line {:keys [timeout-ms], :or {timeout-ms Integer/MAX_VALUE}, :as opts})</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L137\">view source</a></div></div><div class=\"public anchor\" id=\"var-stream-.3Estrings\"><h3>stream-&gt;strings</h3><div class=\"usage\"><code>(stream-&gt;strings input)</code><code>(stream-&gt;strings input bufsize charset)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/process.clj#L5\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.profile.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.profile documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.profile.html#var-current-times\"><div class=\"inner\"><span>current-times</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.profile.html#var-reset-times.21\"><div class=\"inner\"><span>reset-times!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.profile.html#var-time-ms\"><div class=\"inner\"><span>time-ms</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.profile.html#var-with-times\"><div class=\"inner\"><span>with-times</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.profile</h1><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"public anchor\" id=\"var-current-times\"><h3>current-times</h3><div class=\"usage\"><code>(current-times)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Get the current time map</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/profile.clj#L19\">view source</a></div></div><div class=\"public anchor\" id=\"var-reset-times.21\"><h3>reset-times!</h3><div class=\"usage\"><code>(reset-times!)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Clear times out of current time map</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/profile.clj#L20\">view source</a></div></div><div class=\"public anchor\" id=\"var-time-ms\"><h3>time-ms</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(time-ms kw &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Time an operation returning the results.  Puts time in double milliseconds\ninto the time map.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/profile.clj#L9\">view source</a></div></div><div class=\"public anchor\" id=\"var-with-times\"><h3>with-times</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(with-times &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns {:result :times}. Run a block of code with time map bound to a new map.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/profile.clj#L22\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.protocols.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.protocols documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var--.3Ecollection\"><div class=\"inner\"><span>-&gt;collection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var--.3Einit-val-fn\"><div class=\"inner\"><span>-&gt;init-val-fn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var--.3Eiterable\"><div class=\"inner\"><span>-&gt;iterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var--.3Emerge-fn\"><div class=\"inner\"><span>-&gt;merge-fn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var--.3Erfn\"><div class=\"inner\"><span>-&gt;rfn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var--.3Espliterator\"><div class=\"inner\"><span>-&gt;spliterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-add-fn\"><div class=\"inner\"><span>add-fn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-BitSet\"><div class=\"inner\"><span>BitSet</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-bitset.3F\"><div class=\"inner\"><span>bitset?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-BulkSetOps\"><div class=\"inner\"><span>BulkSetOps</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-cardinality\"><div class=\"inner\"><span>cardinality</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-contained-datatype\"><div class=\"inner\"><span>contained-datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ContainedDatatype\"><div class=\"inner\"><span>ContainedDatatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-contains-fn\"><div class=\"inner\"><span>contains-fn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-contains-range.3F\"><div class=\"inner\"><span>contains-range?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-convertible-to-collection.3F\"><div class=\"inner\"><span>convertible-to-collection?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-convertible-to-iterable.3F\"><div class=\"inner\"><span>convertible-to-iterable?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-count\"><div class=\"inner\"><span>count</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-Counted\"><div class=\"inner\"><span>Counted</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-Datatype\"><div class=\"inner\"><span>Datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-datatype\"><div class=\"inner\"><span>datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-difference\"><div class=\"inner\"><span>difference</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-estimate-count\"><div class=\"inner\"><span>estimate-count</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-EstimateCount\"><div class=\"inner\"><span>EstimateCount</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-Finalize\"><div class=\"inner\"><span>Finalize</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-finalize\"><div class=\"inner\"><span>finalize</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-intersection\"><div class=\"inner\"><span>intersection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-intersects-range.3F\"><div class=\"inner\"><span>intersects-range?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-managed-blocker\"><div class=\"inner\"><span>managed-blocker</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ManagedBlocker\"><div class=\"inner\"><span>ManagedBlocker</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-max-set-value\"><div class=\"inner\"><span>max-set-value</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-min-set-value\"><div class=\"inner\"><span>min-set-value</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-PAdd\"><div class=\"inner\"><span>PAdd</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ParallelReducer\"><div class=\"inner\"><span>ParallelReducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ParallelReduction\"><div class=\"inner\"><span>ParallelReduction</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-preduce\"><div class=\"inner\"><span>preduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-reduce-intersection\"><div class=\"inner\"><span>reduce-intersection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-reduce-union\"><div class=\"inner\"><span>reduce-union</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-Reducer\"><div class=\"inner\"><span>Reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-reducible.3F\"><div class=\"inner\"><span>reducible?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-Reduction\"><div class=\"inner\"><span>Reduction</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-returned-datatype\"><div class=\"inner\"><span>returned-datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ReturnedDatatype\"><div class=\"inner\"><span>ReturnedDatatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-serialize-.3Ebytes\"><div class=\"inner\"><span>serialize-&gt;bytes</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-SerializeObjBytes\"><div class=\"inner\"><span>SerializeObjBytes</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-set.3F\"><div class=\"inner\"><span>set?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-SetOps\"><div class=\"inner\"><span>SetOps</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-simplified-contained-datatype\"><div class=\"inner\"><span>simplified-contained-datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-simplified-datatype\"><div class=\"inner\"><span>simplified-datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-simplified-returned-datatype\"><div class=\"inner\"><span>simplified-returned-datatype</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-Split\"><div class=\"inner\"><span>Split</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-split\"><div class=\"inner\"><span>split</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ToCollection\"><div class=\"inner\"><span>ToCollection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ToIterable\"><div class=\"inner\"><span>ToIterable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-ToSpliterator\"><div class=\"inner\"><span>ToSpliterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-union\"><div class=\"inner\"><span>union</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-wrap-array\"><div class=\"inner\"><span>wrap-array</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-wrap-array-growable\"><div class=\"inner\"><span>wrap-array-growable</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-WrapArray\"><div class=\"inner\"><span>WrapArray</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.protocols.html#var-xor\"><div class=\"inner\"><span>xor</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.protocols</h1><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"public anchor\" id=\"var--.3Ecollection\"><h3>-&gt;collection</h3><div class=\"usage\"><code>(-&gt;collection item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L18\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Einit-val-fn\"><h3>-&gt;init-val-fn</h3><div class=\"usage\"><code>(-&gt;init-val-fn item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns the initial values for a parallel reduction.  This function\ntakes no arguments and returns the initial accumulator.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L66\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Eiterable\"><h3>-&gt;iterable</h3><div class=\"usage\"><code>(-&gt;iterable item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L13\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Emerge-fn\"><h3>-&gt;merge-fn</h3><div class=\"usage\"><code>(-&gt;merge-fn item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns the merge function for a parallel reduction.  This function takes\ntwo accumulators  and returns a or modified accumulator.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L83\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Erfn\"><h3>-&gt;rfn</h3><div class=\"usage\"><code>(-&gt;rfn item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns the reduction function for a parallel reduction. This function takes\ntwo arguments, the accumulator and a value from the collection and returns a new\nor modified accumulator.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L66\">view source</a></div></div><div class=\"public anchor\" id=\"var--.3Espliterator\"><h3>-&gt;spliterator</h3><div class=\"usage\"><code>(-&gt;spliterator m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L204\">view source</a></div></div><div class=\"public anchor\" id=\"var-add-fn\"><h3>add-fn</h3><div class=\"usage\"><code>(add-fn l)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L113\">view source</a></div></div><div class=\"public anchor\" id=\"var-BitSet\"><h3>BitSet</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Protocol for efficiently dealing with bitsets</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-bitset.3F\"><h3>bitset?</h3><div class=\"usage\"><code>(bitset? item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-BulkSetOps\"><h3>BulkSetOps</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L131\">view source</a></div></div><div class=\"public anchor\" id=\"var-cardinality\"><h3>cardinality</h3><div class=\"usage\"><code>(cardinality item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Some sets don't work with clojure's count function.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-contained-datatype\"><h3>contained-datatype</h3><div class=\"usage\"><code>(contained-datatype o)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Datatype of contained datatype - may be nil if not a container</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L168\">view source</a></div></div><div class=\"public anchor\" id=\"var-ContainedDatatype\"><h3>ContainedDatatype</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L168\">view source</a></div></div><div class=\"public anchor\" id=\"var-contains-fn\"><h3>contains-fn</h3><div class=\"usage\"><code>(contains-fn item)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an efficient function for deciding if this set contains a single item.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-contains-range.3F\"><h3>contains-range?</h3><div class=\"usage\"><code>(contains-range? item sidx eidx)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-convertible-to-collection.3F\"><h3>convertible-to-collection?</h3><div class=\"usage\"><code>(convertible-to-collection? item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L18\">view source</a></div></div><div class=\"public anchor\" id=\"var-convertible-to-iterable.3F\"><h3>convertible-to-iterable?</h3><div class=\"usage\"><code>(convertible-to-iterable? item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L13\">view source</a></div></div><div class=\"public anchor\" id=\"var-count\"><h3>count</h3><div class=\"usage\"><code>(count m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L10\">view source</a></div></div><div class=\"public anchor\" id=\"var-Counted\"><h3>Counted</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L10\">view source</a></div></div><div class=\"public anchor\" id=\"var-Datatype\"><h3>Datatype</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L154\">view source</a></div></div><div class=\"public anchor\" id=\"var-datatype\"><h3>datatype</h3><div class=\"usage\"><code>(datatype o)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns the datatype <a href=\":int8, :int16, etc\">:int8, :int16, etc</a> -- if known --\nelse the type can be assumed to be an object type.  The return value may not be a keyword\nbut it must be comparable with identical?</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L154\">view source</a></div></div><div class=\"public anchor\" id=\"var-difference\"><h3>difference</h3><div class=\"usage\"><code>(difference l r)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-estimate-count\"><h3>estimate-count</h3><div class=\"usage\"><code>(estimate-count m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L195\">view source</a></div></div><div class=\"public anchor\" id=\"var-EstimateCount\"><h3>EstimateCount</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L195\">view source</a></div></div><div class=\"public anchor\" id=\"var-Finalize\"><h3>Finalize</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Generic protocol for things that finalize results of reductions.  Defaults to deref of\ninstance of IDeref or identity.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L48\">view source</a></div></div><div class=\"public anchor\" id=\"var-finalize\"><h3>finalize</h3><div class=\"usage\"><code>(finalize this val)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L48\">view source</a></div></div><div class=\"public anchor\" id=\"var-intersection\"><h3>intersection</h3><div class=\"usage\"><code>(intersection l r)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-intersects-range.3F\"><h3>intersects-range?</h3><div class=\"usage\"><code>(intersects-range? item sidx eidx)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-managed-blocker\"><h3>managed-blocker</h3><div class=\"usage\"><code>(managed-blocker m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L201\">view source</a></div></div><div class=\"public anchor\" id=\"var-ManagedBlocker\"><h3>ManagedBlocker</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L201\">view source</a></div></div><div class=\"public anchor\" id=\"var-max-set-value\"><h3>max-set-value</h3><div class=\"usage\"><code>(max-set-value item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-min-set-value\"><h3>min-set-value</h3><div class=\"usage\"><code>(min-set-value item)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L136\">view source</a></div></div><div class=\"public anchor\" id=\"var-PAdd\"><h3>PAdd</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Define a function to mutably add items to a collection.  This function must return\nthe collection -- it must be useable in a reduce as the rf.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L113\">view source</a></div></div><div class=\"public anchor\" id=\"var-ParallelReducer\"><h3>ParallelReducer</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Parallel reducers are simple a single object that you can pass into preduce as\nopposed to 3 separate functions.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L83\">view source</a></div></div><div class=\"public anchor\" id=\"var-ParallelReduction\"><h3>ParallelReduction</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Protocol to define a parallel reduction in a collection-specific pathway.  Specializations\nare in impl as that is where the parallelization routines are found.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L40\">view source</a></div></div><div class=\"public anchor\" id=\"var-preduce\"><h3>preduce</h3><div class=\"usage\"><code>(preduce coll init-val-fn rfn merge-fn options)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Container-specific parallelized reduction.  Reductions must respect the pool passed in via\nthe options.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L40\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduce-intersection\"><h3>reduce-intersection</h3><div class=\"usage\"><code>(reduce-intersection l data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L131\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduce-union\"><h3>reduce-union</h3><div class=\"usage\"><code>(reduce-union l data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L131\">view source</a></div></div><div class=\"public anchor\" id=\"var-Reducer\"><h3>Reducer</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Reducer is the basic reduction abstraction as a single object.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L66\">view source</a></div></div><div class=\"public anchor\" id=\"var-reducible.3F\"><h3>reducible?</h3><div class=\"usage\"><code>(reducible? coll)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L23\">view source</a></div></div><div class=\"public anchor\" id=\"var-Reduction\"><h3>Reduction</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Faster check than satisfies? to see if something is reducible</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L23\">view source</a></div></div><div class=\"public anchor\" id=\"var-returned-datatype\"><h3>returned-datatype</h3><div class=\"usage\"><code>(returned-datatype o)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L183\">view source</a></div></div><div class=\"public anchor\" id=\"var-ReturnedDatatype\"><h3>ReturnedDatatype</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L183\">view source</a></div></div><div class=\"public anchor\" id=\"var-serialize-.3Ebytes\"><h3>serialize-&gt;bytes</h3><div class=\"usage\"><code>(serialize-&gt;bytes o)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L150\">view source</a></div></div><div class=\"public anchor\" id=\"var-SerializeObjBytes\"><h3>SerializeObjBytes</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L150\">view source</a></div></div><div class=\"public anchor\" id=\"var-set.3F\"><h3>set?</h3><div class=\"usage\"><code>(set? l)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-SetOps\"><h3>SetOps</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Simple protocol for set operations to make them uniformly extensible to new objects.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-simplified-contained-datatype\"><h3>simplified-contained-datatype</h3><div class=\"usage\"><code>(simplified-contained-datatype o)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Exactly :int64 :float64 :object or nil</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L168\">view source</a></div></div><div class=\"public anchor\" id=\"var-simplified-datatype\"><h3>simplified-datatype</h3><div class=\"usage\"><code>(simplified-datatype o)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Returns exactly :int64, :float64, or :object</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L154\">view source</a></div></div><div class=\"public anchor\" id=\"var-simplified-returned-datatype\"><h3>simplified-returned-datatype</h3><div class=\"usage\"><code>(simplified-returned-datatype o)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L183\">view source</a></div></div><div class=\"public anchor\" id=\"var-Split\"><h3>Split</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L198\">view source</a></div></div><div class=\"public anchor\" id=\"var-split\"><h3>split</h3><div class=\"usage\"><code>(split m)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L198\">view source</a></div></div><div class=\"public anchor\" id=\"var-ToCollection\"><h3>ToCollection</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L18\">view source</a></div></div><div class=\"public anchor\" id=\"var-ToIterable\"><h3>ToIterable</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L13\">view source</a></div></div><div class=\"public anchor\" id=\"var-ToSpliterator\"><h3>ToSpliterator</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L204\">view source</a></div></div><div class=\"public anchor\" id=\"var-union\"><h3>union</h3><div class=\"usage\"><code>(union l r)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div><div class=\"public anchor\" id=\"var-wrap-array\"><h3>wrap-array</h3><div class=\"usage\"><code>(wrap-array ary)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L145\">view source</a></div></div><div class=\"public anchor\" id=\"var-wrap-array-growable\"><h3>wrap-array-growable</h3><div class=\"usage\"><code>(wrap-array-growable ary ptr)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L145\">view source</a></div></div><div class=\"public anchor\" id=\"var-WrapArray\"><h3>WrapArray</h3><h4 class=\"type\">protocol</h4><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L145\">view source</a></div></div><div class=\"public anchor\" id=\"var-xor\"><h3>xor</h3><div class=\"usage\"><code>(xor l r)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/protocols.clj#L118\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.reduce.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.reduce documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var--.3Econsumer\"><div class=\"inner\"><span>-&gt;consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-bind-double-consumer-reducer.21\"><div class=\"inner\"><span>bind-double-consumer-reducer!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-compose-reducers\"><div class=\"inner\"><span>compose-reducers</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-consume.21\"><div class=\"inner\"><span>consume!</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-consumer-accumulator\"><div class=\"inner\"><span>consumer-accumulator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-consumer-preducer\"><div class=\"inner\"><span>consumer-preducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-consumer-reducer\"><div class=\"inner\"><span>consumer-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-double-accumulator\"><div class=\"inner\"><span>double-accumulator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-double-consumer-accumulator\"><div class=\"inner\"><span>double-consumer-accumulator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-double-consumer-preducer\"><div class=\"inner\"><span>double-consumer-preducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-double-consumer-reducer\"><div class=\"inner\"><span>double-consumer-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-immut-map-kv\"><div class=\"inner\"><span>immut-map-kv</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-indexed-accum\"><div class=\"inner\"><span>indexed-accum</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-indexed-double-accum\"><div class=\"inner\"><span>indexed-double-accum</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-indexed-long-accum\"><div class=\"inner\"><span>indexed-long-accum</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-long-accumulator\"><div class=\"inner\"><span>long-accumulator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-long-consumer-accumulator\"><div class=\"inner\"><span>long-consumer-accumulator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-long-consumer-reducer\"><div class=\"inner\"><span>long-consumer-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-options-.3Eparallel-options\"><div class=\"inner\"><span>options-&gt;parallel-options</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-parallel-reducer\"><div class=\"inner\"><span>parallel-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-preduce\"><div class=\"inner\"><span>preduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-preduce-reducer\"><div class=\"inner\"><span>preduce-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-preduce-reducers\"><div class=\"inner\"><span>preduce-reducers</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reduce-reducer\"><div class=\"inner\"><span>reduce-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reduce-reducers\"><div class=\"inner\"><span>reduce-reducers</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reducer-.3Ecompletef\"><div class=\"inner\"><span>reducer-&gt;completef</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reducer-.3Erf\"><div class=\"inner\"><span>reducer-&gt;rf</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reducer-with-finalize\"><div class=\"inner\"><span>reducer-with-finalize</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reducer-xform-.3Ereducer\"><div class=\"inner\"><span>reducer-xform-&gt;reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.reduce.html#var-reducible-merge\"><div class=\"inner\"><span>reducible-merge</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.reduce</h1><div class=\"doc\"><div class=\"markdown\"><p>Protocol-based parallel reduction architecture and helper functions.</p>\n</div></div><div class=\"public anchor\" id=\"var--.3Econsumer\"><h3>-&gt;consumer</h3><div class=\"usage\"><code>(-&gt;consumer cfn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an instance of a consumer, double consumer, or long consumer.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L474\">view source</a></div></div><div class=\"public anchor\" id=\"var-bind-double-consumer-reducer.21\"><h3>bind-double-consumer-reducer!</h3><div class=\"usage\"><code>(bind-double-consumer-reducer! cls-type ctor)</code><code>(bind-double-consumer-reducer! ctor)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Bind a classtype as a double consumer parallel reducer - the consumer must implement\nDoubleConsumer, ham_fisted.Reducible, and IDeref.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L660\">view source</a></div></div><div class=\"public anchor\" id=\"var-compose-reducers\"><h3>compose-reducers</h3><div class=\"usage\"><code>(compose-reducers reducers)</code><code>(compose-reducers options reducers)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a map or sequence of reducers return a new reducer that produces a map or\nvector of results.</p>\n<p>If data is a sequence then context is guaranteed to be an object array.</p>\n<p>Options:</p>\n<ul>\n<li><code>:rfn-datatype</code> - One of nil, :int64, or :float64.  This indicates that the rfn's\nshould all be uniform as accepting longs, doubles, or generically objects.  Defaults\nto nil.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L203\">view source</a></div></div><div class=\"public anchor\" id=\"var-consume.21\"><h3>consume!</h3><div class=\"usage\"><code>(consume! consumer coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Consumer a collection.  This is simply a reduction where the return value\nis ignored.</p>\n<p>Returns the consumer.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L490\">view source</a></div></div><div class=\"public anchor\" id=\"var-consumer-accumulator\"><h3>consumer-accumulator</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Generic reduction function using a consumer</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L411\">view source</a></div></div><div class=\"public anchor\" id=\"var-consumer-preducer\"><h3>consumer-preducer</h3><div class=\"usage\"><code>(consumer-preducer constructor)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Bind a consumer as a parallel reducer.</p>\n<p>Consumer must implement java.util.function.Consumer,\nham_fisted.Reducible and clojure.lang.IDeref.</p>\n<p>Returns instance of type bound.</p>\n<p>See documentation for <a href=\"declare-double-consumer-preducer!\">declare-double-consumer-preducer!</a>.</p>\n<pre><code></code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L638\">view source</a></div></div><div class=\"public anchor\" id=\"var-consumer-reducer\"><h3>consumer-reducer</h3><div class=\"usage\"><code>(consumer-reducer ctor)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Make a parallel double consumer reducer given a function that takes no arguments and is\nguaranteed to produce a double consumer which also implements Reducible and IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L706\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-accumulator\"><h3>double-accumulator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(double-accumulator accvar varvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Type-hinted double reduction accumulator.\nconsumer:</p>\n<pre><code class=\"language-clojure\">  ham-fisted.api&gt; (reduce (double-accumulator acc v (+ (double acc) v))\n                             0.0\n                             (range 1000))\n#&lt;SimpleSum@2fbcf20: 499500.0&gt;\nham-fisted.api&gt; @*1\n499500.0\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L151\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-consumer-accumulator\"><h3>double-consumer-accumulator</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Converts from a double consumer to a double reduction accumulator that returns the\nconsumer:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce double-consumer-accumulator\n                             (Sum$SimpleSum.)\n                             (range 1000))\n#&lt;SimpleSum@2fbcf20: 499500.0&gt;\nham-fisted.api&gt; @*1\n499500.0\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L382\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-consumer-preducer\"><h3>double-consumer-preducer</h3><div class=\"usage\"><code>(double-consumer-preducer constructor)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a preducer for a double consumer.</p>\n<p>Consumer must implement java.util.function.DoubleConsumer,\nham_fisted.Reducible and clojure.lang.IDeref.</p>\n<pre><code class=\"language-clojure\">user&gt; (require '[ham-fisted.api :as hamf])\nnil\nuser&gt; (import '[java.util.function DoubleConsumer])\njava.util.function.DoubleConsumer\nuser&gt; (import [ham_fisted Reducible])\nham_fisted.Reducible\nuser&gt; (import '[clojure.lang IDeref])\nclojure.lang.IDeref\nuser&gt; (deftype MeanR [^{:unsynchronized-mutable true :tag 'double} sum\n                      ^{:unsynchronized-mutable true :tag 'long} n-elems]\n        DoubleConsumer\n        (accept [this v] (set! sum (+ sum v)) (set! n-elems (unchecked-inc n-elems)))\n        Reducible\n        (reduce [this o]\n          (set! sum (+ sum (.-sum ^MeanR o)))\n          (set! n-elems (+ n-elems (.-n-elems ^MeanR o)))\n          this)\n        IDeref (deref [this] (/ sum n-elems)))\nuser.MeanR\nuser&gt; (hamf/declare-double-consumer-preducer! MeanR (MeanR. 0 0))\nnil\n  user&gt; (hamf/preduce-reducer (double-consumer-preducer #(MeanR. 0 0)) (hamf/range 200000))\n99999.5\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L507\">view source</a></div></div><div class=\"public anchor\" id=\"var-double-consumer-reducer\"><h3>double-consumer-reducer</h3><div class=\"usage\"><code>(double-consumer-reducer ctor)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Make a parallel double consumer reducer given a function that takes no arguments and is\nguaranteed to produce a double consumer which also implements Reducible and IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L678\">view source</a></div></div><div class=\"public anchor\" id=\"var-immut-map-kv\"><h3>immut-map-kv</h3><div class=\"usage\"><code>(immut-map-kv keyfn valfn data)</code><code>(immut-map-kv ks vs)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L186\">view source</a></div></div><div class=\"public anchor\" id=\"var-indexed-accum\"><h3>indexed-accum</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(indexed-accum accvar idxvar varvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an indexed accumulator that recieves and additional long index\nduring a reduction:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce (indexed-accum\n                         acc idx v (conj acc [idx v]))\n                        []\n                        (range 5))\n[[0 0] [1 1] [2 2] [3 3] [4 4]]\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L420\">view source</a></div></div><div class=\"public anchor\" id=\"var-indexed-double-accum\"><h3>indexed-double-accum</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(indexed-double-accum accvar idxvar varvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an indexed double accumulator that recieves and additional long index\nduring a reduction:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce (indexed-double-accum\n                         acc idx v (conj acc [idx v]))\n                        []\n                        (range 5))\n[[0 0.0] [1 1.0] [2 2.0] [3 3.0] [4 4.0]]\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L438\">view source</a></div></div><div class=\"public anchor\" id=\"var-indexed-long-accum\"><h3>indexed-long-accum</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(indexed-long-accum accvar idxvar varvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create an indexed long accumulator that recieves and additional long index\nduring a reduction:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce (indexed-long-accum\n                         acc idx v (conj acc [idx v]))\n                        []\n                        (range 5))\n[[0 0] [1 1] [2 2] [3 3] [4 4]]\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L456\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-accumulator\"><h3>long-accumulator</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(long-accumulator accvar varvar &amp; code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Type-hinted double reduction accumulator.\nconsumer:</p>\n<pre><code class=\"language-clojure\">  ham-fisted.api&gt; (reduce (double-accumulator acc v (+ (double acc) v))\n                             0.0\n                             (range 1000))\n#&lt;SimpleSum@2fbcf20: 499500.0&gt;\nham-fisted.api&gt; @*1\n499500.0\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L169\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-consumer-accumulator\"><h3>long-consumer-accumulator</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Converts from a long consumer to a long reduction accumulator that returns the\nconsumer:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce double-consumer-accumulator\n                             (Sum$SimpleSum.)\n                             (range 1000))\n#&lt;SimpleSum@2fbcf20: 499500.0&gt;\nham-fisted.api&gt; @*1\n499500.0\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L396\">view source</a></div></div><div class=\"public anchor\" id=\"var-long-consumer-reducer\"><h3>long-consumer-reducer</h3><div class=\"usage\"><code>(long-consumer-reducer ctor)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Make a parallel double consumer reducer given a function that takes no arguments and is\nguaranteed to produce a double consumer which also implements Reducible and IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L692\">view source</a></div></div><div class=\"public anchor\" id=\"var-options-.3Eparallel-options\"><h3>options-&gt;parallel-options</h3><div class=\"usage\"><code>(options-&gt;parallel-options options)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Convert an options map to a parallel options object.</p>\n<p>Options:</p>\n<ul>\n<li><code>:pool</code> - supply the forkjoinpool to use.</li>\n<li><code>:max-batch-size</code> - Defaults to 64000, used for index-based  parallel pathways to control\nthe number size of each parallelized batch.</li>\n<li><code>:ordered?</code> - When true process inputs and provide results in order.</li>\n<li><code>:parallelism</code> - The amount of parallelism to expect.  Defaults to the number of threads\nin the fork-join pool provided.</li>\n<li><code>:cat-parallelism</code> - Either <code>:seq-wise</code> or <code>:elem-wise</code> - when parallelizing over a\nconcatenation of containers either parallelize each container meaning call preduce on each\ncontainer using many threads per container or use one thread per container - <code>seq-wise</code>.  Defaults\nto <code>seq-wise</code> as this doesn't require each container itself to support parallelization but relies on\nthe sequence of containers to be long enough to saturate the processor.  Can also be set at time of\ncontainer construction - see <a href=\"ham-fisted.lazy-noncaching.html#var-concat-opts\">lazy-noncaching/concat-opts</a>.</li>\n<li><code>:put-timeout-ms</code> - The time to wait to put data into the queue.  This is a safety mechanism\nso that if the processing system fails we don't just keep putting things into a queue.</li>\n<li><code>:unmerged-result?</code> - Use with care.  For parallel reductions do not perform the merge step\nbut instead return the sequence of partially reduced results.</li>\n<li><code>:n-lookahead</code> - How for to look ahead for pmap and upmap to add new jobs to the queue.  Defaults\nto `(* 2 parallelism).</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L27\">view source</a></div></div><div class=\"public anchor\" id=\"var-parallel-reducer\"><h3>parallel-reducer</h3><div class=\"usage\"><code>(parallel-reducer init-fn rfn merge-fn fin-fn)</code><code>(parallel-reducer init-fn rfn merge-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Implement a parallel reducer by explicitly passing in the various required functions.</p>\n<ul>\n<li>'init-fn' - Takes no argumenst and returns a new accumulation target.</li>\n<li>'rfn' - clojure rf function - takes two arguments, the accumulation target and a new value\nand produces a new accumulation target.</li>\n<li>'merge-fn' - Given two accumulation targets returns a new combined accumulation target.</li>\n<li>'fin-fn' - optional - Given an accumulation target returns the desired final type.</li>\n</ul>\n<pre><code class=\"language-clojure\">user&gt; (hamf-rf/preduce-reducer\n       (hamf-rf/parallel-reducer\n        hamf/mut-set\n        #(do (.add ^java.util.Set %1 %2) %1)\n        hamf/union\n        hamf/sort)\n       (lznc/map (fn ^long [^long v] (rem v 13)) (hamf/range 1000000)))\n[0 1 2 3 4 5 6 7 8 9 10 11 12]\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L587\">view source</a></div></div><div class=\"public anchor\" id=\"var-preduce\"><h3>preduce</h3><div class=\"usage\"><code>(preduce init-val-fn rfn merge-fn coll)</code><code>(preduce init-val-fn rfn merge-fn options coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Parallelized reduction.  Currently coll must either be random access or a lznc map/filter\nchain based on one or more random access entities, hashmaps and sets from this library or\nany java.util set, hashmap or concurrent versions of these.  If input cannot be\nparallelized this lowers to a normal serial reduction.</p>\n<p>For potentially small-n invocations providing the parallel options explicitly will improve\nperformance surprisingly - converting the options map to the parallel options object\ntakes a bit of time.</p>\n<ul>\n<li><code>init-val-fn</code> - Potentially called in reduction threads to produce each initial value.</li>\n<li><code>rfn</code> - normal clojure reduction function.  Typehinting the second argument to double\nor long will sometimes produce a faster reduction.</li>\n<li><code>merge-fn</code> - Merge two reduction results into one.</li>\n</ul>\n<p>Options:</p>\n<ul>\n<li><code>:pool</code> - The fork-join pool to use.  Defaults to common pool which assumes reduction is\ncpu-bound.</li>\n<li><code>:parallelism</code> - What parallelism to use - defaults to pool's <code>getParallelism</code> method.</li>\n<li><code>:max-batch-size</code> - Rough maximum batch size for indexed or grouped reductions.  This\ncan both even out batch times and ensure you don't get into safepoint trouble with\njdk-8.</li>\n<li><code>:min-n</code> - minimum number of elements before initiating a parallelized reduction -\nDefaults to 1000 but you should customize this particular to your specific reduction.</li>\n<li><code>:ordered?</code> - True if results should be in order.  Unordered results sometimes are\nslightly faster but again you should test for your specific situation..</li>\n<li><code>:cat-parallelism</code> - Either <code>:seq-wise</code> or <code>:elem-wise</code>, defaults to <code>:seq-wise</code>.\nTest for your specific situation, this really is data-dependent. This contols how a\nconcat primitive parallelizes the reduction across its contains.  Elemwise means each\ncontainer's reduction is individually parallelized while seqwise indicates to do a\npmap style initial reduction across containers then merge the results.</li>\n<li><code>:put-timeout-ms</code> - Number of milliseconds to wait for queue space before throwing\nan exception in unordered reductions.  Defaults to 50000.</li>\n<li><code>:unmerged-result?</code> - Defaults to false.  When true, the sequence of results\nbe returned directly without any merge steps in a lazy-noncaching container.  Beware\nthe noncaching aspect -- repeatedly evaluating this result may kick off the parallelized\nreduction multiple times.  To ensure caching if unsure call <code>seq</code> on the result.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L75\">view source</a></div></div><div class=\"public anchor\" id=\"var-preduce-reducer\"><h3>preduce-reducer</h3><div class=\"usage\"><code>(preduce-reducer reducer options coll)</code><code>(preduce-reducer reducer coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given an instance of <a href=\"ham-fisted.protocols.html#var-ParallelReducer\">ham-fisted.protocols/ParallelReducer</a>, perform a parallel\nreduction.</p>\n<p>In the case where the result is requested unmerged then finalize will\nbe called on each result in a lazy noncaching way.  In this case you can use a\nnon-parallelized reducer and simply get a sequence of results as opposed to one.</p>\n<ul>\n<li>reducer - instance of ParallelReducer</li>\n<li>options - Same options as preduce.</li>\n<li>coll - something potentially with a parallelizable reduction.</li>\n</ul>\n<p>See options for <a href=\"ham-fisted.reduce.html#var-preduce\">ham-fisted.reduce/preduce</a>.</p>\n<p>Additional Options:</p>\n<ul>\n<li><code>:skip-finalize?</code> - when true, the reducer's finalize method is not called on the result.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L119\">view source</a></div></div><div class=\"public anchor\" id=\"var-preduce-reducers\"><h3>preduce-reducers</h3><div class=\"usage\"><code>(preduce-reducers reducers options coll)</code><code>(preduce-reducers reducers coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a map or sequence of <a href=\"ham-fisted.protocols.html#var-ParallelReducer\">ham-fisted.protocols/ParallelReducer</a>, produce a map or\nsequence of reduced values. Reduces over input coll once in parallel if coll is large\nenough.  See options for <a href=\"ham-fisted.reduce.html#var-preduce\">ham-fisted.reduce/preduce</a>.</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (preduce-reducers {:sum (Sum.) :mult *} (range 20))\n{:mult 0, :sum #&lt;Sum@5082c3b7: {:sum 190.0, :n-elems 20}&gt;}\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L259\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduce-reducer\"><h3>reduce-reducer</h3><div class=\"usage\"><code>(reduce-reducer reducer coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Serially reduce a reducer.</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce-reducer (Sum.) (range 1000))\n#&lt;Sum@afbedb: {:sum 499500.0, :n-elems 1000}&gt;\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L349\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduce-reducers\"><h3>reduce-reducers</h3><div class=\"usage\"><code>(reduce-reducers reducers coll)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Serially reduce a map or sequence of reducers into a map or sequence of results.</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce-reducers {:a (Sum.) :b *} (range 1 21))\n{:b 2432902008176640000, :a #&lt;Sum@6bcebeb1: {:sum 210.0, :n-elems 20}&gt;}\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L363\">view source</a></div></div><div class=\"public anchor\" id=\"var-reducer-.3Ecompletef\"><h3>reducer-&gt;completef</h3><div class=\"usage\"><code>(reducer-&gt;completef reducer)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return fold-compatible pair of <a href=\"reducef, completef\">reducef, completef</a> given a parallel reducer.\nNote that folded reducers are not finalized as of this time:</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (def data (vec (range 200000)))\n#'ham-fisted.api/data\nham-fisted.api&gt; (r/fold (reducer-&gt;completef (Sum.)) (reducer-&gt;rfn (Sum.)) data)\n#&lt;Sum@858c206: {:sum 1.99999E10, :n-elems 200000}&gt;\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L317\">view source</a></div></div><div class=\"public anchor\" id=\"var-reducer-.3Erf\"><h3>reducer-&gt;rf</h3><div class=\"usage\"><code>(reducer-&gt;rf reducer)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a reducer, return a transduce-compatible rf -</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (transduce (clojure.core/map #(+ % 2)) (reducer-&gt;rf (Sum.)) (range 200))\n{:sum 20300.0, :n-elems 200}\n</code></pre>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L301\">view source</a></div></div><div class=\"public anchor\" id=\"var-reducer-with-finalize\"><h3>reducer-with-finalize</h3><div class=\"usage\"><code>(reducer-with-finalize reducer fin-fn)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L337\">view source</a></div></div><div class=\"public anchor\" id=\"var-reducer-xform-.3Ereducer\"><h3>reducer-xform-&gt;reducer</h3><div class=\"usage\"><code>(reducer-xform-&gt;reducer reducer xform)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a reducer and a transducer xform produce a new reducer which will apply\nthe transducer pipeline before is reduction function.</p>\n<pre><code class=\"language-clojure\">ham-fisted.api&gt; (reduce-reducer (reducer-xform-&gt;reducer (Sum.) (clojure.core/filter even?))\n                                (range 1000))\n#&lt;Sum@479456: {:sum 249500.0, :n-elems 500}&gt;\n</code></pre>\n<p>!! - If you use a stateful transducer here then you must <em>not</em> use the reducer in a\nparallelized reduction.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L273\">view source</a></div></div><div class=\"public anchor\" id=\"var-reducible-merge\"><h3>reducible-merge</h3><div class=\"usage\"></div><div class=\"doc\"><div class=\"markdown\"><p>Parallel reduction merge function that expects both sides to be an instances of\nReducible</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/reduce.clj#L416\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.set.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.set documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch current\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var--.3Einteger-random-access\"><div class=\"inner\"><span>-&gt;integer-random-access</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-bitset\"><div class=\"inner\"><span>bitset</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-bitset.3F\"><div class=\"inner\"><span>bitset?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-cardinality\"><div class=\"inner\"><span>cardinality</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-contains-fn\"><div class=\"inner\"><span>contains-fn</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-contains-range.3F\"><div class=\"inner\"><span>contains-range?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-difference\"><div class=\"inner\"><span>difference</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-intersection\"><div class=\"inner\"><span>intersection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-intersects-range.3F\"><div class=\"inner\"><span>intersects-range?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-java-concurrent-hashset\"><div class=\"inner\"><span>java-concurrent-hashset</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-java-hashset\"><div class=\"inner\"><span>java-hashset</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-map-invert\"><div class=\"inner\"><span>map-invert</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-max-set-value\"><div class=\"inner\"><span>max-set-value</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-min-set-value\"><div class=\"inner\"><span>min-set-value</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-mut-set\"><div class=\"inner\"><span>mut-set</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-reduce-intersection\"><div class=\"inner\"><span>reduce-intersection</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-reduce-union\"><div class=\"inner\"><span>reduce-union</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-set\"><div class=\"inner\"><span>set</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-set.3F\"><div class=\"inner\"><span>set?</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-union\"><div class=\"inner\"><span>union</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-unique\"><div class=\"inner\"><span>unique</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-unique-reducer\"><div class=\"inner\"><span>unique-reducer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.set.html#var-xor\"><div class=\"inner\"><span>xor</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.set</h1><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"public anchor\" id=\"var--.3Einteger-random-access\"><h3>-&gt;integer-random-access</h3><div class=\"usage\"><code>(-&gt;integer-random-access s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a set (or bitset), return a efficient, sorted random access structure.  This assumes\nthe set contains integers.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L284\">view source</a></div></div><div class=\"public anchor\" id=\"var-bitset\"><h3>bitset</h3><div class=\"usage\"><code>(bitset)</code><code>(bitset data)</code><code>(bitset start end)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a java.util.Bitset.  The two argument version assumes you are passing in the\nstart, end of a monotonically incrementing range.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L84\">view source</a></div></div><div class=\"public anchor\" id=\"var-bitset.3F\"><h3>bitset?</h3><div class=\"usage\"><code>(bitset? s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return true if this is a bitset</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L254\">view source</a></div></div><div class=\"public anchor\" id=\"var-cardinality\"><h3>cardinality</h3><div class=\"usage\"><code>(cardinality s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return the cardinality (size) of a given set.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L248\">view source</a></div></div><div class=\"public anchor\" id=\"var-contains-fn\"><h3>contains-fn</h3><div class=\"usage\"><code>(contains-fn s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an IFn that returns efficiently returns true if the set contains\na given element.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L241\">view source</a></div></div><div class=\"public anchor\" id=\"var-contains-range.3F\"><h3>contains-range?</h3><div class=\"usage\"><code>(contains-range? s sidx eidx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>bitset-specific query that returns true if the set contains all the integers from\nsidx to eidx non-inclusive.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L260\">view source</a></div></div><div class=\"public anchor\" id=\"var-difference\"><h3>difference</h3><div class=\"usage\"><code>(difference l r)</code></div><div class=\"doc\"><div class=\"markdown\"><p>set difference</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L214\">view source</a></div></div><div class=\"public anchor\" id=\"var-intersection\"><h3>intersection</h3><div class=\"usage\"><code>(intersection)</code><code>(intersection l)</code><code>(intersection l r)</code></div><div class=\"doc\"><div class=\"markdown\"><p>set intersection</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L200\">view source</a></div></div><div class=\"public anchor\" id=\"var-intersects-range.3F\"><h3>intersects-range?</h3><div class=\"usage\"><code>(intersects-range? s sidx eidx)</code></div><div class=\"doc\"><div class=\"markdown\"><p>bitset-specific query that returns true if the set contains any the integers from\nsidx to eidx non-inclusive.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L267\">view source</a></div></div><div class=\"public anchor\" id=\"var-java-concurrent-hashset\"><h3>java-concurrent-hashset</h3><div class=\"usage\"><code>(java-concurrent-hashset)</code><code>(java-concurrent-hashset data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a concurrent hashset.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L61\">view source</a></div></div><div class=\"public anchor\" id=\"var-java-hashset\"><h3>java-hashset</h3><div class=\"usage\"><code>(java-hashset)</code><code>(java-hashset data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a java hashset</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L53\">view source</a></div></div><div class=\"public anchor\" id=\"var-map-invert\"><h3>map-invert</h3><div class=\"usage\"><code>(map-invert m)</code></div><div class=\"doc\"><div class=\"markdown\"><p>invert a map such that the keys are the vals and the vals are the keys</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L229\">view source</a></div></div><div class=\"public anchor\" id=\"var-max-set-value\"><h3>max-set-value</h3><div class=\"usage\"><code>(max-set-value s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a bitset, return the maximum set value.  Errors if the bitset is empty.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L279\">view source</a></div></div><div class=\"public anchor\" id=\"var-min-set-value\"><h3>min-set-value</h3><div class=\"usage\"><code>(min-set-value s)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Given a bitset, return the minimum set value.  Errors if the bitset is empty.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L274\">view source</a></div></div><div class=\"public anchor\" id=\"var-mut-set\"><h3>mut-set</h3><div class=\"usage\"><code>(mut-set)</code><code>(mut-set data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return a mutable set.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L30\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduce-intersection\"><h3>reduce-intersection</h3><div class=\"usage\"><code>(reduce-intersection)</code><code>(reduce-intersection l)</code><code>(reduce-intersection l &amp; data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L207\">view source</a></div></div><div class=\"public anchor\" id=\"var-reduce-union\"><h3>reduce-union</h3><div class=\"usage\"><code>(reduce-union)</code><code>(reduce-union l)</code><code>(reduce-union l &amp; data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Reduce a number of objects into one object via union</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L192\">view source</a></div></div><div class=\"public anchor\" id=\"var-set\"><h3>set</h3><div class=\"usage\"><code>(set)</code><code>(set data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return an immutable set</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L38\">view source</a></div></div><div class=\"public anchor\" id=\"var-set.3F\"><h3>set?</h3><div class=\"usage\"><code>(set? data)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L48\">view source</a></div></div><div class=\"public anchor\" id=\"var-union\"><h3>union</h3><div class=\"usage\"><code>(union l r)</code></div><div class=\"doc\"><div class=\"markdown\"><p>set union</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L184\">view source</a></div></div><div class=\"public anchor\" id=\"var-unique\"><h3>unique</h3><div class=\"usage\"><code>(unique options data)</code><code>(unique data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a set of unique items.  Parallelized and non-lazy.</p>\n<p>See options for <a href=\"ham-fisted.set.html#var-unique-reducer\">unique-reducer</a> and <a href=\"ham-fisted.api-preduce-reducer\">ham-fisted.api/preduce-reducer</a>.</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L334\">view source</a></div></div><div class=\"public anchor\" id=\"var-unique-reducer\"><h3>unique-reducer</h3><div class=\"usage\"><code>(unique-reducer options)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a parallel reducer that creates a set.</p>\n<p>Options:</p>\n<ul>\n<li><code>:set-constructor</code> construct something that implements <a href=\"ham-fisted.protocols.html#var-add-fn\">ham-fisted.protocols/add-fn</a>\nand <a href=\"ham-fisted.protocols.html#var-union\">ham-fisted.protocols/union</a></li>\n<li><code>:add-fn</code> Pass in user-defined add function as opposed to using protocol lookup to\nfind it.</li>\n</ul>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L311\">view source</a></div></div><div class=\"public anchor\" id=\"var-xor\"><h3>xor</h3><div class=\"usage\"><code>(xor l r)</code></div><div class=\"doc\"><div class=\"markdown\"><p>set xor - difference of intersection from union</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/set.clj#L221\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/ham-fisted.spliterator.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>ham-fisted.spliterator documentation</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 \"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2 current\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"sidebar secondary\"><h3><a href=\"#top\"><span class=\"inner\">Public Vars</span></a></h3><ul><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var--.3Espliterator\"><div class=\"inner\"><span>-&gt;spliterator</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-deref-consumer\"><div class=\"inner\"><span>deref-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-deref-double-consumer\"><div class=\"inner\"><span>deref-double-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-deref-long-consumer\"><div class=\"inner\"><span>deref-long-consumer</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-elements\"><div class=\"inner\"><span>elements</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-psum\"><div class=\"inner\"><span>psum</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-split-parallel-reduce\"><div class=\"inner\"><span>split-parallel-reduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-split-reduce\"><div class=\"inner\"><span>split-reduce</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-split-to-max-size\"><div class=\"inner\"><span>split-to-max-size</span></div></a></li><li class=\"depth-1\"><a href=\"ham-fisted.spliterator.html#var-sum-fast\"><div class=\"inner\"><span>sum-fast</span></div></a></li></ul></div><div class=\"namespace-docs\" id=\"content\"><h1 class=\"anchor\" id=\"top\">ham-fisted.spliterator</h1><div class=\"doc\"><div class=\"markdown\"><p>Support for spliterator reduction and parallel reduction.</p>\n</div></div><div class=\"public anchor\" id=\"var--.3Espliterator\"><h3>-&gt;spliterator</h3><div class=\"usage\"><code>(-&gt;spliterator ii)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L82\">view source</a></div></div><div class=\"public anchor\" id=\"var-deref-consumer\"><h3>deref-consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(deref-consumer varname accept-code deref-code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a Consumer with support for IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L75\">view source</a></div></div><div class=\"public anchor\" id=\"var-deref-double-consumer\"><h3>deref-double-consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(deref-double-consumer varname accept-code deref-code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a DoubleConsumer with support for IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L68\">view source</a></div></div><div class=\"public anchor\" id=\"var-deref-long-consumer\"><h3>deref-long-consumer</h3><h4 class=\"type\">macro</h4><div class=\"usage\"><code>(deref-long-consumer varname accept-code deref-code)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Create a LongConsumer with support for IDeref</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L54\">view source</a></div></div><div class=\"public anchor\" id=\"var-elements\"><h3>elements</h3><div class=\"usage\"><code>(elements data)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Return all the elements referenced by this spliterator as a persistent list</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L184\">view source</a></div></div><div class=\"public anchor\" id=\"var-psum\"><h3>psum</h3><div class=\"usage\"><code>(psum vv)</code></div><div class=\"doc\"><div class=\"markdown\"><p>spliterator based parallel summation - does not account for Double/NaN</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L181\">view source</a></div></div><div class=\"public anchor\" id=\"var-split-parallel-reduce\"><h3>split-parallel-reduce</h3><div class=\"usage\"><code>(split-parallel-reduce executor-service split ideal-split init-fn rfn merge-fn)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Perform a parallel reduction of a spliterator using the provided ExecutorService</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L150\">view source</a></div></div><div class=\"public anchor\" id=\"var-split-reduce\"><h3>split-reduce</h3><div class=\"usage\"><code>(split-reduce rfn split)</code><code>(split-reduce rfn acc split)</code></div><div class=\"doc\"><div class=\"markdown\"><p>Reduce over a spliterator.  Special support exists for IFn$LLL and IFn$DDD</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L84\">view source</a></div></div><div class=\"public anchor\" id=\"var-split-to-max-size\"><h3>split-to-max-size</h3><div class=\"usage\"><code>(split-to-max-size split max-size op)</code></div><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L192\">view source</a></div></div><div class=\"public anchor\" id=\"var-sum-fast\"><h3>sum-fast</h3><div class=\"usage\"><code>(sum-fast vv)</code></div><div class=\"doc\"><div class=\"markdown\"><p>spliterator based serial summation</p>\n</div></div><div class=\"src-link\"><a href=\"https://github.com/cnuernber/ham-fisted/blob/master/src/ham_fisted/spliterator.clj#L173\">view source</a></div></div></div></body></html>"
  },
  {
    "path": "docs/highlight/solarized-light.css",
    "content": "/*\n\nOrginal Style from ethanschoonover.com/solarized (c) Jeremy Hull <sourdrums@gmail.com>\n\n*/\n\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  background: #fdf6e3;\n  color: #657b83;\n}\n\n.hljs-comment,\n.hljs-quote {\n  color: #93a1a1;\n}\n\n/* Solarized Green */\n.hljs-keyword,\n.hljs-selector-tag,\n.hljs-addition {\n  color: #859900;\n}\n\n/* Solarized Cyan */\n.hljs-number,\n.hljs-string,\n.hljs-meta .hljs-meta-string,\n.hljs-literal,\n.hljs-doctag,\n.hljs-regexp {\n  color: #2aa198;\n}\n\n/* Solarized Blue */\n.hljs-title,\n.hljs-section,\n.hljs-name,\n.hljs-selector-id,\n.hljs-selector-class {\n  color: #268bd2;\n}\n\n/* Solarized Yellow */\n.hljs-attribute,\n.hljs-attr,\n.hljs-variable,\n.hljs-template-variable,\n.hljs-class .hljs-title,\n.hljs-type {\n  color: #b58900;\n}\n\n/* Solarized Orange */\n.hljs-symbol,\n.hljs-bullet,\n.hljs-subst,\n.hljs-meta,\n.hljs-meta .hljs-keyword,\n.hljs-selector-attr,\n.hljs-selector-pseudo,\n.hljs-link {\n  color: #cb4b16;\n}\n\n/* Solarized Red */\n.hljs-built_in,\n.hljs-deletion {\n  color: #dc322f;\n}\n\n.hljs-formula {\n  background: #eee8d5;\n}\n\n.hljs-emphasis {\n  font-style: italic;\n}\n\n.hljs-strong {\n  font-weight: bold;\n}\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html PUBLIC \"\"\n    \"\">\n<html><head><meta charset=\"UTF-8\" /><title>Ham-Fisted 3.029</title><script async=\"true\" src=\"https://www.googletagmanager.com/gtag/js?id=G-XJYNJF48RM\"></script><script>window.dataLayer = window.dataLayer || [];\n  function gtag(){dataLayer.push(arguments);}\n  gtag('js', new Date());\n\n  gtag('config', 'G-XJYNJF48RM');</script><link rel=\"stylesheet\" type=\"text/css\" href=\"css/default.css\" /><link rel=\"stylesheet\" type=\"text/css\" href=\"highlight/solarized-light.css\" /><script type=\"text/javascript\" src=\"highlight/highlight.min.js\"></script><script type=\"text/javascript\" src=\"js/jquery.min.js\"></script><script type=\"text/javascript\" src=\"js/page_effects.js\"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id=\"header\"><h2>Generated by <a href=\"https://github.com/weavejester/codox\">Codox</a> with <a href=\"https://github.com/xsc/codox-theme-rdash\">RDash UI</a> theme</h2><h1><a href=\"index.html\"><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></a></h1></div><div class=\"sidebar primary\"><h3 class=\"no-link\"><span class=\"inner\">Project</span></h3><ul class=\"index-link\"><li class=\"depth-1 current\"><a href=\"index.html\"><div class=\"inner\">Index</div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Topics</span></h3><ul><li class=\"depth-1 \"><a href=\"Reductions.html\"><div class=\"inner\"><span>Reductions</span></div></a></li></ul><h3 class=\"no-link\"><span class=\"inner\">Namespaces</span></h3><ul><li class=\"depth-1\"><div class=\"no-link\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>ham-fisted</span></div></div></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.api.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>api</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.bloom-filter.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>bloom-filter</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.defprotocol.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>defprotocol</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.fjp.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>fjp</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.function.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>function</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.hlet.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>hlet</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.iterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>iterator</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.lazy-noncaching.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>lazy-noncaching</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.mut-map.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>mut-map</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.primitive-invoke.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>primitive-invoke</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.process.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>process</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.profile.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>profile</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.protocols.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>protocols</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.reduce.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>reduce</span></div></a></li><li class=\"depth-2 branch\"><a href=\"ham-fisted.set.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>set</span></div></a></li><li class=\"depth-2\"><a href=\"ham-fisted.spliterator.html\"><div class=\"inner\"><span class=\"tree\"><span class=\"top\"></span><span class=\"bottom\"></span></span><span>spliterator</span></div></a></li></ul></div><div class=\"namespace-index\" id=\"content\"><h1><span class=\"project-title\"><span class=\"project-name\">Ham-Fisted</span> <span class=\"project-version\">3.029</span></span></h1><div class=\"doc\"><p>High Performance Clojure Primitives.</p></div><h2>Topics</h2><ul class=\"topics\"><li><a href=\"Reductions.html\">Reductions</a></li></ul><h2>Namespaces</h2><div class=\"namespace\"><h3><a href=\"ham-fisted.api.html\">ham-fisted.api</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Fast mutable and immutable associative data structures based on bitmap trie\nhashmaps. Mutable pathways implement the <code>java.util.Map</code> or <code>Set</code> interfaces\nincluding in-place update features such as compute or computeIfPresent.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.api.html#var--.3Ecollection\">-&gt;collection</a> </li><li> <a href=\"ham-fisted.api.html#var--.3Erandom-access\">-&gt;random-access</a> </li><li> <a href=\"ham-fisted.api.html#var--.3Ereducible\">-&gt;reducible</a> </li><li> <a href=\"ham-fisted.api.html#var-add-all.21\">add-all!</a> </li><li> <a href=\"ham-fisted.api.html#var-add-constant.21\">add-constant!</a> </li><li> <a href=\"ham-fisted.api.html#var-apply-concat\">apply-concat</a> </li><li> <a href=\"ham-fisted.api.html#var-apply-concatv\">apply-concatv</a> </li><li> <a href=\"ham-fisted.api.html#var-argsort\">argsort</a> </li><li> <a href=\"ham-fisted.api.html#var-array-list\">array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-assoc.21\">assoc!</a> </li><li> <a href=\"ham-fisted.api.html#var-binary-search\">binary-search</a> </li><li> <a href=\"ham-fisted.api.html#var-boolean-array\">boolean-array</a> </li><li> <a href=\"ham-fisted.api.html#var-boolean-array-list\">boolean-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-byte-array\">byte-array</a> </li><li> <a href=\"ham-fisted.api.html#var-byte-array-list\">byte-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-char-array\">char-array</a> </li><li> <a href=\"ham-fisted.api.html#var-char-array-list\">char-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-clear.21\">clear!</a> </li><li> <a href=\"ham-fisted.api.html#var-clear-memoized-fn.21\">clear-memoized-fn!</a> </li><li> <a href=\"ham-fisted.api.html#var-complement\">complement</a> </li><li> <a href=\"ham-fisted.api.html#var-concata\">concata</a> </li><li> <a href=\"ham-fisted.api.html#var-concatv\">concatv</a> </li><li> <a href=\"ham-fisted.api.html#var-cond\">cond</a> </li><li> <a href=\"ham-fisted.api.html#var-conj.21\">conj!</a> </li><li> <a href=\"ham-fisted.api.html#var-constant-count\">constant-count</a> </li><li> <a href=\"ham-fisted.api.html#var-constant-countable.3F\">constant-countable?</a> </li><li> <a href=\"ham-fisted.api.html#var-constantly\">constantly</a> </li><li> <a href=\"ham-fisted.api.html#var-count\">count</a> </li><li> <a href=\"ham-fisted.api.html#var-custom-counted-ireduce\">custom-counted-ireduce</a> </li><li> <a href=\"ham-fisted.api.html#var-custom-ireduce\">custom-ireduce</a> </li><li> <a href=\"ham-fisted.api.html#var-darange\">darange</a> </li><li> <a href=\"ham-fisted.api.html#var-dbl-ary-cls\">dbl-ary-cls</a> </li><li> <a href=\"ham-fisted.api.html#var-difference\">difference</a> </li><li> <a href=\"ham-fisted.api.html#var-dnth\">dnth</a> </li><li> <a href=\"ham-fisted.api.html#var-double-array\">double-array</a> </li><li> <a href=\"ham-fisted.api.html#var-double-array-list\">double-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-drop\">drop</a> </li><li> <a href=\"ham-fisted.api.html#var-drop-last\">drop-last</a> </li><li> <a href=\"ham-fisted.api.html#var-drop-min\">drop-min</a> </li><li> <a href=\"ham-fisted.api.html#var-dsummary\">dsummary</a> </li><li> <a href=\"ham-fisted.api.html#var-dvec\">dvec</a> </li><li> <a href=\"ham-fisted.api.html#var-empty-map\">empty-map</a> </li><li> <a href=\"ham-fisted.api.html#var-empty-set\">empty-set</a> </li><li> <a href=\"ham-fisted.api.html#var-empty-vec\">empty-vec</a> </li><li> <a href=\"ham-fisted.api.html#var-empty.3F\">empty?</a> </li><li> <a href=\"ham-fisted.api.html#var-evict-memoized-call\">evict-memoized-call</a> </li><li> <a href=\"ham-fisted.api.html#var-filterv\">filterv</a> </li><li> <a href=\"ham-fisted.api.html#var-first\">first</a> </li><li> <a href=\"ham-fisted.api.html#var-float-array\">float-array</a> </li><li> <a href=\"ham-fisted.api.html#var-float-array-list\">float-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-fnth\">fnth</a> </li><li> <a href=\"ham-fisted.api.html#var-freq-reducer\">freq-reducer</a> </li><li> <a href=\"ham-fisted.api.html#var-frequencies\">frequencies</a> </li><li> <a href=\"ham-fisted.api.html#var-fvec\">fvec</a> </li><li> <a href=\"ham-fisted.api.html#var-group-by\">group-by</a> </li><li> <a href=\"ham-fisted.api.html#var-group-by-consumer\">group-by-consumer</a> </li><li> <a href=\"ham-fisted.api.html#var-group-by-reduce\">group-by-reduce</a> </li><li> <a href=\"ham-fisted.api.html#var-group-by-reducer\">group-by-reducer</a> </li><li> <a href=\"ham-fisted.api.html#var-hash-map\">hash-map</a> </li><li> <a href=\"ham-fisted.api.html#var-iarange\">iarange</a> </li><li> <a href=\"ham-fisted.api.html#var-immut-list\">immut-list</a> </li><li> <a href=\"ham-fisted.api.html#var-immut-map\">immut-map</a> </li><li> <a href=\"ham-fisted.api.html#var-immut-set\">immut-set</a> </li><li> <a href=\"ham-fisted.api.html#var-in-fork-join-task.3F\">in-fork-join-task?</a> </li><li> <a href=\"ham-fisted.api.html#var-inc-consumer\">inc-consumer</a> </li><li> <a href=\"ham-fisted.api.html#var-inc-consumer-reducer\">inc-consumer-reducer</a> </li><li> <a href=\"ham-fisted.api.html#var-int-array\">int-array</a> </li><li> <a href=\"ham-fisted.api.html#var-int-array-list\">int-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-intersect-sets\">intersect-sets</a> </li><li> <a href=\"ham-fisted.api.html#var-intersection\">intersection</a> </li><li> <a href=\"ham-fisted.api.html#var-inth\">inth</a> </li><li> <a href=\"ham-fisted.api.html#var-into\">into</a> </li><li> <a href=\"ham-fisted.api.html#var-into-array\">into-array</a> </li><li> <a href=\"ham-fisted.api.html#var-ivec\">ivec</a> </li><li> <a href=\"ham-fisted.api.html#var-java-concurrent-hashmap\">java-concurrent-hashmap</a> </li><li> <a href=\"ham-fisted.api.html#var-java-hashmap\">java-hashmap</a> </li><li> <a href=\"ham-fisted.api.html#var-java-hashset\">java-hashset</a> </li><li> <a href=\"ham-fisted.api.html#var-java-linked-hashmap\">java-linked-hashmap</a> </li><li> <a href=\"ham-fisted.api.html#var-keys\">keys</a> </li><li> <a href=\"ham-fisted.api.html#var-larange\">larange</a> </li><li> <a href=\"ham-fisted.api.html#var-last\">last</a> </li><li> <a href=\"ham-fisted.api.html#var-linear-merge-iterable\">linear-merge-iterable</a> </li><li> <a href=\"ham-fisted.api.html#var-lines\">lines</a> </li><li> <a href=\"ham-fisted.api.html#var-linked-hashmap\">linked-hashmap</a> </li><li> <a href=\"ham-fisted.api.html#var-lnth\">lnth</a> </li><li> <a href=\"ham-fisted.api.html#var-long-array\">long-array</a> </li><li> <a href=\"ham-fisted.api.html#var-long-array-list\">long-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-lsum\">lsum</a> </li><li> <a href=\"ham-fisted.api.html#var-lsummary\">lsummary</a> </li><li> <a href=\"ham-fisted.api.html#var-lvec\">lvec</a> </li><li> <a href=\"ham-fisted.api.html#var-make-map-entry\">make-map-entry</a> </li><li> <a href=\"ham-fisted.api.html#var-map-intersection\">map-intersection</a> </li><li> <a href=\"ham-fisted.api.html#var-map-union\">map-union</a> </li><li> <a href=\"ham-fisted.api.html#var-map-union-java-hashmap\">map-union-java-hashmap</a> </li><li> <a href=\"ham-fisted.api.html#var-mapmap\">mapmap</a> </li><li> <a href=\"ham-fisted.api.html#var-mapv\">mapv</a> </li><li> <a href=\"ham-fisted.api.html#var-mean\">mean</a> </li><li> <a href=\"ham-fisted.api.html#var-memoize\">memoize</a> </li><li> <a href=\"ham-fisted.api.html#var-memoize-cache-as-map\">memoize-cache-as-map</a> </li><li> <a href=\"ham-fisted.api.html#var-merge\">merge</a> </li><li> <a href=\"ham-fisted.api.html#var-merge-iterator\">merge-iterator</a> </li><li> <a href=\"ham-fisted.api.html#var-merge-with\">merge-with</a> </li><li> <a href=\"ham-fisted.api.html#var-mmax-idx\">mmax-idx</a> </li><li> <a href=\"ham-fisted.api.html#var-mmax-key\">mmax-key</a> </li><li> <a href=\"ham-fisted.api.html#var-mmin-idx\">mmin-idx</a> </li><li> <a href=\"ham-fisted.api.html#var-mmin-key\">mmin-key</a> </li><li> <a href=\"ham-fisted.api.html#var-mode\">mode</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-hashtable-map\">mut-hashtable-map</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-list\">mut-list</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-long-hashtable-map\">mut-long-hashtable-map</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-long-map\">mut-long-map</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-map\">mut-map</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-map-rf\">mut-map-rf</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-map-union.21\">mut-map-union!</a> </li><li> <a href=\"ham-fisted.api.html#var-mut-set\">mut-set</a> </li><li> <a href=\"ham-fisted.api.html#var-mutable-map.3F\">mutable-map?</a> </li><li> <a href=\"ham-fisted.api.html#var-not\">not</a> </li><li> <a href=\"ham-fisted.api.html#var-obj-ary\">obj-ary</a> </li><li> <a href=\"ham-fisted.api.html#var-object-array\">object-array</a> </li><li> <a href=\"ham-fisted.api.html#var-object-array-list\">object-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-ovec\">ovec</a> </li><li> <a href=\"ham-fisted.api.html#var-persistent.21\">persistent!</a> </li><li> <a href=\"ham-fisted.api.html#var-pgroups\">pgroups</a> </li><li> <a href=\"ham-fisted.api.html#var-pmap\">pmap</a> </li><li> <a href=\"ham-fisted.api.html#var-pmap-io\">pmap-io</a> </li><li> <a href=\"ham-fisted.api.html#var-pmap-opts\">pmap-opts</a> </li><li> <a href=\"ham-fisted.api.html#var-range\">range</a> </li><li> <a href=\"ham-fisted.api.html#var-re-matches\">re-matches</a> </li><li> <a href=\"ham-fisted.api.html#var-reduced-.3E\">reduced-&gt;</a> </li><li> <a href=\"ham-fisted.api.html#var-reindex\">reindex</a> </li><li> <a href=\"ham-fisted.api.html#var-repeat\">repeat</a> </li><li> <a href=\"ham-fisted.api.html#var-rest\">rest</a> </li><li> <a href=\"ham-fisted.api.html#var-reverse\">reverse</a> </li><li> <a href=\"ham-fisted.api.html#var-short-array\">short-array</a> </li><li> <a href=\"ham-fisted.api.html#var-short-array-list\">short-array-list</a> </li><li> <a href=\"ham-fisted.api.html#var-shuffle\">shuffle</a> </li><li> <a href=\"ham-fisted.api.html#var-sort\">sort</a> </li><li> <a href=\"ham-fisted.api.html#var-sort-by\">sort-by</a> </li><li> <a href=\"ham-fisted.api.html#var-sorta\">sorta</a> </li><li> <a href=\"ham-fisted.api.html#var-splice\">splice</a> </li><li> <a href=\"ham-fisted.api.html#var-subvec\">subvec</a> </li><li> <a href=\"ham-fisted.api.html#var-sum\">sum</a> </li><li> <a href=\"ham-fisted.api.html#var-sum-fast\">sum-fast</a> </li><li> <a href=\"ham-fisted.api.html#var-sum-stable-nelems\">sum-stable-nelems</a> </li><li> <a href=\"ham-fisted.api.html#var-take\">take</a> </li><li> <a href=\"ham-fisted.api.html#var-take-last\">take-last</a> </li><li> <a href=\"ham-fisted.api.html#var-take-min\">take-min</a> </li><li> <a href=\"ham-fisted.api.html#var-transient\">transient</a> </li><li> <a href=\"ham-fisted.api.html#var-transient-map-rf\">transient-map-rf</a> </li><li> <a href=\"ham-fisted.api.html#var-union\">union</a> </li><li> <a href=\"ham-fisted.api.html#var-union-reduce-maps\">union-reduce-maps</a> </li><li> <a href=\"ham-fisted.api.html#var-update-vals\">update-vals</a> </li><li> <a href=\"ham-fisted.api.html#var-update-values\">update-values</a> </li><li> <a href=\"ham-fisted.api.html#var-upgroups\">upgroups</a> </li><li> <a href=\"ham-fisted.api.html#var-upmap\">upmap</a> </li><li> <a href=\"ham-fisted.api.html#var-vals\">vals</a> </li><li> <a href=\"ham-fisted.api.html#var-vec\">vec</a> </li><li> <a href=\"ham-fisted.api.html#var-vector\">vector</a> </li><li> <a href=\"ham-fisted.api.html#var-wrap-array\">wrap-array</a> </li><li> <a href=\"ham-fisted.api.html#var-wrap-array-growable\">wrap-array-growable</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.bloom-filter.html\">ham-fisted.bloom-filter</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Simple fast bloom filter based on apache parquet BlockSplitBloomFilter.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.bloom-filter.html#var-add-uuids.21\">add-uuids!</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-bitset-size\">bitset-size</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-bloom-filter\">bloom-filter</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-bloom-filter-.3Ebyte-array\">bloom-filter-&gt;byte-array</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-byte-array-.3Ebloom-filter\">byte-array-&gt;bloom-filter</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-byte-array-cls\">byte-array-cls</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-contains.3F\">contains?</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-hash-obj\">hash-obj</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-insert-hash.21\">insert-hash!</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-insert-obj\">insert-obj</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-make-long-hash-predicate\">make-long-hash-predicate</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-make-obj-predicate\">make-obj-predicate</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-make-uuid-hasher\">make-uuid-hasher</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-make-uuid-pred\">make-uuid-pred</a> </li><li> <a href=\"ham-fisted.bloom-filter.html#var-serialize-.3Ebytes\">serialize-&gt;bytes</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.defprotocol.html\">ham-fisted.defprotocol</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Alternative protocol implementation.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.defprotocol.html#var-defprotocol\">defprotocol</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-extend\">extend</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-extend-protocol\">extend-protocol</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-extend-type\">extend-type</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-extenders\">extenders</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-extends.3F\">extends?</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-find-protocol-cache-method\">find-protocol-cache-method</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-find-protocol-method\">find-protocol-method</a> </li><li> <a href=\"ham-fisted.defprotocol.html#var-satisfies.3F\">satisfies?</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.fjp.html\">ham-fisted.fjp</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Support for java.util.concurrent.ForkJoinPool-specific operations such as managed block and task fork/join.\nAdditionally supports concept of 'exception-safe' via wrapping executing code and unwrapper result post\nexecution in order avoid wrapping exceptions and breaking calling code that may be expecting specific\nexception types.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.fjp.html#var-common-pool\">common-pool</a> </li><li> <a href=\"ham-fisted.fjp.html#var-common-pool-parallelism\">common-pool-parallelism</a> </li><li> <a href=\"ham-fisted.fjp.html#var-compute\">compute</a> </li><li> <a href=\"ham-fisted.fjp.html#var-exception-safe\">exception-safe</a> </li><li> <a href=\"ham-fisted.fjp.html#var-fork-task\">fork-task</a> </li><li> <a href=\"ham-fisted.fjp.html#var-in-fork-join-pool.3F\">in-fork-join-pool?</a> </li><li> <a href=\"ham-fisted.fjp.html#var-join\">join</a> </li><li> <a href=\"ham-fisted.fjp.html#var-managed-block\">managed-block</a> </li><li> <a href=\"ham-fisted.fjp.html#var-managed-block-unwrap\">managed-block-unwrap</a> </li><li> <a href=\"ham-fisted.fjp.html#var-on-cp\">on-cp</a> </li><li> <a href=\"ham-fisted.fjp.html#var-safe-common-pool\">safe-common-pool</a> </li><li> <a href=\"ham-fisted.fjp.html#var-safe-fork-task\">safe-fork-task</a> </li><li> <a href=\"ham-fisted.fjp.html#var-task\">task</a> </li><li> <a href=\"ham-fisted.fjp.html#var-unsafe-common-pool\">unsafe-common-pool</a> </li><li> <a href=\"ham-fisted.fjp.html#var-unwrap-safe\">unwrap-safe</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.function.html\">ham-fisted.function</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Helpers for working with <a href=\"https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html\">java.util.function</a>\npackage objects.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.function.html#var--.3Ebi-function\">-&gt;bi-function</a> </li><li> <a href=\"ham-fisted.function.html#var--.3Efunction\">-&gt;function</a> </li><li> <a href=\"ham-fisted.function.html#var--.3Elong-predicate\">-&gt;long-predicate</a> </li><li> <a href=\"ham-fisted.function.html#var-bi-consumer\">bi-consumer</a> </li><li> <a href=\"ham-fisted.function.html#var-bi-function\">bi-function</a> </li><li> <a href=\"ham-fisted.function.html#var-binary-operator\">binary-operator</a> </li><li> <a href=\"ham-fisted.function.html#var-binary-predicate\">binary-predicate</a> </li><li> <a href=\"ham-fisted.function.html#var-binary-predicate-or-null\">binary-predicate-or-null</a> </li><li> <a href=\"ham-fisted.function.html#var-comp-nan-first\">comp-nan-first</a> </li><li> <a href=\"ham-fisted.function.html#var-comp-nan-last\">comp-nan-last</a> </li><li> <a href=\"ham-fisted.function.html#var-consumer\">consumer</a> </li><li> <a href=\"ham-fisted.function.html#var-double-.3Elong\">double-&gt;long</a> </li><li> <a href=\"ham-fisted.function.html#var-double-.3Eobj\">double-&gt;obj</a> </li><li> <a href=\"ham-fisted.function.html#var-double-binary-operator\">double-binary-operator</a> </li><li> <a href=\"ham-fisted.function.html#var-double-consumer\">double-consumer</a> </li><li> <a href=\"ham-fisted.function.html#var-double-predicate\">double-predicate</a> </li><li> <a href=\"ham-fisted.function.html#var-double-unary-operator\">double-unary-operator</a> </li><li> <a href=\"ham-fisted.function.html#var-function\">function</a> </li><li> <a href=\"ham-fisted.function.html#var-long-.3Edouble\">long-&gt;double</a> </li><li> <a href=\"ham-fisted.function.html#var-long-.3Eobj\">long-&gt;obj</a> </li><li> <a href=\"ham-fisted.function.html#var-long-binary-operator\">long-binary-operator</a> </li><li> <a href=\"ham-fisted.function.html#var-long-consumer\">long-consumer</a> </li><li> <a href=\"ham-fisted.function.html#var-long-predicate\">long-predicate</a> </li><li> <a href=\"ham-fisted.function.html#var-long-unary-operator\">long-unary-operator</a> </li><li> <a href=\"ham-fisted.function.html#var-make-comparator\">make-comparator</a> </li><li> <a href=\"ham-fisted.function.html#var-make-double-comparator\">make-double-comparator</a> </li><li> <a href=\"ham-fisted.function.html#var-make-long-comparator\">make-long-comparator</a> </li><li> <a href=\"ham-fisted.function.html#var-obj-.3Edouble\">obj-&gt;double</a> </li><li> <a href=\"ham-fisted.function.html#var-obj-.3Elong\">obj-&gt;long</a> </li><li> <a href=\"ham-fisted.function.html#var-predicate\">predicate</a> </li><li> <a href=\"ham-fisted.function.html#var-rcomp\">rcomp</a> </li><li> <a href=\"ham-fisted.function.html#var-unary-operator\">unary-operator</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.hlet.html\">ham-fisted.hlet</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Extensible let to allow efficient typed destructuring.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.hlet.html#var-extend-let\">extend-let</a> </li><li> <a href=\"ham-fisted.hlet.html#var-let\">let</a> </li><li> <a href=\"ham-fisted.hlet.html#var-let-extension-names\">let-extension-names</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.iterator.html\">ham-fisted.iterator</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Generialized efficient pathways involving iterators.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.iterator.html#var--.3Eiterator\">-&gt;iterator</a> </li><li> <a href=\"ham-fisted.iterator.html#var-ary-iter\">ary-iter</a> </li><li> <a href=\"ham-fisted.iterator.html#var-blocking-queue-.3Eiterable\">blocking-queue-&gt;iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-const-iterable\">const-iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-ctx-iter\">ctx-iter</a> </li><li> <a href=\"ham-fisted.iterator.html#var-current-iterator\">current-iterator</a> </li><li> <a href=\"ham-fisted.iterator.html#var-dedup-first-by\">dedup-first-by</a> </li><li> <a href=\"ham-fisted.iterator.html#var-doiter\">doiter</a> </li><li> <a href=\"ham-fisted.iterator.html#var-has-next.3F\">has-next?</a> </li><li> <a href=\"ham-fisted.iterator.html#var-iter-cons\">iter-cons</a> </li><li> <a href=\"ham-fisted.iterator.html#var-iter-take\">iter-take</a> </li><li> <a href=\"ham-fisted.iterator.html#var-iter-take-while\">iter-take-while</a> </li><li> <a href=\"ham-fisted.iterator.html#var-iterable\">iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-linear-merge-iterator\">linear-merge-iterator</a> </li><li> <a href=\"ham-fisted.iterator.html#var-maybe-next\">maybe-next</a> </li><li> <a href=\"ham-fisted.iterator.html#var-merge-iterable\">merge-iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-next\">next</a> </li><li> <a href=\"ham-fisted.iterator.html#var-non-nil.3F\">non-nil?</a> </li><li> <a href=\"ham-fisted.iterator.html#var-once-iterable\">once-iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-seq-iterable\">seq-iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-seq-once-iterable\">seq-once-iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-unstable-merge-iterable\">unstable-merge-iterable</a> </li><li> <a href=\"ham-fisted.iterator.html#var-wrap-iter\">wrap-iter</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.lazy-noncaching.html\">ham-fisted.lazy-noncaching</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Lazy, noncaching implementation of many clojure.core functions.  There are several benefits of carefully\nconstructed lazy noncaching versions:</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.lazy-noncaching.html#var--.3Ecollection\">-&gt;collection</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var--.3Eiterable\">-&gt;iterable</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var--.3Erandom-access\">-&gt;random-access</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var--.3Ereducible\">-&gt;reducible</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-apply-concat\">apply-concat</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-as-random-access\">as-random-access</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-boolean-alength\">boolean-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-byte-alength\">byte-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-cartesian-map\">cartesian-map</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-char-alength\">char-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-complement\">complement</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-concat\">concat</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-concat-opts\">concat-opts</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-cond\">cond</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-constant-count\">constant-count</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-constant-countable.3F\">constant-countable?</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-count\">count</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-countable-arrays\">countable-arrays</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-define-drop-tducer\">define-drop-tducer</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-define-take-tducer\">define-take-tducer</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-double-alength\">double-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-drop\">drop</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-empty-vec\">empty-vec</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-every.3F\">every?</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-filter\">filter</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-float-alength\">float-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-int-alength\">int-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-into-array\">into-array</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-long-alength\">long-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-make-readonly-list\">make-readonly-list</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-map\">map</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-map-indexed\">map-indexed</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-map-reducible\">map-reducible</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-object-alength\">object-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-object-array\">object-array</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-partition-all\">partition-all</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-partition-by\">partition-by</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-partition-by-comparator\">partition-by-comparator</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-partition-by-cost\">partition-by-cost</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-reindex\">reindex</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-remove\">remove</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-repeatedly\">repeatedly</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-seed-.3Erandom\">seed-&gt;random</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-shift\">shift</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-short-alength\">short-alength</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-shuffle\">shuffle</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-take\">take</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-tuple-map\">tuple-map</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-type-single-arg-ifn\">type-single-arg-ifn</a> </li><li> <a href=\"ham-fisted.lazy-noncaching.html#var-type-zero-arg-ifn\">type-zero-arg-ifn</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.mut-map.html\">ham-fisted.mut-map</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Functions for working with java's mutable map interface</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.mut-map.html#var-compute.21\">compute!</a> </li><li> <a href=\"ham-fisted.mut-map.html#var-compute-if-absent.21\">compute-if-absent!</a> </li><li> <a href=\"ham-fisted.mut-map.html#var-compute-if-present.21\">compute-if-present!</a> </li><li> <a href=\"ham-fisted.mut-map.html#var-keyset\">keyset</a> </li><li> <a href=\"ham-fisted.mut-map.html#var-values\">values</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.primitive-invoke.html\">ham-fisted.primitive-invoke</a></h3><div class=\"doc\"><div class=\"markdown\"><p>For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions\nand this makes quite a difference in tight loops.  Often times, however, functions are passed by values\nor returned from if-statements and then you need to explicitly call the primitive overload - this makes\nthat pathway less verbose.  Functions must first be check-casted to their primitive types and then\ncalling them will use their primitive overloads avoiding all casting.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ed\">-&gt;d</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edd\">-&gt;dd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddd\">-&gt;ddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddd\">-&gt;dddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddddd\">-&gt;ddddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddddl\">-&gt;ddddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddddo\">-&gt;ddddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddl\">-&gt;dddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddld\">-&gt;dddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddll\">-&gt;dddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddlo\">-&gt;dddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddo\">-&gt;dddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddod\">-&gt;dddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddol\">-&gt;dddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edddoo\">-&gt;dddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddl\">-&gt;ddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddld\">-&gt;ddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddldd\">-&gt;ddldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddldl\">-&gt;ddldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddldo\">-&gt;ddldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddll\">-&gt;ddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlld\">-&gt;ddlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlll\">-&gt;ddlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddllo\">-&gt;ddllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlo\">-&gt;ddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlod\">-&gt;ddlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddlol\">-&gt;ddlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddloo\">-&gt;ddloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddo\">-&gt;ddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddod\">-&gt;ddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddodd\">-&gt;ddodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddodl\">-&gt;ddodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddodo\">-&gt;ddodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddol\">-&gt;ddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddold\">-&gt;ddold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddoll\">-&gt;ddoll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddolo\">-&gt;ddolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddoo\">-&gt;ddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddood\">-&gt;ddood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddool\">-&gt;ddool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eddooo\">-&gt;ddooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edl\">-&gt;dl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edld\">-&gt;dld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldd\">-&gt;dldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlddd\">-&gt;dlddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlddl\">-&gt;dlddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlddo\">-&gt;dlddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldl\">-&gt;dldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldld\">-&gt;dldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldll\">-&gt;dldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldlo\">-&gt;dldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldo\">-&gt;dldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldod\">-&gt;dldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldol\">-&gt;dldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edldoo\">-&gt;dldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edll\">-&gt;dll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlld\">-&gt;dlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlldd\">-&gt;dlldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlldl\">-&gt;dlldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlldo\">-&gt;dlldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlll\">-&gt;dlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edllld\">-&gt;dllld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edllll\">-&gt;dllll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlllo\">-&gt;dlllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edllo\">-&gt;dllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edllod\">-&gt;dllod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edllol\">-&gt;dllol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlloo\">-&gt;dlloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlo\">-&gt;dlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlod\">-&gt;dlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlodd\">-&gt;dlodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlodl\">-&gt;dlodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlodo\">-&gt;dlodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlol\">-&gt;dlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlold\">-&gt;dlold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edloll\">-&gt;dloll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlolo\">-&gt;dlolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edloo\">-&gt;dloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlood\">-&gt;dlood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlool\">-&gt;dlool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edlooo\">-&gt;dlooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edo\">-&gt;do</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edod\">-&gt;dod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodd\">-&gt;dodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoddd\">-&gt;doddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoddl\">-&gt;doddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoddo\">-&gt;doddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodl\">-&gt;dodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodld\">-&gt;dodld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodll\">-&gt;dodll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodlo\">-&gt;dodlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodo\">-&gt;dodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodod\">-&gt;dodod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodol\">-&gt;dodol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edodoo\">-&gt;dodoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edol\">-&gt;dol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edold\">-&gt;dold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoldd\">-&gt;doldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoldl\">-&gt;doldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoldo\">-&gt;doldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoll\">-&gt;doll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edolld\">-&gt;dolld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edolll\">-&gt;dolll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edollo\">-&gt;dollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edolo\">-&gt;dolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edolod\">-&gt;dolod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edolol\">-&gt;dolol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoloo\">-&gt;doloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoo\">-&gt;doo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edood\">-&gt;dood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoodd\">-&gt;doodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoodl\">-&gt;doodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoodo\">-&gt;doodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edool\">-&gt;dool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoold\">-&gt;doold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edooll\">-&gt;dooll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoolo\">-&gt;doolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edooo\">-&gt;dooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoood\">-&gt;doood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoool\">-&gt;doool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Edoooo\">-&gt;doooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3El\">-&gt;l</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eld\">-&gt;ld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldd\">-&gt;ldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddd\">-&gt;lddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldddd\">-&gt;ldddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldddl\">-&gt;ldddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldddo\">-&gt;ldddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddl\">-&gt;lddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddld\">-&gt;lddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddll\">-&gt;lddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddlo\">-&gt;lddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddo\">-&gt;lddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddod\">-&gt;lddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddol\">-&gt;lddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elddoo\">-&gt;lddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldl\">-&gt;ldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldld\">-&gt;ldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldldd\">-&gt;ldldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldldl\">-&gt;ldldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldldo\">-&gt;ldldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldll\">-&gt;ldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlld\">-&gt;ldlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlll\">-&gt;ldlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldllo\">-&gt;ldllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlo\">-&gt;ldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlod\">-&gt;ldlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldlol\">-&gt;ldlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldloo\">-&gt;ldloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldo\">-&gt;ldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldod\">-&gt;ldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldodd\">-&gt;ldodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldodl\">-&gt;ldodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldodo\">-&gt;ldodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldol\">-&gt;ldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldold\">-&gt;ldold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldoll\">-&gt;ldoll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldolo\">-&gt;ldolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldoo\">-&gt;ldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldood\">-&gt;ldood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldool\">-&gt;ldool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eldooo\">-&gt;ldooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ell\">-&gt;ll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elld\">-&gt;lld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldd\">-&gt;lldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellddd\">-&gt;llddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellddl\">-&gt;llddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellddo\">-&gt;llddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldl\">-&gt;lldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldld\">-&gt;lldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldll\">-&gt;lldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldlo\">-&gt;lldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldo\">-&gt;lldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldod\">-&gt;lldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldol\">-&gt;lldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elldoo\">-&gt;lldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elll\">-&gt;lll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellld\">-&gt;llld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellldd\">-&gt;llldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellldl\">-&gt;llldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellldo\">-&gt;llldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellll\">-&gt;llll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elllld\">-&gt;lllld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elllll\">-&gt;lllll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellllo\">-&gt;llllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elllo\">-&gt;lllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elllod\">-&gt;lllod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elllol\">-&gt;lllol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellloo\">-&gt;llloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ello\">-&gt;llo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellod\">-&gt;llod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellodd\">-&gt;llodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellodl\">-&gt;llodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellodo\">-&gt;llodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellol\">-&gt;llol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellold\">-&gt;llold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elloll\">-&gt;lloll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellolo\">-&gt;llolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elloo\">-&gt;lloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellood\">-&gt;llood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellool\">-&gt;llool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Ellooo\">-&gt;llooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elo\">-&gt;lo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elod\">-&gt;lod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodd\">-&gt;lodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloddd\">-&gt;loddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloddl\">-&gt;loddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloddo\">-&gt;loddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodl\">-&gt;lodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodld\">-&gt;lodld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodll\">-&gt;lodll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodlo\">-&gt;lodlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodo\">-&gt;lodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodod\">-&gt;lodod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodol\">-&gt;lodol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elodoo\">-&gt;lodoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elol\">-&gt;lol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elold\">-&gt;lold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloldd\">-&gt;loldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloldl\">-&gt;loldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloldo\">-&gt;loldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloll\">-&gt;loll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elolld\">-&gt;lolld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elolll\">-&gt;lolll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elollo\">-&gt;lollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elolo\">-&gt;lolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elolod\">-&gt;lolod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elolol\">-&gt;lolol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloloo\">-&gt;loloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloo\">-&gt;loo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elood\">-&gt;lood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloodd\">-&gt;loodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloodl\">-&gt;loodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloodo\">-&gt;loodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elool\">-&gt;lool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloold\">-&gt;loold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elooll\">-&gt;looll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloolo\">-&gt;loolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Elooo\">-&gt;looo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloood\">-&gt;loood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloool\">-&gt;loool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eloooo\">-&gt;loooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eod\">-&gt;od</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodd\">-&gt;odd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddd\">-&gt;oddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodddd\">-&gt;odddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodddl\">-&gt;odddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodddo\">-&gt;odddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddl\">-&gt;oddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddld\">-&gt;oddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddll\">-&gt;oddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddlo\">-&gt;oddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddo\">-&gt;oddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddod\">-&gt;oddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddol\">-&gt;oddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoddoo\">-&gt;oddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodl\">-&gt;odl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodld\">-&gt;odld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodldd\">-&gt;odldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodldl\">-&gt;odldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodldo\">-&gt;odldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodll\">-&gt;odll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlld\">-&gt;odlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlll\">-&gt;odlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodllo\">-&gt;odllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlo\">-&gt;odlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlod\">-&gt;odlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodlol\">-&gt;odlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodloo\">-&gt;odloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodo\">-&gt;odo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodod\">-&gt;odod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eododd\">-&gt;ododd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eododl\">-&gt;ododl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eododo\">-&gt;ododo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodol\">-&gt;odol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodold\">-&gt;odold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodoll\">-&gt;odoll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodolo\">-&gt;odolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodoo\">-&gt;odoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodood\">-&gt;odood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodool\">-&gt;odool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eodooo\">-&gt;odooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eol\">-&gt;ol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eold\">-&gt;old</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldd\">-&gt;oldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolddd\">-&gt;olddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolddl\">-&gt;olddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolddo\">-&gt;olddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldl\">-&gt;oldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldld\">-&gt;oldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldll\">-&gt;oldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldlo\">-&gt;oldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldo\">-&gt;oldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldod\">-&gt;oldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldol\">-&gt;oldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoldoo\">-&gt;oldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoll\">-&gt;oll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolld\">-&gt;olld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolldd\">-&gt;olldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolldl\">-&gt;olldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolldo\">-&gt;olldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolll\">-&gt;olll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eollld\">-&gt;ollld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eollll\">-&gt;ollll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolllo\">-&gt;olllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eollo\">-&gt;ollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eollod\">-&gt;ollod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eollol\">-&gt;ollol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolloo\">-&gt;olloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolo\">-&gt;olo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolod\">-&gt;olod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolodd\">-&gt;olodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolodl\">-&gt;olodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolodo\">-&gt;olodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolol\">-&gt;olol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolold\">-&gt;olold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eololl\">-&gt;ololl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eololo\">-&gt;ololo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoloo\">-&gt;oloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolood\">-&gt;olood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolool\">-&gt;olool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eolooo\">-&gt;olooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eood\">-&gt;ood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodd\">-&gt;oodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooddd\">-&gt;ooddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooddl\">-&gt;ooddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooddo\">-&gt;ooddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodl\">-&gt;oodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodld\">-&gt;oodld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodll\">-&gt;oodll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodlo\">-&gt;oodlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodo\">-&gt;oodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodod\">-&gt;oodod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodol\">-&gt;oodol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoodoo\">-&gt;oodoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eool\">-&gt;ool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoold\">-&gt;oold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooldd\">-&gt;ooldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooldl\">-&gt;ooldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooldo\">-&gt;ooldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooll\">-&gt;ooll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolld\">-&gt;oolld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolll\">-&gt;oolll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoollo\">-&gt;oollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolo\">-&gt;oolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolod\">-&gt;oolod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoolol\">-&gt;oolol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooloo\">-&gt;ooloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoood\">-&gt;oood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooodd\">-&gt;ooodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooodl\">-&gt;ooodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooodo\">-&gt;ooodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoool\">-&gt;oool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooold\">-&gt;ooold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eoooll\">-&gt;oooll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooolo\">-&gt;ooolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooood\">-&gt;ooood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var--.3Eooool\">-&gt;ooool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-d\">d</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dd\">dd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddd\">ddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddd\">dddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddddd\">ddddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddddl\">ddddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddddo\">ddddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddl\">dddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddld\">dddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddll\">dddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddlo\">dddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddo\">dddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddod\">dddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddol\">dddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dddoo\">dddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddl\">ddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddld\">ddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddldd\">ddldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddldl\">ddldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddldo\">ddldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddll\">ddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddlld\">ddlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddlll\">ddlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddllo\">ddllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddlo\">ddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddlod\">ddlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddlol\">ddlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddloo\">ddloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddo\">ddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddod\">ddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddodd\">ddodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddodl\">ddodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddodo\">ddodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddol\">ddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddold\">ddold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddoll\">ddoll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddolo\">ddolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddoo\">ddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddood\">ddood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddool\">ddool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ddooo\">ddooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dl\">dl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dld\">dld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldd\">dldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlddd\">dlddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlddl\">dlddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlddo\">dlddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldl\">dldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldld\">dldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldll\">dldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldlo\">dldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldo\">dldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldod\">dldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldol\">dldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dldoo\">dldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dll\">dll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlld\">dlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlldd\">dlldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlldl\">dlldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlldo\">dlldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlll\">dlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dllld\">dllld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dllll\">dllll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlllo\">dlllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dllo\">dllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dllod\">dllod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dllol\">dllol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlloo\">dlloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlo\">dlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlod\">dlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlodd\">dlodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlodl\">dlodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlodo\">dlodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlol\">dlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlold\">dlold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dloll\">dloll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlolo\">dlolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dloo\">dloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlood\">dlood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlool\">dlool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dlooo\">dlooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-do\">do</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dod\">dod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodd\">dodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doddd\">doddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doddl\">doddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doddo\">doddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodl\">dodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodld\">dodld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodll\">dodll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodlo\">dodlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodo\">dodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodod\">dodod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodol\">dodol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dodoo\">dodoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dol\">dol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dold\">dold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doldd\">doldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doldl\">doldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doldo\">doldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doll\">doll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dolld\">dolld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dolll\">dolll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dollo\">dollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dolo\">dolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dolod\">dolod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dolol\">dolol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doloo\">doloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doo\">doo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dood\">dood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doodd\">doodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doodl\">doodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doodo\">doodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dool\">dool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doold\">doold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dooll\">dooll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doolo\">doolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-dooo\">dooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doood\">doood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doool\">doool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-doooo\">doooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-l\">l</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ld\">ld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldd\">ldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddd\">lddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldddd\">ldddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldddl\">ldddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldddo\">ldddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddl\">lddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddld\">lddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddll\">lddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddlo\">lddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddo\">lddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddod\">lddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddol\">lddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lddoo\">lddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldl\">ldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldld\">ldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldldd\">ldldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldldl\">ldldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldldo\">ldldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldll\">ldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldlld\">ldlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldlll\">ldlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldllo\">ldllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldlo\">ldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldlod\">ldlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldlol\">ldlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldloo\">ldloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldo\">ldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldod\">ldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldodd\">ldodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldodl\">ldodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldodo\">ldodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldol\">ldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldold\">ldold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldoll\">ldoll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldolo\">ldolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldoo\">ldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldood\">ldood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldool\">ldool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ldooo\">ldooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ll\">ll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lld\">lld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldd\">lldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llddd\">llddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llddl\">llddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llddo\">llddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldl\">lldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldld\">lldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldll\">lldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldlo\">lldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldo\">lldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldod\">lldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldol\">lldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lldoo\">lldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lll\">lll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llld\">llld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llldd\">llldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llldl\">llldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llldo\">llldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llll\">llll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lllld\">lllld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lllll\">lllll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llllo\">llllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lllo\">lllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lllod\">lllod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lllol\">lllol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llloo\">llloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llo\">llo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llod\">llod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llodd\">llodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llodl\">llodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llodo\">llodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llol\">llol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llold\">llold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lloll\">lloll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llolo\">llolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lloo\">lloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llood\">llood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llool\">llool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-llooo\">llooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lo\">lo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lod\">lod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodd\">lodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loddd\">loddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loddl\">loddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loddo\">loddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodl\">lodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodld\">lodld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodll\">lodll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodlo\">lodlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodo\">lodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodod\">lodod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodol\">lodol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lodoo\">lodoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lol\">lol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lold\">lold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loldd\">loldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loldl\">loldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loldo\">loldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loll\">loll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lolld\">lolld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lolll\">lolll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lollo\">lollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lolo\">lolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lolod\">lolod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lolol\">lolol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loloo\">loloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loo\">loo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lood\">lood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loodd\">loodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loodl\">loodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loodo\">loodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-lool\">lool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loold\">loold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-looll\">looll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loolo\">loolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-looo\">looo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loood\">loood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loool\">loool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-loooo\">loooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-od\">od</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odd\">odd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddd\">oddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odddd\">odddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odddl\">odddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odddo\">odddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddl\">oddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddld\">oddld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddll\">oddll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddlo\">oddlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddo\">oddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddod\">oddod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddol\">oddol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oddoo\">oddoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odl\">odl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odld\">odld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odldd\">odldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odldl\">odldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odldo\">odldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odll\">odll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odlld\">odlld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odlll\">odlll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odllo\">odllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odlo\">odlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odlod\">odlod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odlol\">odlol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odloo\">odloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odo\">odo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odod\">odod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ododd\">ododd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ododl\">ododl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ododo\">ododo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odol\">odol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odold\">odold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odoll\">odoll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odolo\">odolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odoo\">odoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odood\">odood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odool\">odool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-odooo\">odooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ol\">ol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-old\">old</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldd\">oldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olddd\">olddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olddl\">olddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olddo\">olddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldl\">oldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldld\">oldld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldll\">oldll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldlo\">oldlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldo\">oldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldod\">oldod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldol\">oldol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oldoo\">oldoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oll\">oll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olld\">olld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olldd\">olldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olldl\">olldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olldo\">olldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olll\">olll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ollld\">ollld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ollll\">ollll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olllo\">olllo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ollo\">ollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ollod\">ollod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ollol\">ollol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olloo\">olloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olo\">olo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olod\">olod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olodd\">olodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olodl\">olodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olodo\">olodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olol\">olol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olold\">olold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ololl\">ololl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ololo\">ololo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oloo\">oloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olood\">olood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olool\">olool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-olooo\">olooo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ood\">ood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodd\">oodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooddd\">ooddd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooddl\">ooddl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooddo\">ooddo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodl\">oodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodld\">oodld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodll\">oodll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodlo\">oodlo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodo\">oodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodod\">oodod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodol\">oodol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oodoo\">oodoo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ool\">ool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oold\">oold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooldd\">ooldd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooldl\">ooldl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooldo\">ooldo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooll\">ooll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oolld\">oolld</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oolll\">oolll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oollo\">oollo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oolo\">oolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oolod\">oolod</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oolol\">oolol</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooloo\">ooloo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oood\">oood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooodd\">ooodd</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooodl\">ooodl</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooodo\">ooodo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oool\">oool</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooold\">ooold</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-oooll\">oooll</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooolo\">ooolo</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooood\">ooood</a> </li><li> <a href=\"ham-fisted.primitive-invoke.html#var-ooool\">ooool</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.process.html\">ham-fisted.process</a></h3><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.process.html#var-destroy-forcibly.21\">destroy-forcibly!</a> </li><li> <a href=\"ham-fisted.process.html#var-launch\">launch</a> </li><li> <a href=\"ham-fisted.process.html#var-launch-jvm\">launch-jvm</a> </li><li> <a href=\"ham-fisted.process.html#var-out-rf\">out-rf</a> </li><li> <a href=\"ham-fisted.process.html#var-println-rf\">println-rf</a> </li><li> <a href=\"ham-fisted.process.html#var-process-descendants\">process-descendants</a> </li><li> <a href=\"ham-fisted.process.html#var-quiet-rf\">quiet-rf</a> </li><li> <a href=\"ham-fisted.process.html#var-record-rf\">record-rf</a> </li><li> <a href=\"ham-fisted.process.html#var-sh\">sh</a> </li><li> <a href=\"ham-fisted.process.html#var-stream-.3Estrings\">stream-&gt;strings</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.profile.html\">ham-fisted.profile</a></h3><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.profile.html#var-current-times\">current-times</a> </li><li> <a href=\"ham-fisted.profile.html#var-reset-times.21\">reset-times!</a> </li><li> <a href=\"ham-fisted.profile.html#var-time-ms\">time-ms</a> </li><li> <a href=\"ham-fisted.profile.html#var-with-times\">with-times</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.protocols.html\">ham-fisted.protocols</a></h3><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.protocols.html#var--.3Ecollection\">-&gt;collection</a> </li><li> <a href=\"ham-fisted.protocols.html#var--.3Einit-val-fn\">-&gt;init-val-fn</a> </li><li> <a href=\"ham-fisted.protocols.html#var--.3Eiterable\">-&gt;iterable</a> </li><li> <a href=\"ham-fisted.protocols.html#var--.3Emerge-fn\">-&gt;merge-fn</a> </li><li> <a href=\"ham-fisted.protocols.html#var--.3Erfn\">-&gt;rfn</a> </li><li> <a href=\"ham-fisted.protocols.html#var--.3Espliterator\">-&gt;spliterator</a> </li><li> <a href=\"ham-fisted.protocols.html#var-add-fn\">add-fn</a> </li><li> <a href=\"ham-fisted.protocols.html#var-BitSet\">BitSet</a> </li><li> <a href=\"ham-fisted.protocols.html#var-bitset.3F\">bitset?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-BulkSetOps\">BulkSetOps</a> </li><li> <a href=\"ham-fisted.protocols.html#var-cardinality\">cardinality</a> </li><li> <a href=\"ham-fisted.protocols.html#var-contained-datatype\">contained-datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ContainedDatatype\">ContainedDatatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-contains-fn\">contains-fn</a> </li><li> <a href=\"ham-fisted.protocols.html#var-contains-range.3F\">contains-range?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-convertible-to-collection.3F\">convertible-to-collection?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-convertible-to-iterable.3F\">convertible-to-iterable?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-count\">count</a> </li><li> <a href=\"ham-fisted.protocols.html#var-Counted\">Counted</a> </li><li> <a href=\"ham-fisted.protocols.html#var-Datatype\">Datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-datatype\">datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-difference\">difference</a> </li><li> <a href=\"ham-fisted.protocols.html#var-estimate-count\">estimate-count</a> </li><li> <a href=\"ham-fisted.protocols.html#var-EstimateCount\">EstimateCount</a> </li><li> <a href=\"ham-fisted.protocols.html#var-Finalize\">Finalize</a> </li><li> <a href=\"ham-fisted.protocols.html#var-finalize\">finalize</a> </li><li> <a href=\"ham-fisted.protocols.html#var-intersection\">intersection</a> </li><li> <a href=\"ham-fisted.protocols.html#var-intersects-range.3F\">intersects-range?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-managed-blocker\">managed-blocker</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ManagedBlocker\">ManagedBlocker</a> </li><li> <a href=\"ham-fisted.protocols.html#var-max-set-value\">max-set-value</a> </li><li> <a href=\"ham-fisted.protocols.html#var-min-set-value\">min-set-value</a> </li><li> <a href=\"ham-fisted.protocols.html#var-PAdd\">PAdd</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ParallelReducer\">ParallelReducer</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ParallelReduction\">ParallelReduction</a> </li><li> <a href=\"ham-fisted.protocols.html#var-preduce\">preduce</a> </li><li> <a href=\"ham-fisted.protocols.html#var-reduce-intersection\">reduce-intersection</a> </li><li> <a href=\"ham-fisted.protocols.html#var-reduce-union\">reduce-union</a> </li><li> <a href=\"ham-fisted.protocols.html#var-Reducer\">Reducer</a> </li><li> <a href=\"ham-fisted.protocols.html#var-reducible.3F\">reducible?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-Reduction\">Reduction</a> </li><li> <a href=\"ham-fisted.protocols.html#var-returned-datatype\">returned-datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ReturnedDatatype\">ReturnedDatatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-serialize-.3Ebytes\">serialize-&gt;bytes</a> </li><li> <a href=\"ham-fisted.protocols.html#var-SerializeObjBytes\">SerializeObjBytes</a> </li><li> <a href=\"ham-fisted.protocols.html#var-set.3F\">set?</a> </li><li> <a href=\"ham-fisted.protocols.html#var-SetOps\">SetOps</a> </li><li> <a href=\"ham-fisted.protocols.html#var-simplified-contained-datatype\">simplified-contained-datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-simplified-datatype\">simplified-datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-simplified-returned-datatype\">simplified-returned-datatype</a> </li><li> <a href=\"ham-fisted.protocols.html#var-Split\">Split</a> </li><li> <a href=\"ham-fisted.protocols.html#var-split\">split</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ToCollection\">ToCollection</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ToIterable\">ToIterable</a> </li><li> <a href=\"ham-fisted.protocols.html#var-ToSpliterator\">ToSpliterator</a> </li><li> <a href=\"ham-fisted.protocols.html#var-union\">union</a> </li><li> <a href=\"ham-fisted.protocols.html#var-wrap-array\">wrap-array</a> </li><li> <a href=\"ham-fisted.protocols.html#var-wrap-array-growable\">wrap-array-growable</a> </li><li> <a href=\"ham-fisted.protocols.html#var-WrapArray\">WrapArray</a> </li><li> <a href=\"ham-fisted.protocols.html#var-xor\">xor</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.reduce.html\">ham-fisted.reduce</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Protocol-based parallel reduction architecture and helper functions.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.reduce.html#var--.3Econsumer\">-&gt;consumer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-bind-double-consumer-reducer.21\">bind-double-consumer-reducer!</a> </li><li> <a href=\"ham-fisted.reduce.html#var-compose-reducers\">compose-reducers</a> </li><li> <a href=\"ham-fisted.reduce.html#var-consume.21\">consume!</a> </li><li> <a href=\"ham-fisted.reduce.html#var-consumer-accumulator\">consumer-accumulator</a> </li><li> <a href=\"ham-fisted.reduce.html#var-consumer-preducer\">consumer-preducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-consumer-reducer\">consumer-reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-double-accumulator\">double-accumulator</a> </li><li> <a href=\"ham-fisted.reduce.html#var-double-consumer-accumulator\">double-consumer-accumulator</a> </li><li> <a href=\"ham-fisted.reduce.html#var-double-consumer-preducer\">double-consumer-preducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-double-consumer-reducer\">double-consumer-reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-immut-map-kv\">immut-map-kv</a> </li><li> <a href=\"ham-fisted.reduce.html#var-indexed-accum\">indexed-accum</a> </li><li> <a href=\"ham-fisted.reduce.html#var-indexed-double-accum\">indexed-double-accum</a> </li><li> <a href=\"ham-fisted.reduce.html#var-indexed-long-accum\">indexed-long-accum</a> </li><li> <a href=\"ham-fisted.reduce.html#var-long-accumulator\">long-accumulator</a> </li><li> <a href=\"ham-fisted.reduce.html#var-long-consumer-accumulator\">long-consumer-accumulator</a> </li><li> <a href=\"ham-fisted.reduce.html#var-long-consumer-reducer\">long-consumer-reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-options-.3Eparallel-options\">options-&gt;parallel-options</a> </li><li> <a href=\"ham-fisted.reduce.html#var-parallel-reducer\">parallel-reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-preduce\">preduce</a> </li><li> <a href=\"ham-fisted.reduce.html#var-preduce-reducer\">preduce-reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-preduce-reducers\">preduce-reducers</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reduce-reducer\">reduce-reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reduce-reducers\">reduce-reducers</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reducer-.3Ecompletef\">reducer-&gt;completef</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reducer-.3Erf\">reducer-&gt;rf</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reducer-with-finalize\">reducer-with-finalize</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reducer-xform-.3Ereducer\">reducer-xform-&gt;reducer</a> </li><li> <a href=\"ham-fisted.reduce.html#var-reducible-merge\">reducible-merge</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.set.html\">ham-fisted.set</a></h3><div class=\"doc\"><div class=\"markdown\"></div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.set.html#var--.3Einteger-random-access\">-&gt;integer-random-access</a> </li><li> <a href=\"ham-fisted.set.html#var-bitset\">bitset</a> </li><li> <a href=\"ham-fisted.set.html#var-bitset.3F\">bitset?</a> </li><li> <a href=\"ham-fisted.set.html#var-cardinality\">cardinality</a> </li><li> <a href=\"ham-fisted.set.html#var-contains-fn\">contains-fn</a> </li><li> <a href=\"ham-fisted.set.html#var-contains-range.3F\">contains-range?</a> </li><li> <a href=\"ham-fisted.set.html#var-difference\">difference</a> </li><li> <a href=\"ham-fisted.set.html#var-intersection\">intersection</a> </li><li> <a href=\"ham-fisted.set.html#var-intersects-range.3F\">intersects-range?</a> </li><li> <a href=\"ham-fisted.set.html#var-java-concurrent-hashset\">java-concurrent-hashset</a> </li><li> <a href=\"ham-fisted.set.html#var-java-hashset\">java-hashset</a> </li><li> <a href=\"ham-fisted.set.html#var-map-invert\">map-invert</a> </li><li> <a href=\"ham-fisted.set.html#var-max-set-value\">max-set-value</a> </li><li> <a href=\"ham-fisted.set.html#var-min-set-value\">min-set-value</a> </li><li> <a href=\"ham-fisted.set.html#var-mut-set\">mut-set</a> </li><li> <a href=\"ham-fisted.set.html#var-reduce-intersection\">reduce-intersection</a> </li><li> <a href=\"ham-fisted.set.html#var-reduce-union\">reduce-union</a> </li><li> <a href=\"ham-fisted.set.html#var-set\">set</a> </li><li> <a href=\"ham-fisted.set.html#var-set.3F\">set?</a> </li><li> <a href=\"ham-fisted.set.html#var-union\">union</a> </li><li> <a href=\"ham-fisted.set.html#var-unique\">unique</a> </li><li> <a href=\"ham-fisted.set.html#var-unique-reducer\">unique-reducer</a> </li><li> <a href=\"ham-fisted.set.html#var-xor\">xor</a> </li></ul></div></div><div class=\"namespace\"><h3><a href=\"ham-fisted.spliterator.html\">ham-fisted.spliterator</a></h3><div class=\"doc\"><div class=\"markdown\"><p>Support for spliterator reduction and parallel reduction.</p>\n</div></div><div class=\"index\"><p>Public variables and functions:</p><ul><li> <a href=\"ham-fisted.spliterator.html#var--.3Espliterator\">-&gt;spliterator</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-deref-consumer\">deref-consumer</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-deref-double-consumer\">deref-double-consumer</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-deref-long-consumer\">deref-long-consumer</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-elements\">elements</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-psum\">psum</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-split-parallel-reduce\">split-parallel-reduce</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-split-reduce\">split-reduce</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-split-to-max-size\">split-to-max-size</a> </li><li> <a href=\"ham-fisted.spliterator.html#var-sum-fast\">sum-fast</a> </li></ul></div></div></div></body></html>"
  },
  {
    "path": "docs/js/page_effects.js",
    "content": "function visibleInParent(element) {\n    var position = $(element).position().top\n    return position > -50 && position < ($(element).offsetParent().height() - 50)\n}\n\nfunction hasFragment(link, fragment) {\n    return $(link).attr(\"href\").indexOf(\"#\" + fragment) != -1\n}\n\nfunction findLinkByFragment(elements, fragment) {\n    return $(elements).filter(function(i, e) { return hasFragment(e, fragment)}).first()\n}\n\nfunction scrollToCurrentVarLink(elements) {\n    var elements = $(elements);\n    var parent   = elements.offsetParent();\n\n    if (elements.length == 0) return;\n\n    var top    = elements.first().position().top;\n    var bottom = elements.last().position().top + elements.last().height();\n\n    if (top >= 0 && bottom <= parent.height()) return;\n\n    if (top < 0) {\n        parent.scrollTop(parent.scrollTop() + top);\n    }\n    else if (bottom > parent.height()) {\n        parent.scrollTop(parent.scrollTop() + bottom - parent.height());\n    }\n}\n\nfunction setCurrentVarLink() {\n    $('.secondary a').parent().removeClass('current')\n    $('.anchor').\n        filter(function(index) { return visibleInParent(this) }).\n        each(function(index, element) {\n            findLinkByFragment(\".secondary a\", element.id).\n                parent().\n                addClass('current')\n        });\n    scrollToCurrentVarLink('.secondary .current');\n}\n\nvar hasStorage = (function() { try { return localStorage.getItem } catch(e) {} }())\n\nfunction scrollPositionId(element) {\n    var directory = window.location.href.replace(/[^\\/]+\\.html$/, '')\n    return 'scroll::' + $(element).attr('id') + '::' + directory\n}\n\nfunction storeScrollPosition(element) {\n    if (!hasStorage) return;\n    localStorage.setItem(scrollPositionId(element) + \"::x\", $(element).scrollLeft())\n    localStorage.setItem(scrollPositionId(element) + \"::y\", $(element).scrollTop())\n}\n\nfunction recallScrollPosition(element) {\n    if (!hasStorage) return;\n    $(element).scrollLeft(localStorage.getItem(scrollPositionId(element) + \"::x\"))\n    $(element).scrollTop(localStorage.getItem(scrollPositionId(element) + \"::y\"))\n}\n\nfunction persistScrollPosition(element) {\n    recallScrollPosition(element)\n    $(element).scroll(function() { storeScrollPosition(element) })\n}\n\nfunction sidebarContentWidth(element) {\n    var widths = $(element).find('.inner').map(function() { return $(this).innerWidth() })\n    return Math.max.apply(Math, widths)\n}\n\nfunction calculateSize(width, snap, margin, minimum) {\n    if (width == 0) {\n        return 0\n    }\n    else {\n        return Math.max(minimum, (Math.ceil(width / snap) * snap) + (margin * 2))\n    }\n}\n\nfunction resizeSidebars() {\n    var primaryWidth   = sidebarContentWidth('.primary')\n    var secondaryWidth = 0\n\n    if ($('.secondary').length != 0) {\n        secondaryWidth = sidebarContentWidth('.secondary')\n    }\n\n    // snap to grid\n    primaryWidth   = calculateSize(primaryWidth, 32, 13, 160)\n    secondaryWidth = calculateSize(secondaryWidth, 32, 13, 160)\n\n    $('.primary').css('width', primaryWidth)\n    $('.secondary').css('width', secondaryWidth).css('left', primaryWidth + 1)\n\n    if (secondaryWidth > 0) {\n        $('#content').css('left', primaryWidth + secondaryWidth + 2)\n    }\n    else {\n        $('#content').css('left', primaryWidth + 1)\n    }\n}\n\n$(window).ready(resizeSidebars)\n$(window).ready(setCurrentVarLink)\n$(window).ready(function() { persistScrollPosition('.primary')})\n$(window).ready(function() {\n    $('#content').scroll(setCurrentVarLink)\n    $(window).resize(setCurrentVarLink)\n    $(window).resize(resizeSidebars)\n})\n"
  },
  {
    "path": "java/ham_fisted/ArrayHelpers.java",
    "content": "package ham_fisted;\n\n\n\npublic class ArrayHelpers\n{\n  public static Object checkedAget(Object[] data, int nelems, int idx) {\n    ArrayLists.checkIndex(idx, nelems);\n    return data[idx];\n  }\n  public static void aset(boolean[] data, int idx, boolean val) {\n    data[idx] = val;\n  }\n  public static void aset(byte[] data, int idx, byte val) {\n    data[idx] = val;\n  }\n  public static void aset(short[] data, int idx, short val) {\n    data[idx] = val;\n  }\n  public static void aset(char[] data, int idx, char val) {\n    data[idx] = val;\n  }\n  public static void aset(int[] data, int idx, int val) {\n    data[idx] = val;\n  }\n  public static void aset(long[] data, int idx, long val) {\n    data[idx] = val;\n  }\n  public static void aset(float[] data, int idx, float val) {\n    data[idx] = val;\n  }\n  public static void aset(double[] data, int idx, double val) {\n    data[idx] = val;\n  }\n  public static void aset(Object[] data, int idx, Object val) {\n    data[idx] = val;\n  }\n\n  public static void accumPlus(byte[] data, int idx, byte val) {\n    data[idx] += val;\n  }\n  public static void accumPlus(short[] data, int idx, short val) {\n    data[idx] += val;\n  }\n  public static void accumPlus(char[] data, int idx, char val) {\n    data[idx] += val;\n  }\n  public static void accumPlus(int[] data, int idx, int val) {\n    data[idx] += val;\n  }\n  public static void accumPlus(long[] data, int idx, long val) {\n    data[idx] += val;\n  }\n  public static void accumPlus(float[] data, int idx, float val) {\n    data[idx] += val;\n  }\n  public static void accumPlus(double[] data, int idx, double val) {\n    data[idx] += val;\n  }\n\n  public static void accumMul(byte[] data, int idx, byte val) {\n    data[idx] *= val;\n  }\n  public static void accumMul(short[] data, int idx, short val) {\n    data[idx] *= val;\n  }\n  public static void accumMul(char[] data, int idx, char val) {\n    data[idx] *= val;\n  }\n  public static void accumMul(int[] data, int idx, int val) {\n    data[idx] *= val;\n  }\n  public static void accumMul(long[] data, int idx, long val) {\n    data[idx] *= val;\n  }\n  public static void accumMul(float[] data, int idx, float val) {\n    data[idx] *= val;\n  }\n  public static void accumMul(double[] data, int idx, double val) {\n    data[idx] *= val;\n  }\n\n  //For some sizes 4 or less manual copy is faster than system.arraycopy.\n  //Interestingly enough, this differs depending on of this is an object array\n  //or a primitive array with the breakeven for an object array being around 8\n  public static void manualCopy(Object[] src, int soff, Object[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(byte[] src, int soff, byte[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(short[] src, int soff, short[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(char[] src, int soff, char[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(int[] src, int soff, int[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(long[] src, int soff, long[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(float[] src, int soff, float[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n  public static void manualCopy(double[] src, int soff, double[] dst, int doff, int len) {\n    int send = soff + len;\n    for (; soff < send; ++soff, ++doff)\n      dst[doff] = src[soff];\n  }\n\n}\n"
  },
  {
    "path": "java/ham_fisted/ArrayImmutList.java",
    "content": "package ham_fisted;\n\n\nimport static ham_fisted.ChunkedList.*;\nimport static ham_fisted.HashProviders.*;\n\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util.ListIterator;\nimport java.util.Collection;\nimport java.util.Arrays;\nimport java.util.Objects;\nimport java.util.NoSuchElementException;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\n\nimport clojure.lang.Indexed;\nimport clojure.lang.IReduce;\nimport clojure.lang.IKVReduce;\nimport clojure.lang.IHashEq;\nimport clojure.lang.Seqable;\nimport clojure.lang.Reversible;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IPersistentVector;\nimport clojure.lang.IObj;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.Murmur3;\nimport clojure.lang.Util;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.IFn;\nimport clojure.lang.IteratorSeq;\nimport clojure.lang.ISeq;\nimport clojure.lang.MapEntry;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.ITransientVector;\nimport clojure.lang.APersistentVector;\n\n\npublic class ArrayImmutList\n  extends APersistentVector\n  implements IMutList, RandomAccess, Indexed, IReduce, IKVReduce,\n\t     IHashEq, Seqable, Reversible, ChunkedListOwner, IPersistentVector,\n\t     IObj, IEditableCollection, UpdateValues, ArrayLists.ArrayOwner\n{\n  final Object[] data;\n  public final int startidx;\n  public final int nElems;\n  public final IPersistentMap m;\n  int _hash = 0;\n\n  public static final ArrayImmutList EMPTY = new ArrayImmutList(new Object[0], 0,0,null);\n\n  public ArrayImmutList(Object[] d, int sidx, int eidx, IPersistentMap meta ) {\n    data = d;\n    startidx = sidx;\n    nElems = eidx - sidx;\n    m = meta;\n  }\n  public static ArrayImmutList create(boolean owning, Object[] d,\n\t\t\t\t      int sidx, int eidx, IPersistentMap meta) {\n    d = owning ? d : d.clone();\n    return new ArrayImmutList(d, sidx, eidx, meta);\n  }\n  public static IPersistentVector create(boolean owning, IPersistentMap meta, Object... data) {\n    return create(owning, data, 0, data.length, meta);\n  }\n  final int indexCheck(int idx) {\n    return ChunkedList.indexCheck(startidx, nElems, idx);\n  }\n  final int wrapIndexCheck(int idx) {\n    return ChunkedList.wrapIndexCheck(startidx, nElems, idx);\n  }\n  public ChunkedListSection getChunkedList() {\n    return new ChunkedListSection(ChunkedList.create(true, null, data).data, startidx, startidx+nElems);\n  }\n  public final int hashCode() {\n    if (_hash == 0) {\n      final int ne = nElems;\n      final int eidx = startidx + ne;\n      int hash = 1;\n      final Object[] mdata = data;\n      for(int sidx = startidx; sidx < eidx; ++sidx) {\n\thash = 31 * hash + Util.hasheq(mdata[sidx]);\n      }\n      _hash = hash = Murmur3.mixCollHash(hash, ne);\n    }\n    return _hash;\n  }\n  public final int hasheq() { return hashCode(); }\n  public final boolean equiv(HashProvider hp, Object other) {\n    if(other == this) return true;\n    if(other == null) return false;\n    if(other instanceof ArrayImmutList) {\n      final int ne = nElems;\n      final ArrayImmutList olist = (ArrayImmutList)other;\n      if(olist.nElems != ne) return false;\n      final int sidx = startidx;\n      final int osidx = olist.startidx;\n      final Object[] mdata = data;\n      final Object[] odata = olist.data;\n      for(int idx = 0; idx < ne; ++idx)\n\tif(!hp.equals(mdata[idx+sidx], odata[idx+osidx]))\n\t  return false;\n      return true;\n    } else {\n      return CljHash.listEquiv(this, other);\n    }\n  }\n  public final boolean equiv(Object other) {\n    return equiv(defaultHashProvider, other);\n  }\n  public final boolean equals(Object other) {\n    return equiv(other);\n  }\n  public final String toString() {\n    return Transformables.sequenceToString(this);\n  }\n  public final IPersistentMap meta() { return m; }\n  public final ArrayImmutList withMeta(IPersistentMap m) {\n    return new ArrayImmutList(data, startidx, startidx+nElems, m);\n  }\n  public void clear() { throw new RuntimeException(\"Unimplemented\"); }\n  public boolean remove(Object c) { throw new RuntimeException(\"Unimplemented\"); }\n  public Character remove(int idx) { throw new RuntimeException(\"Unimplemented\"); }\n  public boolean add(Object c) { throw new RuntimeException(\"Unimplemented\"); }\n  public void add(int idx, Object c) { throw new RuntimeException(\"Unimplemented\"); }\n  public boolean addAll(int idx, Collection c)\n  { throw new RuntimeException(\"Unimplemented\"); }\n  public Character set(int idx, Object c) { throw new RuntimeException(\"Unimplemented\"); }\n  public boolean retainAll(Collection c) { throw new RuntimeException(\"Unimplemented\"); }\n  public boolean removeAll(Collection c) { throw new RuntimeException(\"Unimplemented\"); }\n  public boolean addAll(Collection c) { throw new RuntimeException(\"Unimplemented\"); }\n  public Object get(int idx) {\n    return data[ChunkedList.indexCheck(startidx, nElems, idx)];\n  }\n  public final int indexOf(Object obj) {\n    final int ne = nElems;\n    final int sidx = startidx;\n    final Object[] mdata = data;\n    for(int idx = 0; idx < ne; ++idx)\n      if (Objects.equals(obj, mdata[idx+sidx]))\n\treturn idx;\n    return -1;\n  }\n  public final int lastIndexOf(Object obj) {\n    final int ne = nElems;\n    final int nne = ne - 1;\n    final int sidx = startidx;\n    final Object[] mdata = data;\n    for(int idx = 0; idx < ne; ++idx) {\n      int ridx = nne - idx;\n      if (Objects.equals(obj, mdata[ridx+sidx]))\n\treturn ridx;\n    }\n    return -1;\n  }\n  public final int size() { return nElems; }\n  public final int length() { return nElems; }\n  public final int count() { return nElems; }\n  public final boolean contains(Object obj) {\n    return indexOf(obj) != -1;\n  }\n  public boolean isEmpty() { return nElems == 0; }\n  public Object[] fillArray(Object[] retval) {\n    System.arraycopy(data, startidx, retval, 0, nElems);\n    return retval;\n  }\n  public Object[] toArray() {\n    return fillArray(new Object[nElems]);\n  }\n  public Object[] toArray(Object[] marker) {\n    return fillArray(Arrays.copyOf(marker, nElems));\n  }\n  public ArrayImmutList subList(int sidx, int endidx) {\n    ChunkedList.sublistCheck(sidx, endidx, nElems);\n    return new ArrayImmutList(data, sidx+startidx, endidx + startidx, m);\n  }\n  static class Iter implements Iterator {\n    final Object[] data;\n    final int endidx;\n    int idx;\n    public Iter(Object[] d, int startidx, int nElems) {\n      data = d;\n      idx = startidx;\n      endidx = startidx + nElems;\n    }\n    public final boolean hasNext() { return idx < endidx; }\n    public final Object next() {\n      if (!hasNext())\n\tthrow new NoSuchElementException();\n      final Object retval = data[idx];\n      ++idx;\n      return retval;\n    }\n  }\n  public final Iterator iterator() { return new Iter(data, startidx, nElems); }\n  static class RIter implements Iterator {\n    final Object[] data;\n    final int nne;\n    final int sidx;\n\n    int idx;\n    public RIter(Object[] d, int startidx, int nElems) {\n      data = d;\n      nne = nElems - 1;\n      sidx = startidx + nne;\n      idx = 0;\n    }\n    public final boolean hasNext() { return idx <= nne; }\n    public final Object next() {\n      if (!hasNext())\n\tthrow new NoSuchElementException();\n      final Object retval = data[sidx - idx];\n      ++idx;\n      return retval;\n    }\n  }\n  public final Iterator riterator() { return new RIter(data, startidx, nElems); }\n  public final Object nth(int idx, Object notFound) {\n    final int ne = nElems;\n    if (idx < 0)\n      idx = idx + ne;\n    if (idx < 0 || idx >= ne) return notFound;\n    return data[idx+startidx];\n  }\n  public final Object nth(int idx) {\n    return data[ChunkedList.indexCheck(startidx, nElems, idx < 0 ? idx + nElems : idx)];\n  }\n  public final Object invoke(Object idx) {\n    if (Util.isInteger(idx))\n      return nth(RT.intCast(idx));\n    return null;\n  }\n  public final Object invoke(Object idx, Object notFound) {\n    if (Util.isInteger(idx))\n      return nth(RT.intCast(idx), notFound);\n    return notFound;\n  }\n  public final Object valAt(Object idx) {\n    return invoke(idx);\n  }\n  public final Object valAt(Object idx, Object notFound) {\n    return invoke(idx, notFound);\n  }\n  public final IMapEntry entryAt(Object key) {\n    if(Util.isInteger(key)) {\n      final int idx = RT.intCast(key);\n      if (idx >= 0 && idx < nElems)\n\treturn MapEntry.create(idx, get(idx));\n    }\n    return null;\n  }\n  public final boolean containsKey(Object key) {\n    if(Util.isInteger(key)) {\n      final int idx = RT.intCast(key);\n      return idx >= 0 && idx < nElems;\n    }\n    return false;\n  }\n  public final ArrayImmutList empty() { return EMPTY.withMeta(m); }\n  public final Object reduce(IFn f, Object init) {\n    final int ne = startidx + nElems;\n    final Object[] d = data;\n    for(int idx = startidx; idx < ne; ++idx) {\n      init = f.invoke(init, d[idx]);\n      if(RT.isReduced(init))\n\treturn ((IDeref)init).deref();\n    }\n    return init;\n  }\n  public final Object kvreduce(IFn fn, Object init) {\n    final int sidx = startidx;\n    final Object[] d = data;\n    final int ne = nElems;\n    for(int idx = 0; idx < ne && !RT.isReduced(init); ++idx) {\n      init = fn.invoke(init, idx, d[sidx+idx]);\n    }\n    return Reductions.unreduce(init);\n  }\n  public final ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(iterator()); }\n  public final ISeq rseq() { return LazyChunkedSeq.chunkIteratorSeq(riterator()); }\n  Object[] asArray() {\n    if(startidx == 0 && nElems == data.length)\n      return data;\n    return Arrays.copyOfRange(data, startidx, (int)(startidx + nElems));\n  }\n  public final IPersistentVector cons(Object obj) {\n    final int ne = nElems;\n    final int nne = nElems + 1;\n    Object[] newD = Arrays.copyOfRange(data, startidx, startidx + nne);\n    newD[ne] = obj;\n    if(nne >= 32)\n      return TreeList.create(true, m, newD);\n    return new ArrayImmutList(newD, 0, nne, m);\t\n  }\n  public final IPersistentVector assocN(int idx, Object obj) {\n    final int ne = nElems;\n    final int sidx = startidx;\n    if (idx == ne)\n      return cons(obj);\n    indexCheck(idx);\n    Object[] newD = Arrays.copyOfRange(data, sidx, sidx+ne);\n    newD[idx] = obj;\n    return new ArrayImmutList(newD, 0, ne, m);\n  }\n  public final IPersistentVector assoc(Object idx, Object obj) {\n    if (!Util.isInteger(idx))\n      throw new RuntimeException(\"Vector indexes must be integers: \" + String.valueOf(idx));\n    return assocN(RT.intCast(idx), obj);\n  }\n  public final ArrayImmutList pop() {\n    final int ne = nElems;\n    if (ne == 0)\n      throw new RuntimeException(\"Attempt to pop empty vector\");\n    final Object[] newD = Arrays.copyOfRange(data, startidx, startidx + ne-1);\n    return new ArrayImmutList(newD, 0, ne-1, m);\n  }\n  public final Object peek() {\n    if (nElems == 0)\n      return null;\n    return get(nElems-1);\n  }\n  public final MutTreeList asTransient() {\n    return MutTreeList.create(false, m, asArray());\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final ArrayImmutList updateValue(Object key, Function fn) {\n    int idx = RT.intCast(key);\n    if (idx < 0)\n      idx = nElems + idx;\n    if(idx >= nElems)\n      throw new RuntimeException(\"Index out of range: \" + String.valueOf(key));\n    final Object[] newD = Arrays.copyOfRange(data, startidx, startidx+nElems);\n    newD[idx] = fn.apply(newD[idx]);\n    return new ArrayImmutList(newD, 0, nElems, m);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final ArrayImmutList updateValues(BiFunction fn) {\n    final int ne = nElems;\n    final Object[] newD = Arrays.copyOfRange(data, startidx, startidx+nElems);\n\n    for(int idx = 0; idx < ne; ++idx)\n      newD[idx] = fn.apply(idx, newD[idx]);\n\n    return new ArrayImmutList(newD, 0, nElems, m);\n  }\n  public ArraySection getArraySection() {\n    return new ArraySection(data, startidx, startidx+nElems);\n  }\n  public void move(int sidx, int eidx, int count) { throw new RuntimeException(\"Unimplemented\"); }\n  public void fill(int sidx, int eidx, Object v) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public Object copyOfRange(int sidx, int eidx) {\n    return Arrays.copyOfRange(data, startidx + sidx, startidx + eidx);\n  }\n  public Object copyOf(int len) {\n    return Arrays.copyOfRange(data, startidx + 0, startidx + len);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ArrayLists.java",
    "content": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.Arrays;\nimport java.lang.reflect.Array;\nimport java.util.Comparator;\nimport java.util.Collections;\nimport java.util.Collection;\nimport java.util.Random;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util.function.DoubleBinaryOperator;\nimport java.util.function.LongBinaryOperator;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.function.IntFunction;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IObj;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.IFn;\nimport clojure.lang.IReduce;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.IPersistentVector;\nimport clojure.lang.Associative;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.Util;\nimport clojure.lang.MapEntry;\nimport clojure.lang.IPersistentStack;\nimport clojure.lang.ITransientCollection;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.IPersistentCollection;\nimport it.unimi.dsi.fastutil.bytes.ByteArrays;\nimport it.unimi.dsi.fastutil.bytes.ByteComparator;\nimport it.unimi.dsi.fastutil.shorts.ShortArrays;\nimport it.unimi.dsi.fastutil.shorts.ShortComparator;\nimport it.unimi.dsi.fastutil.chars.CharArrays;\nimport it.unimi.dsi.fastutil.chars.CharComparator;\nimport it.unimi.dsi.fastutil.ints.IntArrays;\nimport it.unimi.dsi.fastutil.ints.IntComparator;\nimport it.unimi.dsi.fastutil.longs.LongArrays;\nimport it.unimi.dsi.fastutil.longs.LongComparator;\nimport it.unimi.dsi.fastutil.floats.FloatArrays;\nimport it.unimi.dsi.fastutil.floats.FloatComparator;\nimport it.unimi.dsi.fastutil.doubles.DoubleArrays;\nimport it.unimi.dsi.fastutil.doubles.DoubleComparator;\n\nimport it.unimi.dsi.fastutil.objects.ObjectArrays;\n\n\npublic class ArrayLists {\n  public static int checkIndex(final int idx, final int dlen) {\n    if (idx >= 0 && idx < dlen) return idx;\n    return ChunkedList.indexCheck(0, dlen, idx);\n  }\n  public static int wrapCheckIndex(int idx, final int dlen) {\n    if(idx < 0)\n      idx += dlen;\n    return checkIndex(idx, dlen);\n  }\n  public static void checkIndexRange(int dlen, int ssidx, int seidx) {\n    ChunkedList.checkIndexRange(0, dlen, ssidx, seidx);\n  }\n  public static void checkIndexRange(long dlen, long ssidx, long seidx) {\n    ChunkedList.checkIndexRange(0, dlen, ssidx, seidx);\n  }\n  public static DoubleConsumer asDoubleConsumer(Object c) {\n    if (c instanceof DoubleConsumer)\n      return (DoubleConsumer) c;\n    return null;\n  }\n  public static LongConsumer asLongConsumer(Object c) {\n    if (c instanceof LongConsumer)\n      return (LongConsumer) c;\n    return null;\n  }\n  public interface ArrayOwner {\n    ArraySection getArraySection();\n    void fill(int sidx, int eidx, Object v);\n    Object copyOfRange(int sidx, int eidx);\n    Object copyOf(int len);\n    //overwrite \n    void move(int sourceIdx, int dstIdx, int count);\n  }\n  public interface ArrayPersistentVector extends IMutList<Object>, IPersistentVector {\n    IPersistentVector unsafeImmut();\n    default boolean equiv(Object other) {\n      return IMutList.super.equiv(other);\n    }\n    default IPersistentVector cons(Object o) { return immut().cons(o); }\n    default IPersistentVector assocN(int i, Object o) {\n      return immut().assocN(i, o);\n    }\n    default int length() { return size(); }\n    default Associative assoc(Object idx, Object o) {\n      return immut().assoc(idx, o);\n    }\n    default IPersistentStack pop() {\n      final int nElems = size();\n      if (nElems == 0)\n\tthrow new RuntimeException(\"Can't pop empty vector\");\n      if (nElems == 1)\n\treturn ImmutList.EMPTY.withMeta(meta());\n      return immut().pop();\n    }\n    default Object peek() {\n      final int nElems = size();\n      if (nElems == 0)\n\treturn null;\n      return get(nElems-1);\n    }\n    default ImmutList empty() {\n      return ImmutList.EMPTY.withMeta(meta());\n    }\n  }\n  @SuppressWarnings(\"unchecked\")\n  static boolean fillRangeArrayCopy(Object dest, long sidx, long eidx,\n\t\t\t\t    long startidx, Object ll) {\n    //True means this function took care of the transfer, false means\n    //fallback to a more generalized transfer\n    if(ll instanceof RandomAccess) {\n      final List l = (List)ll;\n      if (l.isEmpty()) return true;\n      final long endidx = startidx + l.size();\n      checkIndexRange(eidx-sidx, startidx, endidx);\n    }\n    if(ll instanceof ArrayOwner) {\n      final ArraySection as = ((ArrayOwner)ll).getArraySection();\n      final int sz = as.size();\n      if(dest.getClass().isAssignableFrom(as.array.getClass())) {\n\tSystem.arraycopy(as.array, as.sidx, dest, (int)(sidx+startidx), sz);\n\treturn true;\n      }\n    }\n    return false;\n  }\n\n  static List immutShuffleDefault(IMutList m, Random r) {\n    final IMutList retval = m.cloneList();\n    retval.shuffle(r);\n    return retval;\n  }\n  @SuppressWarnings(\"unchecked\")\n  static List immutSortDefault(IMutList m, Comparator c) {\n    final IMutList retval = m.cloneList();\n    retval.sort(c);\n    return retval;\n  }\n  public interface IArrayList extends IMutList<Object>, ArrayOwner, TypedList,\n\t\t\t\t      ArrayPersistentVector {\n    default void add(int idx, int count, Object obj) {\n      int nElems = size();\n      idx = checkIndex(idx, nElems+1);\n      int ne = nElems + count;\n      final Object d = ensureCapacity(ne);\n      setSize(ne);\n      if(idx != nElems) {\n\tmove(idx, idx+count, nElems - idx);\n      }\n      fillRange(idx, idx+count, obj);\n    }\n    default Class containedType() { return getArraySection().array.getClass().getComponentType(); }\n    default IPersistentVector unsafeImmut() { return ImmutList.create(true, meta(), (Object[])getArraySection().array); }\n    default List immutShuffle(Random r) { return immutShuffleDefault(this, r); }\n    default List immutSort(Comparator c) { return immutSortDefault(this, c); }\n    default void fillRange(long startidx, long endidx, Object v) {\n      checkIndexRange(size(), startidx, endidx);\n      fill((int)startidx, (int)endidx, v);\n    }\n    default void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tArrayPersistentVector.super.fillRangeReducible(startidx, v);\n      }\n    }\n    default void setSize(int size ) { throw new RuntimeException(\"unimplemented\"); }\n    default Object ensureCapacity(int newlen) {\n      throw new RuntimeException(\"unimplemented\");\n    }\n  }\n  public interface ILongArrayList extends LongMutList, ArrayOwner, TypedList,\n\t\t\t\t\t  ArrayPersistentVector\n  {\n    default void add(int idx, int count, Object obj) {\n      int nElems = size();\n      idx = checkIndex(idx, nElems+1);\n      int ne = nElems + count;\n      final Object d = ensureCapacity(ne);\n      setSize(ne);\n      if(idx != nElems) {\n\tmove(idx, idx+count, nElems - idx);\n      }\t\n      fillRange(idx, idx+count, obj);\n    }\n    default Class containedType() { return getArraySection().array.getClass().getComponentType(); }\n    default IPersistentVector unsafeImmut() { return ImmutList.create(true, meta(), (Object[])getArraySection().array); }\n    default List immutShuffle(Random r) { return immutShuffleDefault(this, r); }\n    default List immutSort(Comparator c) { return immutSortDefault(this, c); }\n    default void fillRange(long startidx, long endidx, Object v) {\n      checkIndexRange(size(), startidx, endidx);\n      fill((int)startidx, (int)endidx, v);\n    }\n    default void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, (int)startidx, v))\n\tLongMutList.super.fillRangeReducible(startidx, v);\n    }\n    default Object reduce(IFn rfn, Object init) {\n      return LongMutList.super.reduce(rfn, init);\n    }\n    default Object toNativeArray() { return copyOf(size()); }\n    default void setSize(int size ) { throw new RuntimeException(\"unimplemented\"); }\n    default Object ensureCapacity(int newlen) {\n      throw new RuntimeException(\"unimplemented\");\n    }\n  }\n  public interface IDoubleArrayList extends DoubleMutList, ArrayOwner, TypedList,\n\t\t\t\t\t    ArrayPersistentVector\n  {\n    default void add(int idx, int count, Object obj) {\n      int nElems = size();\n      idx = checkIndex(idx, nElems+1);\n      int ne = nElems + count;\n      setSize(ne);\n      final Object d = ensureCapacity(ne);\n      if(idx != nElems) {\n\tmove(idx, idx+count, nElems - idx);\n      }\t\n      fillRange(idx, idx+count, obj);\n    }\n    default Class containedType() { return getArraySection().array.getClass().getComponentType(); }\n    default IPersistentVector unsafeImmut() { return ImmutList.create(true, meta(), (Object[])getArraySection().array); }\n    default List immutShuffle(Random r) { return immutShuffleDefault(this, r); }\n    default List immutSort(Comparator c) { return immutSortDefault(this, c); }\n    default void fillRange(long startidx, long endidx, Object v) {\n      checkIndexRange(size(), startidx, endidx);\n      fill((int)startidx, (int)endidx, v);\n    }\n    default void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v))\n\tDoubleMutList.super.fillRangeReducible(startidx, v);\n    }\n    default Object toNativeArray() { return copyOf(size()); }\n    default void setSize(int size ) { throw new RuntimeException(\"unimplemented\"); }\n    default Object ensureCapacity(int newlen) {\n      throw new RuntimeException(\"unimplemented\");\n    }\n  }\n\n  static int fixSubArrayBinarySearch(final int sidx, final int len, final int res) {\n    return res < 0 ? -1 - (res + sidx) : res - sidx;\n  }\n\n  public static Object[] objectArray(int len) { return new Object[len]; }\n\n  public static class ObjectArraySubList implements IArrayList {\n    public final Object[] data;\n    public final int sidx;\n    public final int eidx;\n    public final int nElems;\n    public final IPersistentMap meta;\n    public ObjectArraySubList(Object[] d, int _sidx, int _eidx, IPersistentMap m) {\n      data = d;\n      sidx = _sidx;\n      eidx = _eidx;\n      nElems = eidx - sidx;\n      meta = m;\n    }\n    public boolean isCompatible(Object other) {\n      return other instanceof Object[];\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, eidx); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return nElems; }\n    public Object get(int idx) { return data[checkIndex(idx, nElems) + sidx]; }\n    public Object nth(int idx) {\n      return data[checkIndex(idx < 0 ? idx + nElems : idx, nElems) + sidx];\n    }\n    public Object set(int idx, Object obj) {\n      idx = checkIndex(idx, nElems) + sidx;\n      final Object retval = data[idx];\n      data[idx] = obj;\n      return retval;\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return (IMutList<Object>)toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, eidx, m);\n    }\n    public Object[] toArray() {\n      return Arrays.copyOfRange(data, sidx, eidx);\n    }\n    public void sort(Comparator<? super Object> c) {\n      if(c == null)\n\tObjectArrays.parallelQuickSort(data, sidx, eidx);\n      else\n\tObjectArrays.parallelQuickSort(data, sidx, eidx, c);\n    }\n    public void shuffle(Random r) {\n      ObjectArrays.shuffle(data, sidx, eidx, r);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      return fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t     c == null ? ObjectArrays.binarySearch(data, sidx, eidx, v)\n\t\t\t\t     : ObjectArrays.binarySearch(data, sidx, eidx, v, c));\n\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void forEach(Consumer c) {\n      final int es = eidx;\n      final Object[] d = data;\n      for(int ss = sidx; ss < es; ++ss)\n\tc.accept(d[ss]);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ss = (int)startidx + sidx;\n\tfinal int ee = sidx + size();\n\tReductions.serialReduction(new Reductions.IndexedAccum( startidx+sidx, new IFn.OLOO() {\n\t    public Object invokePrim(Object acc, long idx, Object v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \" is out of range: \" +\n\t\t\t\t\t\t    String.valueOf(size()));\n\t      ((Object[])acc)[(int)idx] = v;\n\t      return acc;\n\t    }}), data, v);\n      }\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      final int ee = eidx;\n      final Object[] d = data;\n      for(int idx = sidx; idx < ee; ++idx ) {\n\tacc = rfn.invoke(acc, d[idx]);\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n      return acc;\n    }\n    public IPersistentVector immut() {\n      return ArrayImmutList.create(true, data, sidx, eidx, meta());\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx + ssidx, sidx + seidx, v);\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static int newArrayLen(int len) {\n    return len < 100000 ? len * 2 : (int)(len * 1.5);\n  }\n\n  public static long newArrayLen(long len) {\n    return len < 100000 ? len * 2 : (long)(len * 1.5);\n  }\n\n  public static class ObjectArrayList implements IArrayList, ITransientCollection {\n    Object[] data;\n    int nElems;\n    IPersistentMap meta;\n    public ObjectArrayList(Object[] d, int ne, IPersistentMap meta) {\n      data = d;\n      nElems = ne;\n    }\n    public ObjectArrayList(int capacity) {\n      this(new Object[capacity], 0, null);\n    }\n    public ObjectArrayList() {\n      this(4);\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return new ObjectArrayList((Object[])copyOf(nElems),\n\t\t\t\t\t\t\t     nElems, meta); }\n    public ArraySection getArraySection() { return new ArraySection(data, 0, nElems); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public void clear() { nElems = 0; }\n    public int size() { return nElems; }\n    public void setSize(int sz) { nElems = sz; }\n    public Object get(int idx) { return data[checkIndex(idx, nElems)]; }\n    public Object set(int idx, Object obj) {\n      idx = checkIndex(idx, nElems);\n      final Object retval = data[idx];\n      data[idx] = obj;\n      return retval;\n    }\n    public int capacity() { return data.length; }\n    public Object[] ensureCapacity(int len) {\n      Object[] d = data;\n      if (len >= d.length) {\n\td = data = Arrays.copyOf(d, newArrayLen(len));\n      }\n      return d;\n    }\n    public boolean add(Object obj) {\n      final int ne = nElems;\n      final Object [] d = ensureCapacity(ne+1);\n      d[ne] = obj;\n      nElems = ne+1;\n      return true;\n    }\n    public void add(int idx, Object obj) {\n      idx = checkIndex(idx, nElems);\n      if (idx == nElems) { add(obj); return; }\n\n      final int ne = nElems;\n      final Object [] d = ensureCapacity(ne+1);\n      System.arraycopy(d, idx, d, idx+1, ne - idx);\n      d[idx] = obj;\n      nElems = ne+1;\n    }\n    /// Extra method because some things that implement IReduceInit are not\n    /// collections.\n    public boolean addAllReducible(Object c) {\n      final int sz = size();\n      if (c instanceof RandomAccess) {\n\tfinal List cl = (List) c;\n\tif (cl.isEmpty() ) return false;\n\tfinal int cs = cl.size();\n\tensureCapacity(cs+sz);\n\tnElems += cs;\n\t//Hit fastpath\n\tfillRangeReducible(sz, cl);\n      } else  {\n\tIArrayList.super.addAllReducible(c);\n      }\n      return sz != size();\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return (IMutList<Object>)toList(data, ssidx, seidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      meta = m;\n      return this;\n    }\n    public Object[] toArray() {\n      return Arrays.copyOf(data, nElems);\n    }\n    public void removeRange(int startidx, int endidx) {\n      checkIndexRange(nElems, startidx, endidx);\n      System.arraycopy(data, startidx, data, endidx, nElems - endidx);\n      Arrays.fill(data, endidx, nElems, null);\n      nElems -= endidx - startidx;\n    }\n    public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems)).reduce(fn); }\n    public Object reduce(IFn fn, Object init) { return ((IReduceInit)subList(0, nElems)).reduce(fn,init); }\n    public void sort(Comparator<? super Object> c) {\n      subList(0, nElems).sort(c);\n    }\n    public void shuffle(Random r) {\n      ((IMutList)subList(0, nElems)).shuffle(r);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void forEach(Consumer c) {\n      final int es = nElems;\n      final Object[] d = data;\n      for(int ss = 0; ss < es; ++ss)\n\tc.accept(d[ss]);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      subList(0, size()).fillRangeReducible(startidx, v);\n    }\n    public IPersistentVector immut() {\n      return ArrayImmutList.create(true, data, 0, nElems, meta());\n    }\n    public IPersistentCollection persistent() {\n      return immut();\n    }\n    public final ObjectArrayList conj(Object obj) {\n      add(obj);\n      return this;\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(nElems, ssidx, seidx);\n      Arrays.fill(data, ssidx, seidx, v);\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      return Arrays.copyOfRange(data, ssidx, seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOf(data, len);\n    }\n    public static ObjectArrayList wrap(final Object[] data, int nElems, IPersistentMap m) {\n      if (data.length < nElems)\n\tthrow new RuntimeException(\"Array len less than required\");\n      return new ObjectArrayList(data, nElems, m);\n    }\n    public static ObjectArrayList wrap(final Object[] data, IPersistentMap m) {\n      return new ObjectArrayList(data, data.length, m);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static Object[] toArray(Collection c) {\n    if( c instanceof RandomAccess ) {\n      List l = (List)c;\n      final int ne = l.size();\n      Object[] rv = new Object[l.size()];\n      for(int idx = 0; idx < ne; ++idx)\n\trv[idx] = l.get(idx);\n      return rv;\n    } else {\n      final ObjectArrayList res = new ObjectArrayList();\n      res.addAllReducible(c);\n      return res.toArray();\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static <T> T[] toArray(Collection c, T[] d) {\n    if(c instanceof RandomAccess) {\n      List l = (List)c;\n      final int ne = l.size();\n      final T[] rv = Arrays.copyOf(d, ne);\n      for(int idx = 0; idx < ne; ++idx) {\n\trv[idx] = (T)l.get(idx);\n      }\n      return rv;\n    }\n    final ObjectArrayList res = ObjectArrayList.wrap(d, 0, null);\n    res.addAllReducible(c);\n    return (T[])res.toArray();\n  }\n\n  public static IMutList<Object> toList(final Object[] data, final int sidx, final int eidx, final IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new ObjectArraySubList(data, sidx, eidx, meta);\n  }\n  public static IMutList<Object> toList(final Object[] data) { return toList(data, 0, data.length, null); }\n\n\n  public static class ByteArraySubList implements ILongArrayList {\n    public final byte[] data;\n    public final int dlen;\n    public final int sidx;\n    public final IPersistentMap meta;\n    public ByteArraySubList(byte[] d, int s, int len, IPersistentMap _meta) {\n      data = d;\n      sidx = s;\n      dlen = len;\n      meta = _meta;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, sidx + dlen); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return dlen; }\n    public Byte get(int idx) { return data[checkIndex(idx, dlen) + sidx]; }\n    public long getLong(int idx) { return data[checkIndex(idx, dlen) + sidx]; }\n    public void setLong(int idx, long oobj) {\n      data[checkIndex(idx, dlen) + sidx] = RT.byteCast(oobj);\n    }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, sidx+dlen)); }\n    public IntComparator indexComparator() {\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return Byte.compare(data[lidx+sidx], data[ridx+sidx]);\n\t}\n      };\n    }\n    public LongMutList subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return (LongMutList)toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return new ByteArraySubList(data, sidx, sidx + dlen, m);\n    }\n    public Object[] toArray() {\n      final int sz = size();\n      Object[] retval = new Object[size()];\n      for (int idx = 0; idx < sz; ++idx)\n\tretval[idx] = data[idx+sidx];\n      return retval;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void sort(Comparator<? super Object> c) {\n      if (c == null)\n\tArrays.sort(data, sidx, sidx+dlen);\n      else {\n\tILongArrayList.super.sort(c);\n      }\n    }\n    public void shuffle(Random r) {\n      ByteArrays.shuffle(data, sidx, sidx+dlen, r);\n    }\n    public static ByteComparator asByteComparator(Comparator c) {\n      if (c instanceof ByteComparator)\n\treturn (ByteComparator)c;\n      else if (c instanceof LongComparator) {\n\tfinal LongComparator lc = (LongComparator)c;\n\treturn new ByteComparator() {\n\t  public int compare(byte l, byte r) { return lc.compare(l,r); }\n\t};\n      }\n      return null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final byte vv = RT.byteCast(Casts.longCast(v));\n      final ByteComparator bc = asByteComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? ByteArrays.binarySearch(data, sidx, sidx+size(), vv) : ByteArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n      return ILongArrayList.super.binarySearch(v, c);\n    }\n\n    public Object longReduction(IFn.OLO rfn, Object init) {\n      final int es = sidx + dlen;\n      final byte[] d = data;\n      for(int ss = sidx; ss < es && !RT.isReduced(init); ++ss)\n\tinit = rfn.invokePrim(init, d[ss]);\n      return Reductions.unreduce(init);\n    }\n\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ss = (int)startidx + sidx;\n\tfinal int ee = sidx + size();\n\tReductions.serialReduction(new Reductions.IndexedLongAccum( startidx+sidx,\n\t\t\t\t\t\t\t\t    new IFn.OLLO() {\n\t    public Object invokePrim(Object acc, long idx, long v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \" is out of range: \" +\n\t\t\t\t\t\t    String.valueOf(size()));\n\t      data[(int)idx] = RT.byteCast(v);\n\t      return data;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx + ssidx, sidx + seidx, RT.byteCast(Casts.longCast(v)));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static IMutList<Object> toList(final byte[] data, final int sidx, final int eidx, final IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new ByteArraySubList(data, sidx, dlen, meta);\n  }\n  public static IMutList<Object> toList(final byte[] data) { return toList(data, 0, data.length, null); }\n\n\n  public static class ShortArraySubList implements ILongArrayList {\n    public final short[] data;\n    public final int sidx;\n    public final int dlen;\n    public final IPersistentMap meta;\n\n    public ShortArraySubList(short[] d, int s, int len, IPersistentMap _meta) {\n      data = d;\n      sidx = s;\n      dlen = len;\n      meta = _meta;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, sidx+dlen)); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, sidx + dlen); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return dlen; }\n    public long getLong(int idx) { return data[checkIndex(idx, dlen) + sidx]; }\n    public void setLong(int idx, long oobj) {\n      data[checkIndex(idx, dlen) + sidx] = RT.shortCast(Casts.longCast(oobj));\n    }\n    public IntComparator indexComparator() {\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return Short.compare(data[lidx+sidx], data[ridx+sidx]);\n\t}\n      };\n    }\n    public LongMutList subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return (LongMutList)toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, sidx + dlen, m);\n    }\n    public Object[] toArray() {\n      final int sz = size();\n      Object[] retval = new Object[size()];\n      for (int idx = 0; idx < sz; ++idx)\n\tretval[idx] = data[idx+sidx];\n      return retval;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void sort(Comparator c) {\n      if (c == null)\n\tArrays.sort(data, sidx, sidx+dlen);\n      else {\n\tfinal Object[] odata = toArray();\n\tArrays.sort(odata, c);\n\tfinal short[] d = data;\n\tfinal int sz = size();\n\tfinal int ss = sidx;\n\tfor (int idx = 0; idx < sz; ++idx) {\n\t  d[idx+ss] = (short)odata[idx];\n\t}\n      }\n    }\n\n    public void shuffle(Random r) {\n      ShortArrays.shuffle(data, sidx, sidx+dlen, r);\n    }\n    public static ShortComparator asShortComparator(Comparator c) {\n      if (c instanceof ShortComparator)\n\treturn (ShortComparator)c;\n      else if (c instanceof LongComparator) {\n\tfinal LongComparator lc = (LongComparator)c;\n\treturn new ShortComparator() {\n\t  public int compare(short l, short r) { return lc.compare(l,r); }\n\t};\n      }\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final short vv = RT.shortCast(Casts.longCast(v));\n      final ShortComparator bc = asShortComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? ShortArrays.binarySearch(data, sidx, sidx+size(), vv) : ShortArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n      return ILongArrayList.super.binarySearch(v, c);\n    }\n    public Object longReduction(IFn.OLO rfn, Object init) {\n      final int es = sidx + dlen;\n      final short[] d = data;\n      for(int ss = sidx; ss < es && !RT.isReduced(init); ++ss)\n\tinit = rfn.invokePrim(init, d[ss]);\n      return Reductions.unreduce(init);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ss = (int)startidx + sidx;\n\tfinal int ee = sidx + size();\n\tReductions.serialReduction(new Reductions.IndexedLongAccum( startidx+sidx,\n\t\t\t\t\t\t\t\t    new IFn.OLLO() {\n\t    public Object invokePrim(Object acc, long idx, long v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \" is out of range: \" +\n\t\t\t\t\t\t    String.valueOf(size()));\n\t      data[(int)idx] = RT.shortCast(v);\n\t      return data;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx + ssidx, sidx + seidx, RT.shortCast(Casts.longCast(v)));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, size());\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static IMutList<Object> toList(final short[] data, final int sidx, final int eidx, final IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new ShortArraySubList(data, sidx, dlen, meta);\n  }\n  public static IMutList<Object> toList(final short[] data) { return toList(data, 0, data.length, null); }\n\n  public static int[] intArray(int len) { return new int[len]; }\n  public static class IntArraySubList implements ILongArrayList {\n    public final int[] data;\n    public final int sidx;\n    public final int eidx;\n    public final int nElems;\n    public final IPersistentMap meta;\n    public IntArraySubList(int[] d, int _sidx, int _eidx, IPersistentMap m) {\n      data = d;\n      sidx = _sidx;\n      eidx = _eidx;\n      nElems = eidx - sidx;\n      meta = m;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, eidx)); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, eidx); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return nElems; }\n    public long getLong(int idx) { return data[checkIndex(idx, nElems) + sidx]; }\n    static void setLong(final int[] d, final int sidx, final int nElems,\n\t\t\tint idx, final long obj) {\n      int v = RT.intCast(obj);\n      idx = checkIndex(idx, nElems) + sidx;\n      d[idx] = v;\n    }\n    public void setLong(int idx, long obj) {\n      setLong(data, sidx, nElems, idx, obj);\n    }\n    public LongMutList subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return (LongMutList)toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, eidx, m);\n    }\n    public Object[] toArray() {\n      final int[] d = data;\n      final int ss = sidx;\n      final int ne = nElems;\n      Object[] retval = new Object[ne];\n      for(int idx = 0; idx < ne; ++idx)\n\tretval[idx] = d[idx+ss];\n      return retval;\n    }\n    public int[] toIntArray() {\n      return Arrays.copyOfRange(data, sidx, eidx);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static IntComparator indexComparator(int[] d, int sidx, Comparator c) {\n      if (c == null) {\n\tif (sidx != 0) {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return Integer.compare(d[lidx+sidx], d[ridx+sidx]);\n\t    }\n\t  };\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return Integer.compare(d[lidx], d[ridx]);\n\t    }\n\t  };\n\t}\n      } else {\n\tif(c instanceof LongComparator) {\n\t  final LongComparator lc = (LongComparator) c;\n\t  if (sidx != 0) {\n\t    return new IntComparator() {\n\t      public int compare(int lidx, int ridx) {\n\t\treturn lc.compare(d[lidx+sidx], d[ridx+sidx]);\n\t      }\n\t    };\n\t  } else {\n\t    return new IntComparator() {\n\t      public int compare(int lidx, int ridx) {\n\t\treturn lc.compare(d[lidx], d[ridx]);\n\t      }\n\t    };\n\t  }\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return c.compare(d[lidx+sidx], d[ridx+sidx]);\n\t    }\n\t  };\n\t}\n      }\n    }\n    public IntComparator indexComparator() {\n      return indexComparator(data, sidx, null);\n    }\n    public IntComparator indexComparator(Comparator c) {\n      return indexComparator(data, sidx, c);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static IntComparator toIntComparator(Comparator c) {\n      if (c instanceof IntComparator)\n\treturn (IntComparator) c;\n      else\n\treturn new IntComparator() {\n\tpublic int compare(int lhs, int rhs) {\n\t  return c.compare(lhs, rhs);\n\t}\n      };\n    }\n    public void sort(Comparator<? super Object> c) {\n      if(c == null)\n\tIntArrays.parallelQuickSort(data, sidx, eidx);\n      else {\n\tIntArrays.parallelQuickSort(data, sidx, eidx, toIntComparator(c));\n      }\n    }\n    public void shuffle(Random r) {\n      IntArrays.shuffle(data, sidx, eidx, r);\n    }\n    public static IntComparator asIntComparator(Comparator c) {\n      if (c instanceof IntComparator)\n\treturn (IntComparator)c;\n      else if (c instanceof LongComparator) {\n\tfinal LongComparator lc = (LongComparator)c;\n\treturn new IntComparator() {\n\t  public int compare(int l, int r) { return lc.compare(l,r); }\n\t};\n      }\n      return null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final int vv = RT.intCast(Casts.longCast(v));\n      final IntComparator bc = asIntComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? IntArrays.binarySearch(data, sidx, sidx+size(), vv) : IntArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n\treturn ILongArrayList.super.binarySearch(v, c);\n    }\n    public int[] sortIndirect(Comparator c) {\n      final int sz = size();\n      int[] retval = iarange(0, sz, 1);\n      if(sz < 2)\n\treturn retval;\n      if(c == null)\n\tIntArrays.parallelQuickSortIndirect(retval, data, sidx, eidx);\n      else\n\tIntArrays.parallelQuickSort(retval, indexComparator(c));\n      return retval;\n    }\n    public Object reduce(IFn rfn, Object init) {\n      return ILongArrayList.super.reduce(rfn, init);\n    }\n    public Object longReduction(IFn.OLO rfn, Object init) {\n      final int es = eidx;\n      final int[] d = data;\n      for(int ss = sidx; ss < es && !RT.isReduced(init); ++ss)\n\tinit = rfn.invokePrim(init, d[ss]);\n      return Reductions.unreduce(init);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int[] d = data;\n\tfinal int ee = sidx + size();\n\tReductions.serialReduction(new Reductions.IndexedLongAccum( startidx + sidx,\n\t\t\t\t\t\t\t\t    new IFn.OLLO() {\n\t    public Object invokePrim(Object acc, long idx, long v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \"> length \"  + String.valueOf(size()));\n\t      d[(int)idx] = RT.intCast(v);\n\t      return d;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx + ssidx, sidx + seidx, RT.intCast(Casts.longCast(v)));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, size());\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static class IntArrayList implements ILongArrayList {\n    int[] data;\n    int nElems;\n    IPersistentMap meta;\n    public IntArrayList(int[] d, int ne, IPersistentMap meta) {\n      data = d;\n      nElems = ne;\n    }\n    public IntArrayList(int capacity) {\n      this(new int[capacity], 0, null);\n    }\n    public IntArrayList() {\n      this(4);\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return new IntArrayList((int[])copyOf(nElems),\n\t\t\t\t\t\t\t  nElems, meta); }\n    public ArraySection getArraySection() { return new ArraySection(data, 0, nElems); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return nElems; }\n    public void setSize(int sz) { nElems = sz; }\n    public long getLong(int idx) { return data[checkIndex(idx, nElems)]; }\n    public void setLong(int idx, long obj) {\n      IntArraySubList.setLong(data, 0, nElems, idx, obj);\n    }\n    public int capacity() { return data.length; }\n    public void clear() { nElems = 0; }\n    public int[] ensureCapacity(int len) {\n      int[] d = data;\n      if (len >= d.length) {\n\td = data = Arrays.copyOf(d, len < 100000 ? len * 2 : (int)(len * 1.5));\n      }\n      return d;\n    }\n    public void addLong(long obj) {\n      int val = RT.intCast(obj);\n      final int ne = nElems;\n      final int[] d = ensureCapacity(ne+1);\n      d[ne] = val;\n      nElems = ne+1;\n    }\n    public void add(int idx, Object obj) {\n      idx = wrapCheckIndex(idx, nElems);\n      if (idx == nElems) { add(obj); return; }\n\n      final int val = RT.intCast(Casts.longCast(obj));\n      final int ne = nElems;\n      final int[] d = ensureCapacity(ne+1);\n      System.arraycopy(d, idx, d, idx+1, ne - idx);\n      d[idx] = val;\n      nElems = ne+1;\n    }\n    public boolean addAllReducible(Object c) {\n      final int sz = size();\n      if (c instanceof RandomAccess) {\n\tfinal List cl = (List) c;\n\tif (cl.isEmpty() ) return false;\n\tfinal int cs = cl.size();\n\tensureCapacity(cs+sz);\n\tnElems += cs;\n\t//Hit fastpath\n\tfillRangeReducible(sz, cl);\n      } else {\n\tILongArrayList.super.addAllReducible(c);\n      }\n      return sz != size();\n    }\n    public boolean addAll(int sidx, Collection <? extends Object> c) {\n      sidx = wrapCheckIndex(sidx, nElems);\n      if (c.isEmpty()) return false;\n      final int cs = c.size();\n      final int sz = size();\n      final int eidx = sidx + cs;\n      ensureCapacity(cs+sz);\n      nElems += cs;\n      System.arraycopy(data, sidx, data, eidx, sz - sidx);\n      fillRangeReducible(sidx, c);\n      return true;\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx, seidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      meta = m;\n      return this;\n    }\n    public Object[] toArray() {\n      return subList(0, nElems).toArray();\n    }\n    public int[] toIntArray() {\n      return Arrays.copyOf(data, nElems);\n    }\n    public void fillRange(long startidx, long endidx, Object v) {\n      ((RangeList)subList(0, nElems)).fillRange(startidx, endidx, v);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      subList(0,size()).fillRangeReducible(startidx, v);\n    }\n    public void addRange(final int startidx, final int endidx, final Object v) {\n      final int ne = nElems;\n      checkIndexRange(ne, startidx, endidx);\n      final int rangeLen = endidx - startidx;\n      final int newLen = ne + rangeLen;\n      ensureCapacity(newLen);\n      System.arraycopy(data, startidx, data, endidx, nElems - startidx);\n      fillRange(startidx, endidx, v);\n    }\n    public void removeRange(int startidx, int endidx) {\n      checkIndexRange(nElems, startidx, endidx);\n      System.arraycopy(data, startidx, data, endidx, nElems - endidx);\n      nElems -= endidx - startidx;\n    }\n    public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems)).reduce(fn); }\n    public Object reduce(IFn fn, Object init) { return ((IReduceInit)subList(0, nElems)).reduce(fn,init); }\n    public Object longReduction(IFn.OLO op, long init) {\n      return ((LongMutList)subList(0, nElems)).longReduction(op, init);\n    }\n    public void sort(Comparator<? super Object> c) {\n      subList(0, nElems).sort(c);\n    }\n    public void shuffle(Random r) {\n      ((IMutList)subList(0, nElems)).shuffle(r);\n    }\n    public int[] sortIndirect(Comparator c) {\n      return ((IMutList)subList(0, nElems)).sortIndirect(c);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      return ((IMutList)subList(0, nElems)).binarySearch(v, c);\n    }\n    public IntComparator indexComparator() {\n      return IntArraySubList.indexComparator(data, 0, null);\n    }\n    public IntComparator indexComparator(Comparator c) {\n      return IntArraySubList.indexComparator(data, 0, c);\n    }\n    public Object longReduction(IFn.OLO rfn, Object init) {\n      final int es = nElems;\n      final int[] d = data;\n      for(int ss = 0; ss < es && !RT.isReduced(init); ++ss)\n\tinit = rfn.invokePrim(init, d[ss]);\n      return Reductions.unreduce(init);\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, ssidx, seidx, RT.intCast(Casts.longCast(v)));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, size());\n      return Arrays.copyOfRange(data, ssidx, seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOf(data, len);\n    }\n    public static IntArrayList wrap(final int[] data, int nElems, IPersistentMap m) {\n      if (data.length < nElems)\n\tthrow new RuntimeException(\"Array len less than required\");\n      return new IntArrayList(data, nElems, m);\n    }\n    public static IntArrayList wrap(final int[] data, IPersistentMap m) {\n      return new IntArrayList(data, data.length, m);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static IntComparator intIndexComparator(List srcData, Comparator comp) {\n    if(comp != null) {\n      if(srcData instanceof IMutList) {\n\treturn ((IMutList)srcData).indexComparator(comp);\n      } else {\n\treturn new IntComparator() {\n\t  public int compare(int l, int r) {\n\t    return comp.compare(srcData.get(l), srcData.get(r));\n\t  }\n\t};\n      }\n    } else {\n      if (srcData instanceof IMutList) {\n\treturn ((IMutList)srcData).indexComparator();\n      } else {\n\treturn new IntComparator() {\n\t  public int compare(int l, int r) {\n\t    return ((Comparable)srcData.get(l)).compareTo(srcData.get(r));\n\t  }\n\t};\n      }\n    }\n  }\n\n  public static IMutList<Object> toList(final int[] data, final int sidx, final int eidx, IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new IntArraySubList(data, sidx, eidx, meta);\n  }\n  public static IMutList<Object> toList(final int[] data) { return toList(data, 0, data.length, null); }\n\n  public static long[] longArray(int len) { return new long[len]; }\n  public static class LongArraySubList implements ILongArrayList {\n    public final long[] data;\n    public final int sidx;\n    public final int eidx;\n    public final int nElems;\n    public final IPersistentMap meta;\n    public LongArraySubList(long[] d, int _sidx, int _eidx, IPersistentMap m) {\n      data = d;\n      sidx = _sidx;\n      eidx = _eidx;\n      nElems = eidx - sidx;\n      meta = m;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, eidx); }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, eidx)); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return nElems; }\n    public long getLong(int idx) { return data[checkIndex(idx, nElems) + sidx]; }\n    public Object get(int idx) { return data[checkIndex(idx, nElems) + sidx]; }\n    public Object nth(int idx) {\n      return data[checkIndex(idx < 0 ? idx + nElems : idx, nElems) + sidx];\n    }\n    static void setLong(final long[] d, final int sidx, final int nElems,\n\t\t\tint idx, final long v) {\n      idx = checkIndex(idx, nElems) + sidx;\n      d[idx] = v;\n    }\n    public void setLong(int idx, long obj) {\n      setLong(data, sidx, nElems, idx, obj);\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, eidx, m);\n    }\n    public Object[] toArray() {\n      final long[] d = data;\n      final int ss = sidx;\n      final int ne = nElems;\n      Object[] retval = new Object[ne];\n      for(int idx = 0; idx < ne; ++idx)\n\tretval[idx] = d[idx+ss];\n      return retval;\n    }\n    public long[] toLongArray() {\n      return Arrays.copyOfRange(data, sidx, eidx);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static IntComparator indexComparator(long[] d, int sidx, Comparator c) {\n      if (c == null) {\n\tif (sidx != 0) {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return Long.compare(d[lidx+sidx], d[ridx+sidx]);\n\t    }\n\t  };\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return Long.compare(d[lidx], d[ridx]);\n\t    }\n\t  };\n\t}\n      } else {\n\tif(c instanceof LongComparator) {\n\t  final LongComparator lc = (LongComparator) c;\n\t  if (sidx != 0) {\n\t    return new IntComparator() {\n\t      public int compare(int lidx, int ridx) {\n\t\treturn lc.compare(d[lidx+sidx], d[ridx+sidx]);\n\t      }\n\t    };\n\t  } else {\n\t    return new IntComparator() {\n\t      public int compare(int lidx, int ridx) {\n\t\treturn lc.compare(d[lidx], d[ridx]);\n\t      }\n\t    };\n\t  }\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return c.compare(d[lidx+sidx], d[ridx+sidx]);\n\t    }\n\t  };\n\t}\n      }\n    }\n    public IntComparator indexComparator() {\n      return indexComparator(data, sidx, null);\n    }\n    public IntComparator indexComparator(Comparator c) {\n      return indexComparator(data, sidx, c);\n\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static LongComparator toLongComparator(Comparator c) {\n      if (c instanceof LongComparator)\n\treturn (LongComparator) c;\n      else\n\treturn new LongComparator() {\n\tpublic int compare(long lhs, long rhs) {\n\t  return c.compare(lhs, rhs);\n\t}\n      };\n    }\n    public void sort(Comparator<? super Object> c) {\n      if(c == null)\n\tLongArrays.parallelQuickSort(data, sidx, eidx);\n      else {\n\tLongArrays.parallelQuickSort(data, sidx, eidx, toLongComparator(c));\n      }\n    }\n    public int[] sortIndirect(Comparator c) {\n      final int sz = size();\n      int[] retval = iarange(0, sz, 1);\n      if(sz < 2)\n\treturn retval;\n      if(c == null)\n\tLongArrays.parallelQuickSortIndirect(retval, data, sidx, eidx);\n      else\n\tIntArrays.parallelQuickSort(retval, indexComparator(c));\n      return retval;\n    }\n    public void shuffle(Random r) {\n      LongArrays.shuffle(data, sidx, eidx, r);\n    }\n    public static LongComparator asLongComparator(Comparator c) {\n      if (c instanceof LongComparator)\n\treturn (LongComparator)c;\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final long vv = Casts.longCast(v);\n      final LongComparator bc = asLongComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? LongArrays.binarySearch(data, sidx, sidx+size(), vv) : LongArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n      return ILongArrayList.super.binarySearch(v, c);\n    }\n    public Object longReduction(IFn.OLO rfn, Object init) {\n      final int ee = size();\n      final long[] d = data;\n      for(int idx = 0; idx < ee && !RT.isReduced(init); ++idx)\n\tinit = rfn.invokePrim(init, data[idx+sidx]);\n      return Reductions.unreduce(init);\n    }\n    public void longForEach(LongConsumer c) {\n      final int es = eidx;\n      final long[] d = data;\n      for(int ss = sidx; ss < es; ++ss)\n\tc.accept(d[ss]);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ee = sidx + size();\n\tfinal long[] d = data;\n\tReductions.serialReduction(new Reductions.IndexedLongAccum( startidx + sidx,\n\t\t\t\t\t\t\t\t    new IFn.OLLO() {\n\t    public Object invokePrim(Object acc, long idx, long v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx-sidx) +\n\t\t\t\t\t\t    \" > length: \" + String.valueOf(size()));\n\t      d[(int)idx] = v;\n\t      return d;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx + ssidx, sidx + seidx, Casts.longCast(v));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static class LongArrayList implements ILongArrayList {\n    long[] data;\n    int nElems;\n    IPersistentMap meta;\n    public LongArrayList(long[] d, int ne, IPersistentMap meta) {\n      data = d;\n      nElems = ne;\n    }\n    public LongArrayList(int capacity) {\n      this(new long[capacity], 0, null);\n    }\n    public LongArrayList() {\n      this(4);\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return new LongArrayList((long[])copyOf(nElems),\n\t\t\t\t\t\t\t   nElems, meta); }\n    public ArraySection getArraySection() { return new ArraySection(data, 0, nElems); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public void clear() { nElems = 0; }\n    public int size() { return nElems; }\n    public void setSize(int sz) { nElems = sz; }\n    public long getLong(int idx) { return data[checkIndex(idx, nElems)]; }\n    public void setLong(int idx, long obj) {\n      LongArraySubList.setLong(data, 0, nElems, idx, obj);\n    }\n    public int capacity() { return data.length; }\n    public long[] ensureCapacity(int len) {\n      long[] d = data;\n      if (len >= d.length) {\n\td = data = Arrays.copyOf(d, len < 100000 ? len * 2 : (int)(len * 1.5));\n      }\n      return d;\n    }\n    public void addLong(long val) {\n      final int ne = nElems;\n      final long[] d = ensureCapacity(ne+1);\n      d[ne] = val;\n      nElems = ne+1;\n    }\n    public boolean add(Object obj) { addLong(Casts.longCast(obj)); return true; }\n    public void add(int idx, Object obj) {\n      idx = wrapCheckIndex(idx, nElems);\n      if (idx == nElems) { add(obj); return; }\n\n      final long val = Casts.longCast(obj);\n      final int ne = nElems;\n      final long[] d = ensureCapacity(ne+1);\n      System.arraycopy(d, idx, d, idx+1, ne - idx);\n      d[idx] = val;\n      nElems = ne+1;\n    }\n    public boolean addAllReducible(Object c) {\n      final int sz = size();\n      if (c instanceof RandomAccess) {\n\tfinal List cl = (List) c;\n\tif (cl.isEmpty() ) return false;\n\tfinal int cs = cl.size();\n\tensureCapacity(cs+sz);\n\tnElems += cs;\n\t//Hit fastpath\n\tfillRangeReducible(sz, cl);\n      } else {\n\tILongArrayList.super.addAllReducible(c);\n      }\n      return sz != size();\n    }\n    public boolean addAll(int sidx, Collection <? extends Object> c) {\n      sidx = wrapCheckIndex(sidx, nElems);\n      if (c.isEmpty()) return false;\n      final int cs = c.size();\n      final int sz = size();\n      final int eidx = sidx + cs;\n      ensureCapacity(cs+sz);\n      nElems += cs;\n      System.arraycopy(data, sidx, data, eidx, sz - sidx);\n      fillRangeReducible(sidx, c);\n      return true;\n    }\n    public Object remove(int idx) {\n      idx = wrapCheckIndex(idx, nElems);\n      final int ne = nElems;\n      final int nne = ne - 1;\n      final long[] d = data;\n      final long retval = d[idx];\n      if (idx != nne) {\n\tfinal int copyLen = ne - idx - 1;\n\tSystem.arraycopy(d, idx+1, d, idx, copyLen);\n      }\n      --nElems;\n      return retval;\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx, seidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      meta = m;\n      return this;\n    }\n    public Object[] toArray() {\n      return subList(0, nElems).toArray();\n    }\n    public long[] toLongArray() {\n      return Arrays.copyOf(data, nElems);\n    }\n    public void fillRange(long startidx, long endidx, Object v) {\n      ((RangeList)subList(0, nElems)).fillRange(startidx, endidx, v);\n    }\n    public void fillRangeReducible(long startidx, List v) {\n      ((RangeList)subList(0, nElems)).fillRangeReducible(startidx, v);\n    }\n    public void addRange(final int startidx, final int endidx, final Object v) {\n      final int ne = nElems;\n      checkIndexRange(ne, startidx, endidx);\n      final int rangeLen = endidx - startidx;\n      final int newLen = ne + rangeLen;\n      ensureCapacity(newLen);\n      System.arraycopy(data, startidx, data, endidx, nElems - startidx);\n    }\n    public void removeRange(int startidx, int endidx) {\n      checkIndexRange(nElems, startidx, endidx);\n      System.arraycopy(data, startidx, data, endidx, nElems - endidx);\n      nElems -= endidx - startidx;\n    }\n    public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems)).reduce(fn); }\n    public Object reduce(IFn fn, Object init) { return ((IReduceInit)subList(0, nElems)).reduce(fn,init); }\n    public Object longReduction(IFn.OLO op, Object init) {\n      return ((LongMutList)subList(0, nElems)).longReduction(op, init);\n    }\n    public IntComparator indexComparator() {\n      return LongArraySubList.indexComparator(data, 0, null);\n    }\n    public IntComparator indexComparator(Comparator c) {\n      return LongArraySubList.indexComparator(data, 0, c);\n    }\n    public void sort(Comparator<? super Object> c) {\n      subList(0, nElems).sort(c);\n    }\n    public void shuffle(Random r) {\n      ((IMutList)subList(0, nElems)).shuffle(r);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      return ((IMutList)subList(0, nElems)).binarySearch(v, c);\n    }\n    public int[] sortIndirect(Comparator c) {\n      return ((IMutList)subList(0, nElems)).sortIndirect(c);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      subList(0,size()).fillRangeReducible(startidx, v);\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, ssidx, seidx, Casts.longCast(v));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, nElems);\n      return Arrays.copyOfRange(data, ssidx, seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOf(data, len);\n    }\n    public static LongArrayList wrap(final long[] data, int nElems, IPersistentMap m) {\n      if (data.length < nElems)\n\tthrow new RuntimeException(\"Array len less than required\");\n      return new LongArrayList(data, nElems, m);\n    }\n    public static LongArrayList wrap(final long[] data, IPersistentMap m) {\n      return new LongArrayList(data, data.length, m);\n    }\n  }\n\n\n  public static IMutList<Object> toList(final long[] data, final int sidx, final int eidx, IPersistentMap meta) {\n    return new LongArraySubList(data, sidx, eidx, meta);\n  }\n  public static IMutList<Object> toList(final long[] data) { return toList(data, 0, data.length, null); }\n\n  public static float[] floatArray(int len) { return new float[len]; }\n  public static class FloatArraySubList implements IDoubleArrayList {\n    public final float[] data;\n    public final int sidx;\n    public final int dlen;\n    public final IPersistentMap meta;\n\n    public FloatArraySubList(float[] d, int s, int len, IPersistentMap _meta) {\n      data = d;\n      sidx = s;\n      dlen = len;\n      meta = _meta;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, sidx+dlen)); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, sidx + dlen); }\n    public int size() { return dlen; }\n    public Float get(int idx) { return data[checkIndex(idx, dlen) + sidx]; }\n    public double getDouble(int idx) { return data[checkIndex(idx, dlen) + sidx];}\n    public void setDouble(int idx, double v) {\n      float obj = (float)v;\n      idx = checkIndex(idx, dlen) + sidx;\n      data[idx] = obj;\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, sidx + dlen, m);\n    }\n    public Object[] toArray() {\n      final int sz = size();\n      Object[] retval = new Object[size()];\n      for (int idx = 0; idx < sz; ++idx)\n\tretval[idx] = data[idx+sidx];\n      return retval;\n    }\n    public float[] toFloatArray() {\n      return Arrays.copyOfRange(data, sidx, sidx + dlen);\n    }\n    public IntComparator indexComparator() {\n      if (sidx == 0) {\n\treturn new IntComparator() {\n\t  public int compare(int lidx, int ridx) {\n\t    return Float.compare(data[lidx], data[ridx]);\n\t  }\n\t};\n      } else {\n\treturn new IntComparator() {\n\t  public int compare(int lidx, int ridx) {\n\t    return Float.compare(data[lidx+sidx], data[ridx+sidx]);\n\t  }\n\t};\n      }\n    }\n    public IntComparator indexComparator(Comparator c) {\n      if (c == null) return indexComparator();\n      if (c instanceof DoubleComparator) {\n\tfinal DoubleComparator dc = (DoubleComparator)c;\n\tif (sidx == 0) {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return dc.compare(data[lidx], data[ridx]);\n\t    }\n\t  };\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return dc.compare(data[lidx+sidx], data[ridx+sidx]);\n\t    }\n\t  };\n\t}\n      } else {\n\treturn IDoubleArrayList.super.indexComparator(c);\n      }\n    }\n    public static FloatComparator asFloatComparator(Comparator c) {\n      if (c instanceof FloatComparator)\n\treturn (FloatComparator)c;\n      else if (c instanceof DoubleComparator) {\n\tfinal DoubleComparator lc = (DoubleComparator)c;\n\treturn new FloatComparator() {\n\t  public int compare(float l, float r) { return lc.compare(l,r); }\n\t};\n      }\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void sort(Comparator c) {\n      if(c == null) {\n\tFloatArrays.parallelQuickSort(data, sidx, sidx+dlen);\n      } else {\n\tFloatComparator fc = asFloatComparator(c);\n\tif (fc != null)\n\t  FloatArrays.parallelQuickSort(data, sidx, sidx+dlen, fc);\n\telse\n\t  IDoubleArrayList.super.sort(c);\n      }\n    }\n    public void shuffle(Random r) {\n      FloatArrays.shuffle(data, sidx, sidx+dlen, r);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final float vv = RT.floatCast(Casts.doubleCast(v));\n      final FloatComparator bc = asFloatComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? FloatArrays.binarySearch(data, sidx, sidx+size(), vv) : FloatArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n      return IDoubleArrayList.super.binarySearch(v, c);\n    }\n    public Object doubleReduction(IFn.ODO rfn, Object init) {\n      final int es = sidx + dlen;\n      final float[] d = data;\n      for(int ss = sidx; ss < es && !RT.isReduced(init); ++ss)\n\tinit = rfn.invokePrim(init, d[ss]);\n      return Reductions.unreduce(init);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ee = sidx + size();\n\tfinal float[] d = data;\n\tReductions.serialReduction(new Reductions.IndexedDoubleAccum( startidx+sidx,\n\t\t\t\t\t\t\t\t      new IFn.OLDO() {\n\t    public Object invokePrim(Object acc, long idx, double v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \" is out of range: \" +\n\t\t\t\t\t\t    String.valueOf(size()));\n\t      d[(int)idx] = (float)v;\n\t      return d;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, ssidx, seidx, (float)Casts.doubleCast(v));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, dlen);\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static IMutList<Object> toList(final float[] data, final int sidx, final int eidx, IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new FloatArraySubList(data, sidx, dlen, meta);\n  }\n  public static IMutList<Object> toList(final float[] data) { return toList(data, 0, data.length, null); }\n\n  public static double[] doubleArray(int len) {\n    return new double[len];\n  }\n\n  public static class DoubleArraySubList implements IDoubleArrayList {\n    public final double[] data;\n    public final int sidx;\n    public final int eidx;\n    public final int nElems;\n    public final IPersistentMap meta;\n    public DoubleArraySubList(double[] d, int _sidx, int _eidx, IPersistentMap m) {\n      data = d;\n      sidx = _sidx;\n      eidx = _eidx;\n      nElems = eidx - sidx;\n      meta = m;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, eidx)); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, eidx); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public int size() { return nElems; }\n    public double getDouble(int idx) { return data[checkIndex(idx, nElems) + sidx]; }\n    public Object get(int idx) { return data[checkIndex(idx, nElems) + sidx]; }\n    public Object nth(int idx) {\n      if(idx < 0)\n\tidx += nElems;\n      return data[checkIndex(idx, nElems) + sidx];\n    }\n    static void setDouble(final double[] d, final int sidx, final int nElems,\n\t\t\tint idx, final double v) {\n      idx = checkIndex(idx, nElems) + sidx;\n      d[idx] = v;\n    }\n    public void setDouble(int idx, double obj) {\n      setDouble(data, sidx, nElems, idx, obj);\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, eidx, m);\n    }\n    public Object[] toArray() {\n      final double[] d = data;\n      final int ss = sidx;\n      final int ne = nElems;\n      Object[] retval = new Object[ne];\n      for(int idx = 0; idx < ne; ++idx)\n\tretval[idx] = d[idx+ss];\n      return retval;\n    }\n    public double[] toDoubleArray() {\n      return Arrays.copyOfRange(data, sidx, eidx);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static IntComparator indexComparator(final double[] d, final int sidx,\n\t\t\t\t\t\tfinal Comparator comp) {\n      if (comp == null) {\n\tif (sidx != 0) {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return Double.compare(d[lidx+sidx], d[ridx+sidx]);\n\t    }\n\t  };\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return Double.compare(d[lidx], d[ridx]);\n\t    }\n\t  };\n\t}\n      } else {\n\tif (comp instanceof DoubleComparator) {\n\t  final DoubleComparator dc = (DoubleComparator)comp;\n\t  if(sidx != 0) {\n\t    return new IntComparator() {\n\t      public int compare(int lidx, int ridx) {\n\t\treturn dc.compare(d[lidx+sidx], d[ridx+sidx]);\n\t      }\n\t    };\n\t  } else {\n\t    return new IntComparator() {\n\t      public int compare(int lidx, int ridx) {\n\t\treturn dc.compare(d[lidx], d[ridx]);\n\t      }\n\t    };\n\t  }\n\t} else {\n\t  return new IntComparator() {\n\t    public int compare(int lidx, int ridx) {\n\t      return comp.compare(d[lidx+sidx], d[ridx+sidx]);\n\t    }\n\t  };\n\t}\n      }\n    }\n    public IntComparator indexComparator() {\n      return indexComparator(data, sidx, null);\n    }\n    public IntComparator indexComparator(Comparator c) {\n      return indexComparator(data, sidx, c);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static DoubleComparator toDoubleComparator(Comparator c) {\n      if (c instanceof DoubleComparator)\n\treturn (DoubleComparator) c;\n      return null;\n    }\n    public void sort(Comparator<? super Object> c) {\n      if(c == null)\n\tDoubleArrays.parallelQuickSort(data, sidx, eidx);\n      else {\n\tDoubleComparator dc = toDoubleComparator(c);\n\tif (dc != null) {\n\t  DoubleArrays.parallelQuickSort(data, sidx, eidx, toDoubleComparator(c));\n\t} else {\n\t  IDoubleArrayList.super.sort(c);\n\t}\n      }\n    }\n    public int[] sortIndirect(Comparator c) {\n      final int sz = size();\n      int[] retval = iarange(0, sz, 1);\n      if(sz < 2)\n\treturn retval;\n      if(c == null)\n\tDoubleArrays.parallelQuickSortIndirect(retval, data, sidx, eidx);\n      else\n\tIntArrays.parallelQuickSort(retval, indexComparator(c));\n      return retval;\n    }\n    public void shuffle(Random r) {\n      DoubleArrays.shuffle(data, sidx, eidx, r);\n    }\n    public static DoubleComparator asDoubleComparator(Comparator c) {\n      if (c instanceof DoubleComparator)\n\treturn (DoubleComparator)c;\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final double vv = RT.doubleCast(Casts.doubleCast(v));\n      final DoubleComparator bc = asDoubleComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? DoubleArrays.binarySearch(data, sidx, sidx+size(), vv) : DoubleArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n      return IDoubleArrayList.super.binarySearch(v, c);\n    }\n    public Object doubleReduction(IFn.ODO rfn, Object init) {\n      final int es = eidx;\n      final double[] d = data;\n      for(int ss = sidx; ss < es && !RT.isReduced(init); ++ss)\n\tinit = rfn.invokePrim(init, d[ss]);\n      return Reductions.unreduce(init);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ee = sidx + size();\n\tfinal double[] d = data;\n\tReductions.serialReduction(new Reductions.IndexedDoubleAccum( startidx+sidx,\n\t\t\t\t\t\t\t\t      new IFn.OLDO() {\n\t    public Object invokePrim(Object acc, long idx, double v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \"> length \" + String.valueOf(size()));\n\t      d[(int)idx] = v;\n\t      return d;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx + ssidx, sidx + seidx, Casts.doubleCast(v));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, nElems);\n      return Arrays.copyOfRange(data, sidx + ssidx, sidx + seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx + len);\n    }\n  }\n\n  public static class DoubleArrayList implements IDoubleArrayList {\n    double[] data;\n    int nElems;\n    IPersistentMap meta;\n    public DoubleArrayList(double[] d, int ne, IPersistentMap meta) {\n      data = d;\n      nElems = ne;\n    }\n    public DoubleArrayList(int capacity) {\n      this(new double[capacity], 0, null);\n    }\n    public DoubleArrayList() {\n      this(4);\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public IMutList cloneList() { return new DoubleArrayList((double[])copyOf(nElems),\n\t\t\t\t\t\t\t     nElems, meta); }\n    public ArraySection getArraySection() { return new ArraySection(data, 0, nElems); }\n    public Class containedType() { return data.getClass().getComponentType(); }\n    public void clear() { nElems = 0; }\n    public int size() { return nElems; }\n    public void setSize(int sz) { nElems = sz; }\n    public double getDouble(int idx) { return data[checkIndex(idx, nElems)]; }\n    public void setDouble(int idx, double obj) {\n      DoubleArraySubList.setDouble(data, 0, nElems, idx, obj);\n    }\n    public int capacity() { return data.length; }\n    public double[] ensureCapacity(int len) {\n      double[] d = data;\n      if (len >= d.length) {\n\td = data = Arrays.copyOf(d, len < 100000 ? len * 2 : (int)(len * 1.5));\n      }\n      return d;\n    }\n    public void addDouble(double obj) {\n      final int ne = nElems;\n      final double[] d = ensureCapacity(ne+1);\n      d[ne] = obj;\n      nElems = ne+1;\n    }\n    public boolean add(Object obj) { addDouble(Casts.doubleCast(obj)); return true; }\n    public void add(int idx, Object obj) {\n      if (idx == nElems) { add(obj); return; }\n      idx = wrapCheckIndex(idx, nElems);\n\n      final double val = Casts.doubleCast(obj);\n      final int ne = nElems;\n      final double[] d = ensureCapacity(ne+1);\n      System.arraycopy(d, idx, d, idx+1, ne - idx);\n      d[idx] = val;\n      nElems = ne+1;\n    }\n    public boolean addAllReducible(Object c) {\n      final int sz = size();\n      if (c instanceof RandomAccess) {\n\tfinal List cl = (List) c;\n\tif (cl.isEmpty() ) return false;\n\tfinal int cs = cl.size();\n\tensureCapacity(cs+sz);\n\tnElems += cs;\n\t//Hit fastpath\n\tfillRangeReducible(sz, cl);\n      } else {\n\tIDoubleArrayList.super.addAllReducible(c);\n      }\n      return sz != size();\n    }\n    public boolean addAll(int sidx, Collection <? extends Object> c) {\n      sidx = wrapCheckIndex(sidx, nElems);\n      if (c.isEmpty()) return false;\n      final int cs = c.size();\n      final int sz = size();\n      final int eidx = sidx + cs;\n      ensureCapacity(cs+sz);\n      nElems += cs;\n      System.arraycopy(data, sidx, data, eidx, sz - sidx);\n      if (c instanceof List) {\n\t//Hit fastpath\n\tfillRangeReducible(sidx, (List)c);\n      } else {\n\tint idx = sidx;\n\tfor(Object o: c) {\n\t  set(idx, o);\n\t  ++idx;\n\t}\n      }\n      return true;\n    }\n    public Object remove(int idx) {\n      idx = wrapCheckIndex(idx, nElems);\n      final int ne = nElems;\n      final int nne = ne - 1;\n      final double[] d = data;\n      final double retval = d[idx];\n      if (idx != nne) {\n\tfinal int copyLen = ne - idx - 1;\n\tSystem.arraycopy(d, idx+1, d, idx, copyLen);\n      }\n      --nElems;\n      return retval;\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx, seidx, meta());\n    }\n    public void fillRangeReducible(long startidx, List v) {\n      ((IMutList)subList(0, nElems)).fillRangeReducible(startidx, v);\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      meta = m;\n      return this;\n    }\n    public Object[] toArray() {\n      return subList(0, nElems).toArray();\n    }\n    public double[] toDoubleArray() {\n      return Arrays.copyOf(data, nElems);\n    }\n    public void removeRange(int startidx, int endidx) {\n      checkIndexRange(size(), startidx, endidx);\n      System.arraycopy(data, startidx, data, endidx, nElems - endidx);\n      nElems -= endidx - startidx;\n    }\n    public Object reduce(IFn fn) { return ((IReduce)subList(0, nElems)).reduce(fn); }\n    public Object reduce(IFn fn, Object init) {\n      return ((IReduceInit)subList(0, nElems)).reduce(fn,init);\n    }\n    public Object doubleReduction(IFn.ODO fn, Object init) {\n      return ((DoubleMutList)subList(0, nElems)).doubleReduction(fn, init);\n    }\n    public IntComparator indexComparator() {\n      return DoubleArraySubList.indexComparator(data, 0, null);\n    }\n    public IntComparator indexComparator(Comparator c) {\n      return DoubleArraySubList.indexComparator(data, 0, c);\n    }\n    public void sort(Comparator<? super Object> c) {\n      subList(0, nElems).sort(c);\n    }\n    public void shuffle(Random r) {\n      ((IMutList)subList(0, nElems)).shuffle(r);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      return ((IMutList)subList(0, nElems)).binarySearch(v, c);\n    }\n    public int[] sortIndirect(Comparator c) {\n      return ((IMutList)subList(0, nElems)).sortIndirect(c);\n    }\n    public void doubleForEach(DoubleConsumer c) {\n      final int es = nElems;\n      final double[] d = data;\n      for(int ss = 0; ss < es; ++ss)\n\tc.accept(d[ss]);\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, ssidx, seidx, Casts.doubleCast(v));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, nElems);\n      return Arrays.copyOfRange(data, ssidx, seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOf(data, len);\n    }\n    public static DoubleArrayList wrap(final double[] data, int nElems, IPersistentMap m) {\n      if (data.length < nElems)\n\tthrow new RuntimeException(\"Array len less than required\");\n      return new DoubleArrayList(data, nElems, m);\n    }\n    public static DoubleArrayList wrap(final double[] data, IPersistentMap m) {\n      return new DoubleArrayList(data, data.length, m);\n    }\n  }\n\n  public static IMutList<Object> toList(final double[] data, final int sidx, final int eidx, IPersistentMap meta) {\n    return new DoubleArraySubList(data, sidx, eidx, meta);\n  }\n  public static IMutList<Object> toList(final double[] data) { return toList(data, 0, data.length, null); }\n\n  public static class CharArraySubList implements ILongArrayList {\n    public final char[] data;\n    public final int sidx;\n    public final int dlen;\n    public final IPersistentMap meta;\n    public CharArraySubList(char[] d, int s, int len, IPersistentMap m) {\n      data = d;\n      sidx = s;\n      dlen = len;\n      meta = m;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, sidx + dlen); }\n    public int size() { return dlen; }\n    public Character set(int idx, Object obj) {\n      idx = checkIndex(idx, dlen);\n      char rv = data[idx];\n      data[idx] = Casts.charCast(obj);\n      return rv;\n    }\n    public Character get(int idx) { return data[checkIndex(idx, dlen) + sidx]; }\n    public long getLong(int idx) { return data[checkIndex(idx, dlen) + sidx]; }\n    public void setLong(int idx, long obj) {\n      char v = Casts.charCast(obj);\n      idx = checkIndex(idx, dlen) + sidx;\n      data[idx] = v;\n    }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, sidx + dlen, m);\n    }\n    public Object[] toArray() {\n      final int sz = size();\n      Object[] retval = new Object[size()];\n      for (int idx = 0; idx < sz; ++idx)\n\tretval[idx] = data[idx+sidx];\n      return retval;\n    }\n    public static CharComparator asCharComparator(Comparator c) {\n      if (c instanceof CharComparator)\n\treturn (CharComparator)c;\n      else if (c instanceof LongComparator) {\n\tfinal LongComparator lc = (LongComparator)c;\n\treturn new CharComparator() {\n\t  public int compare(char l, char r) { return lc.compare(l,r); }\n\t};\n      }\n      return null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void sort(Comparator c) {\n      if(c==null)\n\tCharArrays.parallelQuickSort(data, sidx, sidx+dlen);\n      else {\n\tCharComparator cc = asCharComparator(c);\n\tif( cc != null)\n\t  CharArrays.parallelQuickSort(data, sidx, sidx+dlen, cc);\n\telse\n\t  ILongArrayList.super.sort(c);\n      }\n    }\n    public void shuffle(Random r) {\n      CharArrays.shuffle(data, sidx, sidx+dlen, r);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public int binarySearch(Object v, Comparator c) {\n      final char vv = RT.charCast(Casts.longCast(v));\n      final CharComparator bc = asCharComparator(c);\n      if(c == null || bc != null)\n\treturn fixSubArrayBinarySearch(sidx, size(),\n\t\t\t\t       bc == null ? CharArrays.binarySearch(data, sidx, sidx+size(), vv) : CharArrays.binarySearch(data, sidx, sidx+size(), vv, bc));\n      return ILongArrayList.super.binarySearch(v, c);\n    }\n    public Object reduce(IFn rfn, Object init) {\n      final int sz = size();\n      for (int idx = 0; idx < sz && !RT.isReduced(init); ++idx)\n\tinit = rfn.invoke(init, data[idx+sidx]);\n      return Reductions.unreduce(init);\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ss = (int)startidx + sidx;\n\tfinal int ee = sidx + size();\n\tReductions.serialReduction(new Reductions.IndexedAccum( startidx+sidx,\n\t\t\t\t\t\t\t\tnew IFn.OLOO() {\n\t    public Object invokePrim(Object acc, long idx, Object v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \" is out of range: \" +\n\t\t\t\t\t\t    String.valueOf(size()));\n\t      data[(int)idx] = Casts.charCast(v);\n\t      return data;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, ssidx+sidx, seidx+sidx, RT.charCast(Casts.longCast((v==null)?0:v)));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndex(ssidx, size());\n      return Arrays.copyOfRange(data, ssidx+sidx, seidx+sidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static IMutList<Object> toList(final char[] data, final int sidx, final int eidx, IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new CharArraySubList(data, sidx, dlen, meta);\n  }\n  public static IMutList<Object> toList(final char[] data) { return toList(data, 0, data.length, null); }\n\n\n  public static class BooleanArraySubList implements IArrayList {\n    public final boolean[] data;\n    public final int sidx;\n    public final int dlen;\n    public final IPersistentMap meta;\n\n    public BooleanArraySubList(boolean[] d, int s, int len, IPersistentMap m) {\n      data = d;\n      sidx = s;\n      dlen = len;\n      meta = m;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public ArraySection getArraySection() { return new ArraySection(data, sidx, sidx + dlen); }\n    public int size() { return dlen; }\n    public boolean getBoolean(int idx) { return data[checkIndex(idx, dlen)+sidx]; }\n    public void setBoolean(int idx, boolean obj) {\n      data[checkIndex(idx, dlen)+sidx] = obj;\n    }\n    public long getLong(int idx) { return Casts.longCast(data[checkIndex(idx, dlen)+sidx]); }\n    public void setLong(int idx, long obj) {\n      data[checkIndex(idx, dlen)+sidx] = Casts.booleanCast(obj);\n    }\n    public Object get(int idx) { return getBoolean(idx); }\n    public Object set(int idx, Object v) {\n      final boolean retval = getBoolean(idx);\n      setBoolean(idx, Casts.booleanCast(v));\n      return retval;\n    }\n    public IMutList cloneList() { return (IMutList)toList(Arrays.copyOfRange(data, sidx, sidx+dlen)); }\n    public IMutList<Object> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, size());\n      return toList(data, ssidx + sidx, seidx + sidx, meta());\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) {\n      return (IObj)toList(data, sidx, sidx + dlen, m);\n    }\n    public Object[] toArray() {\n      final int sz = size();\n      Object[] retval = new Object[size()];\n      for (int idx = 0; idx < sz; ++idx)\n\tretval[idx] = data[idx+sidx];\n      return retval;\n    }\n    public void fillRangeReducible(long startidx, Object v) {\n      final ArraySection as = getArraySection();\n      if (!fillRangeArrayCopy(as.array, as.sidx, as.eidx, startidx, v)) {\n\tfinal int ss = (int)startidx + sidx;\n\tfinal int ee = sidx + size();\n\tReductions.serialReduction(new Reductions.IndexedAccum( startidx+sidx,\n\t\t\t\t\t\t\t\tnew IFn.OLOO() {\n\t    public Object invokePrim(Object acc, long idx, Object v) {\n\t      if(idx >= ee)\n\t\tthrow new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx - sidx) +\n\t\t\t\t\t\t    \" is out of range: \" +\n\t\t\t\t\t\t    String.valueOf(size()));\n\t      data[(int)idx] = Casts.booleanCast(v);\n\t      return data;\n\t    }}), data, v);\n      }\n    }\n    public void move(int sidx, int eidx, int count) {\n      checkIndexRange(size(), eidx, eidx + count);\n      System.arraycopy(data, sidx, data, eidx, count);\n    }\n    public void fill(int ssidx, int seidx, Object v) {\n      checkIndexRange(size(), ssidx, seidx);\n      Arrays.fill(data, sidx+ssidx, sidx+seidx, Casts.booleanCast(v));\n    }\n    public Object copyOfRange(int ssidx, int seidx) {\n      checkIndexRange(size(), ssidx, seidx);\n      return Arrays.copyOfRange(data, sidx+ssidx, sidx+seidx);\n    }\n    public Object copyOf(int len) {\n      return Arrays.copyOfRange(data, sidx, sidx+len);\n    }\n  }\n\n  public static IMutList<Object> toList(final boolean[] data, final int sidx, final int eidx, IPersistentMap meta) {\n    final int dlen = eidx - sidx;\n    return new BooleanArraySubList(data, sidx, dlen, meta);\n  }\n  public static IMutList<Object> toList(final boolean[] data) { return toList(data, 0, data.length, null); }\n\n\n  public static IMutList<Object> toList(Object obj, int sidx, int eidx, IPersistentMap meta) {\n    if (obj == null) return null;\n    Class cls = obj.getClass();\n    if(!cls.isArray())\n      throw new RuntimeException(\"Object is not an array: \" + String.valueOf(obj));\n    if(obj instanceof Object[])\n      return toList((Object[])obj, sidx, eidx, meta);\n    else if (cls == long[].class)\n      return toList((long[])obj, sidx, eidx, meta);\n    else if (cls == double[].class)\n      return toList((double[])obj, sidx, eidx, meta);\n    else if (cls == byte[].class)\n      return toList((byte[])obj, sidx, eidx, meta);\n    else if (cls == short[].class)\n      return toList((short[])obj, sidx, eidx, meta);\n    else if (cls == int[].class)\n      return toList((int[])obj, sidx, eidx, meta);\n    else if (cls == float[].class)\n      return toList((float[])obj, sidx, eidx, meta);\n    else if (cls == char[].class)\n      return toList((char[])obj, sidx, eidx, meta);\n    else if (cls == boolean[].class)\n      return toList((boolean[])obj, sidx, eidx, meta);\n    else\n      throw new RuntimeException(\"Invalid array type.\");\n  }\n\n  public static IMutList<Object> toList(Object obj) {\n    if (obj == null) return null;\n    Class cls = obj.getClass();\n    if(!cls.isArray())\n      throw new RuntimeException(\"Object is not an array: \" + String.valueOf(obj));\n    return toList(obj, 0, Array.getLength(obj), null);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static IMutList<Object> toList(ArraySection data) {\n    if(data == null) return null;\n    if(data instanceof IMutList)\n      return (IMutList)data;\n    return toList(data.array, data.sidx, data.eidx, null);\n  }\n\n  public static int[] iarange(int start, int end, int step) {\n    final int len = (end - start)/step;\n    if (len < 0 )\n      throw new RuntimeException(\"Invalid range - start: \" + String.valueOf(start) +\n\t\t\t\t \" end: \" + String.valueOf(end) +\n\t\t\t\t \" step: \" + String.valueOf(step));\n    final int[] retval = new int[len];\n    for(int idx = 0; idx < len; ++idx) {\n      retval[idx] = start + idx * step;\n    }\n    return retval;\n  }\n  public static long[] larange(long start, long end, long step) {\n    final int len = RT.intCast((end - start)/step);\n    if (len < 0 )\n      throw new RuntimeException(\"Invalid range.\");\n    final long[] retval = new long[len];\n    for(int idx = 0; idx < len; ++idx) {\n      retval[idx] = start + idx * step;\n    }\n    return retval;\n  }\n  public static double[] darange(double start, double end, double step) {\n    final int len = RT.intCast((end - start)/step);\n    if (len < 0 )\n      throw new RuntimeException(\"Invalid range.\");\n    final double[] retval = new double[len];\n    for(int idx = 0; idx < len; ++idx) {\n      retval[idx] = start + idx * step;\n    }\n    return retval;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ArraySection.java",
    "content": "package ham_fisted;\n\n\n\npublic class ArraySection\n{\n  public final Object array;\n  public final int sidx;\n  public final int eidx;\n  public ArraySection(Object ary, int _sidx, int _eidx) {\n    if(! (_eidx >= _sidx))\n      throw new RuntimeException(\"End index: \" + String.valueOf(_eidx) + \" is not >= start index: \" + String.valueOf(_sidx));\n\n    array = ary;\n    sidx = _sidx;\n    eidx = _eidx;\n  }\n  public ArraySection(ArraySection other) {\n    this(other.array, other.sidx, other.eidx);\n  }\n  public int size() { return eidx - sidx; }\n  public String toString() {\n    return \"ArraySection<\" + array.getClass().getComponentType().getCanonicalName() + \">[\" + String.valueOf(sidx) + \":\" + String.valueOf(eidx) + \"]\";\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/BatchReducer.java",
    "content": "package ham_fisted;\n\nimport clojure.lang.Sequential;\nimport clojure.lang.IDeref;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.function.Consumer;\n\npublic class BatchReducer implements IFnDef.O, ITypedReduce, Sequential, Iterable {\n  final IFn batchSrc;\n  List batchData;\n  int idx;\n  int nElems;\n\n  public BatchReducer(IFn batchSrc) {\n    this.batchSrc = batchSrc;\n    batchData = null;\n    idx = 0;\n    nElems = 0;\n  }\n  public Object reduce(IFn rfn, Object acc) {\n    List bd = batchData;\n    int ix = idx;\n    int ne = nElems;\n    do {\n      if(ix == ne) {\n\tbd = (List)batchSrc.invoke();\n\tix = 0;\n\tne = bd.size();\n      }\n      acc = rfn.invoke(acc, bd.get(ix++));\n    } while(!RT.isReduced(acc));\n    batchData = bd;\n    idx = ix;\n    nElems = ne;\n    return ((IDeref)acc).deref();\n  }\n  public Object invoke() {\n    if(idx == nElems) {\n      batchData = (List)batchSrc.invoke();\n      idx = 0;\n      nElems = batchData.size();\n    }\n    return batchData.get(idx++);\n  }\n  public Iterator iterator() {\n    final IFn invoker = this;\n    return new Iterator() {\n      public boolean hasNext() { return true; }\n      public Object next() { return invoker.invoke(); }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  public void forEach(Consumer c) { ITypedReduce.super.forEach(c); }\n}\n"
  },
  {
    "path": "java/ham_fisted/BatchedList.java",
    "content": "package ham_fisted;\n\nimport clojure.lang.IDeref;\n\npublic class BatchedList implements IMutList, IDeref {\n  public static final int tailWidth = 64;\n  public static final int leafWidth = 64;\n  Object[] tail = new Object[tailWidth];\n  int nTail;\n  Object[][] leafTail = new Object[leafWidth][];\n  int nLeafTail;\n  public static class Link {\n    public final Object[][] leaf;\n    public Link next;\n    public Link(Object[][] leaf) {\n      this.leaf = leaf;\n      this.next = null;\n    }\n  }\n  Link first;\n  Link last;\n  int count;\n  public BatchedList() {\n    first = null;\n    last = null;\n    count = 0;\n  }\n  public boolean add(Object obj) {\n    if(nTail == tailWidth) {\n      if(nLeafTail == leafWidth) {\n\tLink l = new Link(leafTail);\n\tleafTail = new Object[leafWidth][];\n\tnLeafTail = 0;\n\tif(first == null) first = l;\n\tif(last != null)\n\t  last.next = l;\n\tlast = l;\n      } else {\n\tleafTail[nLeafTail++] = tail;\n      }\n      tail = new Object[tailWidth];\n      nTail = 0;\n    }\n    tail[nTail++] = obj;\n    ++count;\n    return true;\n  }\n  public Object get(int idx) { throw new RuntimeException(); }\n  public int count() { return count; }\n  public int size() { return count; }\n  public void clear() {\n    nTail = 0;\n    first = null;\n    last = null;\n    count = 0;\n  }\n  public TreeList deref() {\n    return TreeList.EMPTY;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/BiFunctions.java",
    "content": "package ham_fisted;\n\n\nimport java.util.function.BiFunction;\n\n\npublic class BiFunctions {\n  public static final BiFunction incBiFn = (k, v)-> v == null ? Long.valueOf(1) : Long.valueOf(((long)v) + 1);\n  public static final BiFunction rhsWins = (v1,v2)->v2;\n}\n"
  },
  {
    "path": "java/ham_fisted/BlockSplitBloomFilter.java",
    "content": "/*\n * Licensed to the Apache Software Foundation (ASF) under one\n * or more contributor license agreements.  See the NOTICE file\n * distributed with this work for additional information\n * regarding copyright ownership.  The ASF licenses this file\n * to you under the Apache License, Version 2.0 (the\n * \"License\"); you may not use this file except in compliance\n * with the License.  You may obtain a copy of the License at\n *\n *   http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing,\n * software distributed under the License is distributed on an\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n * KIND, either express or implied.  See the License for the\n * specific language governing permissions and limitations\n * under the License.\n */\n\n//package org.apache.parquet.column.values.bloomfilter;\npackage ham_fisted;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.OutputStream;\nimport java.nio.ByteBuffer;\nimport java.nio.ByteOrder;\nimport java.nio.IntBuffer;\nimport java.util.Arrays;\nimport net.openhft.hashing.LongHashFunction;\n\n/*\n * This Bloom filter is implemented using block-based Bloom filter algorithm from Putze et al.'s\n * \"Cache-, Hash- and Space-Efficient Bloom filters\". The basic idea is to hash the item to a tiny\n * Bloom filter which size fit a single cache line or smaller. This implementation sets 8 bits in\n * each tiny Bloom filter. Each tiny Bloom filter is 32 bytes to take advantage of 32-byte SIMD\n * instruction.\n */\npublic class BlockSplitBloomFilter {\n  // Bytes in a tiny Bloom filter block.\n  private static final int BYTES_PER_BLOCK = 32;\n\n  // Bits in a tiny Bloom filter block.\n  private static final int BITS_PER_BLOCK = 256;\n\n  // The lower bound of bloom filter size, set to the size of a tiny Bloom filter block.\n  public static final int LOWER_BOUND_BYTES = 32;\n\n  // The upper bound of bloom filter size, set to default row group size.\n  public static final int UPPER_BOUND_BYTES = 128 * 1024 * 1024;\n\n  // The number of bits to set in a tiny Bloom filter\n  private static final int BITS_SET_PER_BLOCK = 8;\n\n  // The metadata in the header of a serialized Bloom filter is four four-byte values: the number of bytes,\n  // the filter algorithm, the hash algorithm, and the compression.\n  public static final int HEADER_SIZE = 16;\n\n  // The default false positive probability value\n  public static final double DEFAULT_FPP = 0.01;\n\n  // The underlying byte array for Bloom filter bitset.\n  private byte[] bitset;\n\n  // A integer array buffer of underlying bitset to help setting bits.\n  private IntBuffer intBuffer;\n\n  private int maximumBytes = UPPER_BOUND_BYTES;\n  private int minimumBytes = LOWER_BOUND_BYTES;\n\n\n  private int[] mask = new int[BITS_SET_PER_BLOCK];\n\n  // The block-based algorithm needs 8 odd SALT values to calculate eight indexes\n  // of bits to set, one per 32-bit word.\n  private static final int[] SALT = {\n    0x47b6137b, 0x44974d91, 0x8824ad5b, 0xa2b7289d, 0x705495c7, 0x2df1424b, 0x9efc4947, 0x5c6bfb31\n  };\n\n  public BlockSplitBloomFilter(int numBytes) {\n    this.minimumBytes = LOWER_BOUND_BYTES;\n    this.maximumBytes = UPPER_BOUND_BYTES;\n    initBitset(numBytes);\n  }\n\n  public byte[] bitset() { return bitset; }\n\n  /**\n   * Construct the Bloom filter with given bitset, it is used when reconstructing\n   * Bloom filter from parquet file.\n   *\n   * @param bitset       The given bitset to construct Bloom filter.\n   * @param hashStrategy The hash strategy Bloom filter apply.\n   */\n  public BlockSplitBloomFilter(byte[] bitset) {\n    if (bitset == null) {\n      throw new RuntimeException(\"Given bitset is null\");\n    }\n\n    this.bitset = bitset;\n    this.intBuffer = ByteBuffer.wrap(bitset).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();\n  }\n\n  /**\n   * Create a new bitset for Bloom filter.\n   *\n   * @param numBytes The number of bytes for Bloom filter bitset. The range of num_bytes should be within\n   *                 [minimumBytes, maximumBytes], it will be rounded up/down\n   *                 to lower/upper bound if num_bytes is out of range and also will rounded up to a power\n   *                 of 2. It uses XXH64 as its default hash function and block-based algorithm\n   *                 as default algorithm.\n   */\n  private void initBitset(int numBytes) {\n    if (numBytes < minimumBytes) {\n      numBytes = minimumBytes;\n    }\n    // Get next power of 2 if it is not power of 2.\n    if ((numBytes & (numBytes - 1)) != 0) {\n      numBytes = Integer.highestOneBit(numBytes) << 1;\n    }\n    if (numBytes > maximumBytes || numBytes < 0) {\n      numBytes = maximumBytes;\n    }\n    this.bitset = new byte[numBytes];\n    this.intBuffer = ByteBuffer.wrap(bitset).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();\n  }\n\n  private int[] setMask(int key) {\n    // The following three loops are written separately so that they could be\n    // optimized for vectorization.\n    for (int i = 0; i < BITS_SET_PER_BLOCK; ++i) {\n      mask[i] = key * SALT[i];\n    }\n\n    for (int i = 0; i < BITS_SET_PER_BLOCK; ++i) {\n      mask[i] = mask[i] >>> 27;\n    }\n\n    for (int i = 0; i < BITS_SET_PER_BLOCK; ++i) {\n      mask[i] = 0x1 << mask[i];\n    }\n\n    return mask;\n  }\n\n\n  public void insertHash(long hash) {\n    long numBlocks = bitset.length / BYTES_PER_BLOCK;\n    long lowHash = hash >>> 32;\n    int blockIndex = (int) ((lowHash * numBlocks) >> 32);\n    int key = (int) hash;\n\n    // Calculate mask for bucket.\n    int[] mask = setMask(key);\n    for (int i = 0; i < BITS_SET_PER_BLOCK; i++) {\n      int value = intBuffer.get(blockIndex * (BYTES_PER_BLOCK / 4) + i);\n      value |= mask[i];\n      intBuffer.put(blockIndex * (BYTES_PER_BLOCK / 4) + i, value);\n    }\n  }\n\n\n  public boolean findHash(long hash) {\n    long numBlocks = bitset.length / BYTES_PER_BLOCK;\n    long lowHash = hash >>> 32;\n    int blockIndex = (int) ((lowHash * numBlocks) >> 32);\n    int key = (int) hash;\n\n    // Calculate mask for the tiny Bloom filter.\n    int[] mask = setMask(key);\n    for (int i = 0; i < BITS_SET_PER_BLOCK; i++) {\n      if (0 == (intBuffer.get(blockIndex * (BYTES_PER_BLOCK / 4) + i) & mask[i])) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  private static void checkArgument(boolean arg, String message) {\n    if(!arg) throw new RuntimeException(message);\n  }\n  /**\n   * Calculate optimal size according to the number of distinct values and false positive probability.\n   *\n   * @param n: The number of distinct values.\n   * @param p: The false positive probability.\n   * @return optimal number of bits of given n and p.\n   */\n  public static int optimalNumOfBits(long n, double p) {\n    checkArgument((p > 0.0 && p < 1.0), \"FPP should be less than 1.0 and great than 0.0\");\n    final double m = -8 * n / Math.log(1 - Math.pow(p, 1.0 / 8));\n    int numBits = (int) m;\n\n    // Handle overflow.\n    if (numBits > UPPER_BOUND_BYTES << 3 || m < 0) {\n      numBits = UPPER_BOUND_BYTES << 3;\n    }\n\n    // Round numBits up to (k * BITS_PER_BLOCK)\n    numBits = (numBits + BITS_PER_BLOCK - 1) & ~BITS_PER_BLOCK;\n\n    if (numBits < (LOWER_BOUND_BYTES << 3)) {\n      numBits = LOWER_BOUND_BYTES << 3;\n    }\n    return numBits;\n  }\n\n\n  public int getBitsetSize() {\n    return this.bitset.length;\n  }\n\n\n  public static long hash(byte[] input) {\n    return LongHashFunction.xx().hashBytes(input);\n  }\n\n\n  public boolean equals(Object object) {\n    if (object == this) {\n      return true;\n    }\n    if (object instanceof BlockSplitBloomFilter) {\n      BlockSplitBloomFilter that = (BlockSplitBloomFilter) object;\n      return Arrays.equals(this.bitset, that.bitset);\n    }\n    return false;\n  }\n\n\n  public boolean canMergeFrom(BlockSplitBloomFilter otherBloomFilter) {\n    return otherBloomFilter != null\n      && getBitsetSize() == otherBloomFilter.getBitsetSize();\n  }\n\n  public void merge(BlockSplitBloomFilter otherBloomFilter) throws IOException {\n    checkArgument(otherBloomFilter != null, \"The BloomFilter to merge shouldn't be null\");\n    checkArgument(\n        canMergeFrom(otherBloomFilter),\n        \"BloomFilters must have the same size of bitset.\");\n    byte[] otherBits = otherBloomFilter.bitset;\n    for (int i = 0; i < otherBits.length; i++) {\n      bitset[i] |= otherBits[i];\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/Casts.java",
    "content": "package ham_fisted;\n\n\n\nimport clojure.lang.Util;\nimport clojure.lang.RT;\n\n\npublic class Casts {\n  public static boolean booleanCast(Object obj) {\n    if(obj == null)\n      return false;\n    if(obj instanceof Boolean)\n      return (Boolean)obj;\n    if(obj instanceof Number) {\n      final Number nobj = (Number)obj;\n      return Util.isInteger(obj) ? nobj.longValue() != 0 : booleanCast(nobj.doubleValue());\n    }\n    if(obj instanceof Character)\n      return ((Character)obj).charValue() != 0;\n    return true;\n  }\n  public static boolean booleanCast(long obj) {\n    return obj != 0;\n  }\n  public static boolean booleanCast(double obj) {\n    return Double.isNaN(obj) ? false : obj != 0.0;\n  }\n  public static boolean booleanCast(float obj) {\n    return Float.isNaN(obj) ? false : obj != 0.0f;\n }\n  public static boolean booleanCast(boolean obj) {\n    return obj;\n  }\n  public static char charCast(double obj) {\n    if(!Double.isFinite(obj))\n      throw new RuntimeException(\"Non-finite double cannot be casted to long: \"\n\t\t\t\t + String.valueOf(obj));\n    return RT.charCast(obj);\n  }\n  public static char charCast(float obj) {\n    if(!Float.isFinite(obj))\n      throw new RuntimeException(\"Non-finite float cannot be casted to long: \"\n\t\t\t\t + String.valueOf(obj));\n    return RT.charCast(obj);\n  }\n  public static char charCast(long obj) {\n    return RT.charCast(obj);\n  }\n  public static char charCast(Object obj) {\n    if(obj == null)\n      return (char)0;\n    else if (obj instanceof Boolean)\n      return ((Boolean)obj) ? (char)1 : (char)0;\n    else if (obj instanceof Number) {\n      final Number nobj = (Number)obj;\n      if(obj instanceof Double)\n\treturn charCast(nobj.doubleValue());\n      else if(obj instanceof Float)\n\treturn charCast(nobj.floatValue());\n      else\n\treturn charCast(nobj.longValue());\n    }\n    return RT.charCast(obj);\n  }\n  public static long charLongCast(Object obj) {\n    return (long)charCast(obj);\n  }\n  public static long longCast(Object obj) {\n    if (obj instanceof Long)\n      return (long)obj;\n    if(obj instanceof Integer)\n      return (int)obj;\n    if (obj instanceof Boolean)\n      return ((Boolean)obj) ? 1 : 0;\n    else if (obj instanceof Double)\n      return longCast(((Double)obj).doubleValue());\n    else if (obj instanceof Float)\n      return longCast(((Float)obj).floatValue());\n    else if (obj instanceof Number)\n      return RT.longCast(obj);\n    else if (obj instanceof Character)\n      return (long)(Character)obj;\n    else\n      throw new RuntimeException(\"Object cannot be casted to long: \" + obj);\n  }\n  public static long longCast(long obj) {\n    return obj;\n  }\n  public static long longCast(char obj) {\n    return obj;\n  }\n  public static long longCast(double obj) {\n    if(!Double.isFinite(obj))\n      throw new RuntimeException(\"Non-finite double cannot be casted to long: \"\n\t\t\t\t + String.valueOf(obj));\n    return (long)obj;\n  }\n  public static long longCast(float obj) {\n    if(!Float.isFinite(obj))\n      throw new RuntimeException(\"Non-finite float cannot be casted to long: \"\n\t\t\t\t + String.valueOf(obj));\n    return (long)obj;\n  }\n  public static long longCast(boolean obj) {\n    return obj ? 1 : 0;\n  }\n  public static double doubleCast(Object obj) {\n    if (obj == null)\n      return Double.NaN;\n    if (obj instanceof Double)\n      return (Double)obj;\n    if (obj instanceof Long)\n      return (double)(Long)obj;\n    if (obj instanceof Boolean)\n      return ((Boolean)obj) ? 1.0 : 0.0;\n    return RT.doubleCast(obj);\n  }\n  public static double doubleCast(long obj) {\n    return (double)obj;\n  }\n  public static double doubleCast(double obj) {\n    return obj;\n  }\n  public static double doubleCast(float obj) {\n    return (double)obj;\n  }\n  public static double doubleCast(boolean obj) {\n    return obj ? 1.0 : 0.0;\n  }\n  public static float floatCast(float obj) { return obj; }\n  public static float floatCast(Object obj) {\n    return (obj instanceof Float) ? ((Float)obj).floatValue() : (float)doubleCast(obj);\n  }\n  public static int intCast(int obj) { return obj; }\n  public static int intCast(Object obj) {\n    return (obj instanceof Integer) ? ((Integer)obj).intValue() : (int)longCast(obj);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ChunkedList.java",
    "content": "package ham_fisted;\n\nimport static ham_fisted.IntegerOps.*;\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.NoSuchElementException;\nimport java.util.Collection;\nimport java.util.ListIterator;\nimport java.util.Objects;\n\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.ISeq;\nimport clojure.lang.IteratorSeq;\nimport clojure.lang.Util;\nimport clojure.lang.Murmur3;\nimport clojure.lang.Reduced;\n\n\npublic final class ChunkedList {\n  Object[][] data;\n  //Global capacity ignoring offset\n  int capacity;\n  //nElems for this sub-chunk - true nElems is nElems + offset\n  int nElems;\n\n  final IPersistentMap meta;\n\n  static final int numChunks(int capacity) {\n    return (capacity + 31)/32;\n  }\n\n  static final int lastChunkSize(int capacity) {\n    if (capacity == 0)\n      return 4;\n    final int leftover = capacity % 32;\n    if (leftover == 0)\n      return 32;\n    return Math.max(4, nextPow2(leftover));\n  }\n\n  public ChunkedList(int initSize) {\n    initSize = Math.max(initSize, 16);\n    final int nChunks = numChunks(initSize);\n    final int leftover = lastChunkSize(initSize);\n    data = new Object[nChunks][];\n    final int nnc = nChunks - 1;\n    for (int idx = 0; idx < nChunks; ++idx)\n      data[idx] = new Object[idx == nnc ? leftover : 32];\n\n    nElems = 0;\n    capacity = (32 * (nChunks-1)) + leftover;\n    meta = null;\n  }\n\n  public ChunkedList() {this(0);}\n\n  ChunkedList(Object[][] d, int c, int e, IPersistentMap m) {\n    data = d;\n    capacity = c;\n    nElems = e;\n    meta = m;\n  }\n\n  ChunkedList(ChunkedList other, boolean shallow) {\n    if (shallow) {\n      data = other.data;\n    } else {\n      final Object[][] odata = other.data;\n      final Object[][] mdata = odata.clone();\n      final int ne = mdata.length;\n      for (int idx = 0; idx < ne; ++idx)\n\tmdata[idx] = odata[idx].clone();\n      data = mdata;\n    }\n    capacity = other.capacity;\n    nElems = other.nElems;\n    meta = other.meta;\n  }\n\n  static ChunkedList create(boolean owning, IPersistentMap meta, Object... data) {\n    final int dlen = data.length;\n    if (owning && dlen <= 32) {\n      return new ChunkedList(new Object[][] { data }, dlen, dlen, null);\n    } else {\n      final int nElems = data.length;\n      final int nChunks = numChunks(nElems);\n      final Object[][] mdata = new Object[nChunks][];\n      int idx = 0;\n      while(idx < nElems) {\n\tfinal int clen = Math.min(32, nElems - idx);\n\tfinal Object[] chunk = new Object[clen];\n\tSystem.arraycopy(data, idx, chunk, 0, clen);\n\tmdata[idx/32] = chunk;\n\tidx += clen;\n      }\n      return new ChunkedList(mdata, nElems, nElems, meta);\n    }\n  }\n\n  ChunkedList clone(int startidx, int endidx, int extraAlloc, boolean deep) {\n    final int ne = endidx - startidx;\n    final int nne = ne + extraAlloc;\n    final boolean shallow = deep == false && ((startidx % 32) == 0);\n    final Object[][] mdata = data;\n    if(shallow) {\n      final Object[][] odata = Arrays.copyOfRange(mdata,\n\t\t\t\t\t\t  startidx/32,\n\t\t\t\t\t\t  (endidx + extraAlloc + 31)/32);\n      return new ChunkedList(odata, nne, nne, meta);\n    }\n    final int nChunks = numChunks(nne);\n    final int nnc = nChunks - 1;\n    final Object[][] retval = new Object[nChunks][];\n    final int sidx = startidx;\n    int dstCapacity = 0;\n    while(startidx < endidx) {\n      final int leftover = endidx - startidx;\n      final Object[] srcc = mdata[startidx/32];\n\n      final int eidx = startidx % 32;\n      final int deidx = (startidx - sidx) % 32;\n      final int dcidx = (startidx - sidx) / 32;\n      Object[] dstc = retval[dcidx];\n      if (dstc == null) {\n\tdstc = dcidx == nnc ? new Object[nne%32] : new Object[32];\n\tretval[dcidx] = dstc;\n\tdstCapacity += dstc.length;\n      }\n      final int copyLen = Math.min(leftover, Math.min(srcc.length - eidx,\n\t\t\t\t\t\t      dstc.length - deidx));\n      // System.out.println(\"srcc: \" + String.valueOf(srcc.length) + \" eidx: \" + String.valueOf(eidx) +\n      // \t\t\t \" dstc: \" + String.valueOf(dstc.length) + \" deidx: \" + String.valueOf(deidx) +\n      // \t\t\t \" copyLen: \" + String.valueOf(copyLen));\n      System.arraycopy(srcc, eidx, dstc, deidx, copyLen);\n      startidx += copyLen;\n    }\n    return new ChunkedList(retval, dstCapacity, nne, meta);\n  }\n\n  ChunkedList clone(int startidx, int endidx) { return clone(startidx, endidx, 0, true); }\n\n  void clear(int offset, int len) {\n    if (offset == 0 && len == nElems) {\n      final Object[][] mdata = data;\n      final int nChunks = data.length;\n      final int ne = nElems;\n      int idx = 0;\n      while(idx < ne) {\n\tfinal Object[] chunk = mdata[idx / 32];\n\tfinal int eidx = idx % 32;\n\tArrays.fill(chunk, eidx, chunk.length - eidx, null);\n\tidx += 32 - eidx;\n      }\n      nElems = 0;\n    } else {\n      shorten(offset, offset+len);\n    }\n  }\n\n  void clear() { clear(0, nElems); }\n\n  void enlarge(int cap) {\n    if (cap <= capacity) return;\n\n    final int nChunks = numChunks(cap);\n    final int nnc = nChunks -1;\n    final int leftover = lastChunkSize(cap);\n    // System.out.println(\"leftover: \" + String.valueOf(leftover) + \" Requested Capacity: \" +\n    // \t\t       String.valueOf(cap));\n    Object[][] mdata = data;\n    if (nChunks != mdata.length)\n      mdata = Arrays.copyOf(mdata, nChunks);\n\n    for(int idx = 0; idx < nChunks; ++idx) {\n      final Object[] existing = mdata[idx];\n      if (existing == null || existing.length != 32) {\n\tfinal int targetLen = idx == nnc ? leftover : 32;\n\tfinal int exLen = existing == null ? 0 : existing.length;\n\tif (exLen != targetLen) {\n\t  mdata[idx] = existing == null ? new Object[targetLen] : Arrays.copyOf(existing, targetLen);\n\t}\n      }\n    }\n    data = mdata;\n    capacity = (32 * (nChunks-1)) + leftover;\n  }\n\n  final Object setValueRV(int idx, Object obj) {\n    final Object[] ary = data[idx / 32];\n    final int eidx = idx % 32;\n    final Object rv = ary[eidx];\n    ary[eidx] = obj;\n    return rv;\n  }\n  final void setValue(int idx, Object obj) {\n    data[idx / 32][idx % 32] = obj;\n  }\n  final Object getValue(final int idx) {\n    return data[idx / 32][idx % 32];\n  }\n\n  public static final void sublistCheck(long sidx, long eidx, long nElems) {\n    if(sidx < 0 || sidx > nElems)\n      throw new IndexOutOfBoundsException(\"Start index out of range: start-index(\"\n\t\t\t\t\t  + String.valueOf(sidx) +\"), n-elems(\"\n\t\t\t\t\t  + String.valueOf(nElems) + \")\");\n    if(eidx < 0 || eidx > nElems)\n      throw new IndexOutOfBoundsException(\"End index out of range: end-index(\"\n\t\t\t\t\t  + String.valueOf(eidx) +\"), n-elems(\"\n\t\t\t\t\t  + String.valueOf(nElems) + \")\");\n    if(eidx < sidx)\n      throw new IndexOutOfBoundsException(\"End index underflow: end-index(\"\n\t\t\t\t\t  + String.valueOf(eidx) +\") < start-index(\"\n\t\t\t\t\t  + String.valueOf(sidx) + \")\");\n  }\n\n  public static final int indexCheck(int nElems, int idx) {\n    if (idx < 0 || idx >= nElems)\n      throw new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx) + \"out of range 0-\" + String.valueOf(nElems));\n    return idx;\n  }\n\n  public static final int indexCheck(int startidx, int nElems, int idx) {\n    return indexCheck(nElems,idx) + startidx;\n  }\n\n\n  public static final long indexCheck(long startidx, long nElems, long idx) {\n    if (idx < 0 || idx >= nElems)\n      throw new IndexOutOfBoundsException(\"Index \" + String.valueOf(idx) + \"out of range 0-\" + String.valueOf(nElems));\n    return idx + startidx;\n  }\n\n  static final int wrapIndexCheck(int startidx, int nElems, int idx) {\n    if (idx < 0)\n      idx = nElems + idx;\n    return indexCheck(startidx, nElems, idx);\n  }\n\n\n  static public final void checkIndexRange(int startidx, int nElems, int sidx, int eidx) {\n    final int rne = eidx - sidx;\n    if(rne == 0 )\n      return;\n    indexCheck(startidx, nElems, sidx);\n    if (rne < 0)\n      throw new RuntimeException(\"Range end: \" + String.valueOf(eidx)\n\t\t\t\t + \" is less than start: \" + String.valueOf(sidx));\n    if(eidx > nElems)\n      throw new RuntimeException(\"Range end point: \" + String.valueOf(eidx)\n\t\t\t\t + \" is past end of valid range: \" +\n\t\t\t\t String.valueOf(nElems));\n  }\n\n  static public final void checkIndexRange(long startidx, long nElems, long sidx, long eidx) {\n    final long rne = eidx - sidx;\n    if(rne == 0 )\n      return;\n    indexCheck(startidx, nElems, sidx);\n    if (rne < 0)\n      throw new RuntimeException(\"Range end: \" + String.valueOf(eidx)\n\t\t\t\t + \" is less than start: \" + String.valueOf(sidx));\n    if(eidx > nElems)\n      throw new RuntimeException(\"Range end polong: \" + String.valueOf(eidx)\n\t\t\t\t + \" is past end of valid range: \" +\n\t\t\t\t String.valueOf(nElems));\n  }\n\n  final boolean add(Object obj) {\n    final int ne = nElems;\n    final int cap = capacity;\n    // System.out.println(\"Capacity: \" + String.valueOf(cap) + \" ne: \" + String.valueOf(ne));\n    if (ne >= cap)\n      enlarge(cap+1);\n\n    data[nElems/32][nElems%32] = obj;\n    nElems = ne + 1;\n    return true;\n  }\n\n  final void widen(final int startidx, final int endidx) {\n    final int wne = endidx - startidx;\n    if (wne == 0) return;\n    final int ne = nElems;\n    final int cap = capacity;\n    enlarge(ne + wne);\n    int copyNe = ne - startidx;\n    final Object[][] mdata = data;\n    //Copy contiguous sections starting from the end so we\n    //do not overwrite elements we later need to move.\n    while(copyNe > 0) {\n      //Get the last valid index to move data into for start/end blocks\n      final int sidx = startidx + copyNe - 1;\n      final int eidx = endidx + copyNe - 1;\n      //Find chunks related to those indexes.\n      Object[] srcc = mdata[sidx / 32];\n      Object[] endc = mdata[eidx / 32];\n      //Find the relative end indexes in the blocks\n      final int srceidx = sidx % 32;\n      final int endeidx = eidx % 32;\n      final int copyLen = Math.min(copyNe, Math.min(srceidx+1, endeidx+1));\n      // System.out.println(\"Widen - srceidx: \" + String.valueOf(srceidx)\n      // \t\t\t + \" - endeidx: \" + String.valueOf(endeidx)\n      // \t\t\t + \" - copyNe: \" + String.valueOf(copyNe)\n      // \t\t\t + \" - copyLen: \" + String.valueOf(copyLen));\n      System.arraycopy(srcc, srceidx - copyLen + 1,\n\t\t       endc, endeidx - copyLen + 1,\n\t\t       copyLen);\n      copyNe -= copyLen;\n    }\n    nElems = ne + wne;\n  }\n\n  final void shorten(int startidx, int endidx) {\n    if(startidx == 0 && endidx == nElems) {\n      clear();\n      return;\n    }\n    final int ne = nElems;\n    final int wne = endidx - startidx;\n    int copyNe = ne - endidx;\n    final Object[][] mdata = data;\n    while(copyNe > 0) {\n      final Object[] startc = data[startidx/32];\n      final Object[] endc = data[endidx/32];\n      final int seidx = startidx % 32;\n      final int eeidx = endidx % 32;\n      int copyLen = Math.min(copyNe, Math.min(startc.length - seidx,\n\t\t\t\t\t      endc.length - eeidx));\n      // System.out.println(\"Shorten - startidx: \" + String.valueOf(startidx)\n      // \t\t\t + \" - endidx: \" + String.valueOf(endidx)\n      // \t\t\t + \" - copyNe: \" + String.valueOf(copyNe)\n      // \t\t\t + \" - copyLen: \" + String.valueOf(copyLen));\n      System.arraycopy(endc, eeidx, startc, seidx, copyLen);\n      copyNe -= copyLen;\n      startidx += copyLen;\n      endidx += copyLen;\n    }\n    //Zero out remaining blocks to ensure we don't hold onto any object references.\n    clear(startidx, wne);\n    nElems = ne - wne;\n  }\n\n  //Extremely inefficent operation.  Make another list and insert the list all at once.\n  final void add(Object obj, int idx) {\n    final int ne = nElems;\n\n    if (idx > ne)\n      throw new RuntimeException(\"Index out of range: \" + String.valueOf(idx) +\n\t\t\t\t \" > \" + String.valueOf(ne));\n    if (idx == ne) {\n      add(obj);\n      return;\n    }\n\n    widen(idx, idx+1);\n    setValue(idx,obj);\n  }\n\n  final ChunkedList conj(int startidx, int endidx, Object obj) {\n    ChunkedList retval = clone(startidx, endidx, 1, false);\n    final int nc = endidx - startidx;\n    final Object[][] mdata = retval.data;\n    final int cidx = nc/32;\n    Object[] chunk = mdata[cidx];\n    final int eidx = nc % 32;\n    if (chunk == null) {\n      chunk = new Object[1];\n    } else {\n      chunk = Arrays.copyOf(chunk, eidx+1);\n    }\n    mdata[cidx] = chunk;\n    chunk[eidx] = obj;\n    return retval;\n  }\n\n  final ChunkedList assoc(int startidx, int endidx, int idx, Object obj) {\n    final int nc = endidx - startidx;\n    if (idx == nc)\n      return conj(startidx, endidx, obj);\n    ChunkedList retval = clone(startidx, endidx, 0, false);\n    final int cidx = idx / 32;\n    final int eidx = idx % 32;\n    final Object[][] mdata = retval.data;\n    Object[] edata = mdata[cidx].clone();\n    edata[eidx] = obj;\n    mdata[cidx] = edata;\n    return retval;\n  }\n\n  final ChunkedList pop(int startidx, int endidx) {\n    ChunkedList retval = clone(startidx, endidx-1, 0, false);\n    final int nc = endidx - startidx;\n    final Object[][] rdata = retval.data;\n    final int cidx = nc/32;\n    if ( rdata.length > cidx ) {\n      final Object[] c = rdata[cidx];\n      final int eidx = nc % 32;\n      if (c.length > eidx) {\n\trdata[cidx] = Arrays.copyOf(c, eidx);\n      }\n    }\n    return retval;\n  }\n\n  final int size() { return nElems; }\n\n  final void fillRange(int startidx, int endidx, Object v) {\n    final Object[][] mdata = data;\n    for(; startidx < endidx; ++startidx)\n      mdata[startidx/32][startidx%32] = v;\n  }\n\n  final void fillRangeReduce(final int startidx, Object v) {\n    final Object[][] mdata = data;\n    Reductions.serialReduction(new Reductions.IndexedAccum(new IFnDef.OLOO() {\n\tpublic Object invokePrim(Object acc, long idx, Object v) {\n\t  final int ss = (int)idx+startidx;\n\t  ((Object[][])acc)[ss/32][ss%32] = v;\n\t  return acc;\n\t}\n      }), mdata, v);\n  }\n\n  final void addRange(int startidx, int endidx, Object v) {\n    widen(startidx, endidx);\n    final Object[][] mdata = data;\n    for(; startidx < endidx; ++startidx)\n      mdata[startidx/32][startidx%32] = v;\n  }\n\n  final Object[] fillArray(int startidx, int endidx, Object[] retval) {\n    final int finalCidx = endidx / 32;\n    final int finalEidx = endidx % 32;\n    int cidx = startidx / 32;\n    int eidx = startidx % 32;\n    final Object[][] mdata = data;\n    int dstOff = 0;\n    while(cidx <= finalCidx) {\n      final int copyLen = cidx == finalCidx ? finalEidx - eidx : 32 - eidx;\n      //In the case where the end idx falls exactly on a boundary we get a copyLen of 0 here.\n      if(copyLen > 0) {\n\tSystem.arraycopy(mdata[cidx], eidx, retval, dstOff, copyLen);\n\tdstOff += copyLen;\n      }\n      eidx = 0;\n      ++cidx;\n    }\n    return retval;\n  }\n\n  final Object[] fillArray(Object[] retval) {\n    return fillArray(0, nElems, retval);\n  }\n\n  final Object[] toArray(int startidx, int endidx) {\n    return fillArray(startidx, endidx, new Object[endidx - startidx]);\n  }\n\n  final Object[] toArray() {\n    return toArray(0, nElems);\n  }\n\n  static class CLIter implements Iterator {\n    final int finalCidx;\n    final int finalEidx;\n    final Object[][] data;\n    int cidx;\n    int eidx;\n    Object[] chunk;\n    public CLIter(int startidx, int endidx, Object[][] _data) {\n      finalCidx = endidx / 32;\n      finalEidx = endidx % 32;\n      cidx = startidx / 32;\n      eidx = (startidx % 32) - 1;\n      data = _data;\n      advance();\n    }\n    final void advance() {\n      ++eidx;\n      if (eidx == 32) {\n\t++cidx;\n\teidx = 0;\n\tchunk = null;\n      }\n    }\n    public final boolean hasNext() {\n      if(cidx < finalCidx)\n\treturn true;\n      return eidx < finalEidx;\n    }\n    public final Object next() {\n      if ( cidx >= finalCidx &&\n\t   eidx >= finalEidx )\n\tthrow new NoSuchElementException();\n      if (chunk == null)\n\tchunk = data[cidx];\n      final Object retval = chunk[eidx];\n      advance();\n      return retval;\n    }\n  }\n\n  public Iterator iterator(int startidx, int endidx) {\n    return new CLIter(startidx, endidx, data);\n  }\n\n  public Iterator iterator() {\n    return iterator(0, nElems);\n  }\n\n  static class RIterator implements Iterator {\n    final int startidx;\n    final Object[][] data;\n    int idx;\n    public RIterator( int sidx, int eidx, Object[][] d) {\n      startidx = sidx;\n      idx = eidx;\n      data = d;\n      advance();\n    }\n    void advance() {\n      --idx;\n    }\n    public final boolean hasNext() { return idx >= startidx; }\n    public final Object next() {\n      if (idx < startidx)\n\tthrow new NoSuchElementException();\n      final Object retval = data[idx/32][idx%32];\n      advance();\n      return retval;\n    }\n  }\n\n  public Iterator riterator(int startidx, int endidx) {\n    return new RIterator(startidx, endidx, data);\n  }\n\n  static class ListIter<E> implements ListIterator<E> {\n    final int startidx;\n    final int endidx;\n    final Object[][] data;\n    int idx;\n    int prevIdx;\n\n    ListIter(int sidx, int eidx, Object[][] d) {\n      startidx = sidx;\n      endidx = eidx;\n      data = d;\n      idx = sidx;\n      prevIdx = idx;\n    }\n    public void add(E obj) { throw new RuntimeException(\"Unimplemented.\"); }\n    public void remove() { throw new RuntimeException(\"Unimplemented.\"); }\n    public final boolean hasNext() { return idx < endidx; }\n    public final boolean hasPrevious() { return idx > startidx; }\n    @SuppressWarnings(\"unchecked\")\n    public final E next() {\n      if (idx == endidx)\n\tthrow new NoSuchElementException();\n      final Object retval = data[idx/32][idx%32];\n      prevIdx = idx;\n      ++idx;\n      return (E)retval;\n    }\n    public final int nextIndex() {\n      return idx - startidx;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public final E previous() {\n      --idx;\n      if (idx < startidx)\n\tthrow new NoSuchElementException();\n      prevIdx = idx;\n      return (E)data[idx/32][idx%32];\n    }\n    public final int previousIndex() {\n      return idx - startidx - 1;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public final void set(E v) {\n      data[prevIdx/32][prevIdx%32] = v;\n    }\n  }\n\n  <E> ListIterator<E> listIterator(int startidx, int endidx, E marker) {\n    return new ListIter<E>(startidx, endidx, data);\n  }\n\n  static class ChunkedListSection {\n    public final Object[][] data;\n    public final int startidx;\n    public final int endidx;\n    public int size() { return endidx - startidx; }\n    public ChunkedListSection(Object[][] cl, int sidx, int eidx) {\n      data = cl;\n      startidx = sidx;\n      endidx = eidx;\n    }\n  }\n\n\n  interface ChunkedListOwner {\n    ChunkedListSection getChunkedList();\n  }\n\n  Object reduce(final int startidx, final int endidx, final IFn f, final Object start) {\n    final Object[][] mdata = data;\n    Object ret = start;\n    int sidx = startidx;\n    while(sidx < endidx && !RT.isReduced(ret)) {\n      final Object[] cdata = mdata[sidx/32];\n      int cstart = sidx % 32;\n      final int clen = Math.min(endidx - sidx, 32 - cstart);\n      final int cstop = clen + cstart;\n      for(int idx = cstart; idx < cstop && !RT.isReduced(ret); ++idx)\n\tret = f.invoke(ret, cdata[idx]);\n      sidx += clen;\n    }\n    return Reductions.unreduce(ret);\n  }\n\n  Object reduce(final int startidx, final int endidx, IFn f) {\n    if(startidx == endidx)\n      return f.invoke();\n    return reduce(startidx+1, endidx, f, getValue(startidx));\n  }\n\n  Object kvreduce(int startidx, int endidx, IFn f, Object init) {\n    final Object[][] mdata = data;\n    for (int i=startidx; i<endidx && !RT.isReduced(init); i++) {\n      init = f.invoke(init, i - startidx, mdata[i/32][i%32]);\n    }\n    return init;\n  }\n\n  final ISeq seq(int startidx, int endidx) {\n    return IteratorSeq.create(iterator(startidx, endidx));\n  }\n\n  final ISeq rseq(int startidx, int endidx) {\n    return IteratorSeq.create(riterator(startidx, endidx));\n  }\n\n  final int hasheq(int startidx, int endidx) {\n    int hash = 1;\n    final int n = endidx - startidx;\n    final Object[][] mdata = data;\n    for( ; startidx < endidx; ++startidx) {\n      hash = 31 * hash + Util.hasheq(mdata[startidx/32][startidx%32]);\n    }\n    hash = Murmur3.mixCollHash(hash, n);\n    return hash;\n  }\n  final boolean equiv(int sidx, int eidx, Object o) {\n    if(o instanceof RandomAccess) {\n      List lo = (List)o;\n      final int osz = lo.size();\n      final int sz = eidx - sidx;\n      if(osz != sz)\n\treturn false;\n      final int ee = eidx;\n      int idx = 0;\n      final Object[][] d = data;\n      while(idx < sz) {\n\tfinal int midx = idx + sidx;\n\tfinal Object[] chunk = d[midx / 32];\n\tint cidx = midx % 32;\n\tfinal int chunkSize = Math.min(32 - cidx, sz - idx);\n\tfinal int endChunkIdx = idx + chunkSize;\n\tfor(; idx < endChunkIdx; ++idx, ++cidx) {\n\t  final Object vv = chunk[cidx];\n\t  if(CljHash.equiv(vv, lo.get(idx)) == false)\n\t    return false;\n\t}\n      }\n      return true;\n    } else if (o instanceof Iterable) {\n      final Object[][] d = data;\n      final int ss = sidx;\n      return (Boolean)Reductions.serialReduction(new Reductions.IndexedAccum(new IFnDef.OLOO() {\n\t  public Object invokePrim(Object acc, long idx, Object v) {\n\t    final int iidx = (int)idx + ss;\n\t    if(iidx >= eidx)\n\t      return new Reduced(false);\n\t    final Object vv = d[iidx/32][iidx%32];\n\t    if(CljHash.equiv(vv, v) == false)\n\t      return new Reduced(false);\n\t    return acc;\n\t  }\n\t}), true, o);\n    } else {\n      return false;\n    }\n  }\n  final IPersistentMap meta() { return meta; }\n  final ChunkedList withMeta(IPersistentMap m) {\n    return new ChunkedList(data, capacity, nElems, m);\n  }\n  final int indexOf(int startidx, int endidx, Object obj) {\n    final int ne = endidx - startidx;\n    final Object[][] mdata = data;\n    for(int idx = 0; idx < ne; ++idx)\n      if (Objects.equals(obj, mdata[idx/32][idx%32]))\n\treturn idx;\n    return -1;\n  }\n  final int lastIndexOf(int startidx, int endidx, Object obj) {\n    final int ne = endidx - startidx;\n    final int nne = ne - 1;\n    final Object[][] mdata = data;\n    for(int idx = 0; idx < ne; ++idx) {\n      final int ridx = nne - idx + startidx;\n      if (Objects.equals(obj, mdata[ridx/32][ridx%32]))\n\treturn ridx;\n    }\n    return -1;\n  }\n  final boolean contains(int startidx, int endidx, Object obj) {\n    return indexOf(startidx, endidx, obj) != -1;\n  }\n\n  final boolean containsAll(int startidx, int endidx, Collection<?> c) {\n    final int ne = endidx - startidx;\n    Iterator minC;\n    Iterator maxC;\n    if (ne < c.size()) {\n      minC = this.iterator(startidx, endidx);\n      maxC = c.iterator();\n    } else {\n      maxC = this.iterator(startidx, endidx);\n      minC = c.iterator();\n    }\n    //This set can contain null.\n    // HashSet<Object> hc = new HashSet<Object>();\n    // while(minC.hasNext()) hc.add(minC.next());\n    // while(maxC.hasNext()) {\n    //   if (!hc.contains(maxC.next()))\n    // \treturn false;\n    // }\n    // return true;\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/CljHash.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.List;\nimport java.util.Iterator;\nimport java.util.RandomAccess;\nimport java.util.Collection;\nimport clojure.lang.Murmur3;\nimport clojure.lang.APersistentMap;\nimport clojure.lang.Util;\nimport clojure.lang.RT;\nimport clojure.lang.Numbers;\nimport clojure.lang.IPersistentCollection;\nimport clojure.lang.Reduced;\n\n\npublic class CljHash {\n\n  public static int mapHashcode(Map data) {\n    return Murmur3.hashUnordered(data.entrySet());\n  }\n  public static int setHashcode(Set data) {\n    return Murmur3.hashUnordered(data);\n  }\n\n  public static boolean equiv(Object k1, Object k2) {\n    if(k1 == k2)\n      return true;\n    //Somewhat faster version of equiv *if* both are longs or both are doubles.\n    //which happens to be a very common case in Clojure.\n    return k1 != null ? nonNullEquiv(k1,k2) : false;\n  }\n\n  public static boolean nonNullEquiv(Object k1, Object k2) {\n    //Small carveout to accelerate long,long and double,double equivalence.\n    if( k1 instanceof Number) {\n      if( k1 instanceof Long && k2 instanceof Long)\n\treturn (long)k1 == (long)k2;\n\n      if ( k1 instanceof Double && k2 instanceof Double)\n\treturn (double)k1 == (double)k2;\n\n      if(k2 instanceof Number)\n\treturn Numbers.equal((Number)k1, (Number)k2);\n      return false;\n    }\n    if(k1 instanceof IPersistentCollection || k2 instanceof IPersistentCollection)\n      return Util.pcequiv(k1,k2);\n    return k1.equals(k2);\n  }\n\n  public static boolean mapEquiv(Map lhs, Object rhs) {\n    if(rhs instanceof Map) {\n      final Map rm = (Map)rhs;\n      if(lhs.size() == rm.size()) {\n\treturn (Boolean)Reductions.serialReduction(new IFnDef() {\n\t    public Object invoke(Object acc, Object v) {\n\t      Map.Entry me = (Map.Entry)v;\n\t      if(!equiv(lhs.get(me.getKey()), me.getValue()))\n\t\treturn new Reduced(false);\n\t      return acc;\n\t    }\n\t  }, true, rhs);\n      }\n    }\n    return false;\n  }\n\n\n  public static boolean setEquiv(Set data, Object rhs) {\n    if (rhs instanceof Set) {\n      Set rhsMap = (Set)rhs;\n      if (data.size() != rhsMap.size()) return false;\n\n      for(Object obj: rhsMap) {\n\tif (data.contains(obj) == false)\n\t  return false;\n      }\n      return true;\n    }\n    return false;\n  }\n\n  public static class ListHasheqConsumer implements java.util.function.Consumer {\n    public int hash;\n    public int n;\n    public ListHasheqConsumer() {\n      hash = 1;\n      n = 0;\n    }\n    public void accept(Object obj) {\n      hash = 31 * hash + Util.hasheq(obj);\n      ++n;\n    }\n    public int hash() {\n      return Murmur3.mixCollHash(hash, n);\n    }\n  }\n\n  public static int listHasheq(List l) {\n    ListHasheqConsumer c = new ListHasheqConsumer();\n    Reductions.serialReduction(c, l);\n    return c.hash();\n  }\n  \n  public static boolean listEquiv(List l, Object rhs) {\n    if (l == rhs) return true;\n    if (rhs == null) return false;\n    if (rhs instanceof RandomAccess) {\n      List r = (List)rhs;\n      final int sz = l.size();\n      if(sz != r.size()) return false;\n      for(int idx = 0; idx < sz; ++idx) {\n\tif(!equiv(l.get(idx), r.get(idx)))\n\t  return false;\n      }\n      return true;\n    } else if ( rhs instanceof Iterable) {\n      Collection r = rhs instanceof Collection ? (Collection)rhs : (Collection)RT.seq(rhs);\n      Iterator iter = r.iterator();\n      final int sz = l.size();\n      int idx;\n      for(idx = 0; idx < sz && iter.hasNext(); ++idx) {\n\tif(!equiv(l.get(idx), iter.next()))\n\t  return false;\n      }\n      return idx != sz || iter.hasNext() ? false : true;\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ConstList.java",
    "content": "package ham_fisted;\n\nimport java.util.Comparator;\nimport java.util.Random;\nimport java.util.List;\nimport java.util.Arrays;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.RT;\nimport clojure.lang.IFn;\nimport it.unimi.dsi.fastutil.ints.IntComparator;\n\n\npublic class ConstList implements IMutList<Object>, TypedList {\n  public final long nElems;\n  public final Object value;\n  public final IPersistentMap meta;\n  public ConstList(long _nElems, Object _v, IPersistentMap m) {\n    nElems = _nElems;\n    value = _v;\n    meta = m;\n  }\n  public IMutList cloneList() { return this; }\n  public Class containedType() { return value != null ? value.getClass() : Object.class; }\n  public static ConstList create(long nElems, Object value, IPersistentMap m) {\n    if (value instanceof Long || value instanceof Integer\n\t|| value instanceof Short || value instanceof Byte\n\t|| value instanceof Character)\n      return new LongConstList(nElems, Casts.longCast(value), m);\n    if (value instanceof Double || value instanceof Float)\n      return new DoubleConstList(nElems, Casts.doubleCast(value), m);\n    return new ConstList(nElems, value, m);\n  }\n  public int size() { return RT.intCast(nElems); }\n  public Object get(int idx) {\n    return value;\n  }\n  public ConstList subList(long sidx, long eidx) {\n    ChunkedList.sublistCheck(sidx, eidx, nElems);\n    return create(eidx-sidx, value, meta);\n  }\n  public ConstList subList(int sidx, int eidx) {\n    return subList((long)sidx, (long)eidx);\n  }\n  public void sort(Comparable c) { }\n  public ConstList immutSort(Comparable c) { return this; }\n  public ConstList ImmutSort() { return this; }\n  public ConstList reverse() { return this; }\n  public int[] sortIndirect() { return ArrayLists.iarange(0, size(), 1); }\n  public Object[] toArray() {\n    Object[] retval = new Object[size()];\n    Arrays.fill(retval, value);\n    return retval;\n  }\n  public int[] toIntArray() {\n    int v = RT.intCast(Casts.longCast(value));\n    int[] retval = new int[size()];\n    Arrays.fill(retval, v);\n    return retval;\n  }\n  public long[] toLongArray() {\n    long v = Casts.longCast(value);\n    long[] retval = new long[size()];\n    Arrays.fill(retval, v);\n    return retval;\n  }\n  public double[] toDoubleArray() {\n    double v = Casts.doubleCast(value);\n    double[] retval = new double[size()];\n    Arrays.fill(retval, v);\n    return retval;\n  }\n  public ConstList reindex(int[] indexes) {\n    return ConstList.create(indexes.length, value, meta);\n  }\n  public List immutShuffle(Random r) { return this; }\n  public IntComparator indexComparator(Comparator c) {\n    return new IntComparator() { public int compare(int l, int r) {return 0;}};\n  }\n  public IPersistentMap meta() { return meta; }\n  public ConstList withMeta(IPersistentMap m) {\n    return ConstList.create(nElems, value, m);\n  }\n  public static class LongConstList extends ConstList implements LongMutList {\n    public final long lval;\n    public LongConstList(long ne, long v, IPersistentMap m ) {\n      super(ne, v, m);\n      lval = v;\n    }\n    public Class containedType() { return Long.TYPE; }\n    public long getLong(int idx) { return lval; }\n    public Object reduce(IFn rfn, Object init) { return LongMutList.super.reduce(rfn, init); }\n  }\n  public static class DoubleConstList extends ConstList implements DoubleMutList {\n    public final double lval;\n    public DoubleConstList(long ne, double v, IPersistentMap m ) {\n      super(ne, v, m);\n      lval = v;\n    }\n    public Class containedType() { return Double.TYPE; }\n    public double getDouble(int idx) { return lval; }\n    public Object reduce(IFn rfn, Object init) { return DoubleMutList.super.reduce(rfn, init); }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ConsumerAccumulators.java",
    "content": "package ham_fisted;\n\n\npublic class ConsumerAccumulators {\n  public static class DoubleConsumerAccumulator implements IFnDef.ODO  {\n    public static final DoubleConsumerAccumulator INST = new DoubleConsumerAccumulator();\n    public DoubleConsumerAccumulator(){}\n    public Object invokePrim(Object acc, double val) {\n      ((java.util.function.DoubleConsumer)acc).accept(val);\n      return acc;\n    }\n  }\n  public static class LongConsumerAccumulator implements IFnDef.OLO  {\n    public static final LongConsumerAccumulator INST = new LongConsumerAccumulator();\n    public LongConsumerAccumulator(){}\n    public Object invokePrim(Object acc, long val) {\n      ((java.util.function.LongConsumer)acc).accept(val);\n      return acc;\n    }\n  }\n  public static class ConsumerAccumulator implements IFnDef.OOO  {\n    public static final ConsumerAccumulator INST = new ConsumerAccumulator();\n    public ConsumerAccumulator(){}\n    @SuppressWarnings(\"unchecked\")\n    public Object invoke(Object acc, Object val) {\n      ((java.util.function.Consumer)acc).accept(val);\n      return acc;\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/Consumers.java",
    "content": "package ham_fisted;\n\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.function.Function;\nimport java.util.function.DoubleUnaryOperator;\nimport java.util.function.LongUnaryOperator;\nimport java.util.function.Predicate;\nimport java.util.function.DoublePredicate;\nimport java.util.function.LongPredicate;\nimport clojure.lang.IDeref;\n\npublic class Consumers {\n  public interface IDerefDoubleConsumer extends IDeref, DoubleConsumer, Consumer\n  {\n    default void accept(Object v) { accept(Casts.doubleCast(v)); }\n    default void accept(double v) { acceptDouble(v); }\n    void acceptDouble(double v);\n  }\n  public interface IDerefLongConsumer extends IDeref, LongConsumer, Consumer\n  {\n    default void accept(Object v) { accept(Casts.longCast(v)); }\n    default void accept(long v) { acceptLong(v); }\n    void acceptLong(long v);\n  }\n  public interface IDerefConsumer extends IDeref, Consumer {}\n  public interface IDerefIndexedDoubleConsumer extends IDeref, IndexedDoubleConsumer {}\n  public interface IDerefIndexedLongConsumer extends IDeref, IndexedLongConsumer {}\n  public interface IDerefIndexedConsumer extends IDeref, IndexedConsumer {}\n  public static IndexedDoubleConsumer asIndexedDoubleConsumer(Object obj) {\n    if (obj instanceof IndexedDoubleConsumer)\n      return (IndexedDoubleConsumer)obj;\n    return null;\n  }\n  public static IndexedLongConsumer asIndexedLongConsumer(Object obj) {\n    if (obj instanceof IndexedLongConsumer)\n      return (IndexedLongConsumer)obj;\n    return null;\n  }\n  public static IndexedConsumer asIndexedConsumer(Object obj) {\n    if (obj instanceof IndexedConsumer)\n      return (IndexedConsumer)obj;\n    return null;\n  }\n  public static final class IndexedDoubleConsumerConverter implements IDerefDoubleConsumer {\n    long idx;\n    public final IndexedDoubleConsumer c;\n    public IndexedDoubleConsumerConverter(long initIdx, IndexedDoubleConsumer cc) {\n      idx = initIdx;\n      c = cc;\n    }\n    public void acceptDouble(double v) {\n      c.accept(idx, v);\n      ++idx;\n    }\n    public Object deref() { return ((IDeref)c).deref(); }\n  }\n  public static DoubleConsumer toDoubleConsumer(long initIdx, IndexedDoubleConsumer c) {\n    return new IndexedDoubleConsumerConverter(initIdx, c);\n  }\n  public static final class IndexedLongConsumerConverter implements IDerefLongConsumer {\n    long idx;\n    public final IndexedLongConsumer c;\n    public IndexedLongConsumerConverter(long initIdx, IndexedLongConsumer cc) {\n      idx = initIdx;\n      c = cc;\n    }\n    public void acceptLong(long v) {\n      c.accept(idx, v);\n      ++idx;\n    }\n    public Object deref() { return ((IDeref)c).deref(); }\n  }\n  public static LongConsumer toLongConsumer(long initIdx, IndexedLongConsumer c) {\n    return new IndexedLongConsumerConverter(initIdx, c);\n  }\n\n  public static final class IndexedConsumerConverter implements IDerefConsumer {\n    long idx;\n    public final IndexedConsumer c;\n    public IndexedConsumerConverter(long initIdx, IndexedConsumer cc) {\n      idx = initIdx;\n      c = cc;\n    }\n    public void accept(Object v) {\n      c.accept(idx, v);\n      ++idx;\n    }\n    public Object deref() { return ((IDeref)c).deref(); }\n  }\n  public static Consumer toConsumer(long initIdx, IndexedConsumer c) {\n    return new IndexedConsumerConverter(initIdx, c);\n  }\n\n  public static DoubleConsumer map(final DoubleUnaryOperator fn, final DoubleConsumer c) {\n    return new IDerefDoubleConsumer() {\n      public void acceptDouble(double v) {\n\tc.accept(fn.applyAsDouble(v));\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  public static LongConsumer map(final LongUnaryOperator fn, final LongConsumer c) {\n    return new IDerefLongConsumer() {\n      public void acceptLong(long v) {\n\tc.accept(fn.applyAsLong(v));\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  public static Consumer map(final Function fn, final Consumer c) {\n    return new IDerefConsumer() {\n      public void accept(Object v) {\n\tc.accept(fn.apply(v));\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n\n  public static IndexedDoubleConsumer map(final DoubleUnaryOperator fn, final IndexedDoubleConsumer c) {\n    return new IDerefIndexedDoubleConsumer() {\n      public void accept(long idx, double v) {\n\tc.accept(idx, fn.applyAsDouble(v));\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  public static IndexedLongConsumer map(final LongUnaryOperator fn, final IndexedLongConsumer c) {\n    return new IDerefIndexedLongConsumer() {\n      public void accept(long idx, long v) {\n\tc.accept(idx, fn.applyAsLong(v));\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  public static IndexedConsumer map(final Function fn, final IndexedConsumer c) {\n    return new IDerefIndexedConsumer() {\n      public void accept(long idx, Object v) {\n\tc.accept(idx, fn.apply(v));\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n\n  public static DoubleConsumer filter(final DoublePredicate pred, final DoubleConsumer c) {\n    return new IDerefDoubleConsumer() {\n      public void acceptDouble(double v) {\n\tif(pred.test(v))\n\t  c.accept(v);\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  public static LongConsumer filter(final LongPredicate pred, final LongConsumer c) {\n    return new IDerefLongConsumer() {\n      public void acceptLong(long v) {\n\tif(pred.test(v))\n\t  c.accept(v);\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  public static Consumer filter(final Predicate pred, final Consumer c) {\n    return new IDerefConsumer() {\n      public void accept(Object v) {\n\tif(pred.test(v))\n\t  c.accept(v);\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n\n  public static IndexedDoubleConsumer filter(final DoublePredicate pred, final IndexedDoubleConsumer c) {\n    return new IDerefIndexedDoubleConsumer() {\n      public void accept(long idx, double v) {\n\tif(pred.test(v))\n\t  c.accept(idx, v);\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  public static IndexedLongConsumer filter(final LongPredicate pred, final IndexedLongConsumer c) {\n    return new IDerefIndexedLongConsumer() {\n      public void accept(long idx, long v) {\n\tif(pred.test(v))\n\t  c.accept(idx, v);\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  public static IndexedConsumer filter(final Predicate pred, final IndexedConsumer c) {\n    return new IDerefIndexedConsumer() {\n      public void accept(long idx, Object v) {\n\tif(pred.test(v))\n\t  c.accept(idx, v);\n      }\n      public Object deref() {\n\treturn ((IDeref)c).deref();\n      }\n    };\n  }\n\n  public static class IncConsumer implements Consumer, Reducible, IDeref {\n    public static java.util.function.Function cfn = new java.util.function.Function() {\n\tpublic IncConsumer apply(Object obj) { return new IncConsumer(); }\n      };\n    long nElems;\n    public IncConsumer(long v) { nElems = v;}\n    public IncConsumer() { this(0); }\n    public void accept(Object o) { ++nElems; }\n    public void inc() { ++nElems; }\n    public void setValue(int v) { nElems = v;}\n    public IncConsumer reduce(Reducible o) {\n      nElems += ((IncConsumer)o).nElems;\n      return this;\n    }\n    public long value() { return nElems; }\n    public Object deref() { return nElems; }\n  }\n\n}\n"
  },
  {
    "path": "java/ham_fisted/CtxIter.java",
    "content": "package ham_fisted;\n\nimport java.util.Iterator;\nimport java.util.function.Supplier;\n\npublic class CtxIter implements Iterator {\n  public static interface Ctx {\n    public Ctx update();\n    public boolean valid();\n    public Object val();\n  }\n  public final Supplier<Ctx> init;\n  Ctx ctx;\n  public static final int stepInit = 0;\n  public static final int stepUpdate = 1;\n  public static final int stepVal = 2;\n  int step;\n  public CtxIter(Supplier<Ctx> init) {\n    this.init = init;\n    step = stepInit;\n    ctx = null;\n  }\n  void advance() {\n    if(step == stepInit) {\n      ctx = init.get();\n    } else if (step == stepUpdate) {\n      ctx = ctx.update();\n    }\n    step = stepVal;\n  }\n  public int step() { return step; }\n  public Ctx ctx() { return ctx; }\n  public boolean hasNext() {\n    advance();\n    return ctx.valid();\n  }\n  public Object next() {\n    advance();\n    step = stepUpdate;\n    return ctx.val();\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/DoubleMutList.java",
    "content": "package ham_fisted;\n\nimport java.util.Random;\nimport java.util.List;\nimport java.util.Comparator;\nimport java.util.Spliterator;\nimport it.unimi.dsi.fastutil.doubles.DoubleArrays;\nimport it.unimi.dsi.fastutil.doubles.DoubleComparator;\nimport it.unimi.dsi.fastutil.ints.IntComparator;\nimport java.util.function.DoubleConsumer;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\n\n@SuppressWarnings(\"unchecked\")\npublic interface DoubleMutList extends IMutList<Object> {\n  default boolean add(Object obj) { addDouble(Casts.doubleCast(obj)); return true; }\n  default void addLong(long obj) { addDouble(Casts.doubleCast(obj)); }\n  default void addDouble(double v) { throw new RuntimeException(\"Object \" + String.valueOf(getClass()) + \" failed to define addLong method\"); }\n  default void add(int idx, int count, Object v) {\n    double d = Casts.doubleCast(v);\n    int end = idx + count;\n    for(; idx < end; ++idx) addDouble( d );\n  }\n  @SuppressWarnings(\"unchecked\")\n  default Object set(int idx, Object obj) { double v = getDouble(idx); setDouble(idx, Casts.doubleCast(obj)); return v; }\n  default void setBoolean(int idx, boolean obj) { setDouble(idx, obj ? 1.0 : 0.0); }\n  default void setLong(int idx, long obj) { setDouble(idx, (double)obj); }\n  default Object get(int idx) { return getDouble(idx); }\n  default long getLong(int idx) { return (long)getDouble(idx); }\n  static class DoubleSubList extends IMutList.MutSubList<Object> implements DoubleMutList {\n    @SuppressWarnings(\"unchecked\")\n    public DoubleSubList(IMutList l, int ss, int ee) {\n      super(l, ss, ee);\n    }\n    public Object reduce(IFn rfn, Object init) { return DoubleMutList.super.reduce(rfn, init); }\n  }\n  default IMutList<Object> subList(int sidx, int eidx) {\n    ChunkedList.sublistCheck(sidx, eidx, size());\n    return new DoubleSubList(this, sidx, eidx);\n  }\n  default boolean addAllReducible(Object obj) {\n    final int sz = size();\n    Reductions.serialReduction(new IFnDef.ODO() {\n\tpublic Object invokePrim(Object lhs, double rhs) {\n\t  ((IMutList)lhs).addDouble(rhs);\n\t  return lhs;\n\t}\n      }, this, obj);\n    return sz != size();\n  }\n  default void fillRange(long startidx, final long endidx, Object v) {\n    ChunkedList.checkIndexRange(0, size(), startidx, endidx);\n    double l = Casts.doubleCast(v);\n    for(; startidx < endidx; ++startidx) {\n      setDouble((int)startidx, l);\n    }\n  }\n  default void fillRange(final long ss, List l) {\n    if (l.isEmpty())\n      return;\n    final int startidx = (int)ss;\n    final int sz = size();\n    final int endidx = startidx + l.size();\n    ArrayLists.checkIndexRange(size(), startidx, endidx);\n    Reductions.serialReduction(new Reductions.IndexedDoubleAccum(new IFnDef.OLDO() {\n\tpublic Object invokePrim(Object acc, long idx, double v) {\n\t  ((IMutList)acc).setDouble((int)idx+startidx, v);\n\t  return acc;\n\t}\n      }), this, l);\n  }\n  default void addRange(int startidx, int endidx, Object v) {\n    Double l = Double.valueOf(Casts.doubleCast(v));\n    for(; startidx < endidx; ++startidx) {\n      add(startidx, l);\n    }\n  }\n  default IntComparator indexComparator() {\n    return new IntComparator() {\n      public int compare(int lidx, int ridx) {\n\treturn Double.compare(getDouble(lidx), getDouble(ridx));\n      }\n    };\n  }\n  default void sort(Comparator<? super Object> c) {\n    DoubleComparator lc = ArrayLists.DoubleArraySubList.asDoubleComparator(c);\n    if (c == null || lc != null) {\n      final double[] data = toDoubleArray();\n      if(c == null)\n\tDoubleArrays.parallelQuickSort(data);\n      else\n\tDoubleArrays.parallelQuickSort(data, lc);\n      fillRange(0, ArrayLists.toList(data));\n    } else {\n      IMutList.super.sort(c);\n    }\n  }\n  default void shuffle(Random r) {\n    fillRange(0, immutShuffle(r));\n  }\n  default List immutShuffle(Random r) {\n    final double[] bdata = toDoubleArray();\n    DoubleArrays.shuffle(bdata, r);\n    return ArrayLists.toList(bdata);\n  }\n\n  default Object reduce(final IFn rfn, Object init) {\n    return doubleReduction(Transformables.toDoubleReductionFn(rfn), init);\n  }\n  default Object doubleReduction(IFn.ODO rfn, Object init) {\n    final int sz = size();\n    for (int idx = 0; idx < sz && !RT.isReduced(init); ++idx)\n      init = rfn.invokePrim(init, getDouble(idx));\n    return Reductions.unreduce(init);\n  }\n  @SuppressWarnings(\"unchecked\")\n  default Spliterator spliterator() {\n    return new RandomAccessSpliterator.DoubleSpliterator(this, 0, size());\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/FJTask.java",
    "content": "package ham_fisted;\n\nimport clojure.lang.IFn;\nimport clojure.lang.IDeref;\nimport clojure.lang.Delay;\nimport java.util.concurrent.RecursiveTask;\n\npublic class FJTask extends RecursiveTask {\n  public final IDeref c;\n  public FJTask(Object c) {\n    if(c instanceof IDeref) {\n      this.c = (IDeref)c;\n    } else {\n      this.c = new Delay( (IFn) c);\n    }\n  }\n  public Object compute() { return c.deref(); }\n}\n"
  },
  {
    "path": "java/ham_fisted/FMapEntry.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IMapEntry;\n\npublic class FMapEntry<K,V> implements IMutList, Map.Entry<K,V> {\n  public final K k;\n  public final V v;\n  int _hash;\n  IPersistentMap meta;\n  public FMapEntry(K _k, V _v) {\n    k = _k;\n    v = _v;\n    _hash = 0;\n    meta = null;\n  }\n  public FMapEntry(FMapEntry<K,V> e, IPersistentMap m) {\n    k = e.k;\n    v = e.v;\n    _hash = e._hash;\n    meta = m;\n  }\n  public static <K,V> FMapEntry<K,V> create(K k, V v) {\n    return new FMapEntry<K,V>(k,v);\n  }\n  public boolean equals(Object o) { return equiv(o); }\n  public int hashCode() { return hasheq(); }\n  public int hasheq() {\n    if (_hash == 0)\n      _hash = IMutList.super.hasheq();\n    return _hash;\n  }\n  public V setValue( Object v) { throw new RuntimeException(\"Cannot set value.\"); }\n  public K getKey() { return k; }\n  public Object key() { return k; }\n  public V getValue() { return v; }\n  public Object val() { return v; }\n  public int size() { return 2; }\n  public Object get(int idx) {\n    if(idx == 0) return k;\n    if(idx == 1) return v;\n    throw new RuntimeException(\"Index out of range: \" + String.valueOf(idx));\n  }\n  public FMapEntry<K,V> withMeta(IPersistentMap m) { return new FMapEntry<K,V>(this, m); }\n  public IPersistentMap meta() { return meta; }\n}\n"
  },
  {
    "path": "java/ham_fisted/ForkJoinPatterns.java",
    "content": "package ham_fisted;\n\nimport clojure.lang.IFn;\nimport clojure.lang.Delay;\nimport clojure.lang.IDeref;\nimport clojure.java.api.Clojure;\nimport java.util.Spliterator;\n\n\npublic class ForkJoinPatterns {\n  private ForkJoinPatterns(){}\n\n\n  static final Delay pgroupsPtr = new Delay(new IFnDef() {\n      public Object invoke() {\n\treturn ((IDeref)Clojure.var(\"ham-fisted.impl\", \"pgroups\")).deref();\n      }\n    });\n\n  public static Iterable parallelIndexGroups(long nElems, IFn bodyFn, ParallelOptions options) {\n    return (Iterable)((IFn)pgroupsPtr.deref()).invoke(nElems, bodyFn, options);\n  }\n\n  static final Delay pmapPtr = new Delay(new IFnDef() {\n      public Object invoke() {\n\treturn ((IDeref)Clojure.var(\"ham-fisted.impl\", \"pmap\")).deref();\n      }\n    });\n\n  public static Iterable pmap(ParallelOptions options, IFn bodyFn, Object sequences) {\n    return (Iterable)((IFn)pmapPtr.deref()).invoke(options, bodyFn, sequences);\n  }\n\n  static final Delay spliteratorPtr = new Delay(new IFnDef() {\n      public Object invoke() {\n\treturn ((IDeref)Clojure.var(\"ham-fisted.impl\", \"parallel-spliterator-reduce\")).deref();\n      }\n    });\n  public static Object parallelSpliteratorReduce(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t\t\t Spliterator s, ParallelOptions options) {\n    return ((IFn)spliteratorPtr.deref()).invoke(initValFn, rfn, mergeFn, s, options);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/HashBase.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util.function.Function;\nimport java.util.function.Consumer;\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IHashEq;\nimport clojure.lang.IMeta;\nimport clojure.lang.IFn;\nimport clojure.lang.IDeref;\nimport clojure.lang.RT;\n\n\npublic class HashBase implements IMeta {\n  int capacity;\n  int mask;\n  int length;\n  int threshold;\n  float loadFactor;\n  HashNode[] data;\n  IPersistentMap meta;\n  public HashBase(float loadFactor, int initialCapacity,\n\t\t  int length, HashNode[] data,\n\t\t  IPersistentMap meta) {\n    this.loadFactor = loadFactor;\n    this.capacity = IntegerOps.nextPow2(Math.max(4, initialCapacity));\n    this.mask = this.capacity - 1;\n    this.length = length;\n    this.data = data == null ? new HashNode[this.capacity] : data;\n    this.threshold = (int)(capacity * loadFactor);\n    this.meta = meta;\n  }\n  \n  public HashBase(HashBase other, IPersistentMap m) {\n    this.loadFactor = other.loadFactor;\n    this.capacity = other.capacity;\n    this.mask = other.mask;\n    this.length = other.length;\n    this.data = other.data;\n    this.threshold = other.threshold;\n    this.meta = m;\n  }\n  public int capacity() { return capacity; }\n  public int size() { return length; }\n  public int count() { return length; }\n  //protected so clients can override as desired.\n  protected int hash(Object k) {\n    return\n      k == null ? 0 :\n      k instanceof IHashEq ? ((IHashEq)k).hasheq() :\n      IntegerOps.mixhash(k.hashCode());\n  }\n  protected boolean equals(Object lhs, Object rhs) {\n    return\n      lhs == rhs ? true :\n      lhs == null || rhs == null ? false :\n      CljHash.nonNullEquiv(lhs,rhs);\n  }\n  protected void inc(HashNode lf) { ++this.length; }\n  protected void dec(HashNode lf) { --this.length; }\n  protected void modify(HashNode lf) {}\n  protected HashNode newNode(Object key, int hc, Object val) {\n    return new HashNode(this,key,hc,val,null);\n  }\n  \n  Object checkResize(Object rv) {\n    if(this.length >= this.threshold) {\n      final int newCap = this.capacity * 2;\n      final HashNode[] newD = new HashNode[newCap];\n      final HashNode[] oldD = this.data;\n      final int oldCap = oldD.length;\n      final int mask = newCap - 1;\n      for(int idx = 0; idx < oldCap; ++idx) {\n\tHashNode lf;\n\tif((lf = oldD[idx]) != null) {\n\t  oldD[idx] = null;\n\t  if(lf.nextNode == null) {\n\t    newD[lf.hashcode & mask] = lf;\n\t  } else {\n\t    //https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/HashMap.java#L722\n\t    //Because we only allow capacities that are powers of two, we have\n\t    //exactly 2 locations in the new data array where these can go.  We want\n\t    //to avoid writing to any locations more than once and instead make the\n\t    //at most two new linked lists, one for the new high position and one\n\t    //for the new low position.\n\t    HashNode loHead = null, loTail = null, hiHead = null, hiTail = null;\n\t    while(lf != null) {\n\t      HashNode e = lf.setOwner(this);\n\t      lf = lf.nextNode;\n\t      //Check high bit\n\t      if((e.hashcode & oldCap) == 0) {\n\t\tif(loTail == null) loHead = e;\n\t\telse loTail.nextNode = e;\n\t\tloTail = e;\n\t      } else {\n\t\tif(hiTail == null) hiHead = e;\n\t\telse hiTail.nextNode = e;\n\t\thiTail = e;\n\t      }\n\t    }\n\t    if(loHead != null) {\n\t      loTail.nextNode = null;\n\t      newD[idx] = loHead;\n\t    }\n\t    if(hiHead != null) {\n\t      hiTail.nextNode = null;\n\t      newD[idx+oldCap] = hiHead;\n\t    }\n\t  }\n\t}\n      }\n      this.capacity = newCap;\n      this.threshold = (int)(newCap * this.loadFactor);\n      this.mask = mask;\n      this.data = newD;\n    }\n    return rv;\n  }\n  public void clear() {\n    for(int idx = 0; idx < data.length; ++idx) {\n      for(HashNode lf = data[idx]; lf != null; lf = lf.nextNode) {\n\tdec(lf);\n      }\n    }\n    length = 0;\n    Arrays.fill(data, null);\n  }\n  public IPersistentMap meta() { return meta; }\n  static class HTIter implements Iterator {\n    final HashNode[] d;\n    final Function<Map.Entry,Object> fn;\n    HashNode l;\n    int idx;\n    final int dlen;\n    HTIter(HashNode[] data, Function<Map.Entry,Object> fn) {\n      this.d = data;\n      this.fn = fn;\n      this.l = null;\n      this.idx = 0;\n      this.dlen = d.length;\n      advance();\n    }\n    void advance() {\n      if(l != null)\n\tl = l.nextNode;\n      if(l == null) {\n\tfor(; idx < this.dlen && l == null; ++idx)\n\t  l = this.d[idx];\n      }\n    }\n    public boolean hasNext() { return l != null; }\n    public Object next() {\n      HashNode rv = l;\n      advance();\n      return fn.apply(rv);\n    }\n  }\n  static class HTSpliterator implements Spliterator, ITypedReduce {\n    final HashNode[] d;\n    final Function<Map.Entry,Object> fn;\n    int sidx;\n    int eidx;\n    int estimateSize;\n    HashNode l;\n    public HTSpliterator(HashNode[] d, int len, Function<Map.Entry,Object> fn) {\n      this.d = d;\n      this.fn = fn;\n      this.sidx = 0;\n      this.eidx = d.length;\n      this.estimateSize = len;\n      this.l = null;\n    }\n    public HTSpliterator(HashNode[] d, int sidx, int eidx, int es, Function<Map.Entry,Object> fn) {\n      this.d = d;\n      this.fn = fn;\n      this.sidx = sidx;\n      this.eidx = eidx;\n      this.estimateSize = es;\n      this.l = null;\n    }\n    public HTSpliterator trySplit() {\n      final int nIdxs = this.eidx - this.sidx;\n      if(nIdxs > 4) {\n\tfinal int idxLen = nIdxs/2;\n\tfinal int oldIdx = this.eidx;\n\tthis.eidx = this.sidx + idxLen;\n\tthis.estimateSize = this.estimateSize / 2;\n\treturn new HTSpliterator(d, this.eidx, oldIdx, this.estimateSize, this.fn);\n      }\n      return null;\n    }\n    public int characteristics() { return Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.SIZED; }\n    public long estimateSize() { return estimateSize; }\n    public long getExactSizeIfKnown() { return estimateSize(); }\n    @SuppressWarnings(\"unchecked\")\n    public boolean tryAdvance(Consumer c) {\n      if(this.l != null) {\n\tc.accept(this.fn.apply(this.l));\n\tthis.l = this.l.nextNode;\n\treturn true;\n      }\n      for(; sidx < eidx; ++sidx) {\n\tfinal HashNode ll = this.d[sidx];\n\tif(ll != null) {\n\t  c.accept(this.fn.apply(ll));\n\t  this.l = ll.nextNode;\n\t  return true;\n\t}\n      }\n      return false;\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      final HashNode[] dd = this.d;\n      final int ee = this.eidx;\n      final Function<Map.Entry,Object> ffn = this.fn;\n      for(int idx = sidx; idx < ee; ++idx) {\n\tfor(HashNode e = dd[idx]; e != null; e = e.nextNode) {\n\t  acc = rfn.invoke(acc, ffn.apply(e));\n\t  if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t}\n      }\n      return acc;\n    }\n  }\n\n  final boolean containsNodeKey(Object key) {\n    for(HashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n      Object k;\n      if((k = e.k) == key || equals(k, key))\n\treturn true;\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/HashMap.java",
    "content": "package ham_fisted;\n\n\n\nimport java.util.Map;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport java.util.function.Consumer;\nimport java.util.function.BiConsumer;\nimport java.util.Spliterator;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.AbstractSet;\nimport java.util.AbstractCollection;\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IHashEq;\nimport clojure.lang.IDeref;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.IMeta;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.MapEntry;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.IKVReduce;\n\n\npublic class HashMap extends HashBase implements IMap, MapSetOps, UpdateValues {\n  Set keySet;\n  public HashMap(float loadFactor, int initialCapacity,\n\t\t  int length, HashNode[] data,\n\t\t  IPersistentMap meta) {\n    super(loadFactor, initialCapacity, length, data, meta);\n  }\n  public HashMap() {\n    this(0.75f, 0, 0, null, null);\n  }\n  public HashMap(IPersistentMap m) {\n    this(0.75f, 0, 0, null, m);\n  }\n  public HashMap(HashMap other, IPersistentMap m) {\n    super(other, m);\n  }\n\n  public HashMap shallowClone() {\n    return new HashMap(loadFactor, capacity, length, data.clone(), meta);\n  }\n  public HashMap clone() {\n    final int l = data.length;\n    HashNode[] newData = new HashNode[l];\n    HashMap retval = new HashMap(loadFactor, capacity, length, newData, meta);\n    for(int idx = 0; idx < l; ++idx) {\n      HashNode orig = data[idx];\n      if(orig != null)\n\tnewData[idx] = orig.clone(retval);\n    }\n    return retval;\n  }\n  public int hashCode() {\n    return hasheq();\n  }\n  public int hasheq() {\n    return CljHash.mapHashcode(this);\n  }\n  public  boolean equals(Object o) {\n    return equiv(o);\n  }\n  public boolean equiv(Object o) {\n    return CljHash.mapEquiv(this, o);\n  }\n  public int size() { return this.length; }\n  public boolean isEmpty() { return this.length == 0; }\n  public String toString() {\n    final StringBuilder b =\n      (StringBuilder) reduce(new IFnDef() {\n\t  public Object invoke(Object acc, Object v) {\n\t    final StringBuilder b = (StringBuilder)acc;\n\t    final Map.Entry lf = (Map.Entry)v;\n\t    if(b.length() > 2)\n\t      b.append(\",\");\n\t    return b.append(lf.getKey())\n\t      .append(\" \")\n\t      .append(lf.getValue());\n\t  }\n\t}, new StringBuilder().append(\"{\"));\n    return b.append(\"}\").toString();\n  }\n  public Object put(Object key, Object val) {\n    final int hc = hash(key);\n    final int idx = hc & mask;\n    final HashNode init = data[idx];\n    if(init != null) {\n      HashNode e = init;\n      do {\n\tif(e.k == key || equals(e.k, key)) {\n\t  Object rv = e.v;\n\t  e.v = val;\n\t  modify(e);\n\t  return rv;\n\t}\n\te = e.nextNode;\n      } while(e != null);\n    }\n    HashNode lf = newNode(key,hc,val);\n    lf.nextNode = init;\n    data[idx] = lf;\n    return checkResize(null);\n  }\n  public void putAll(Map other) {\n    HashNode[] d = data;\n    int mask = this.mask;\n    for(Object o: other.entrySet()) {\n      Map.Entry ee = (Map.Entry)o;\n      Object k = ee.getKey();\n      int hashcode = hash(k);\n      int idx = hashcode & mask;\n      HashNode e;\n      for(e = d[idx]; e != null && !(k == e.k || equals(k,e.k)); e = e.nextNode);\n      if(e != null) {\n\te.v = ee.getValue();\n      }\n      else {\n\tHashNode n = newNode(k, hashcode, ee.getValue());\n\tn.nextNode = d[idx];\n\td[idx] = n;\n\tcheckResize(null);\n\td = data;\n\tmask = this.mask;\n      }\n    }\n  }\n  public Object getOrDefault(Object key, Object dv) {\n    for(HashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n      Object k;\n      if((k = e.k) == key || equals(k, key))\n\treturn e.v;\n    }\n    return dv;\n  }\n  public Object get(Object key) {\n    for(HashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n      Object k;\n      if((k = e.k) == key || equals(k, key))\n\treturn e.v;\n    }\n    return null;\n  }\n  public IMapEntry entryAt(Object key) {\n    for(HashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n      Object k;\n      if((k = e.k) == key || equals(k, key))\n\treturn MapEntry.create(e.k, e.v);\n    }\n    return null;\n  }\n  public boolean containsKey(Object key) {\n    return containsNodeKey(key);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object compute(Object k, BiFunction bfn) {\n    final int hash = hash(k);\n    final HashNode[] d = this.data;\n    final int idx = hash & this.mask;\n    HashNode e = d[idx], ee = null;\n    for(; e != null && !(e.k == k || equals(e.k, k)); e = e.nextNode) {\n      ee = e;\n    }\n    Object newV = bfn.apply(k, e == null ? null : e.v);\n    if(e != null) {\n      if(newV != null) {\n\te.v = newV;\n\tmodify(e);\n      }\n      else\n\tremoveHashNode(e, ee, idx);\n    } else if(newV != null) {\n      HashNode nn = newNode(k, hash, newV);\n      if(ee != null)\n\tee.nextNode = nn;\n      else\n\td[idx] = nn;\n      checkResize(null);\n    }\n    return newV;\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object computeIfAbsent(Object k, Function afn) {\n    final int hash = hash(k);\n    final HashNode[] d = this.data;\n    final int idx = hash & this.mask;\n    HashNode e = d[idx], ee = null;\n    for(; e != null && !(e.k == k || equals(e.k, k)); e = e.nextNode) {\n      ee = e;\n    }\n    if(e != null) {\n      return e.v;\n    } else {\n      final Object newv = afn.apply(k);\n      if(newv != null) {\n\tHashNode nn = newNode(k, hash, newv);\n\tif(ee != null)\n\t  ee.nextNode = nn;\n\telse\n\t  d[idx] = nn;\n\tcheckResize(null);\n      }\n      return newv;\n    }\n  }\n  Object removeHashNode (HashNode e, HashNode lastNode, int loc) {\n    dec(e);\n    if(lastNode != null)\n      lastNode.nextNode = e.nextNode;\n    else\n      this.data[loc] = e.nextNode;\n    return e.getValue();\n  }\n  \n  public Object remove(Object key) {\n    HashNode lastNode = null;\n    int loc = hash(key) & this.mask;\n    for(HashNode e = this.data[loc]; e != null; e = e.nextNode) {\n      Object k;\n      if((k = e.k) == key || equals(k, key)) {\n\treturn removeHashNode(e, lastNode, loc);\n      }\n      lastNode = e;\n    }\n    return null;\n  }\n  public Object reduce(IFn rfn, Object acc) {\n    final int l = data.length;\n    final HashNode[] d = data;\n    for(int idx = 0; idx < l; ++idx) {\n      for(HashNode e = d[idx]; e != null; e = e.nextNode) {\n\tacc = rfn.invoke(acc, e);\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n    }\n    return acc;\n  }\n  public Object kvreduce(IFn rfn, Object acc) {\n    final int l = data.length;\n    final HashNode[] d = data;\n    for(int idx = 0; idx < l; ++idx) {\n      for(HashNode e = d[idx]; e != null; e = e.nextNode) {\n\tacc = rfn.invoke(acc, e.k, e.v);\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n    }\n    return acc;\n  }\n  public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t  ParallelOptions options ) {\n    return Reductions.parallelCollectionReduction(initValFn, rfn, mergeFn, this.entrySet(), options);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public void replaceAll(BiFunction bfn) {\n    final int l = data.length;\n    for(int idx = 0; idx < l; ++idx) {\n      HashNode lastNode = null;\n      for(HashNode e = this.data[idx]; e != null; e = e.nextNode) {\n\tObject newv = bfn.apply(e.k, e.v);\n\tif(newv != null) {\n\t  e.v = newv;\n\t  lastNode = e;\n\t}\n\telse {\n\t  dec(e);\n\t  if(lastNode != null) {\n\t    lastNode.nextNode = e.nextNode;\n\t  } else {\n\t    data[idx] = e.nextNode;\n\t  }\n\t}\n      }\n    }\n  }\n  public static class HashSetKeySet extends MapKeySet implements SetOps {\n    public HashSetKeySet(HashMap hm) { super(hm); }\n    public PersistentHashSet union(Collection c) {\n      return new PersistentHashSet( new HashSet(((HashMap)data).shallowClone()).union(c) );\n    }\n    public PersistentHashSet intersection(Set c) {\n      return new PersistentHashSet( new HashSet(((HashMap)data).shallowClone()).intersection(c) );\n    }\n    public PersistentHashSet difference(Set c) {\n      return new PersistentHashSet( new HashSet(((HashMap)data).shallowClone()).difference(c) );\n    }\n  }\n\n  public Set keySet() {\n    if(this.keySet  == null )\n      this.keySet = new HashSetKeySet(this);\n    return this.keySet;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static HashMap hashMapUnion(HashMap rv, HashMap om, BiFunction bfn) {\n    final HashNode[] od = om.data;\n    final int l = od.length;\n    HashNode[] rvd = rv.data;\n    int mask = rv.mask;\n    for(int idx = 0; idx < l; ++idx) {\n      for(HashNode lf = od[idx]; lf != null; lf = lf.nextNode) {\n\tfinal Object k = lf.k;\n\tfinal int hashcode = lf.hashcode;\n\tfinal int rvidx = hashcode & mask;\n\tHashNode init = rvd[rvidx], e = init;\n\tfinal Object v = lf.v;\n\tfor(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\tif(e != null) {\n\t  rvd[rvidx] = init.assoc(rv, e.k, hashcode, bfn.apply(e.v, v));\n\t}\n\telse {\n\t  if(init != null)\n\t    rvd[rvidx] = init.assoc(rv, k, hashcode, v);\n\t  else\n\t    rvd[rvidx] = rv.newNode(k, hashcode, v);\n\t  rv.checkResize(null);\n\t  mask = rv.mask;\n\t  rvd = rv.data;\n\t}\n      }\n    }\n    return rv;\n  }\n  @SuppressWarnings(\"unchecked\")\n  public static HashMap reduceUnion(HashMap rv, IReduceInit o, BiFunction bfn) {\n    return (HashMap)o.reduce(new IFnDef() {\n\tpublic Object invoke(Object acc, Object v) {\n\t  Map.Entry lf = (Map.Entry)v;\n\t  final Object k = lf.getKey();\n\t  final int hashcode = rv.hash(k);\n\t  final int rvidx = hashcode & rv.mask;\n\t  final HashNode[] rvd = rv.data;\n\t  HashNode init = rvd[rvidx], e = init;\n\t  for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\t  if(e != null) {\n\t    rvd[rvidx] = init.assoc(rv, e.k, hashcode, bfn.apply(e.v, lf.getValue()));\n\t  }\n\t  else {\n\t    if(init != null)\n\t      rvd[rvidx] = init.assoc(rv, k, hashcode, lf.getValue());\n\t    else\n\t      rvd[rvidx] = rv.newNode(k, hashcode, lf.getValue());\n\t    rv.checkResize(null);\n\t  }\n\t  return rv;\n\t}\n      }, rv);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static HashMap kvReduceUnion(HashMap rv, IKVReduce o, BiFunction bfn) {\n    return (HashMap)o.kvreduce(new IFnDef() {\n\tpublic Object invoke(Object acc, Object k, Object v) {\n\t  final int hashcode = rv.hash(k);\n\t  final int rvidx = hashcode & rv.mask;\n\t  final HashNode[] rvd = rv.data;\n\t  HashNode init = rvd[rvidx], e = init;\n\t  for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\t  if(e != null) {\n\t    rvd[rvidx] = init.assoc(rv, e.k, hashcode, bfn.apply(e.v, v));\n\t  }\n\t  else {\n\t    if(init != null)\n\t      rvd[rvidx] = init.assoc(rv, k, hashcode, v);\n\t    else\n\t      rvd[rvidx] = rv.newNode(k, hashcode, v);\n\t    rv.checkResize(null);\n\t  }\n\t  return rv;\n\t}\n      }, rv);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public static HashMap entrySetUnion(HashMap rv, Map o, BiFunction bfn) {\n    int mask = rv.mask;\n    HashNode[] rvd = rv.data;\n    for(Object ee : o.entrySet()) {\n      Map.Entry lf = (Map.Entry)ee;\n      final Object k = lf.getKey();\n      final int hashcode = rv.hash(k);\n      final int rvidx = hashcode & mask;\n      HashNode init = rvd[rvidx], e = init;\n      for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n      if(e != null) {\n\trvd[rvidx] = init.assoc(rv, e.k, hashcode, bfn.apply(e.v, lf.getValue()));\n      }\n      else {\n\tif(init != null)\n\t  rvd[rvidx] = init.assoc(rv, k, hashcode, lf.getValue());\n\telse\n\t  rvd[rvidx] = rv.newNode(k, hashcode, lf.getValue());\n\trv.checkResize(null);\n\tmask = rv.mask;\n\trvd = rv.data;\n      }\n    }\n    return rv;\n  }\n\n\n\n  public static HashMap union(HashMap rv, Map o, BiFunction bfn) {\n    if(o instanceof HashMap) {\n      return hashMapUnion(rv, (HashMap)o, bfn);\n    } else if (o instanceof IReduceInit) {\n      return reduceUnion(rv, (IReduceInit)o, bfn);\n    } else if (o instanceof IKVReduce) {\n      return kvReduceUnion(rv, (IKVReduce)o, bfn);\n    }\n    else {\n      return entrySetUnion(rv, o, bfn);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public HashMap union(Map o, BiFunction bfn) {\n    return union(this, o, bfn);\n  }\n  @SuppressWarnings(\"unchecked\")\n  static HashMap intersection(HashMap rv, Map o, BiFunction bfn) {\n    final HashNode[] rvd = rv.data;\n    final int ne = rvd.length;\n    for (int idx = 0; idx < ne; ++idx) {\n      HashNode lf = rvd[idx];\n      while(lf != null) {\n\tfinal HashNode curlf = lf;\n\tlf = lf.nextNode;\n\tfinal Object v = o.get(curlf.k);\n\trvd[idx] = (v != null)\n\t  ? rvd[idx].assoc(rv, curlf.k, curlf.hashcode, bfn.apply(curlf.v, v))\n\t  : rvd[idx].dissoc(rv, curlf.k);\n      }\n    }\n    return rv;\n  }\n\n\n  public HashMap intersection(Map o, BiFunction bfn) {\n    return intersection(this, o, bfn);\n  }\n\n  public static HashMap intersection(HashMap rv, Set o) {\n    final HashNode[] rvd = rv.data;\n    final int ne = rvd.length;\n    for (int idx = 0; idx < ne; ++idx) {\n      HashNode lf = rvd[idx];\n      while(lf != null) {\n\tfinal HashNode curlf = lf;\n\tfinal Object k = curlf.k;\n\tlf = lf.nextNode;\n\tif(!o.contains(k))\n\t  rvd[idx] = rvd[idx].dissoc(rv,k);\n      }\n    }\n    return rv;\n  }\n  public HashMap intersection(Set o) {\n    return intersection(this, o);\n  }\n\n\n  @SuppressWarnings(\"unchecked\")\n  static HashMap difference(HashMap rv, Collection o) {\n    final HashNode[] rvd = rv.data;\n    final int mask = rv.mask;\n    for (Object k : o) {\n      final int hashcode = rv.hash(k);\n      final int rvidx = hashcode & mask;\n      HashNode e = rvd[rvidx];\n      for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n      if(e != null) {\n\trvd[rvidx] = rvd[rvidx].dissoc(rv,e.k);\n      }\n    }\n    return rv;\n  }\n\n  public HashMap difference(Collection o) {\n    return difference(this, o);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  static HashMap updateValues(HashMap rv, BiFunction valueMap) {\n    final HashNode[] d = rv.data;\n    final int nl = d.length;\n    for(int idx = 0; idx < nl; ++idx) {\n      HashNode lf = d[idx];\n      while(lf != null) {\n\tHashNode cur = lf;\n\tlf = lf.nextNode;\n\tObject newv = valueMap.apply(cur.k, cur.v);\n\td[idx] = newv == null ? d[idx].dissoc(rv, cur.k) :\n\t  d[idx].assoc(rv, cur.k, cur.hashcode, newv);\n      }\n    }\n    return rv;\n  }\n  public HashMap updateValues(BiFunction valueMap) {\n    return updateValues(this, valueMap);\n  }\n  @SuppressWarnings(\"unchecked\")\n  static HashMap updateValue(HashMap rv, Object k, Function fn) {\n    final int hc = rv.hash(k);\n    final int idx = hc & rv.mask;\n    final HashNode[] data = rv.data;\n    HashNode e = data[idx];\n    for(; e != null && !((e.k == k) || rv.equals(e.k, k)); e = e.nextNode);\n    final Object newv = e != null ? fn.apply(e.v) : fn.apply(null);\n    data[idx] = newv == null ? data[idx].dissoc(rv, k) : data[idx].assoc(rv, k, hc, newv);\n    if(newv != null && e == null) rv.checkResize(null);\n    return rv;\n  }\n\n  public HashMap updateValue(Object k, Function fn) {\n    return updateValue(this, fn);\n  }\n\n  public Iterator iterator(Function<Map.Entry,Object> leafFn) {\n    return new HTIter(this.data, leafFn);\n  }\n  public Spliterator spliterator(Function<Map.Entry,Object> leafFn) { return new HTSpliterator(this.data, this.length, leafFn); }\n}\n"
  },
  {
    "path": "java/ham_fisted/HashNode.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Iterator;\nimport clojure.lang.IMapEntry;\nimport ham_fisted.IMutList;\n\npublic class HashNode implements Map.Entry, IMutList, IMapEntry {\n  public final HashBase owner;\n  public final int hashcode;\n  public final Object k;\n  //compute-at support means we can modify v.\n  Object v;\n  HashNode nextNode;\n\n  public HashNode(HashBase _owner, Object _k, int hc, Object _v, HashNode nn) {\n    owner = _owner;\n    hashcode = hc;\n    k = _k;\n    v = _v;\n    nextNode = nn;\n    _owner.inc(this);\n  }\n  public HashNode(HashBase _owner, Object _k, int hc, Object _v) {\n    this(_owner, _k, hc, _v, null);\n  }\n  public HashNode(HashBase _owner, Object _k, int hc) {\n    this(_owner, _k, hc, null, null);\n  }\n  // Cloning constructor\n  HashNode(HashBase _owner, HashNode prev) {\n    owner = _owner;\n    hashcode = prev.hashcode;\n    k = prev.k;\n    v = prev.v;\n    nextNode = prev.nextNode;\n  }\n  public HashNode setOwner(HashBase nowner) {\n    if (owner == nowner)\n      return this;\n    return new HashNode(nowner, this);\n  }\n  public HashNode clone(HashBase nowner) {\n    HashNode rv = new HashNode(nowner, this);\n    if(nextNode != null)\n      rv.nextNode = nextNode.clone(nowner);\n    return rv;\n  }\n  public final Object key() { return k; }\n  public final Object val() { return v; }\n  public final Object getKey() { return k; }\n  public final Object getValue() { return v; }\n  public Object setValue(Object vv) { Object rv = v; v = vv; return rv; }\n  public final int size() { return 2; }\n  public final Object get(int idx) {\n    if(idx == 0) return k;\n    if(idx == 1) return v;\n    throw new RuntimeException(\"Index out of range.\");\n  }\n  public HashNode assoc(HashBase nowner, Object _k, int hash, Object _v) {\n    HashNode retval = setOwner(nowner);\n    if (k == _k || nowner.equals(_k,k)) {\n      retval.setValue(_v);\n    } else {\n      if (retval.nextNode != null) {\n\tretval.nextNode = retval.nextNode.assoc(nowner, _k, hash, _v);\n      } else {\n\tretval.nextNode = nowner.newNode(_k, hash, _v);\n      }\n    }\n    return retval;\n  }\n  public HashNode dissoc(HashBase nowner, Object _k) {\n    if (k == _k || owner.equals(k, _k)) {\n      nowner.dec(this);\n      return nextNode;\n    }\n    if (nextNode != null) {\n      HashNode nn = nextNode.dissoc(nowner,_k);\n      if (nn != nextNode) {\n\tHashNode retval = setOwner(nowner);\n\tretval.nextNode = nn;\n\treturn retval;\n      }\n    }\n    return this;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/HashProvider.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Objects;\n\n\npublic interface HashProvider {\n  public default int hash(Object obj) {\n    return obj != null ? IntegerOps.mixhash(obj.hashCode()) : 0;\n  }\n  public default boolean equals(Object lhs, Object rhs) {\n    return Objects.equals(lhs,rhs);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/HashProviders.java",
    "content": "package ham_fisted;\n\nimport clojure.lang.Util;\nimport clojure.lang.IHashEq;\n\n\npublic class HashProviders {\n  public static final HashProvider equalHashProvider = new HashProvider(){};\n  /**\n   * Hashcode provider using Clojure's hasheq/equiv pathway\n   */\n  public static final HashProvider equivHashProvider = new HashProvider() {\n      public int hash(Object obj) {\n\treturn Util.hasheq(obj);\n      }\n      public boolean equals(Object lhs, Object rhs) {\n\treturn CljHash.equiv(lhs,rhs);\n      }\n    };\n\n  //Equiv-pathway with small optimizations.\n  public static final HashProvider hybridHashProvider = new HashProvider() {\n      public int hash(Object k) {\n\treturn\t  \n\t  k == null ? 0 :\n\t  k instanceof IHashEq ? ((IHashEq)k).hasheq() :\n\t  IntegerOps.mixhash(k.hashCode());\n      }\n      public boolean equals(Object lhs, Object rhs) {\n\treturn\n\t  lhs == rhs ? true :\n\t  lhs == null || rhs == null ? false :\n\t  CljHash.nonNullEquiv(lhs,rhs);\n      }\n    };\n\n  public static final HashProvider defaultHashProvider = hybridHashProvider;\n}\n"
  },
  {
    "path": "java/ham_fisted/HashSet.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IPersistentMap;\nimport java.util.Iterator;\nimport java.util.Set;\nimport java.util.Spliterator;\nimport java.util.Collection;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.IFn;\nimport clojure.lang.IReduceInit;\n\n\npublic class HashSet extends HashBase implements ISet, SetOps {\n  public static final Object VALUE = new Object();\n  public HashSet(float loadFactor, int initialCapacity,\n\t\t int length, HashNode[] data,\n\t\t IPersistentMap meta) {\n    super(loadFactor, initialCapacity, length, data, meta);\n  }\n  public HashSet() {\n    this(0.75f, 0, 0, null, null);\n  }\n  public HashSet(IPersistentMap m) {\n    this(0.75f, 0, 0, null, m);\n  }\n  public HashSet(HashBase other, IPersistentMap m) {\n    super(other, m);\n  }\n  public HashSet(HashBase other) {\n    super(other, null);\n  }\n  public HashSet shallowClone() {\n    return new HashSet(loadFactor, capacity, length, data.clone(), meta);\n  }\n  public HashSet clone() {\n    final int l = data.length;\n    HashNode[] newData = new HashNode[l];\n    HashSet retval = new HashSet(loadFactor, capacity, length, newData, meta);\n    for(int idx = 0; idx < l; ++idx) {\n      HashNode orig = data[idx];\n      if(orig != null)\n\tnewData[idx] = orig.clone(retval);\n    }\n    return retval;\n  }\n  public int hashCode() {\n    return hasheq();\n  }\n  public int hasheq() {\n    return CljHash.setHashcode(this);\n  }\n  public  boolean equals(Object o) {\n    return equiv(o);\n  }\n  public boolean equiv(Object o) {\n    return CljHash.setEquiv(this, o);\n  }\n  public boolean add(Object key) {\n    final int hc = hash(key);\n    final int idx = hc & this.mask;\n    HashNode lastNode = null;\n    //Avoid unneeded calls to both equals and checkResize\n    for(HashNode e = this.data[idx]; e != null; e = e.nextNode) {\n      lastNode = e;\n      if(e.k == key || equals(e.k, key))\n\treturn false;\n    }\n    HashNode lf = newNode(key,hc,VALUE);\n    if(lastNode != null) {\n      lastNode.nextNode = lf;\n    } else {\n      data[idx] = lf;\n    }\n    checkResize(null);\n    return true;\n  }\n\n  public void addAllReduceGeneric(IReduceInit r) {\n    final HashBase rv = this;\n    r.reduce(new IFnDef() {\n\tpublic Object invoke(Object acc, Object k) {\n\t  final int hc = rv.hash(k);\n\t  final int idx = hc & rv.mask;\n\t  final HashNode[] d = rv.data;\n\t  HashNode e = d[idx];\n\t  for(; e != null && !(k == e.k || rv.equals(k,e.k)); e = e.nextNode);\n\t  if(e == null) {\n\t    final HashNode lf = rv.newNode(k, hc, VALUE);\n\t    lf.nextNode = d[idx];\n\t    d[idx] = lf;\n\t    rv.checkResize(null);\n\t  }\n\t  return this;\n\t}\n      }, this);\n  }\n  public boolean addAll(Collection c) {\n    int sz = length;\n    if(c instanceof HashSet) {\n      HashSet other = (HashSet) c;\n      HashNode[] d = data;\n      int m = mask;\n      final HashNode[] od = other.data;\n      final int odl = od.length;\n      for (int idx = 0; idx < odl; ++idx) {\n\tfor (HashNode e = od[idx]; e != null; e = e.nextNode) {\n\t  // Its tempting to use the hashcode here but we don't know if\n\t  // the other hashset has overridden hash or not.\n\t  int hc = hash(e.k);\n\t  int didx = hc & m;\n\t  HashNode ee = d[didx];\n\t  for(; ee != null && !(ee.k == e.k || equals(ee.k, e.k)); ee = ee.nextNode);\n\t  if( ee == null) {\n\t    HashNode n = newNode(e.k, hc, e.v);\n\t    n.nextNode = d[didx];\n\t    d[didx] = n;\n\t    checkResize(null);\n\t    d = data;\n\t    m = mask;\n\t  }\n\t}\n      }\n    } else if(c instanceof IReduceInit) {\n      addAllReduceGeneric((IReduceInit)c);\n    } else {\n      HashNode[] d = data;\n      int m = mask;\n      for(Object k: c) {\n\tint hc = hash(k);\n\tint idx = hc & m;\n\tHashNode e = d[idx];\n\tfor(; e != null && !(k == e.k || equals(k,e.k)); e = e.nextNode);\n\tif(e == null) {\n\t  HashNode lf = newNode(k, hc, VALUE);\n\t  lf.nextNode = d[idx];\n\t  d[idx] = lf;\n\t  checkResize(null);\n\t  d = data;\n\t  m = mask;\n\t}\n      }\n    }\n    return sz != length;\n  }\n  public boolean remove(Object key) {\n    HashNode lastNode = null;\n    int loc = hash(key) & this.mask;\n    for(HashNode e = this.data[loc]; e != null; e = e.nextNode) {\n      Object k;\n      if((k = e.k) == key || equals(k, key)) {\n\tdec(e);\n\tif(lastNode != null)\n\t  lastNode.nextNode = e.nextNode;\n\telse\n\t  this.data[loc] = e.nextNode;\n\treturn true;\n      }\n      lastNode = e;\n    }\n    return false;\n  }\n  public boolean contains(Object key) {\n    return containsNodeKey(key);\n  }\n  public Iterator iterator() {\n    return new HTIter(this.data, (e)->e.getKey());\n  }\n  public Spliterator spliterator() {\n    return new HTSpliterator(this.data, this.length, (e)->e.getKey());\n  }\n  public Object reduce(IFn rfn, Object acc) {\n    final int l = data.length;\n    for(int idx = 0; idx < l; ++idx) {\n      for(HashNode e = this.data[idx]; e != null; e = e.nextNode) {\n\tacc = rfn.invoke(acc, e.k);\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n    }\n    return acc;\n  }\n\n  public static HashSet union(HashSet rv, Collection rhs) {\n    if(rhs instanceof IReduceInit) {\n      return (HashSet)((IReduceInit)rhs).reduce(new IFnDef() {\n\t  public Object invoke(Object acc, Object k) {\n\t    final int hashcode = rv.hash(k);\n\t    final int rvidx = hashcode & rv.mask;\n\t    HashNode init = rv.data[rvidx], e = init;\n\t    for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\t    if(e == null) {\n\t      if(init != null)\n\t\trv.data[rvidx] = init.assoc(rv, k, hashcode, VALUE);\n\t      else\n\t\trv.data[rvidx] = rv.newNode(k, hashcode, VALUE);\n\t      rv.checkResize(null);\n\t    }\n\t    return rv;\n\t  }\n\t}, rv);\n    } else {\n      HashNode[] rvd = rv.data;\n      int mask = rv.mask;\n      for(Object k: rhs) {\n\tfinal int hashcode = rv.hash(k);\n\tfinal int rvidx = hashcode & mask;\n\tHashNode init = rvd[rvidx], e = init;\n\tfor(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\tif(e == null) {\n\t  if(init != null)\n\t    rvd[rvidx] = init.assoc(rv, k, hashcode, VALUE);\n\t  else\n\t    rvd[rvidx] = rv.newNode(k, hashcode, VALUE);\n\t  rv.checkResize(null);\n\t  mask = rv.mask;\n\t  rvd = rv.data;\n\t}\n      }\n    }\n    return rv;\n  }\n\n  public HashSet union(Collection rhs) {\n    return union(this, rhs);\n  }\n\n  public static HashSet intersection(HashSet rv, Set rhs) {\n    final HashNode[] rvd = rv.data;\n    final int ne = rvd.length;\n    for (int idx = 0; idx < ne; ++idx) {\n      HashNode lf = rvd[idx];\n      while(lf != null) {\n\tfinal Object k = lf.k;\n\tlf = lf.nextNode;\n\tif(!rhs.contains(k))\n\t  rvd[idx] = rvd[idx].dissoc(rv, k);\n      }\n    }\n    return rv;\n  }\n\n  public HashSet intersection(Set rhs) {\n    return intersection(this, rhs);\n  }\n\n  public static HashSet difference(HashSet rv, Set rhs) {\n    final HashNode[] rvd = rv.data;\n    final int mask = rv.mask;\n    if(rhs instanceof IReduceInit) {\n      return (HashSet)((IReduceInit)rhs).reduce(new IFnDef() {\n\t  public Object invoke(Object acc, Object k) {\n\t    final int hashcode = rv.hash(k);\n\t    final int rvidx = hashcode & mask;\n\t    HashNode e = rvd[rvidx];\n\t    for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\t    if(e != null) {\n\t      rvd[rvidx] = rvd[rvidx].dissoc(rv, e.k);\n\t    }\n\t    return rv;\n\t  }\n\t}, rv);\n    } else {\n      for (Object k : rhs) {\n\tfinal int hashcode = rv.hash(k);\n\tfinal int rvidx = hashcode & mask;\n\tHashNode e = rvd[rvidx];\n\tfor(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n\tif(e != null) {\n\t  rvd[rvidx] = rvd[rvidx].dissoc(rv, e.k);\n\t}\n      }\n    }\n    return rv;\n  }\n\n  public HashSet difference(Set rhs) {\n    HashSet rv = shallowClone();\n    final HashNode[] rvd = rv.data;\n    final int mask = rv.mask;\n    for (Object k : rhs) {\n      final int hashcode = rv.hash(k);\n      final int rvidx = hashcode & mask;\n      HashNode e = rvd[rvidx];\n      for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n      if(e != null) {\n\trvd[rvidx] = rvd[rvidx].dissoc(rv, k);\n      }\n    }\n    return rv;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IAMapEntry.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IMapEntry;\nimport java.util.Map;\n\npublic interface IAMapEntry extends Map.Entry, IMutList, IMapEntry {\n  default Object setValue(Object v) { throw new UnsupportedOperationException(); }\n  default Object key() { return getKey(); }\n  default Object val() { return getValue(); }\n  default int size() { return 2; }\n  default Object get(int idx) {\n    if(idx == 0) return getKey();\n    if(idx == 1) return getValue();\n    throw new RuntimeException(\"Index out of range.\");\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IAPersistentMap.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientMap;\n\ninterface IAPersistentMap extends Map, IEditableCollection, IPersistentMap {\n  default int count() { return size(); }\n  default IPersistentMap cons(Object v) { return (IPersistentMap)(asTransient().conj(v).persistent()); }\n  default IPersistentMap assocEx(Object key, Object val) {\n    if(containsKey(key))\n      throw new RuntimeException(\"Object already contains key :\" + String.valueOf(key));\n    return assoc(key, val);\n  }\n  default IPersistentMap assoc(Object key, Object val) {\n    return (IPersistentMap)(asTransient().assoc(key,val).persistent());\n  }\n  default IPersistentMap without(Object key) {\n    return (IPersistentMap)(asTransient().without(key).persistent());\n  }\n  ITransientMap asTransient();\n}\n"
  },
  {
    "path": "java/ham_fisted/IAPersistentSet.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IPersistentSet;\nimport clojure.lang.ITransientSet;\nimport clojure.lang.IEditableCollection;\n\n\npublic interface IAPersistentSet extends ISet, IEditableCollection, IPersistentSet {\n  default int count() { return size(); }\n  default Object get(Object o) { return contains(o) ? o : null; }\n  default IPersistentSet cons(Object o) {\n    return (IPersistentSet)asTransient().conj(o).persistent();\n  }\n  default IPersistentSet disjoin(Object o) {\n    return (IPersistentSet)asTransient().disjoin(o).persistent();\n  }\n  ITransientSet asTransient();\n}\n"
  },
  {
    "path": "java/ham_fisted/IATransientMap.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Map;\nimport clojure.lang.Indexed;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.ITransientAssociative2;\nimport clojure.lang.IKVReduce;\n\n\npublic interface IATransientMap extends ITransientMap, ITransientAssociative2 {\n  default ITransientMap conjVal(Object val) {\n    Object k, v;\n    if(val instanceof Indexed) {\n      Indexed ii = (Indexed)val;\n      k = ii.nth(0);\n      v = ii.nth(1);\n    } else if (val instanceof Map.Entry) {\n      Map.Entry ii = (Map.Entry)val;\n      k = ii.getKey();\n      v = ii.getValue();\n    } else {\n      throw new RuntimeException(\"Value must be either indexed or map entry :\" + String.valueOf(val != null ? val.getClass() : \"null\"));\n    }\n    return assoc(k,v);\n  }\n  default ITransientMap conj(Object val) {\n    if(val instanceof Map) {\n      if(val instanceof IKVReduce) {\n\treturn (IATransientMap)\n\t  ((IKVReduce)val).kvreduce(new IFnDef() {\n\t      public Object invoke(Object acc, Object k, Object v) {\n\t\treturn ((ITransientAssociative2)acc).assoc(k,v);\n\t      }\n\t    }, this);\n      } else {\n\tITransientMap m = this;\n\tfor(Object o: ((Map)val).entrySet()) {\n\t  Map.Entry lf = (Map.Entry)o;\n\t  m = (ITransientMap)((ITransientAssociative2)m).assoc(lf.getKey(), lf.getValue());\n\t}\n\treturn m;\n      }\n    } else {\n      return conjVal(val);\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IATransientSet.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.ITransientSet;\n\n\npublic interface IATransientSet extends ITransientSet {\n  default Object get(Object o) { return contains(o) ? o : null; }\n}\n"
  },
  {
    "path": "java/ham_fisted/ICollectionDef.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.Objects;\nimport java.util.function.Predicate;\n\npublic interface ICollectionDef<E> extends Collection<E> {\n  default boolean add(E e) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default boolean addAll(Collection<? extends E> c) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default void clear() { throw new UnsupportedOperationException(\"Unimplemented\"); }\n\n  default boolean contains(Object o) {\n    for(E e: this) {\n      if(Objects.equals(e, o)) return true;\n    }\n    return false;\n  }\n  default boolean containsAll(Collection<?> c) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n\n  default boolean isEmpty() { return iterator().hasNext() == false; }\n\n  default boolean remove(Object o) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n\n  default boolean removeAll(Collection<?> c) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default boolean removeIf(Predicate<? super E> filter) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default boolean retainAll(Collection<?> c) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default Object[] toArray() { return ArrayLists.toArray(this); }\n  default <T> T[] toArray(T[] d) {\n    return ArrayLists.toArray(this, d);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IFnDef.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.ISeq;\nimport clojure.lang.Util;\nimport clojure.lang.RT;\nimport clojure.lang.ArityException;\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.ArrayList;\nimport java.util.function.Supplier;\nimport java.util.function.DoubleSupplier;\nimport java.util.function.LongSupplier;\nimport java.util.function.Function;\nimport java.util.function.LongFunction;\nimport java.util.function.ToLongFunction;\nimport java.util.function.DoubleFunction;\nimport java.util.function.ToDoubleFunction;\nimport java.util.function.UnaryOperator;\nimport java.util.function.DoubleUnaryOperator;\nimport java.util.function.LongUnaryOperator;\nimport java.util.function.BinaryOperator;\nimport java.util.function.DoubleBinaryOperator;\nimport java.util.function.LongBinaryOperator;\n\n\n//UnaryOperator and BinaryOperator have mutually invalid overloads for andThen so we can't implement\n//those here.\npublic interface IFnDef extends IFn\n{\n\n  default Object call() {\n    return invoke();\n  }\n\n  default void run(){\n    invoke();\n  }\n\n  default Object invoke() {\n    return throwArity(0);\n  }\n\n  default Object invoke(Object arg1) {\n    return throwArity(1);\n  }\n\n  default Object invoke(Object arg1, Object arg2) {\n    return throwArity(2);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3) {\n    return throwArity(3);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4) {\n    return throwArity(4);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {\n    return throwArity(5);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {\n    return throwArity(6);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7)\n  {\n    return throwArity(7);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8) {\n    return throwArity(8);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9) {\n    return throwArity(9);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10) {\n    return throwArity(10);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11) {\n    return throwArity(11);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12) {\n    return throwArity(12);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13)\n  {\n    return throwArity(13);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14)\n  {\n    return throwArity(14);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15) {\n    return throwArity(15);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16) {\n    return throwArity(16);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17) {\n    return throwArity(17);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18) {\n    return throwArity(18);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18, Object arg19) {\n    return throwArity(19);\n  }\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20)\n  {\n    return throwArity(20);\n  }\n\n\n  default Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20,\n\t\t       Object... args)\n  {\n    return throwArity(21);\n  }\n\n  default Object applyTo(ISeq arglist) {\n    return ifaceApplyToHelper(this, Util.ret1(arglist,arglist = null));\n  }\n\n  static public List asRandomAccess(Object arglist) {\n    if(arglist instanceof RandomAccess)\n      return (List)arglist;\n    else if (arglist instanceof Object[])\n      return ArrayLists.toList((Object[])arglist);\n    else\n      return null;\n  }\n  @SuppressWarnings(\"unchecked\")\n  static public Object ifaceApplyToHelper(IFn ifn, Object arglist) {\n    List args = null;\n    if( arglist != null ) {\n      args = asRandomAccess(arglist);\n      if(args == null) {\n\tISeq c = RT.seq(arglist);\n\tif(c != null) {\n\t  ArrayList al = new ArrayList();\n\t  for(; c != null; c = c.next()) {\n\t    al.add(c.first());\n\t  }\n\t  args = al;\n\t}\n      }\n      arglist = null;\n    }\n    switch(args != null ? args.size() : 0) {\n    case 0:\n      return ifn.invoke();\n    case 1:\n      return ifn.invoke(args.get(0));\n    case 2:\n      return ifn.invoke(args.get(0), args.get(1));\n    case 3:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2));\n    case 4:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3));\n    case 5:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4));\n    case 6:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5));\n    case 7:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6));\n    case 8:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7));\n    case 9:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8));\n    case 10:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9));\n    case 11:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10));\n    case 12:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11));\n    case 13:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12));\n    case 14:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13));\n    case 15:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14));\n    case 16:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14),\n\t\t\targs.get(15));\n    case 17:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14),\n\t\t\targs.get(15), args.get(16));\n    case 18:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14),\n\t\t\targs.get(15), args.get(16), args.get(17));\n    case 19:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14),\n\t\t\targs.get(15), args.get(16), args.get(17), args.get(18));\n    case 20:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14),\n\t\t\targs.get(15), args.get(16), args.get(17), args.get(18), args.get(19));\n    default:\n      return ifn.invoke(args.get(0), args.get(1), args.get(2), args.get(3), args.get(4),\n\t\t\targs.get(5), args.get(6), args.get(7), args.get(8), args.get(9),\n\t\t\targs.get(10), args.get(11), args.get(12), args.get(13), args.get(14),\n\t\t\targs.get(15), args.get(16), args.get(17), args.get(18), args.get(19),\n\t\t\targs.subList(20, args.size()).toArray());\n    }\n  }\n\n  default Object throwArity(int n){\n    String name = getClass().getName();\n    throw new ArityException(n, name);\n  }\n\n  public interface O extends IFnDef, Supplier {\n    default Object get() { return invoke(); }\n  }\n\n  public interface D extends IFnDef, DoubleSupplier, Supplier, IFn.D {\n    default double getAsDouble() { return invokePrim(); }\n    default Object get() { return invokePrim(); }\n    default Object invoke() { return invokePrim(); }\n  }\n\n  public interface L extends IFnDef, DoubleSupplier, Supplier, IFn.L {\n    default long getAsLong() { return invokePrim(); }\n    default Object get() { return invokePrim(); }\n    default Object invoke() { return invokePrim(); }\n  }\n\n  public interface OO extends IFnDef, UnaryOperator {\n    default Object apply(Object arg) { return invoke(arg); }\n  }\n\n  public interface OOO extends IFnDef, BinaryOperator {\n    default Object apply(Object l, Object r) { return invoke(l,r); }\n  }\n\n  public interface LO extends IFnDef, IFn.LO, LongFunction {\n    default Object invoke(Object arg) {\n      return invokePrim(Casts.longCast(arg));\n    }\n    default Object apply(long v) { return invokePrim(v); }\n  }\n  public interface LongPredicate extends IFnDef, IFn.LO, LongFunction,\n\t\t\t\t\t java.util.function.LongPredicate {\n    default Object invokePrim(long arg) {\n      return test(arg);\n    }\n    default Object invoke(Object arg) {\n      return test(Casts.longCast(arg));\n    }\n    default Object apply(long v) { return test(v); }\n  }\n  public interface LL extends IFnDef, IFn.LL, LongUnaryOperator {\n    default Object invoke(Object arg) {\n      return invokePrim(Casts.longCast(arg));\n    }\n    default long applyAsLong(long v) {\n      return invokePrim(v);\n    }\n  }\n  public interface OL extends IFnDef, IFn.OL, ToLongFunction {\n    default Object invoke(Object arg) {\n      return invokePrim(arg);\n    }\n    default long applyAsLong(Object v) { return invokePrim(v); }\n  }\n  public interface DO extends IFnDef, IFn.DO, DoubleFunction {\n    default Object invoke(Object arg) {\n      return invokePrim(Casts.doubleCast(arg));\n    }\n    default Object apply(double v) { return invokePrim(v); }\n  }\n  public interface DoublePredicate extends IFnDef, IFn.DO, DoubleFunction,\n\t\t\t\t\t   java.util.function.DoublePredicate {\n    default Object invoke(Object arg) {\n      return test(Casts.doubleCast(arg));\n    }\n    default Object invokePrim(double arg) {\n      return test(arg);\n    }\n    default Object apply(double v) { return test(v); }\n    default DoublePredicate negate() {\n      DoublePredicate prev = this;\n      return new DoublePredicate() {\n\tpublic boolean test(double v) {\n\t  return !prev.test(v);\n\t}\n      };\n    }\n  }\n  public interface DD extends IFnDef, IFn.DD, DoubleUnaryOperator {\n    default Object invoke(Object arg) {\n      return invokePrim(Casts.doubleCast(arg));\n    }\n    default double applyAsDouble(double v) {\n      return invokePrim(v);\n    }\n  }\n  public interface OD extends IFnDef, IFn.OD, ToDoubleFunction {\n    default Object invoke(Object arg) {\n      return invokePrim(arg);\n    }\n    default double applyAsDouble(Object v) { return invokePrim(v); }\n  }\n  public interface LD extends IFnDef, IFn.LD {\n    default Object invoke(Object arg) {\n      return invokePrim(Casts.longCast(arg));\n    }\n  }\n  public interface DL extends IFnDef, IFn.DL {\n    default Object invoke(Object arg) {\n      return invokePrim(Casts.doubleCast(arg));\n    }\n  }\n  @SuppressWarnings(\"unchecked\")\n  public interface Predicate extends IFnDef, UnaryOperator, java.util.function.Predicate {\n    default Object invoke(Object v) { return test(v); }\n    default Object apply(Object arg) { return test(arg); }\n  }\n  public interface DDD extends IFnDef, IFn.DDD, DoubleBinaryOperator {\n    default Object invoke(Object lhs, Object rhs) {\n      return invokePrim(Casts.doubleCast(lhs), Casts.doubleCast(rhs));\n    }\n    default double applyAsDouble(double l, double r) {\n      return invokePrim(l,r);\n    }\n  }\n  public interface LLL extends IFnDef, IFn.LLL, LongBinaryOperator {\n    default Object invoke(Object lhs, Object rhs) {\n      return invokePrim(Casts.longCast(lhs), Casts.longCast(rhs));\n    }\n    default long applyAsLong(long l, long r) {\n      return invokePrim(l,r);\n    }\n  }\n  public interface ODO extends IFnDef, IFn.ODO {\n    default Object invoke(Object lhs, Object rhs) {\n      return invokePrim(lhs, Casts.doubleCast(rhs));\n    }\n  }\n  public interface OLO extends IFnDef, IFn.OLO {\n    default Object invoke(Object lhs, Object rhs) {\n      return invokePrim(lhs, Casts.longCast(rhs));\n    }\n  }\n  public interface LLO extends IFnDef, IFn.LLO {\n    default Object invoke(Object l, Object r) {\n      return invokePrim(Casts.longCast(l), Casts.longCast(r));\n    }\n  }\n\n  public interface OLOO extends IFnDef, IFn.OLOO {\n    default Object invoke(Object acc, Object idx, Object v) {\n      return invokePrim(acc, Casts.longCast(idx), v);\n    }\n  }\n  public interface OLDO extends IFnDef, IFn.OLDO {\n    default Object invoke(Object acc, Object idx, Object v) {\n      return invokePrim(acc, Casts.longCast(idx), Casts.doubleCast(v));\n    }\n  }\n  public interface OLLO extends IFnDef, IFn.OLLO {\n    default Object invoke(Object acc, Object idx, Object v) {\n      return invokePrim(acc, Casts.longCast(idx), Casts.longCast(v));\n    }\n  }\n  public interface DDDD extends IFnDef, IFn.DDDD {\n    default Object invoke (Object a, Object b, Object c) {\n      return invokePrim(Casts.doubleCast(a),\n\t\t\tCasts.doubleCast(b),\n\t\t\tCasts.doubleCast(c));\n    }\n  }\n  public interface LLLL extends IFnDef, IFn.LLLL {\n    default Object invoke (Object a, Object b, Object c) {\n      return invokePrim(Casts.longCast(a),\n\t\t\tCasts.longCast(b),\n\t\t\tCasts.longCast(c));\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IMap.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util.Collection;\nimport java.util.AbstractSet;\nimport java.util.AbstractCollection;\nimport java.util.function.Function;\nimport java.util.function.Consumer;\nimport java.util.function.BiConsumer;\nimport java.util.Objects;\nimport clojure.lang.IFn;\nimport clojure.lang.ILookup;\nimport clojure.lang.IMapIterable;\nimport clojure.lang.Counted;\nimport clojure.lang.MapEquivalence;\nimport clojure.lang.IKVReduce;\nimport clojure.lang.Seqable;\nimport clojure.lang.ISeq;\nimport clojure.lang.RT;\n\n\npublic interface IMap extends Map, ITypedReduce, ILookup, IFnDef, Iterable, IMapIterable, Counted,\n\t\t\t      MapEquivalence, IKVReduce, Seqable\n{\n  Iterator iterator(Function<Map.Entry, Object> fn);\n  default Spliterator spliterator(Function<Map.Entry, Object> fn) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  default Iterator keyIterator() { return iterator((k)->k.getKey()); }\n  default Iterator valIterator() { return iterator((k)->k.getValue()); }\n  default Iterator entryIterator() { return iterator((k)->k); }\n  default Iterator iterator() { return entryIterator(); }\n  @SuppressWarnings(\"unchecked\")\n  default void putAll(Map data) {\n    data.forEach(new BiConsumer() {\n\tpublic void accept(Object k, Object v) {\n\t  put(k,v);\n\t}\n      });\n  }\n  default boolean containsValue(Object val) {\n    return values().contains(val);\n  }\n  default Object valAt(Object k) { return get(k); }\n  @SuppressWarnings(\"unchecked\")\n  default Object valAt(Object k, Object defVal) { return getOrDefault(k, defVal); }\n  default Object invoke(Object k) { return get(k); }\n  @SuppressWarnings(\"unchecked\")\n  default Object invoke(Object k, Object defVal) { return getOrDefault(k, defVal); }\n  default boolean isEmpty() { return this.size() == 0; }\n  @SuppressWarnings(\"unchecked\")\n  default void forEach(Consumer c) {\n    ITypedReduce.super.forEach(c);\n  }\n  default int count() { return size(); }\n  default Object kvreduce(IFn f, Object init) {\n    return reduce(new IFnDef() {\n\tpublic Object invoke(Object acc, Object v) {\n\t  final Map.Entry lf = (Map.Entry)v;\n\t  return f.invoke(acc, lf.getKey(), lf.getValue());\n\t}\n      }, init);\n  }\n  default ISeq seq() {\n    return LazyChunkedSeq.chunkIteratorSeq(iterator());\n  }\n  public static class MapKeySet extends AbstractSet implements ITypedReduce, IFnDef, Counted {\n    public final IMap data;\n    public MapKeySet(IMap data) { this.data = data; }\n    public int size() { return data.size(); }\n    public int count() { return data.size(); }\n    public boolean contains(Object k) { return data.containsKey(k); }\n    public Iterator iterator() { return data.keyIterator(); }\n    public Spliterator spliterator() { return data.spliterator( (k)->k.getKey() ); }\n    public void clear() { data.clear(); }\n    static IFn wrapRfn(IFn rfn) { return new IFnDef() {\n\tpublic Object invoke(Object acc, Object v) {\n\t  return rfn.invoke(acc, ((Map.Entry)v).getKey());\n\t}\n      };\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      return data.reduce(wrapRfn(rfn), acc);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t    ParallelOptions options ) {\n      return data.parallelReduction(initValFn, wrapRfn(rfn), mergeFn, options);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public void forEach(Consumer c) {\n      reduce( new IFnDef() {\n\t  public Object invoke(Object lhs, Object rhs) {\n\t    c.accept(rhs);\n\t    return c;\n\t  }\n\t}, c);\n    }\n    public Object invoke(Object k) { return data.containsKey(k) ? k : null; }\n  }\n  default Set keySet() {\n    return new MapKeySet(this);\n  }\n  public static class MapEntrySet extends AbstractSet implements ITypedReduce, IFnDef, Counted {\n    public final IMap data;\n    public MapEntrySet(IMap data) { this.data = data; }\n    public int size() { return data.size(); }\n    public int count() { return data.size(); }\n    public boolean contains(Object k) {\n      if(!(k instanceof Map.Entry)) return false;\n      Map.Entry e = (Map.Entry)k;\n      return Objects.equals(data.get(e), e.getValue());\n    }\n    public Iterator iterator() { return data.entryIterator(); }\n    public Spliterator spliterator() { return data.spliterator( (k)->k ); }\n    public void clear() { data.clear(); }\n    public Object reduce(IFn rfn, Object acc) {\n      return data.reduce(rfn, acc);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t    ParallelOptions options ) {\n      return data.parallelReduction(initValFn, rfn, mergeFn, options);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public void forEach(Consumer c) {\n      data.forEach(c);\n    }\n    public Object invoke(Object k) { return contains(k); }\n  }\n  default Set entrySet() {\n    return new MapEntrySet(this);\n  }\n  public static class ValueCollection  extends AbstractCollection implements ITypedReduce, Counted {\n    public final IMap data;\n    public ValueCollection(IMap data) { this.data = data;}\n    public final int size() { return data.size(); }\n    public int count() { return data.size(); }\n    public final void clear() {\n      data.clear();\n    }\n    public final Iterator iterator() {\n      return data.valIterator();\n    }\n    @SuppressWarnings(\"unchecked\")\n    public final Spliterator spliterator() {\n      return data.spliterator((k)->k.getValue());\n    }\n    public static IFn wrapRfn(IFn val) {\n      return new IFnDef() {\n\tpublic Object invoke(Object acc, Object e) {\n\t  return val.invoke(acc, ((Map.Entry)e).getValue());\n\t}\n      };\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      return data.reduce(wrapRfn(rfn), acc);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t    ParallelOptions options ) {\n      return data.parallelReduction(initValFn, wrapRfn(rfn), mergeFn, options);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public void forEach(Consumer c) {\n      reduce( new IFnDef() {\n\t  public Object invoke(Object lhs, Object rhs) {\n\t    c.accept(rhs);\n\t    return c;\n\t  }\n\t}, c);\n    }\n  }\n  default Collection values() {\n    return new ValueCollection(this);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IMutList.java",
    "content": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util.ListIterator;\nimport java.util.Objects;\nimport java.util.NoSuchElementException;\nimport java.util.Collection;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport java.util.Random;\nimport java.util.Collections;\nimport java.util.Spliterator;\nimport java.util.function.DoubleBinaryOperator;\nimport java.util.function.LongBinaryOperator;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.stream.IntStream;\nimport java.util.stream.LongStream;\nimport java.util.stream.DoubleStream;\nimport java.util.stream.Stream;\nimport it.unimi.dsi.fastutil.objects.ObjectArrays;\nimport it.unimi.dsi.fastutil.ints.IntArrays;\nimport it.unimi.dsi.fastutil.ints.IntComparator;\nimport it.unimi.dsi.fastutil.longs.LongComparator;\nimport it.unimi.dsi.fastutil.floats.FloatComparator;\nimport it.unimi.dsi.fastutil.doubles.DoubleComparator;\n\n\nimport clojure.lang.Indexed;\nimport clojure.lang.IReduce;\nimport clojure.lang.IKVReduce;\nimport clojure.lang.IHashEq;\nimport clojure.lang.Seqable;\nimport clojure.lang.Sequential;\nimport clojure.lang.Reversible;\nimport clojure.lang.RT;\nimport clojure.lang.Util;\nimport clojure.lang.IFn;\nimport clojure.lang.IDeref;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.MapEntry;\nimport clojure.lang.IteratorSeq;\nimport clojure.lang.ISeq;\nimport clojure.lang.IPersistentVector;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IObj;\nimport clojure.lang.ASeq;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.Associative;\nimport clojure.lang.IChunk;\nimport clojure.lang.IChunkedSeq;\nimport clojure.lang.PersistentList;\nimport clojure.lang.ChunkedCons;\nimport clojure.lang.ArrayChunk;\n\n\npublic interface IMutList<E>\n  extends List<E>, RandomAccess, Indexed, IFnDef, ITypedReduce<E>, IKVReduce, IReduce,\n\t  IHashEq, Seqable, Reversible, IObj, ImmutSort<E>, RangeList, Cloneable,\n\t  Sequential, Associative, Comparable\n\n{\n  default IMutList cloneList() { return (IMutList)ArrayLists.toList(toArray()); }\n  default void clear() { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default boolean add(E v) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  default void add(int idx, E v) {\n    add(idx, 1, v);\n  }\n  default void add(int idx, int count, E v) {\n    int end = idx + count;\n    if(idx == size()) {\n      for(; idx < end; ++idx) add( v );\n    } else {\n      for(; idx < end; ++idx) add( idx, v );\n    }\n  }\n  @SuppressWarnings(\"unchecked\")\n  default void addLong(long v) { add((E)Long.valueOf(v)); }\n  @SuppressWarnings(\"unchecked\")\n  default void addDouble(double v) { add((E)Double.valueOf(v)); }\n  default void removeRange(long startidx, long endidx) {\n    ChunkedList.checkIndexRange(0, size(), startidx, endidx);\n    final int sidx = (int)startidx;\n    for(; startidx < endidx; ++startidx) {\n      remove(sidx);\n    }\n  }\n  @SuppressWarnings(\"unchecked\")\n  default void fillRange(long startidx, final long endidx, Object v) {\n    final int sz = size();\n    ChunkedList.checkIndexRange(0, (long)sz, startidx, endidx);\n    int ss = (int)startidx;\n    final int ee = (int)endidx;\n    for(; ss < ee; ++ss) {\n      set(ss, (E)v);\n    }\n  }\n  @SuppressWarnings(\"unchecked\")\n  default void fillRangeReducible(final long startidx, Object v) {\n    final int sz = size();\n    if (v instanceof RandomAccess) {\n      ChunkedList.checkIndexRange(0, sz, startidx, startidx+((List)v).size());\n    }\n    final int ss = (int)startidx;\n    Reductions.serialReduction(new Reductions.IndexedAccum(new IFnDef.OLOO() {\n\tpublic Object invokePrim(Object acc, long idx, Object v) {\n\t  ((List)acc).set((int)idx+ss, v);\n\t  return acc;\n\t}\n      }), this, v);\n  }\n  default E remove(int idx) {\n    final E retval = get(idx);\n    removeRange(idx, idx+1);\n    return retval;\n  }\n  default boolean remove(Object o) {\n    final int idx = indexOf(o);\n    if ( idx == -1)\n      return false;\n    remove(idx);\n    return true;\n  }\n  default boolean addAll(Collection<? extends E> c) {\n    return addAllReducible(c);\n  }\n  @SuppressWarnings(\"unchecked\")\n  default boolean addAllReducible(Object obj) {\n    final int sz = size();\n    Reductions.serialReduction(new IFnDef() {\n\tpublic Object invoke(Object lhs, Object rhs) {\n\t  ((IMutList<E>)lhs).add((E)rhs);\n\t  return lhs;\n\t}\n      }, this, obj);\n    return sz != size();\n  }\n  default boolean addAll(int idx, Collection<? extends E> c) {\n    if (c.isEmpty())\n      return false;\n    final int sz = size();\n    if (idx == sz)\n      return addAll(c);\n\n    for (E e: c) add(idx++, e);\n    return true;\n  }\n  default boolean removeAll(Collection<?> c) {\n    // HashSet<Object> hs = new HashSet<Object>();\n    // hs.addAll(c);\n    // int sz = size();\n    // final int osz = sz;\n    // for(int idx = 0; idx < sz; ++idx) {\n    //   if(hs.contains(get(idx))) {\n    // \tremove(idx);\n    // \t--idx;\n    // \t--sz;\n    //   }\n    // }\n    // return size() == osz;\n    throw new UnsupportedOperationException();\n  }\n  default boolean retainAll(Collection<?> c) {\n    // HashSet<Object> hs = new HashSet<Object>();\n    // hs.addAll(c);\n    // int sz = size();\n    // final int osz = sz;\n    // for(int idx = 0; idx < sz; ++idx) {\n    //   if(!hs.contains(get(idx))) {\n    // \tremove(idx);\n    // \t--idx;\n    // \t--sz;\n    //   }\n    // }\n    // return size() == osz;\n    throw new UnsupportedOperationException();\n  }\n\n  public static class MutSubList<E> implements IMutList<E> {\n    final IMutList<E> list;\n    final int sidx;\n    final int eidx;\n    final int nElems;\n    public MutSubList(IMutList<E> list, int ss, int ee) {\n      this.list = list;\n      sidx = ss;\n      eidx = ee;\n      nElems = ee - ss;\n    }\n    public int size() { return nElems; }\n    public E get(int idx) {\n      ChunkedList.indexCheck(sidx, nElems, idx);\n      return list.get(sidx+idx);\n    }\n    public long getLong(int idx) {\n      ChunkedList.indexCheck(sidx, nElems, idx);\n      return list.getLong(sidx+idx);\n    }\n    public double getDouble(int idx) {\n      ChunkedList.indexCheck(sidx, nElems, idx);\n      return list.getDouble(sidx+idx);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public E set(int idx, E v) {\n      ChunkedList.indexCheck(sidx, nElems, idx);\n      return list.set(sidx+idx, v);\n    }\n    public void setLong(int idx, long v) {\n      ChunkedList.indexCheck(sidx, nElems, idx);\n      list.setLong(sidx+idx, v);\n    }\n    public void setDouble(int idx, double v) {\n      ChunkedList.indexCheck(sidx, nElems, idx);\n      list.setDouble(sidx+idx, v);\n    }\n    public Object reduce(IFn rfn, Object init) {\n      final int ee = eidx;\n      final IMutList l = list;\n      for(int idx = sidx; idx < ee && !RT.isReduced(init); ++idx)\n\tinit = rfn.invoke(init, l.get(idx));\n      return Reductions.unreduce(init);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public IMutList<E> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, nElems);\n      if(ssidx == 0 && seidx == nElems)\n\treturn this;\n      return list.subList(ssidx + sidx, seidx + sidx);\n    }\n    public IPersistentMap meta() { return list.meta(); }\n    @SuppressWarnings(\"unchecked\")\n    public IMutList<E> withMeta(IPersistentMap meta) {\n      return ((IMutList<E>)list.withMeta(meta)).subList(sidx, eidx);\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  default IMutList<E> subList(int startidx, int endidx) {\n    final int sz = size();\n    if (startidx == 0 && endidx == sz)\n      return this;\n    ChunkedList.sublistCheck(startidx, endidx, size());\n    return new MutSubList<E>(this, startidx, endidx);\n  }\n\n  default int indexOf(Object o) {\n    final int sz = size();\n    for(int idx = 0; idx < sz; ++idx)\n      if (Objects.equals(o, get(idx)))\n\treturn idx;\n    return -1;\n  }\n  default int lastIndexOf(Object o) {\n    final int sz = size();\n    final int ssz = sz - 1;\n    for(int idx = 0; idx < sz; ++idx) {\n      int ridx = ssz - idx;\n      if (Objects.equals(o, get(ridx)))\n\treturn ridx;\n    }\n    return -1;\n  }\n  default boolean contains(Object o) {\n    return indexOf(o) != -1;\n  }\n  default boolean isEmpty() { return size() == 0; }\n\n  default int compareTo(Object o) {\n    final List l = (List)o;\n    final int sz = size();\n    final int lsz = l.size();\n    if(sz < lsz)\n      return -1;\n    else if(sz > lsz)\n      return 1;\n    for(int i = 0; i < sz; i++) {\n      int c = Util.compare(get(i),l.get(i));\n      if(c != 0)\n\treturn c;\n    }\n    return 0;\n  }\n\n  public static class ListIter<E> implements ListIterator<E> {\n    List<E> list;\n    int idx = 0;\n    int previdx = 0;\n    ListIter(List<E> ls, int _idx){list = ls; idx = _idx; previdx = _idx;}\n    public final boolean hasNext() {\n      return idx < list.size();\n    }\n    public final boolean hasPrevious() {\n      return idx > 0;\n    }\n    public final E next() {\n      if(!hasNext())\n\tthrow new NoSuchElementException();\n      final E retval = list.get(idx);\n      previdx = idx;\n      ++idx;\n      return retval;\n    }\n    public final E previous() {\n      if(!hasPrevious())\n\tthrow new NoSuchElementException();\n      --idx;\n      previdx = idx;\n      return list.get(idx);\n    }\n    public final int nextIndex() {\n      return idx;\n    }\n    public final int previousIndex() {\n      return idx-1;\n    }\n    public final void remove() {\n      list.remove(previdx);\n    }\n    public final void set(E e) {\n      list.set(previdx, e);\n    }\n    public final void add(E e) {\n      list.add(previdx, e);\n    }\n  }\n  default ListIterator<E> listIterator(int idx) {\n    if (idx < 0 || idx > size())\n      throw new NoSuchElementException(\"Index(\" + String.valueOf(idx) + \") out of range 0-\" + size());\n    return new ListIter<E>(this, idx);\n  }\n  default ListIterator<E> listIterator() {\n    return listIterator(0);\n  }\n  default Iterator<E> iterator() { return listIterator(0); }\n  public class RIter<E> implements Iterator<E> {\n    List<E> list;\n    int idx;\n    public RIter(List<E> ls) { list = ls; idx = 0; }\n    public final boolean hasNext() { return idx < list.size(); }\n    public final E next() {\n      if(!hasNext())\n\tthrow new NoSuchElementException();\n      int ridx = list.size() - idx - 1;\n      ++idx;\n      return list.get(ridx);\n    }\n  }\n  default Iterator<E> riterator() { return new RIter<E>(this); }\n  default Spliterator<E> spliterator() {\n    return new RandomAccessSpliterator<E>(this);\n  }\n  default Object[] fillArray(Object[] data) {\n    Reductions.serialReduction(new Reductions.IndexedAccum(new IFnDef.OLOO() {\n\tpublic Object invokePrim(Object acc, long idx, Object v) {\n\t  ((Object[])acc)[(int)idx] = v;\n\t  return acc;\n\t}\n      }), data, this);\n    return data;\n  }\n  default Object[] toArray() {\n    return fillArray(new Object[size()]);\n  }\n  default <T> T[] toArray(T[] marker) {\n    final T[] retval = Arrays.copyOf(marker, size());\n    fillArray(retval);\n    return retval;\n  }\n  default Object toNativeArray() {\n    return toArray();\n  }\n  default int[] toIntArray() {\n    final int[] retval = new int[size()];\n    ArrayLists.toList(retval).fillRange(0, this);\n    return retval;\n  }\n  default long[] toLongArray() {\n    final long[] retval = new long[size()];\n    ArrayLists.toList(retval).fillRange(0, this);\n    return retval;\n  }\n  default float[] toFloatArray() {\n    final float[] retval = new float[size()];\n    ArrayLists.toList(retval).fillRange(0, this);\n    return retval;\n  }\n  default double[] toDoubleArray() {\n    final double[] retval = new double[size()];\n    ArrayLists.toList(retval).fillRange(0, this);\n    return retval;\n  }\n  @SuppressWarnings(\"unchecked\")\n  default IntComparator indexComparator() {\n    return new IntComparator() {\n      public int compare(int lidx, int ridx) {\n\treturn ((Comparable)get(lidx)).compareTo(get(ridx));\n      }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  default IntComparator indexComparator(Comparator c) {\n    if(c instanceof DoubleComparator) {\n      final DoubleComparator dc = (DoubleComparator)c;\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return dc.compare(getDouble(lidx), getDouble(ridx));\n\t}\n      };\n    } else if (c instanceof IntComparator) {\n      final IntComparator dc = (IntComparator)c;\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return dc.compare((int)getLong(lidx), (int)getLong(ridx));\n\t}\n      };\n    } else if (c instanceof LongComparator) {\n      final LongComparator dc = (LongComparator)c;\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return dc.compare(getLong(lidx), getLong(ridx));\n\t}\n      };\n    } else if (c instanceof FloatComparator) {\n      final FloatComparator dc = (FloatComparator)c;\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return dc.compare((float)getDouble(lidx), (float)getDouble(ridx));\n\t}\n      };\n    } else {\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return c.compare(get(lidx), get(ridx));\n\t}\n      };\n    }\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  default int[] sortIndirect(Comparator c) {\n    final int sz = size();\n    int[] retval = ArrayLists.iarange(0, sz, 1);\n    final Object[] data = toArray();\n    if (c == null)\n      ObjectArrays.parallelQuickSortIndirect(retval, data);\n    else\n      IntArrays.parallelQuickSort(retval,\n\t\t\t\t  new IntComparator() {\n\t\t\t\t    public int compare(int lhs, int rhs) {\n\t\t\t\t      return c.compare(data[lhs], data[rhs]);\n\t\t\t\t    }\n\t\t\t\t  });\n    return retval;\n  }\n\n  default Object nth(int idx) {\n    final int sz = size();\n    if (idx < 0)\n      idx = idx + sz;\n    return get(idx);\n  }\n  default Object nth(int idx, Object notFound) {\n    final int sz = size();\n    if (idx < 0)\n      idx = idx + sz;\n    return idx < sz && idx > -1 ? get(idx) : notFound;\n  }\n  default E set(int idx, E v) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n  @SuppressWarnings(\"unchecked\")\n  default void setLong(int idx, long v) { set(idx, (E)Long.valueOf(v)); }\n  @SuppressWarnings(\"unchecked\")\n  default void setDouble(int idx, double v) { set(idx, (E)Double.valueOf(v)); }\n  default long getLong(int idx) { return Casts.longCast(get(idx)); }\n  default double getDouble(int idx) {\n    final Object obj = get(idx);\n    return obj != null ? Casts.doubleCast(obj) : Double.NaN;\n  }\n  default void accPlusLong(int idx, long val) {\n    setLong( idx, getLong(idx) + val );\n  }\n  default void accPlusDouble(int idx, double val) {\n    setDouble( idx, getDouble(idx) + val );\n  }\n\n  default Object invoke(Object idx) {\n    return nth(RT.intCast(Casts.longCast(idx)));\n  }\n  default Object invoke(Object idx, Object notFound) {\n    if(Util.isInteger(idx))\n      return nth(RT.intCast(Casts.longCast(idx)), notFound);\n    return notFound;\n  }\n  default Object valAt(Object idx) {\n    return invoke(idx);\n  }\n  default Object valAt(Object idx, Object def) {\n    return invoke(idx, def);\n  }\n  default IMapEntry entryAt(Object key) {\n    if(Util.isInteger(key)) {\n      int idx = RT.intCast(key);\n      if (idx >= 0 && idx < size())\n\treturn MapEntry.create(idx, get(idx));\n    }\n    return null;\n  }\n\n  @SuppressWarnings(\"unimplemented\")\n  default boolean containsAll(Collection<?> c) {\n    // HashSet<Object> hc = new HashSet<Object>();\n    // hc.addAll(c);\n    // for(E e: this) {\n    //   if(!hc.contains(e))\n    // \treturn false;\n    // }\n    // return true;\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean containsKey(Object key) {\n    if(Util.isInteger(key)) {\n      int idx = RT.intCast(key);\n      if (idx >= 0 && idx < size())\n\treturn true;\n    }\n    return false;\n  }\n\n  default int count() { return size(); }\n  default int length() { return size(); }\n\n  default Object reduce(IFn f) {\n    final int sz = size();\n    if (sz == 0 )\n      return f.invoke();\n    Object init = get(0);\n    for(int idx = 1; idx < sz && (!RT.isReduced(init)); ++idx) {\n      init = f.invoke(init, get(idx));\n    }\n    return Reductions.unreduce(init);\n  }\n\n  default Object reduce(IFn f, Object init) {\n    final int sz = size();\n    for(int idx = 0; idx < sz && (!RT.isReduced(init)); ++idx) {\n      init = f.invoke(init, get(idx));\n    }\n    return Reductions.unreduce(init);\n  }\n\n  default Object kvreduce(IFn f, Object init) {\n    final int sz = size();\n    for(int idx = 0; idx < sz && (!RT.isReduced(init)); ++idx) {\n      init = f.invoke(init, idx, get(idx));\n    }\n    return Reductions.unreduce(init);\n  }\n  default Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t   ParallelOptions options) {\n    return Reductions.parallelRandAccessReduction(initValFn, rfn, mergeFn,\n\t\t\t\t\t\t  this, options);\n  }\n  @SuppressWarnings(\"unchecked\")\n  default void forEach(Consumer c) {\n    ITypedReduce.super.forEach(c);\n  }\n  default int hasheq() {\n    return CljHash.listHasheq(this);\n  }\n  default boolean equiv(Object other) {\n    return CljHash.listEquiv(this, other);\n  }\n\n  public static IChunk sublistAsChunk(List data, int sidx) {\n    final int nElems = data.size();\n    final int len = nElems - sidx;\n    if(len > 0) {\n      return new IChunk() {\n\tpublic int count() { return len; }\n\tpublic Object nth(int idx, Object defVal) {\n\t  return (idx < len) ? data.get(idx+sidx) : defVal;\n\t}\n\tpublic Object nth(int idx) {\n\t  if(idx < len)\n\t    return data.get(idx+sidx);\n\t  throw new IndexOutOfBoundsException();\n\t}\n\tpublic IChunk dropFirst() {\n\t  return len > 1 ? sublistAsChunk(data, sidx+1) : null;\n\t}\n\tpublic Object reduce(IFn rfn, Object acc) {\n\t  final int ne = len;\n\t  for(int idx = 0; idx < ne; ++idx) {\n\t    acc = rfn.invoke(acc, data.get(idx+sidx));\n\t    if(RT.isReduced(acc))\n\t      return ((IDeref)acc).deref();\n\t  }\n\t  return acc;\n\t}\n      };\n    }\n    return null;\n  }\n\n  public static IChunkedSeq inplaceSublistSeq(List l, int sidx, int eidx) {\n    final int ne = eidx - sidx;\n    if(ne > 0) {\n      final int len = Math.min(32, ne);\n      return new LazyChunkedSeq(new IFnDef() {\n\t  public Object invoke() {\n\t    return new ChunkedCons(sublistAsChunk(l.subList(sidx, sidx + len), 0),\n\t\t\t\t   (ne - len) <= 0 ? null : inplaceSublistSeq(l, sidx+len, eidx));\n\t  }\n\t});\n    } else {\n      return null;\n    }\n  }\n\n  default IChunkedSeq inplaceSublistSeq() {\n    if(isEmpty()) return null; return inplaceSublistSeq(this, 0, size());\n  }\n\n  public static IChunkedSeq copyingArraySeq(List l, int sidx, int eidx) {\n    final int ne = eidx - sidx;\n    if(ne > 0) {\n      final int len = Math.min(32, ne);\n      return new LazyChunkedSeq(new IFnDef() {\n\t  public Object invoke() {\n\t    return new ChunkedCons(new ArrayChunk(l.subList(sidx, sidx + len).toArray()),\n\t\t\t\t   (ne - len) <= 0 ? null : inplaceSublistSeq(l, sidx+len, eidx));\n\t  }\n\t});\n    } else {\n      return null;\n    }\n  }\n  default IChunkedSeq copyingArraySeq() {\n    if(isEmpty()) return null; return copyingArraySeq(this, 0, size());\n  }\n  default ISeq seq() { return copyingArraySeq(); }\n  default ISeq rseq() {\n    return isEmpty() ? null : new ReverseList(this, meta()).seq();\n  }\n\n  default IPersistentMap meta() { return null; }\n  default IObj withMeta(IPersistentMap meta ) { throw new UnsupportedOperationException(\"Unimplemented\"); }\n\n  @SuppressWarnings(\"unchecked\")\n  default void sort(Comparator<? super E> c) {\n    Comparator cc = (Comparator)c;\n    Object[] finalData;\n    if(c == null) {\n      final Comparable[] data = toArray(new Comparable[0]);\n      Arrays.parallelSort(data);\n      finalData = data;\n    } else {\n      finalData = toArray();\n      Arrays.parallelSort(finalData, cc);\n    }\n    fillRange(0, ArrayLists.toList(finalData));\n  }\n\n  default void shuffle(Random r) {\n    Collections.shuffle(this, r);\n  }\n  default List reindex(int[] indexes) {\n    return ReindexList.create(indexes, this, this.meta());\n  }\n  default List immutShuffle(Random r) {\n    final Object[] retval = toArray();\n    ObjectArrays.shuffle(retval, r);\n    return ArrayLists.toList(retval, 0, size(), meta());\n  }\n  default List reverse() {\n    return ReverseList.create(this, meta());\n  }\n  @SuppressWarnings(\"unchecked\")\n  default int binarySearch(E v, Comparator<? super E> c) {\n    int rv;\n    if(c == null)\n      rv = Collections.binarySearch(this,v,new Comparator<E>() {\n\t  public int compare(E lhs, E rhs) {\n\t    return Util.compare(lhs, rhs);\n\t  }\n\t});\n    else\n      rv = Collections.binarySearch(this,v,c);\n    return rv < 0 ? -1 - rv : rv;\n  }\n  default int binarySearch(E v) { return binarySearch(v, null); }\n  default IPersistentVector immut() { return ArrayImmutList.create(true, toArray(), 0, size(), meta()); }\n  default Associative assoc(Object idx, Object o) {\n    return immut().assoc(idx, o);\n  }\n  default IPersistentVector cons(Object o) {\n    return immut().cons(o);\n  }\n  default IPersistentVector empty() {\n    return ArrayImmutList.EMPTY;\n  }\n\n  //Long stream to account for IMutLists that are longer than Integer.MAX_VALUE.\n  default LongStream indexStream(boolean parallel) {\n    LongStream retval = LongStream.range(0, size());\n    return parallel ? retval.parallel() : retval;\n  }\n\n  default Stream objStream(boolean parallel) {\n    return indexStream(parallel).mapToObj((long idx)->get((int)idx));\n  }\n\n  default DoubleStream doubleStream(boolean parallel) {\n    return indexStream(parallel).mapToDouble((long idx)->getDouble((int)idx));\n  }\n\n  default LongStream longStream(boolean parallel) {\n    return indexStream(parallel).map((long idx)->getLong((int)idx));\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ISeqDef.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.ISeq;\nimport clojure.lang.Sequential;\nimport clojure.lang.IHashEq;\nimport clojure.lang.IPersistentCollection;\nimport clojure.lang.PersistentList;\nimport clojure.lang.Util;\nimport clojure.lang.Counted;\nimport clojure.lang.RT;\nimport clojure.lang.SeqIterator;\nimport clojure.lang.Murmur3;\nimport clojure.lang.Cons;\nimport java.util.List;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.ArrayList;\nimport java.util.Iterator;\nimport java.util.ListIterator;\n\n\npublic interface ISeqDef extends ISeq, Sequential, List, IHashEq {\n  \n  default IPersistentCollection empty(){\n    return PersistentList.EMPTY;\n  }\n  \n  default boolean equiv(Object obj){\n    if(!(obj instanceof Sequential || obj instanceof List))\n      return false;\n\n    if(this instanceof Counted && obj instanceof Counted &&\n       ((Counted)this).count() != ((Counted)obj).count())\n      return false;\n\n    ISeq ms = RT.seq(obj);\n    for(ISeq s = seq(); s != null; s = s.next(), ms = ms.next()) {\n\tif(ms == null || !Util.equiv(s.first(), ms.first()))\n\t  return false;\n      }\n    return ms == null;\n\n  }\n  default boolean seqEquals(Object obj){\n    if(this == obj) return true;\n    if(!(obj instanceof Sequential || obj instanceof List))\n      return false;\n    ISeq ms = RT.seq(obj);\n    for(ISeq s = seq(); s != null; s = s.next(), ms = ms.next()) {\n\tif(ms == null || !Util.equals(s.first(), ms.first()))\n\t  return false;\n    }\n    return ms == null;\n  }\n  default int calcHashCode(){\n    int hash = 1;\n    for(ISeq s = seq(); s != null; s = s.next()) {\n      hash = 31 * hash + (s.first() == null ? 0 : s.first().hashCode());\n    }\n    return hash;\n  }\n\n  default int calcHasheq(){\n    return Murmur3.hashOrdered(this);\n  }\n  \n  default int count(){\n    int i = 1;\n    for(ISeq s = next(); s != null; s = s.next(), i++)\n      if(s instanceof Counted)\n\treturn i + s.count();\n    return i;\n  }\n\n  default ISeq seq(){\n    return this;\n  }\n\n  default ISeq cons(Object o){\n    return new Cons(o, this);\n  }\n\n  default ISeq more(){\n    ISeq s = next();\n    if(s == null)\n      return PersistentList.EMPTY;\n    return s;\n  }\n  \n  @SuppressWarnings(\"unchecked\")\n  default List toArrayList() {\n    ArrayList retval = new ArrayList();\n    for(ISeq s = this; s != null; s = s.next())\n      retval.add(s.first());    \n    return retval;\n  }\n\n  default Object[] toArray(){\n    return toArrayList().toArray();\n  }\n\n  default boolean add(Object o){\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean remove(Object o){\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean addAll(Collection c){\n    throw new UnsupportedOperationException();\n  }\n\n  default void clear(){\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean retainAll(Collection c){\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean removeAll(Collection c){\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean containsAll(Collection c){\n    for(Object o : c)\n      {\n\tif(!contains(o))\n\t  return false;\n      }\n    return true;\n  }\n\n  default Object[] toArray(Object[] a){\n    return RT.seqToPassedArray(seq(), a);\n  }\n\n  default int size(){\n    return count();\n  }\n\n  default boolean isEmpty(){\n    return seq() == null;\n  }\n\n  default boolean contains(Object o){\n    for(ISeq s = seq(); s != null; s = s.next())\n      {\n\tif(Util.equiv(s.first(), o))\n\t  return true;\n      }\n    return false;\n  }\n\n  default Iterator iterator(){\n    return new SeqIterator(this);\n  }\n\n  //////////// List stuff /////////////////\n  @SuppressWarnings(\"unchecked\")\n  default List reify(){\n    return Collections.unmodifiableList(toArrayList());\n  }\n\n  default List subList(int fromIndex, int toIndex){\n    return reify().subList(fromIndex, toIndex);\n  }\n\n  default Object set(int index, Object element){\n    throw new UnsupportedOperationException();\n  }\n\n  default Object remove(int index){\n    throw new UnsupportedOperationException();\n  }\n\n  default int indexOf(Object o){\n    ISeq s = seq();\n    for(int i = 0; s != null; s = s.next(), i++)\n      {\n\tif(Util.equiv(s.first(), o))\n\t  return i;\n      }\n    return -1;\n  }\n\n  default int lastIndexOf(Object o){\n    return reify().lastIndexOf(o);\n  }\n\n  default ListIterator listIterator(){\n    return reify().listIterator();\n  }\n\n  default ListIterator listIterator(int index){\n    return reify().listIterator(index);\n  }\n\n  default Object get(int index){\n    return RT.nth(this, index);\n  }\n\n  default void add(int index, Object element){\n    throw new UnsupportedOperationException();\n  }\n\n  default boolean addAll(int index, Collection c){\n    throw new UnsupportedOperationException();\n  }  \n}\n"
  },
  {
    "path": "java/ham_fisted/ISet.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport java.util.Set;\nimport java.util.Iterator;\nimport java.util.function.Function;\nimport java.util.function.Consumer;\nimport clojure.lang.Counted;\nimport clojure.lang.Seqable;\nimport clojure.lang.ISeq;\nimport clojure.lang.RT;\n\n\n\npublic interface ISet extends Set, ITypedReduce, IFnDef, Counted, Seqable {\n\n  default int count() { return size(); }\n  @SuppressWarnings(\"unchecked\")\n  default boolean addAll(Collection c) {\n    int sz = size();\n    for(Object o: c)\n      add(o);\n    return sz == size();\n  }\n  @SuppressWarnings(\"unchecked\")\n  default void forEach(Consumer c) {\n    ITypedReduce.super.forEach(c);\n  }\n  default boolean retainAll(Collection c) {\n    int sz = size();\n    for(Iterator iter = iterator(); iter.hasNext();) {\n      if(!c.contains(iter.next()))\n\titer.remove();\n    }\n    return sz == size();\n  }\n  default boolean containsAll(Collection c) {\n    for(Object o: c) {\n      if(!contains(c)) return false;\n    }\n    return true;\n  }\n  default boolean removeAll(Collection c) {\n    int sz = size();\n    for(Object o: c) {\n      remove(o);\n    }\n    return sz == size();\n  }\n  default ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(iterator()); }\n  default boolean isEmpty() { return size() == 0; }\n  default Object[] toArray() { return ArrayLists.toArray(this); }\n  default Object[] toArray(Object[] d) {\n    return ArrayLists.toArray(this, d);\n  }\n  default Object invoke(Object arg) { return contains(arg) ? arg : null; }\n}\n"
  },
  {
    "path": "java/ham_fisted/ITypedReduce.java",
    "content": "package ham_fisted;\n\n\nimport java.util.function.DoubleBinaryOperator;\nimport java.util.function.LongBinaryOperator;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.function.IntConsumer;\nimport java.util.concurrent.ForkJoinPool;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.IReduce;\nimport clojure.lang.IFn;\n\n/**\n *  Typed reductions - a typed extension of clojure.lang.IReduceInit and\n *  java.util.Iterable.forEach.\n */\npublic interface ITypedReduce<E> extends IReduceInit, IReduce {\n  default Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t   ParallelOptions options) {\n    return Reductions.serialParallelReduction(initValFn, rfn, options, this);\n  }\n\n\n  static class Reduce1 implements IFnDef {\n    public boolean first;\n    public IFn rfn;\n    public Reduce1(IFn rf) {\n      this.first = true;\n      this.rfn = rf;\n    }\n    public Object invoke(Object acc, Object v) {\n      if(first) {\n\tfirst = false;\n\treturn v;\n      } else {\n\treturn rfn.invoke(acc,v);\n      }\n    }\n  }\n  default Object reduce(IFn rfn) {\n    Reduce1 reducer = new Reduce1(rfn);\n    Object rv = this.reduce(reducer, null);\n    if(reducer.first)\n      return rfn.invoke();\n    else\n      return rv;\n  }\n\n  //Typed this way in order to match java.util.List's forEach\n  @SuppressWarnings(\"unchecked\")\n  default void forEach(Consumer<? super E> c) {\n    //Reduce is strictly more powerful.  You can define consume in terms of reduce with\n    //full generality but you cannot define reduce in terms of consume.\n    reduce( new IFnDef() {\n\tpublic Object invoke(Object lhs, Object rhs) {\n\t  c.accept((E)rhs);\n\t  return c;\n\t}\n      }, c);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ImmutList.java",
    "content": "package ham_fisted;\n\n\nimport static ham_fisted.ChunkedList.*;\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util.ListIterator;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport clojure.lang.Indexed;\nimport clojure.lang.RT;\nimport clojure.lang.IReduce;\nimport clojure.lang.IKVReduce;\nimport clojure.lang.IFn;\nimport clojure.lang.IHashEq;\nimport clojure.lang.Seqable;\nimport clojure.lang.Reversible;\nimport clojure.lang.ISeq;\nimport clojure.lang.IPersistentVector;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IObj;\nimport clojure.lang.MapEntry;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.Util;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.ITransientVector;\nimport clojure.lang.IFn;\nimport clojure.lang.APersistentVector;\n\n\n\npublic class ImmutList\n  extends APersistentVector\n  implements IMutList, IHashEq, ChunkedListOwner, IPersistentVector,\n\t     IEditableCollection, UpdateValues\n{\n  public final int startidx;\n  public final int nElems;\n  final ChunkedList data;\n  int _hash = 0;\n\n  public static final ImmutList EMPTY = new ImmutList(0, 0, new ChunkedList());\n\n  ImmutList(int sidx, int eidx, ChunkedList d) {\n    startidx = sidx;\n    nElems = eidx - sidx;\n    data = d;\n  }\n  public static IPersistentVector create(boolean owning, IPersistentMap meta, Object... data) {\n    if (data.length <= 32)\n      return ArrayImmutList.create(owning, meta, data);\n    return new ImmutList(0, data.length, ChunkedList.create(owning, meta, data));\n  }\n  final int indexCheck(int idx) {\n    return ChunkedList.indexCheck(startidx, nElems, idx);\n  }\n  final int wrapIndexCheck(int idx) {\n    return ChunkedList.wrapIndexCheck(startidx, nElems, idx);\n  }\n  public ChunkedListSection getChunkedList() {\n    return new ChunkedListSection(data.data, startidx, startidx+nElems);\n  }\n  public final int hashCode() {\n    if (_hash == 0) {\n      _hash = data.hasheq(startidx, startidx+nElems);\n    }\n    return _hash;\n  }\n  public final int hasheq() { return hashCode(); }\n  public final boolean equals(Object other) {\n    if (other == this ) return true;\n    return equiv(other);\n  }\n  public final String toString() { return Transformables.sequenceToString(this); }\n  public final boolean equiv(Object other) {\n    //return CljHash.listEquiv(this, other);\n    return data.equiv(startidx, startidx + nElems, other);\n  }\n  public final int size() { return nElems; }\n  public final int count() { return nElems; }\n  public final int length() { return nElems; }\n  public final void clear() {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean add(Object e) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final void add(int idx, Object e) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean addAll(Collection e) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean addAll(int idx, Collection e) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final Object remove(int idx) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean remove(Object o) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean removeAll(Collection c) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean retainAll(Collection c) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  public final boolean isEmpty() { return nElems == 0; }\n  @SuppressWarnings(\"unchecked\")\n  public final Object set(int idx, Object e) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final Object get(int idx) {\n    return data.getValue(indexCheck(idx));\n  }\n  public final int indexOf(Object obj) {\n    return data.indexOf(startidx, startidx+nElems, obj);\n  }\n  public final int lastIndexOf(Object obj) {\n    return data.lastIndexOf(startidx, startidx+nElems, obj);\n  }\n  public final boolean contains(Object obj) {\n    return data.contains(startidx, startidx+nElems, obj);\n  }\n  public final boolean containsAll(Collection c) {\n    return data.containsAll(startidx, startidx+nElems, c);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final Iterator iterator() {\n    return data.iterator(startidx, startidx + nElems);\n  }\n  public final IMutList subList(int sidx, int eidx) {\n    ChunkedList.sublistCheck(sidx, eidx, nElems);\n    return new ImmutList(sidx+startidx, eidx+startidx, data);\n  }\n  public final Object[] toArray() {\n    return data.toArray(startidx, startidx+nElems);\n  }\n  public final Object[] toArray(Object[] marker) {\n    return data.fillArray(startidx, startidx+nElems, Arrays.copyOf(marker, nElems));\n  }\n  public IPersistentMap meta() { return data.meta(); }\n  public ImmutList withMeta(IPersistentMap m) {\n    return new ImmutList(startidx, startidx+nElems, data.withMeta(m));\n  }\n\n  public final Object nth(int idx) { return data.getValue(wrapIndexCheck(idx)); }\n  public final Object nth(int idx, Object notFound) {\n    if (idx < 0)\n      idx = idx + nElems;\n    return data.getValue(indexCheck(idx));\n  }\n  public final Object invoke(Object idx) {\n    return nth(RT.intCast(idx));\n  }\n  public final Object invoke(Object idx, Object notFound) {\n    return nth(RT.intCast(idx), notFound);\n  }\n  public final Object reduce(IFn f) {\n    return data.reduce(startidx, startidx+nElems, f);\n  }\n  public final Object reduce(IFn f, Object init) {\n    return data.reduce(startidx, startidx+nElems, f, init);\n  }\n  public final Object kvreduce(IFn f, Object init) {\n    return data.kvreduce(startidx, startidx+nElems, f, init);\n  }\n  public final ISeq seq() { return data.seq(startidx, startidx+nElems); }\n  public final ISeq rseq() { return data.rseq(startidx, startidx+nElems); }\n  public final ImmutList cons(Object obj) {\n    return new ImmutList(0, nElems+1, data.conj(startidx, startidx+nElems, obj));\n  }\n  public final ImmutList assocN(int idx, Object obj) {\n    if(idx == nElems)\n      return cons(obj);\n    indexCheck(idx);\n    return new ImmutList(0, nElems, data.assoc(startidx, startidx+nElems, idx, obj));\n  }\n  public final ImmutList assoc(Object idx, Object obj) {\n    return assocN(RT.intCast(idx), obj);\n  }\n  public IMapEntry entryAt(Object key) {\n    return IMutList.super.entryAt(key);\n  }\n  public final boolean containsKey(Object key) {\n    if (Util.isInteger(key)) {\n      final int k = RT.intCast(key);\n      return k >= 0 && k < nElems;\n    }\n    return false;\n  }\n  public final ImmutList empty() {\n    return EMPTY.withMeta(meta());\n  }\n  public final Object valAt(Object obj, Object notFound) {\n    if(Util.isInteger(obj)) {\n      int k = RT.intCast(obj);\n      if (k >= 0 && k < nElems)\n\treturn data.getValue(k + startidx);\n    }\n    return notFound;\n  }\n  public final Object valAt(Object obj) {\n    return valAt(obj, null);\n  }\n  public final ImmutList pop() {\n    if (nElems == 0)\n      throw new RuntimeException(\"Can't pop empty vector\");\n    if (nElems == 1)\n      return EMPTY.withMeta(meta());\n    return new ImmutList(0, nElems-1, data.pop(startidx, startidx+nElems));\n  }\n  public final Object peek() {\n    if (nElems == 0)\n      return null;\n    return get(nElems-1);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public ImmutList updateValues(BiFunction valueMap) {\n    ChunkedList retval = data.clone(startidx, startidx+nElems, 0, true);\n    final Object[][] rd = retval.data;\n    final int ne = nElems;\n    int idx = 0;\n    while (idx < ne) {\n      final Object[] chunk = rd[idx/32];\n      final int csize = Math.min(ne-idx, chunk.length);\n      for (int eidx = 0; eidx < csize; ++eidx, ++idx) {\n\tchunk[eidx] = valueMap.apply(idx, chunk[eidx]);\n      }\n    }\n    return new ImmutList(0, ne, retval);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public ImmutList updateValue(Object key, Function valueMap) {\n    if(!Util.isInteger(key))\n      throw new RuntimeException(\"Vector indexes must be integers: \" + String.valueOf(key));\n    int idx = RT.intCast(key);\n    if (idx == nElems)\n      return cons(valueMap.apply(null));\n\n\n    indexCheck(idx);\n    ChunkedList retval = data.clone(startidx, startidx+nElems, 0, false);\n    final Object[][] mdata = retval.data;\n    final int cidx = idx / 32;\n    final int eidx = idx % 32;\n    Object[] chunk = mdata[cidx].clone();\n    mdata[cidx] = chunk;\n    chunk[eidx] = valueMap.apply(chunk[eidx]);\n    return new ImmutList(0, nElems, retval);\n  }\n\n  public final ITransientVector asTransient() {\n    if(nElems == 0)\n      return new MutList();\n    //We know the cloning operation deep copies if startidx isn't a multiple of 32.\n    final boolean ownsEverything = (startidx % 32) != 0;\n    return new TransientList(data.clone(startidx, startidx + nElems, 0, false),\n\t\t\t     nElems, ownsEverything);\n  }\n\n}\n"
  },
  {
    "path": "java/ham_fisted/ImmutSort.java",
    "content": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.Arrays;\nimport java.util.Comparator;\nimport it.unimi.dsi.fastutil.objects.ObjectArrays;\nimport clojure.lang.RT;\nimport clojure.lang.Util;\n\n\npublic interface ImmutSort<E> extends List<E> {\n\n  @SuppressWarnings(\"unchecked\")\n  public static final Comparator defaultComparator = new Comparator() {\n      public int compare(Object l, Object r) {\n\tif(l == r) return 0;\n\tif(l == null) return -1;\n\tif(r == null) return 1;\n\tClass cls = l.getClass();\n\tif(Comparable.class.isAssignableFrom(cls)\n\t   && cls == r.getClass())\n\t  return ((Comparable)l).compareTo(r);\n\treturn Util.compare(l,r);\n      }\n    };\n  @SuppressWarnings(\"unchecked\")\n  public static List immutSortList(List a, Comparator c) {\n    if(c == null)\n      c = defaultComparator;\n    final Object[] data = a.toArray();\n    if (c != null)\n      Arrays.parallelSort(data, 0, data.length, (Comparator)c);\n    else\n      Arrays.parallelSort(data, 0, data.length, c);\n    return ArrayLists.toList(data, 0, data.length, RT.meta(a));\n  }\n  default List immutSort() { return immutSort(null); }  \n  default List immutSort(Comparator c) {\n    return immutSortList(this, c);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/IndexedConsumer.java",
    "content": "package ham_fisted;\n\n\npublic interface IndexedConsumer {\n  public void accept(long index, Object val);\n}\n"
  },
  {
    "path": "java/ham_fisted/IndexedDoubleConsumer.java",
    "content": "package ham_fisted;\n\n\npublic interface IndexedDoubleConsumer {\n  public void accept(long idx, double val);\n}\n"
  },
  {
    "path": "java/ham_fisted/IndexedLongConsumer.java",
    "content": "package ham_fisted;\n\n\npublic interface IndexedLongConsumer {\n  public void accept(long idx, long val);\n}\n"
  },
  {
    "path": "java/ham_fisted/IntegerOps.java",
    "content": "package ham_fisted;\n\n\n/** \n * Static 32 bit and 64 bit integer operations specific to the bitmap trie.\n */\npublic final class IntegerOps {\n  /** Return the next power of 2 >= value.*/\n  public static final int nextPow2(int value) {\n    int highestOneBit = Integer.highestOneBit(value);\n    if (value == highestOneBit) {\n      return value;\n    }\n    return highestOneBit << 1;\n  }\n  /**\n   * 1. unsigned shifted hash right by shift bits.\n   * 2. return last 5 bits.\n   *\n   * @return A number from 0-31 inclusive.\n   */\n  public static final int mask(int shift, int hash) {\n    \n    return (hash >>> shift) & 0x01f;\n  }\n  /**\n   * @return An integer with 1 bit high that indicates which value\n   * from 0-31 inclusive is indicate by the shifted and masked hash.\n   */\n  public static final int bitpos(int shift, int hash) {\n    return 1 << mask(shift, hash);\n  }\n  /**\n   * @return The number of raised bits in bitmap behind\n   * position bit.  This indicates the index in the node's packed \n   * array where data for this bit should be stored.\n   */\n  public static final int index(int bitmap, int bit){\n    return Integer.bitCount(bitmap & (bit - 1));\n  }\n  /** \n   * @return unchecked shift incremented by 5 to indicate\n   * the next 5 bits of the hashcode should be used for the bitmap.\n   */\n  public static final int incShift(int shift) {\n    return shift + 5;\n  }\n  /** \n   * @return unchecked shift incremented by 5 to indicate\n   * the next 5 bits of the hashcode should be used for the bitmap.\n   */\n  public static final int checkedIncShift(int shift) {\n    if (shift >= 30)\n      throw new RuntimeException(\"Invalid shift amount - already at max shift - \"\n\t\t\t\t + String.valueOf(shift));\n    return shift + 5;\n  }\n  /**\n   * Ripped directly from HashMap.java in openjdk source code -\n   *\n   * Computes key.hashCode() and spreads (XORs) higher bits of hash\n   * to lower.  Because the table uses power-of-two masking, sets of\n   * hashes that vary only in bits above the current mask will\n   * always collide. (Among known examples are sets of Float keys\n   * holding consecutive whole numbers in small tables.)  So we\n   * apply a transform that spreads the impact of higher bits\n   * downward. There is a tradeoff between speed, utility, and\n   * quality of bit-spreading. Because many common sets of hashes\n   * are already reasonably distributed (so don't benefit from\n   * spreading), and because we use trees to handle large sets of\n   * collisions in bins, we just XOR some shifted bits in the\n   * cheapest possible way to reduce systematic lossage, as well as\n   * to incorporate impact of the highest bits that would otherwise\n   * never be used in index calculations because of table bounds.\n   */\n  public static final int mixhash(int h) {\n    return h ^ (h >>> 16);\n  }\n\n  public static final int mixhash(Object key) {\n    return (key == null) ? 0 : mixhash(key.hashCode());\n  }\n\n  /**\n   * Set bits starting at sidx and ending at *but including* eidx.\n   */\n  public static final int highBits(int sidx, int eidx) {\n    int retval = 0;\n    for (int idx = sidx; idx <= eidx; ++idx)\n      retval |= 1 << idx;\n    return retval;\n  }\n\n  /** Untested long versions of some of the above\n  public static final long mask(long hash, long shift) {\n    // Return the last 10 bits of hash right shifted shift bits\n    return (hash >>> shift) & 0x03F;\n  }\n  public static final long bitpos(long hash, long shift) {\n    return 1 << mask(hash, shift);\n  }\n  public static final long index(long bitmap, long bit){\n    return Long.bitCount(bitmap & (bit - 1));\n  }\n  public static final long incShift(long shift) {\n    return shift + 6;\n  }\n  */\n}\n"
  },
  {
    "path": "java/ham_fisted/Iter.java",
    "content": "package ham_fisted;\n\nimport java.util.Iterator;\n\npublic interface Iter {\n  Object get();\n  Iter next();\n\n  public static class IteratorIter implements Iter {\n    public final Iterator iter;\n    Object get;\n    public IteratorIter(Iterator iter) {\n      this.iter = iter;\n      get = iter.next();\n    }\n    public Object get() { return get; }\n    public Iter next() {\n      if(iter.hasNext()) {\n\tget = iter.next();\n\treturn this;\n      }\n      return null;\n    }\n  }\n\n  public static class IterIterator implements Iterator {\n    Iter iter;\n    public IterIterator(Iter iter) {\n      this.iter = iter;\n    }\n    public Iter iter() { return iter; }\n    public boolean hasNext() { return iter != null; }\n    public Object next() {\n      Object rv = iter.get();\n      iter = iter.next();\n      return rv;\n    }\n  }\n\n  public static Iter fromIterator(Iterator iter) {\n    return iter != null && iter.hasNext() ? new IteratorIter(iter) : null;\n  }\n\n  public static Iterator fromIter(Iter iter) {\n    return new IterIterator(iter);\n  }\n\n  public static Iter fromIterable(Iterable iable) {\n    return iable != null ? fromIterator(iable.iterator()) : null;\n  }\n  public static Iter prepend(Object obj, Iter item) {\n    return new Iter() {\n      public Object get() { return obj; }\n      public Iter next() { return item; }\n    };\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LazyChunkedSeq.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.IChunkedSeq;\nimport clojure.lang.IChunk;\nimport clojure.lang.ASeq;\nimport clojure.lang.Util;\nimport clojure.lang.PersistentList;\nimport clojure.lang.ISeq;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ChunkedCons;\nimport clojure.lang.ArrayChunk;\nimport java.util.Iterator;\nimport java.util.Arrays;\nimport java.util.concurrent.locks.Lock;\nimport java.util.concurrent.locks.ReentrantLock;\n\npublic class LazyChunkedSeq extends ASeq implements IChunkedSeq {\n  IFn fn;\n  IChunkedSeq mySeq;\n  Throwable e;\n  volatile Lock lock;\n  public LazyChunkedSeq(IFn fn, IChunkedSeq s, Throwable e, IPersistentMap meta) {\n    super(meta);\n    this.fn = fn;\n    this.mySeq = s;\n    this.e = e;\n    this.lock = new ReentrantLock();\n  }\n  public LazyChunkedSeq(IFn fn) {\n    this(fn, null, null, null);\n  }\n  public LazyChunkedSeq withMeta(IPersistentMap m) { return new LazyChunkedSeq(fn, mySeq, e, m); }\n  IChunkedSeq unlockedUnwrap() {\n    if(fn != null) {\n      try {\n\tmySeq = (IChunkedSeq)fn.invoke();\n      } catch (Exception e) {\n\tthis.e = e;\n      }\n      fn = null;\n      lock = null;\n    }\n    if(this.e != null) throw Util.sneakyThrow(e);\n    return mySeq;\n  }\n  IChunkedSeq lockedUnwrap() {\n    if(mySeq != null) return mySeq;\n    Lock l = lock;\n    if(l != null) {\n      l.lock();\n      try {\n\treturn unlockedUnwrap();\n      }finally {\n\tl.unlock();\n      }\n    }\n    return unlockedUnwrap();\n  }\n  public Object first() {\n    IChunkedSeq s = lockedUnwrap();\n    return s != null ? s.first() : null;\n  }\n  public ISeq next() {\n    IChunkedSeq s = lockedUnwrap();\n    return s != null ? s.next() : null;\n  }\n  public ISeq more() {\n    ISeq rv = next();\n    return rv != null ? rv : PersistentList.EMPTY;\n  }\n  public IChunk chunkedFirst() {\n    IChunkedSeq s = lockedUnwrap();\n    return s != null ? s.chunkedFirst() : null;\n  }\n  public ISeq chunkedNext() {\n    IChunkedSeq s = lockedUnwrap();\n    return s != null ? s.chunkedNext() : null;\n  }\n  public ISeq chunkedMore() {\n    ISeq rv = chunkedNext();\n    return rv != null ? rv : PersistentList.EMPTY;\n  }\n\n  public static IChunkedSeq chunkIteratorSeq(Iterator i) {\n    if(i.hasNext()) {\n      return new LazyChunkedSeq(new IFnDef() {\n\t  public Object invoke() {\n\t    Object[] ar = new Object[32];\n\t    int idx;\n\t    for(idx = 0; idx < 32 && i.hasNext(); ++idx)\n\t      ar[idx] = i.next();\n\t    return new ChunkedCons(new ArrayChunk(ar, 0, idx), chunkIteratorSeq(i));\n\t  }\n\t});\n    } else {\n      return null;\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LinkedHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport java.util.function.BiConsumer;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IDeref;\nimport clojure.lang.IReduceInit;\n\n\npublic class LinkedHashMap extends HashMap {\n  //Most recently modified\n  LinkedHashNode firstLink;\n  //Least recently modified\n  LinkedHashNode lastLink;\n  public LinkedHashMap(IPersistentMap meta) {\n    super(meta);\n  }\n  public LinkedHashMap() {\n    this(null);\n  }\n  public LinkedHashMap(float loadFactor, int initialCapacity,\n\t\t       int length, HashNode[] data,\n\t\t       IPersistentMap meta) {\n    super(loadFactor, initialCapacity, length, data, meta);\n  }\n  public LinkedHashMap clone() {\n    LinkedHashMap rv = new LinkedHashMap(loadFactor, capacity, 0, new HashNode[data.length], meta);\n    final HashNode[] data = this.data;\n    final int mask = this.mask;\n    final HashNode[] newData = rv.data;\n    //Table is already correct size - no need to check resize.\n    for(LinkedHashNode lf = lastLink; lf != null; lf = lf.nextLink) {\n      int idx = lf.hashcode & mask;\n      HashNode loc = newData[idx];\n      HashNode newNode = rv.newNode(lf.k, lf.hashcode, lf.v);\n      newData[idx] = newNode;\n      newNode.nextNode = loc;\n    }\n    return rv;\n  }\n  protected HashNode newNode(Object key, int hc, Object val) {\n    return new LinkedHashNode(this,key,hc,val,null);\n  }\n  protected void inc(HashNode lf) {\n    super.inc(lf);\n    LinkedHashNode hn = (LinkedHashNode)lf;\n    if(lastLink == null)\n      lastLink = hn;\n    hn.prevLink = firstLink;\n    if(firstLink != null)\n      firstLink.nextLink = hn;\n    firstLink = hn;\n  }\n  protected static void removeLink(LinkedHashNode hn) {\n    if (hn.prevLink != null)\n      hn.prevLink.nextLink = hn.nextLink;\n    if(hn.nextLink != null)\n      hn.nextLink.prevLink = hn.prevLink;\n  }\n  protected void dec(HashNode lf) {\n    super.dec(lf);\n    LinkedHashNode hn = (LinkedHashNode)lf;\n    if(hn == firstLink)\n      firstLink = hn.prevLink;\n    if(hn == lastLink)\n      lastLink = hn.nextLink;\n    removeLink(hn);\n    hn.nextLink = hn.prevLink = null;\n  }\n  protected void modify(HashNode n) {\n    // The algorithm below is lightly tested but currently linkedhashmaps only\n    // record insertion and deletion events.\n\n    // LinkedHashNode hn = (LinkedHashNode)n;\n    // if(firstLink != hn) {\n    //   removeLink(hn);\n    //   if(hn == lastLink)\n    // \tlastLink = hn.nextLink;\n    //   hn.prevLink = firstLink;\n    //   hn.nextLink = null;\n\n    //   if(firstLink != null)\n    // \tfirstLink.nextLink = hn;\n    //   hn.prevLink = firstLink;\n    //   firstLink = hn;\n    // }\n  }\n  public static class LinkedIter implements Iterator {\n    LinkedHashNode current;\n    Function<Map.Entry,Object> fn;\n    public LinkedIter(Function<Map.Entry,Object> fn, LinkedHashNode c) { this.current = c; this.fn = fn; }\n    public boolean hasNext() { return current != null; }\n    public Object next() {\n      if(current == null) throw new NoSuchElementException();\n      Object rv = fn.apply(current);\n      current = current.nextLink;\n      return rv;\n    }\n  }\n  public Iterator iterator(Function<Map.Entry,Object> fn) {\n    return new LinkedIter(fn, lastLink);\n  }\n  public Object reduce(IFn rfn, Object acc) {\n    for(LinkedHashNode hn = lastLink; hn != null; hn = hn.nextLink) {\n      acc = rfn.invoke(acc, hn);\n      if(RT.isReduced(acc))\n\treturn ((IDeref)acc).deref();\n    }\n    return acc;\n  }\n  public Object kvreduce(IFn rfn, Object acc) {\n    for(LinkedHashNode hn = lastLink; hn != null; hn = hn.nextLink) {\n      acc = rfn.invoke(acc, hn.k, hn.v);\n      if(RT.isReduced(acc))\n\treturn ((IDeref)acc).deref();\n    }\n    return acc;\n  }\n  public HashMap union(Map o, BiFunction bfn) {\n    // reduce union preserves iteration order over o.\n    if(o instanceof LinkedHashMap) {\n      return reduceUnion(this, (IReduceInit)o, bfn);\n    } else {\n      return super.union(o, bfn);\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LinkedHashNode.java",
    "content": "package ham_fisted;\n\n\npublic class LinkedHashNode extends HashNode {\n  //Less recently modified\n  LinkedHashNode prevLink;\n  //More recently modified\n  LinkedHashNode nextLink;\n  public LinkedHashNode(LinkedHashMap owner, Object _k, int hc, Object _v, LinkedHashNode nn) {\n    super(owner, _k, hc, _v, nn);\n  }\n  public HashNode clone(HashMap nowner) {\n    throw new UnsupportedOperationException(\"LinkedHashNodes cannot clone\");\n  }\n  public HashNode setOwner(HashMap nowner) {\n    if(nowner != owner)\n      throw new RuntimeException(\"LinkedHashMap nodes cannot be structurally shared\");\n    return this;\n  }\n  //Linked node assoc/dissoc are not functional like their counterparts -\n  //they just keep the same signature for use in the set algorithms.\n  public final HashNode assoc(HashMap nowner, Object _k, int hash, Object _v) {\n    if(nowner != owner)\n      throw new RuntimeException(\"LinkedHashMap assoc called in functional pathway\");\n    HashNode retval = this;\n    if (owner.equals(_k,k)) {\n      retval.setValue(_v);\n    } else {\n      if (retval.nextNode != null) {\n\tretval.nextNode = retval.nextNode.assoc(nowner, _k, hash, _v);\n      } else {\n\tretval.nextNode = nowner.newNode(k, hash, _v);\n      }\n    }\n    return retval;\n  }\n  public final HashNode dissoc(HashMap nowner, Object _k) {\n    if(nowner != owner)\n      throw new RuntimeException(\"LinkedHashMap assoc called in functional pathway\");\n    if (owner.equals(k, _k)) {\n      owner.dec(this);\n      return nextNode;\n    }\n    if (nextNode != null) {\n      nextNode = nextNode.dissoc(nowner, _k);\n    }\n    return this;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LongAccum.java",
    "content": "package ham_fisted;\n\n\n\nimport java.util.function.LongConsumer;\nimport clojure.lang.IDeref;\n\n\n\npublic class LongAccum implements LongConsumer, IDeref, Reducible {\n  long val;\n  public LongAccum(long v) { val = v; }\n  public LongAccum() { this(0); }\n  public void accept(long v) { val += v; }\n  public Object deref() { return val; }\n  public LongAccum reduce(Reducible other) {\n    val += ((LongAccum)other).val;\n    return this;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LongHashBase.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util.function.Function;\nimport java.util.function.Consumer;\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IHashEq;\nimport clojure.lang.IMeta;\nimport clojure.lang.IFn;\nimport clojure.lang.IDeref;\nimport clojure.lang.RT;\n\n\npublic class LongHashBase implements IMeta {\n  int capacity;\n  int mask;\n  int length;\n  int threshold;\n  float loadFactor;\n  LongHashNode[] data;\n  IPersistentMap meta;\n  public LongHashBase(float loadFactor, int initialCapacity,\n\t\t      int length, LongHashNode[] data,\n\t\t      IPersistentMap meta) {\n    this.loadFactor = loadFactor;\n    this.capacity = IntegerOps.nextPow2(Math.max(4, initialCapacity));\n    this.mask = this.capacity - 1;\n    this.length = length;\n    this.data = data == null ? new LongHashNode[this.capacity] : data;\n    this.threshold = (int)(capacity * loadFactor);\n    this.meta = meta;\n  }\n  \n  public LongHashBase(LongHashBase other, IPersistentMap m) {\n    this.loadFactor = other.loadFactor;\n    this.capacity = other.capacity;\n    this.mask = other.mask;\n    this.length = other.length;\n    this.data = other.data;\n    this.threshold = other.threshold;\n    this.meta = m;\n  }\n  public int size() { return length; }\n  public int count() { return length; }\n  //protected so clients can override as desired.\n  static int hash(long k) {\n    return IntegerOps.mixhash(Long.hashCode(k));\n  }\n  static boolean equals(long lhs, long rhs) {\n    return lhs == rhs;\n  }\n  protected void inc(LongHashNode lf) { ++this.length; }\n  protected void dec(LongHashNode lf) { --this.length; }\n  protected void modify(LongHashNode lf) {}\n  protected LongHashNode newNode(long key, int hc, Object val) {\n    return new LongHashNode(this,key,hc,val,null);\n  }\n  \n  Object checkResize(Object rv) {\n    if(this.length >= this.threshold) {\n      final int newCap = this.capacity * 2;\n      final LongHashNode[] newD = new LongHashNode[newCap];\n      final LongHashNode[] oldD = this.data;\n      final int oldCap = oldD.length;\n      final int mask = newCap - 1;\n      for(int idx = 0; idx < oldCap; ++idx) {\n\tLongHashNode lf;\n\tif((lf = oldD[idx]) != null) {\n\t  oldD[idx] = null;\n\t  if(lf.nextNode == null) {\n\t    newD[lf.hashcode & mask] = lf;\n\t  } else {\n\t    //https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/HashMap.java#L722\n\t    //Because we only allow capacities that are powers of two, we have\n\t    //exactly 2 locations in the new data array where these can go.  We want\n\t    //to avoid writing to any locations more than once and instead make the\n\t    //at most two new linked lists, one for the new high position and one\n\t    //for the new low position.\n\t    LongHashNode loHead = null, loTail = null, hiHead = null, hiTail = null;\n\t    while(lf != null) {\n\t      LongHashNode e = lf.setOwner(this);\n\t      lf = lf.nextNode;\n\t      //Check high bit\n\t      if((e.hashcode & oldCap) == 0) {\n\t\tif(loTail == null) loHead = e;\n\t\telse loTail.nextNode = e;\n\t\tloTail = e;\n\t      } else {\n\t\tif(hiTail == null) hiHead = e;\n\t\telse hiTail.nextNode = e;\n\t\thiTail = e;\n\t      }\n\t    }\n\t    if(loHead != null) {\n\t      loTail.nextNode = null;\n\t      newD[idx] = loHead;\n\t    }\n\t    if(hiHead != null) {\n\t      hiTail.nextNode = null;\n\t      newD[idx+oldCap] = hiHead;\n\t    }\n\t  }\n\t}\n      }\n      this.capacity = newCap;\n      this.threshold = (int)(newCap * this.loadFactor);\n      this.mask = mask;\n      this.data = newD;\n    }\n    return rv;\n  }\n  public void clear() {\n    for(int idx = 0; idx < data.length; ++idx) {\n      for(LongHashNode lf = data[idx]; lf != null; lf = lf.nextNode) {\n\tdec(lf);\n      }\n    }\n    length = 0;\n    Arrays.fill(data, null);\n  }\n  public IPersistentMap meta() { return meta; }\n  static class HTIter implements Iterator {\n    final LongHashNode[] d;\n    final Function<Map.Entry,Object> fn;\n    LongHashNode l;\n    int idx;\n    final int dlen;\n    HTIter(LongHashNode[] data, Function<Map.Entry,Object> fn) {\n      this.d = data;\n      this.fn = fn;\n      this.l = null;\n      this.idx = 0;\n      this.dlen = d.length;\n      advance();\n    }\n    void advance() {\n      if(l != null)\n\tl = l.nextNode;\n      if(l == null) {\n\tfor(; idx < this.dlen && l == null; ++idx)\n\t  l = this.d[idx];\n      }\n    }\n    public boolean hasNext() { return l != null; }\n    public Object next() {\n      LongHashNode rv = l;\n      advance();\n      return fn.apply(rv);\n    }\n  }\n  static class HTSpliterator implements Spliterator, ITypedReduce {\n    final LongHashNode[] d;\n    final Function<Map.Entry,Object> fn;\n    int sidx;\n    int eidx;\n    int estimateSize;\n    LongHashNode l;\n    public HTSpliterator(LongHashNode[] d, int len, Function<Map.Entry,Object> fn) {\n      this.d = d;\n      this.fn = fn;\n      this.sidx = 0;\n      this.eidx = d.length;\n      this.estimateSize = len;\n      this.l = null;\n    }\n    public HTSpliterator(LongHashNode[] d, int sidx, int eidx, int es, Function<Map.Entry,Object> fn) {\n      this.d = d;\n      this.fn = fn;\n      this.sidx = sidx;\n      this.eidx = eidx;\n      this.estimateSize = es;\n      this.l = null;\n    }\n    public HTSpliterator trySplit() {\n      final int nIdxs = this.eidx - this.sidx;\n      if(nIdxs > 4) {\n\tfinal int idxLen = nIdxs/2;\n\tfinal int oldIdx = this.eidx;\n\tthis.eidx = this.sidx + idxLen;\n\tthis.estimateSize = this.estimateSize / 2;\n\treturn new HTSpliterator(d, this.eidx, oldIdx, this.estimateSize, this.fn);\n      }\n      return null;\n    }\n    public int characteristics() { return Spliterator.DISTINCT | Spliterator.IMMUTABLE | Spliterator.SIZED; }\n    public long estimateSize() { return estimateSize; }\n    public long getExactSizeIfKnown() { return estimateSize(); }\n    @SuppressWarnings(\"unchecked\")\n    public boolean tryAdvance(Consumer c) {\n      if(this.l != null) {\n\tc.accept(this.fn.apply(this.l));\n\tthis.l = this.l.nextNode;\n\treturn true;\n      }\n      for(; sidx < eidx; ++sidx) {\n\tfinal LongHashNode ll = this.d[sidx];\n\tif(ll != null) {\n\t  c.accept(this.fn.apply(ll));\n\t  this.l = ll.nextNode;\n\t  return true;\n\t}\n      }\n      return false;\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      final LongHashNode[] dd = this.d;\n      final int ee = this.eidx;\n      final Function<Map.Entry,Object> ffn = this.fn;\n      for(int idx = sidx; idx < ee; ++idx) {\n\tfor(LongHashNode e = dd[idx]; e != null; e = e.nextNode) {\n\t  acc = rfn.invoke(acc, ffn.apply(e));\n\t  if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t}\n      }\n      return acc;\n    }\n  }\n\n  final boolean containsNodeKey(Object kk) {\n    long key = Casts.longCast(kk);\n    for(LongHashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n      if(e.k == key)\n\treturn true;\n    }\n    return false;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LongHashMap.java",
    "content": "package ham_fisted;\n\n\n\nimport java.util.Map;\nimport java.util.Arrays;\nimport java.util.Iterator;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport java.util.function.Consumer;\nimport java.util.function.BiConsumer;\nimport java.util.Spliterator;\nimport java.util.Objects;\nimport java.util.Set;\nimport java.util.AbstractSet;\nimport java.util.AbstractCollection;\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IHashEq;\nimport clojure.lang.IDeref;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.IMeta;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.MapEntry;\n\n\npublic class LongHashMap extends LongHashBase implements IMap, MapSetOps, UpdateValues {\n  Set keySet = null;\n  public LongHashMap(float loadFactor, int initialCapacity,\n\t\t int length, LongHashNode[] data,\n\t\t IPersistentMap meta) {\n    super(loadFactor, initialCapacity, length, data, meta);\n  }\n  public LongHashMap() {\n    this(0.75f, 0, 0, null, null);\n  }\n  public LongHashMap(IPersistentMap m) {\n    this(0.75f, 0, 0, null, m);\n  }\n  public LongHashMap(LongHashMap other, IPersistentMap m) {\n    super(other, m);\n  }\n\n  public LongHashMap shallowClone() {\n    return new LongHashMap(loadFactor, capacity, length, data.clone(), meta);\n  }\n  public LongHashMap clone() {\n    final int l = data.length;\n    LongHashNode[] newData = new LongHashNode[l];\n    LongHashMap retval = new LongHashMap(loadFactor, capacity, length, newData, meta);\n    for(int idx = 0; idx < l; ++idx) {\n      LongHashNode orig = data[idx];\n      if(orig != null)\n\tnewData[idx] = orig.clone(retval);\n    }\n    return retval;\n  }\n  public int hashCode() {\n    return hasheq();\n  }\n  public int hasheq() {\n    return CljHash.mapHashcode(this);\n  }\n  public  boolean equals(Object o) {\n    return equiv(o);\n  }\n  public boolean equiv(Object o) {\n    return CljHash.mapEquiv(this, o);\n  }\n  public int size() { return this.length; }\n  public boolean isEmpty() { return this.length == 0; }\n  public String toString() {\n    final StringBuilder b =\n      (StringBuilder) reduce(new IFnDef() {\n\t  public Object invoke(Object acc, Object v) {\n\t    final StringBuilder b = (StringBuilder)acc;\n\t    final Map.Entry lf = (Map.Entry)v;\n\t    if(b.length() > 2)\n\t      b.append(\",\");\n\t    return b.append(lf.getKey())\n\t      .append(\" \")\n\t      .append(lf.getValue());\n\t  }\n\t}, new StringBuilder().append(\"{\"));\n    return b.append(\"}\").toString();\n  }\n  public Object put(Object kk, Object val) {\n    long key = Casts.longCast(kk);\n    final int hc = hash(key);\n    final int idx = hc & this.mask;\n    LongHashNode lastNode = null;\n    //Avoid unneeded calls to both equals and checkResize\n    for(LongHashNode e = this.data[idx]; e != null; e = e.nextNode) {\n      lastNode = e;\n      if(e.k == key || equals(e.k, key)) {\n\tObject rv = e.v;\n\te.v = val;\n\tmodify(e);\n\treturn rv;\n      }\n    }\n    LongHashNode lf = newNode(key,hc,val);\n    if(lastNode != null) {\n      lastNode.nextNode = lf;\n    } else {\n      data[idx] = lf;\n    }\n    return checkResize(null);\n  }\n  public void putAll(Map other) {\n    LongHashNode[] d = data;\n    int mask = this.mask;\n    for(Object o: other.entrySet()) {\n      Map.Entry ee = (Map.Entry)o;\n      long k = Casts.longCast(ee.getKey());\n      int hashcode = hash(k);\n      int idx = hashcode & mask;\n      LongHashNode e;\n      for(e = d[idx]; e != null && !(k == e.k); e = e.nextNode);\n      if(e != null) {\n\te.v = ee.getValue();\n      }\n      else {\n\tLongHashNode n = newNode(k, hashcode, ee.getValue());\n\tn.nextNode = d[idx];\n\td[idx] = n;\n\tcheckResize(null);\n\td = data;\n\tmask = this.mask;\n      }\n    }\n  }\n  public Object getOrDefault(Object kk, Object dv) {\n    if(kk instanceof Number) {\n      long key = Casts.longCast(kk);\n      for(LongHashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n\tif(e.k == key)\n\t  return e.v;\n      }\n    }\n    return dv;\n  }\n  public Object get(Object kk) {\n    if(kk instanceof Number) {\n      long key = Casts.longCast(kk);\n      for(LongHashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n\tif(e.k == key)\n\t  return e.v;\n      }\n    }\n    return null;\n  }\n  public IMapEntry entryAt(Object kk) {\n    if(kk instanceof Number) {\n      long key = Casts.longCast(kk);\n      for(LongHashNode e = this.data[hash(key) & this.mask]; e != null; e = e.nextNode) {\n\tif(e.k == key)\n\t  return MapEntry.create(e.k, e.v);\n      }\n    }\n    return null;\n  }\n  public boolean containsKey(Object key) {\n    return containsNodeKey(key);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object compute(Object kk, BiFunction bfn) {\n    long k = Casts.longCast(kk);\n    final int hash = hash(k);\n    final LongHashNode[] d = this.data;\n    final int idx = hash & this.mask;\n    LongHashNode e = d[idx], ee = null;\n    for(; e != null && !(e.k == k || equals(e.k, k)); e = e.nextNode) {\n      ee = e;\n    }\n    Object newV = bfn.apply(k, e == null ? null : e.v);\n    if(e != null) {\n      if(newV != null) {\n\te.v = newV;\n\tmodify(e);\n      }\n      else\n\tremove(k, null);\n    } else if(newV != null) {\n      LongHashNode nn = newNode(k, hash, newV);\n      if(ee != null)\n\tee.nextNode = nn;\n      else\n\td[idx] = nn;\n      checkResize(null);\n    }\n    return newV;\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object computeIfAbsent(Object kk, Function afn) {\n    long k = Casts.longCast(kk);\n    final int hash = hash(k);\n    final LongHashNode[] d = this.data;\n    final int idx = hash & this.mask;\n    LongHashNode e = d[idx], ee = null;\n    for(; e != null && !(e.k == k || equals(e.k, k)); e = e.nextNode) {\n      ee = e;\n    }\n    if(e != null) {\n      return e.v;\n    } else {\n      final Object newv = afn.apply(k);\n      if(newv != null) {\n\tLongHashNode nn = newNode(k, hash, newv);\n\tif(ee != null)\n\t  ee.nextNode = nn;\n\telse\n\t  d[idx] = nn;\n\tcheckResize(null);\n      }\n      return newv;\n    }\n  }\n  public Object remove(Object kk) {\n    long key = Casts.longCast(kk);\n    int loc = hash(key) & this.mask;\n    LongHashNode lastNode = null;\n    for(LongHashNode e = this.data[loc]; e != null; e = e.nextNode) {\n      if(e.k == key) {\n\tdec(e);\n\tif(lastNode != null)\n\t  lastNode.nextNode = e.nextNode;\n\telse\n\t  this.data[loc] = e.nextNode;\n\treturn e.getValue();\n      }\n      lastNode = e;\n    }\n    return null;\n  }\n  public Object reduce(IFn rfn, Object acc) {\n    final int l = data.length;\n    LongHashNode[] d = data;\n    for(int idx = 0; idx < l; ++idx) {\n      for(LongHashNode e = d[idx]; e != null; e = e.nextNode) {\n\tacc = rfn.invoke(acc, e);\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n    }\n    return acc;\n  }\n  public Object kvreduce(IFn rfn, Object acc) {\n    final int l = data.length;\n    LongHashNode[] d = data;\n    for(int idx = 0; idx < l; ++idx) {\n      for(LongHashNode e = d[idx]; e != null; e = e.nextNode) {\n\tacc = rfn.invoke(acc, e.k, e.v);\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n    }\n    return acc;\n  }\n  public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t  ParallelOptions options ) {\n    return Reductions.parallelCollectionReduction(initValFn, rfn, mergeFn, this.entrySet(), options);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public void replaceAll(BiFunction bfn) {\n    final int l = data.length;\n    for(int idx = 0; idx < l; ++idx) {\n      LongHashNode lastNode = null;\n      for(LongHashNode e = this.data[idx]; e != null; e = e.nextNode) {\n\tObject newv = bfn.apply(e.k, e.v);\n\tif(newv != null) {\n\t  e.v = newv;\n\t  lastNode = e;\n\t}\n\telse {\n\t  dec(e);\n\t  if(lastNode != null) {\n\t    lastNode.nextNode = e.nextNode;\n\t  } else {\n\t    data[idx] = e.nextNode;\n\t  }\n\t}\n      }\n    }\n  }\n\n  public Set keySet() {\n    if(this.keySet  == null )\n      this.keySet = IMap.super.keySet();\n    return this.keySet;\n   }\n\n  @SuppressWarnings(\"unchecked\")\n  public static LongHashMap union(LongHashMap rv, Map o, BiFunction bfn) {\n    LongHashNode[] rvd = rv.data;\n    int mask = rv.mask;\n    for(Object ee : o.entrySet()) {\n      Map.Entry lf = (Map.Entry)ee;\n      final long k = Casts.longCast(lf.getKey());\n      final int hashcode = rv.hash(k);\n      final int rvidx = hashcode & mask;\n      LongHashNode init = rvd[rvidx], e = init;\n      for(;e != null && !(e.k==k || rv.equals(e.k, k)); e = e.nextNode);\n      if(e != null) {\n\trvd[rvidx] = init.assoc(rv, k, hashcode, bfn.apply(e.v, lf.getValue()));\n      }\n      else {\n\tif(init != null)\n\t  rvd[rvidx] = init.assoc(rv, k, hashcode, lf.getValue());\n\telse\n\t  rvd[rvidx] = rv.newNode(k, hashcode, lf.getValue());\n\trv.checkResize(null);\n\tmask = rv.mask;\n\trvd = rv.data;\n      }\n    }\n    return rv;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public LongHashMap union(Map o, BiFunction bfn) {\n    return union(this, o, bfn);\n  }\n  @SuppressWarnings(\"unchecked\")\n  static LongHashMap intersection(LongHashMap rv, Map o, BiFunction bfn) {\n    final LongHashNode[] rvd = rv.data;\n    final int ne = rvd.length;\n    for (int idx = 0; idx < ne; ++idx) {\n      LongHashNode lf = rvd[idx];\n      while(lf != null) {\n\tfinal LongHashNode curlf = lf;\n\tlf = lf.nextNode;\n\tfinal Object v = o.get(curlf.k);\n\trvd[idx] = (v != null)\n\t  ? rvd[idx].assoc(rv, curlf.k, curlf.hashcode, bfn.apply(curlf.v, v))\n\t  : rvd[idx].dissoc(rv, curlf.k);\n      }\n    }\n    return rv;\n  }\n\n\n  public LongHashMap intersection(Map o, BiFunction bfn) {\n    return intersection(this, o, bfn);\n  }\n\n  public static LongHashMap intersection(LongHashMap rv, Set o) {\n    final LongHashNode[] rvd = rv.data;\n    final int ne = rvd.length;\n    for (int idx = 0; idx < ne; ++idx) {\n      LongHashNode lf = rvd[idx];\n      while(lf != null) {\n\tfinal LongHashNode curlf = lf;\n\tfinal long k = curlf.k;\n\tlf = lf.nextNode;\n\tif(!o.contains(k))\n\t  rvd[idx] = rvd[idx].dissoc(rv,k);\n      }\n    }\n    return rv;\n  }\n  public LongHashMap intersection(Set o) {\n    return intersection(this, o);\n  }\n\n\n  @SuppressWarnings(\"unchecked\")\n  static LongHashMap difference(LongHashMap rv, Collection o) {\n    final LongHashNode[] rvd = rv.data;\n    final int mask = rv.mask;\n    for (Object kk : o) {\n      long k = Casts.longCast(kk);\n      final int hashcode = rv.hash(k);\n      final int rvidx = hashcode & mask;\n      LongHashNode e = rvd[rvidx];\n      for(;e != null && !(e.k==k); e = e.nextNode);\n      if(e != null) {\n\trvd[rvidx] = rvd[rvidx].dissoc(rv, e.k);\n      }\n    }\n    return rv;\n  }\n\n  public LongHashMap difference(Collection o) {\n    return difference(this, o);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  static LongHashMap updateValues(LongHashMap rv, BiFunction valueMap) {\n    final LongHashNode[] d = rv.data;\n    final int nl = d.length;\n    for(int idx = 0; idx < nl; ++idx) {\n      LongHashNode lf = d[idx];\n      while(lf != null) {\n\tLongHashNode cur = lf;\n\tlf = lf.nextNode;\n\tObject newv = valueMap.apply(cur.k, cur.v);\n\td[idx] = newv == null ? d[idx].dissoc(rv, cur.k) :\n\t  d[idx].assoc(rv, cur.k, cur.hashcode, newv);\n      }\n    }\n    return rv;\n  }\n  public LongHashMap updateValues(BiFunction valueMap) {\n    return updateValues(this, valueMap);\n  }\n  @SuppressWarnings(\"unchecked\")\n  static LongHashMap updateValue(LongHashMap rv, Object kk, Function fn) {\n    long k = Casts.longCast(kk);\n    final int hc = rv.hash(k);\n    final int idx = hc & rv.mask;\n    final LongHashNode[] data = rv.data;\n    LongHashNode e = data[idx];\n    for(; e != null && !((e.k == k)); e = e.nextNode);\n    final Object newv = e != null ? fn.apply(e.v) : fn.apply(null);\n    data[idx] = newv == null ? data[idx].dissoc(rv, k) : data[idx].assoc(rv, k, hc, newv);\n    if(newv != null && e == null) rv.checkResize(null);\n    return rv;\n  }\n\n  public LongHashMap updateValue(Object k, Function fn) {\n    return updateValue(this, fn);\n  }\n\n  public Iterator iterator(Function<Map.Entry,Object> leafFn) {\n    return new HTIter(this.data, leafFn);\n  }\n  public Spliterator spliterator(Function<Map.Entry,Object> leafFn) { return new HTSpliterator(this.data, this.length, leafFn); }\n}\n"
  },
  {
    "path": "java/ham_fisted/LongHashNode.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Iterator;\nimport clojure.lang.IMapEntry;\nimport ham_fisted.IMutList;\n\npublic class LongHashNode implements Map.Entry, IMutList, IMapEntry {\n  public final LongHashBase owner;\n  public final int hashcode;\n  public final long k;\n  //compute-at support means we can modify v.\n  Object v;\n  LongHashNode nextNode;\n\n  public LongHashNode(LongHashBase _owner, long _k, int hc, Object _v, LongHashNode nn) {\n    owner = _owner;\n    hashcode = hc;\n    k = _k;\n    v = _v;\n    nextNode = nn;\n    _owner.inc(this);\n  }\n  public LongHashNode(LongHashBase _owner, long _k, int hc, Object _v) {\n    this(_owner, _k, hc, _v, null);\n  }\n  public LongHashNode(LongHashBase _owner, long _k, int hc) {\n    this(_owner, _k, hc, null, null);\n  }\n  LongHashNode(LongHashBase _owner, LongHashNode prev) {\n    owner = _owner;\n    hashcode = prev.hashcode;\n    k = prev.k;\n    v = prev.v;\n    nextNode = prev.nextNode;\n  }\n  public LongHashNode setOwner(LongHashBase nowner) {\n    if (owner == nowner)\n      return this;\n    return new LongHashNode(nowner, this);\n  }\n  public LongHashNode clone(LongHashBase nowner) {\n    LongHashNode rv = new LongHashNode(nowner, this);\n    if(nextNode != null)\n      rv.nextNode = nextNode.clone(nowner);\n    return rv;\n  }\n  public final Object key() { return k; }\n  public final Object val() { return v; }\n  public final Object getKey() { return k; }\n  public final Object getValue() { return v; }\n  public Object setValue(Object vv) { Object rv = v; v = vv; return rv; }\n  public final int size() { return 2; }\n  public final Object get(int idx) {\n    if(idx == 0) return k;\n    if(idx == 1) return v;\n    throw new RuntimeException(\"Index out of range.\");\n  }\n  public LongHashNode assoc(LongHashBase nowner, long _k, int hash, Object _v) {\n    LongHashNode retval = setOwner(nowner);\n    if (k == _k) {\n      retval.setValue(_v);\n    } else {\n      if (retval.nextNode != null) {\n\tretval.nextNode = retval.nextNode.assoc(nowner, _k, hash, _v);\n      } else {\n\tretval.nextNode = nowner.newNode(_k, hash, _v);\n      }\n    }\n    return retval;\n  }\n  public LongHashNode dissoc(LongHashBase nowner, long _k) {\n    if (k == _k) {\n      nowner.dec(this);\n      return nextNode;\n    }\n    if (nextNode != null) {\n      LongHashNode nn = nextNode.dissoc(nowner,_k);\n      if (nn != nextNode) {\n\tLongHashNode retval = setOwner(nowner);\n\tretval.nextNode = nn;\n\treturn retval;\n      }\n    }\n    return this;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/LongMutList.java",
    "content": "package ham_fisted;\n\nimport java.util.Random;\nimport java.util.List;\nimport java.util.Comparator;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.Spliterator;\nimport it.unimi.dsi.fastutil.longs.LongArrays;\nimport it.unimi.dsi.fastutil.longs.LongComparator;\nimport it.unimi.dsi.fastutil.ints.IntComparator;\nimport java.util.function.LongConsumer;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\n\n@SuppressWarnings(\"unchecked\")\npublic interface LongMutList extends IMutList<Object> {\n  default boolean add(Object obj) { addLong(Casts.longCast(obj)); return true; }\n  default void add(int idx, int count, Object v) {\n    long d = Casts.longCast(v);\n    int end = idx + count;\n    for(; idx < end; ++idx) addLong( d );\n  }\n  default void addLong(long v) { throw new RuntimeException(\"Object \" + String.valueOf(getClass()) + \" failed to define addLong method\"); }\n  default void addBoolean( boolean obj ) { addLong(obj ? 1 : 0); }\n  default void addDouble(double obj) { addLong(Casts.longCast(obj));}\n  @SuppressWarnings(\"unchecked\")\n  default Object set(int idx, Object obj) { final long v = getLong(idx); setLong(idx, Casts.longCast(obj)); return v; }\n  default void setBoolean(int idx, boolean obj) { setLong(idx, obj ? 1 : 0); }\n  default void setDouble(int idx, double obj) { setLong(idx, Casts.longCast(obj)); }\n  default Object get(int idx) { return getLong(idx); }\n  default double getDouble(int idx) { return getLong(idx); }\n  default void fillRange(long startidx, final long endidx, Object v) {\n    ChunkedList.checkIndexRange(0, size(), startidx, endidx);\n    long l = Casts.longCast(v);\n    final int ee = (int)endidx;\n    int ss = (int)startidx;\n    for(; ss < ee; ++ss) {\n      setLong(ss, l);\n    }\n  }\n  static class LongSubList extends IMutList.MutSubList<Object> implements LongMutList {\n    @SuppressWarnings(\"unchecked\")\n    public LongSubList(IMutList l, int ss, int ee) {\n      super(l, ss, ee);\n    }\n    public Object reduce(IFn rfn, Object init) { return LongMutList.super.reduce(rfn, init); }\n  }\n  default IMutList<Object> subList(int ssidx, int seidx) {\n    ChunkedList.sublistCheck(ssidx, seidx, size());\n    return new LongSubList(this, ssidx, seidx);\n  }\n  default void fillRange(final long startidx, List l) {\n    if (l.isEmpty())\n      return;\n    final int ss = (int)startidx;\n    final int sz = size();\n    final int endidx = ss + l.size();\n    ArrayLists.checkIndexRange(size(), ss, endidx);\n    Reductions.serialReduction(new Reductions.IndexedLongAccum(new IFnDef.OLLO() {\n\tpublic Object invokePrim(Object acc, long idx, long v) {\n\t  ((IMutList)acc).setLong((int)idx+ss, v);\n\t  return acc;\n\t}\n      }), this, l);\n  }\n  default void addRange(int startidx, int endidx, Object v) {\n    Long l = Long.valueOf(Casts.longCast(v));\n    for(; startidx < endidx; ++startidx) {\n      add(startidx, l);\n    }\n  }\n\n  default boolean addAllReducible(Object obj) {\n    final int sz = size();\n    Reductions.serialReduction(new IFnDef.OLO() {\n\tpublic Object invokePrim(Object lhs, long rhs) {\n\t  ((IMutList)lhs).addLong(rhs);\n\t  return lhs;\n\t}\n      }, this, obj);\n    return sz != size();\n  }\n\n  default IntComparator indexComparator() {\n    return new IntComparator() {\n      public int compare(int lidx, int ridx) {\n\treturn Long.compare(getLong(lidx), getLong(ridx));\n      }\n    };\n  }\n\n  default void sort(Comparator<? super Object> c) {\n    LongComparator lc = ArrayLists.LongArraySubList.asLongComparator(c);\n    if (c == null || lc != null) {\n      final long[] data = toLongArray();\n      if(c == null)\n\tLongArrays.parallelQuickSort(data);\n      else\n\tLongArrays.parallelQuickSort(data, lc);\n      fillRange(0, ArrayLists.toList(data));\n    } else {\n      IMutList.super.sort(c);\n    }\n  }\n  default void shuffle(Random r) {\n    fillRange(0, immutShuffle(r));\n  }\n  default List immutShuffle(Random r) {\n    final long[] data = toLongArray();\n    LongArrays.shuffle(data, r);\n    return ArrayLists.toList(data);\n  }\n\n  default Object reduce(final IFn rfn, Object init) {\n    return longReduction(Transformables.toLongReductionFn(rfn), init);\n  }\n  default Object longReduction(IFn.OLO rfn, Object init) {\n    final int sz = size();\n    for (int idx = 0; idx < sz && !RT.isReduced(init); ++idx)\n      init = rfn.invokePrim(init, getLong(idx));\n    return Reductions.unreduce(init);\n  }\n  @SuppressWarnings(\"unchecked\")\n  default Spliterator spliterator() {\n    return new RandomAccessSpliterator.LongSpliterator(this, 0, size());\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/MapFn.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.ISeq;\n\npublic class MapFn implements IFnDef {\n  public static IFn create(IFn src, IFn dst) {\n    if(src instanceof IFn.OD && dst instanceof IFn.DD) {\n      final IFn.OD ss = (IFn.OD)src;\n      final IFn.DD dd = (IFn.DD)dst;\n      return new IFnDef.OD() {\n\tpublic double invokePrim(Object obj) {\n\t  return dd.invokePrim(ss.invokePrim(obj));\n\t}\n      };\n    }\n    else if (src instanceof IFn.OL && dst instanceof IFn.LL) {\n      final IFn.OL ss = (IFn.OL)src;\n      final IFn.LL dd = (IFn.LL)dst;\n      return new IFnDef.OL() {\n\tpublic long invokePrim(Object obj) {\n\t  return dd.invokePrim(ss.invokePrim(obj));\n\t}\n      };\n    } else if( src instanceof IFn.LL && dst instanceof IFn.LL) {\n      final IFn.LL ss = (IFn.LL)src;\n      final IFn.LL dd = (IFn.LL)dst;\n      return new IFnDef.LL() {\n\tpublic long invokePrim(long v) {\n\t  return dd.invokePrim(ss.invokePrim(v));\n\t}\n      };\n    }\n    else if( src instanceof IFn.DD && dst instanceof IFn.DD) {\n      final IFn.DD ss = (IFn.DD)src;\n      final IFn.DD dd = (IFn.DD)dst;\n      return new IFnDef.DD() {\n\tpublic double invokePrim(double v) {\n\t  return dd.invokePrim(ss.invokePrim(v));\n\t}\n      };\n    } else if( src instanceof IFn.DL && dst instanceof IFn.LL) {\n      final IFn.DL ss = (IFn.DL)src;\n      final IFn.LL dd = (IFn.LL)dst;\n      return new IFnDef.DL() {\n\tpublic long invokePrim(double v) {\n\t  return dd.invokePrim(ss.invokePrim(v));\n\t}\n      };\n    }\n    else if( src instanceof IFn.LD && dst instanceof IFn.DD) {\n      final IFn.LD ss = (IFn.LD)src;\n      final IFn.DD dd = (IFn.DD)dst;\n      return new IFnDef.LD() {\n\tpublic double invokePrim(long v) {\n\t  return dd.invokePrim(ss.invokePrim(v));\n\t}\n      };\n    }\n    //Fallthrough, no special treatment\n    return new MapFn(src, dst);\n  }\n\n  public final IFn srcFn;\n  public final IFn dstFn;\n  private MapFn(IFn sfn, IFn dfn) {\n    srcFn = sfn;\n    dstFn = dfn;\n  }\n\n  public Object invoke() {\n    return dstFn.invoke(srcFn.invoke());\n  }\n\n  public Object invoke(Object arg1) {\n    return dstFn.invoke(srcFn.invoke(arg1));\n  }\n\n  public Object invoke(Object arg1, Object arg2) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7)\n  {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13)\n  {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14)\n  {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15, arg16));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15, arg16, arg17));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18, Object arg19) {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19));\n  }\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20)\n  {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20));\n  }\n\n\n  public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7,\n\t\t       Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14,\n\t\t       Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20,\n\t\t       Object... args)\n  {\n    return dstFn.invoke(srcFn.invoke(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,\n\t\t\t\t     arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19, arg20,\n\t\t\t\t     args));\n  }\n  public Object applyTo(ISeq args) {\n    return dstFn.invoke(srcFn.invoke(args));\n  }\n\n}\n"
  },
  {
    "path": "java/ham_fisted/MapForward.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Iterator;\nimport java.util.Spliterator;\nimport java.util.Set;\nimport java.util.Collection;\nimport java.util.function.BiFunction;\nimport java.util.function.Function;\nimport java.util.function.Consumer;\nimport java.util.function.BiConsumer;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.ITransientAssociative2;\nimport clojure.lang.IMeta;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\nimport clojure.lang.IObj;\nimport clojure.lang.ILookup;\nimport clojure.lang.IHashEq;\nimport clojure.lang.Counted;\nimport clojure.lang.IKVReduce;\nimport clojure.lang.MapEquivalence;\nimport clojure.lang.IMapIterable;\nimport clojure.lang.Seqable;\nimport clojure.lang.ISeq;\nimport clojure.lang.RT;\nimport clojure.lang.MapEntry;\nimport clojure.lang.IMapEntry;\n\n\npublic class MapForward<K,V>\n  implements Map<K,V>, ITypedReduce, IFnDef, IHashEq, ILookup, Counted,\n\t     IMeta, IObj, IKVReduce, MapEquivalence, Seqable {\n  final Map<K,V> ht;\n  final IPersistentMap meta;\n\n  public MapForward(Map<K,V> ht, IPersistentMap meta) { this.ht = ht; this.meta = meta; }\n  public void clear() { ht.clear(); }\n  public V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) {\n    return ht.compute(key, remappingFunction);\n  }\n  public V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) {\n    return ht.computeIfPresent(key, remappingFunction);\n  }\n  public V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) {\n    return ht.computeIfAbsent(key, mappingFunction);\n  }\n  public boolean containsKey(Object key) { return ht.containsKey(key); }\n  public boolean containsValue(Object v) { return ht.containsValue(v); }\n  public Set<Map.Entry<K,V>> entrySet() { return ht.entrySet(); }\n  public boolean equals(Object o) {\n    return CljHash.mapEquiv(ht, o);\n  }\n  public boolean equiv(Object o) { return equals(o); }\n  public void forEach(BiConsumer<? super K,? super V> action) {\n    ht.forEach(action);\n  }\n  public V get(Object k) { return ht.get(k); }\n  public V getOrDefault(Object k, V dv) { return ht.getOrDefault(k, dv); }\n  public int hashCode() { return CljHash.mapHashcode(ht); }\n  public int hasheq() { return hashCode(); }\n  public boolean isEmpty() { return ht.isEmpty(); }\n  public Set<K> keySet() { return ht.keySet(); }\n  public V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) {\n    return ht.merge(key, value, remappingFunction);\n  }\n  public V put(K key, V value) { return ht.put(key, value); }\n  public void putAll(Map<? extends K,? extends V> m) { ht.putAll(m); }\n  public V putIfAbsent(K key, V value) { return ht.putIfAbsent(key, value); }\n  public V remove(Object k) { return ht.remove(k); }\n  public boolean remove(Object key, Object value) { return ht.remove(key,value); }\n  public V replace(K key, V value) { return ht.replace(key, value); }\n  public boolean replace(K key, V oldValue, V newValue) {\n    return ht.replace(key, oldValue, newValue);\n  }\n  public void replaceAll(BiFunction<? super K,? super V,? extends V> function) {\n    ht.replaceAll(function);\n  }\n  public int size() { return ht.size(); }\n  public int count() { return ht.size(); }\n  public Collection<V> values() { return ht.values(); }\n  public Iterator iterator() {\n    return entrySet().iterator();\n  }\n  public Iterator keyIterator() { return keySet().iterator(); }\n  public Iterator valIterator() { return values().iterator(); }\n  public Object reduce(IFn rfn, Object acc) {\n    return Reductions.serialReduction(rfn, acc, entrySet());\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final IMapEntry entryAt(Object key) {\n    return containsKey(key) ? new MapEntry(key, get(key)) : null;\n  }\n  public Object valAt(Object key) {\n    return get(key);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object valAt(Object key, Object notFound) {\n    return getOrDefault(key, (V)notFound);\n  }\n  public final Object invoke(Object arg1) {\n    return get(arg1);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final Object invoke(Object arg1, Object notFound) {\n    return getOrDefault(arg1, (V)notFound);\n  }\n  public ISeq seq() {\n    return LazyChunkedSeq.chunkIteratorSeq(iterator());\n  }\n  public IPersistentMap meta() { return meta; }\n  public MapForward<K,V> withMeta(IPersistentMap m) { return new MapForward<K,V>(ht, m); }\n  @SuppressWarnings(\"unchecked\")\n  public Object kvreduce(IFn f, Object init) {\n    return reduce(new IFnDef() {\n\tpublic Object invoke(Object acc, Object v) {\n\t  final Map.Entry me = (Map.Entry)v;\n\t  return f.invoke(acc, me.getKey(), me.getValue());\n\t}\n      }, init);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/MapSetOps.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Collection;\nimport java.util.function.BiFunction;\n\n\npublic interface MapSetOps {\n  Map union(Map rhs, BiFunction bfn);\n  //Trim to these key-values, apply bfn to resolve vals.\n  Map intersection(Map rhs, BiFunction bfn);\n  //Trim to these keys\n  Map intersection(Set rhs);\n  default Map difference(Map rhs) { return difference(rhs.keySet()); }\n  Map difference(Collection rhs);\n}\n"
  },
  {
    "path": "java/ham_fisted/MergeIterator.java",
    "content": "package ham_fisted;\n\nimport java.util.Iterator;\nimport java.util.Comparator;\nimport java.util.ArrayList;\nimport java.util.function.Predicate;\nimport java.util.PriorityQueue;\nimport java.util.NoSuchElementException;\n\n\npublic class MergeIterator implements Iterator {\n  public static class CurrentIterator implements Iterator {\n    public static final Object invalid = new Object();\n    Object current;\n    Iterator iter;\n    public CurrentIterator(Iterator iter) {\n      this.iter = iter;\n      this.current = invalid;\n    }\n    public CurrentIterator(Iterator iter, Object cur) {\n      this.iter = iter;\n      this.current = cur;\n    }\n    public boolean hasNext() { return iter.hasNext(); }\n    public Object next() {\n      return current = iter.next();\n    }\n    public Object current() { return current; }\n    public boolean hasCurrent() { return current != invalid; }\n    public static CurrentIterator create(Iterator iter) {\n      if(iter.hasNext())\n\treturn new CurrentIterator(iter, iter.next());\n      return null;\n    }\n  }\n\n  java.util.Comparator cmp;\n  CurrentIterator[] iters;\n  int curIdx;\n  Predicate p;\n  @SuppressWarnings(\"unchecked\")\n  int leastIndex() {\n    int nIters = iters.length;\n    if(nIters <= 1) return 0;\n    Object leastv = iters[0].current();\n    int leastIdx = 0;\n    //Potential for binary search here I guess\n    for(int idx = 1; idx < nIters; ++idx) {\n      Object cur = iters[idx].current();\n      if (cmp.compare(leastv, cur) > -1) {\n\tleastv = cur;\n\tleastIdx = idx;\n      }\n    }\n    return leastIdx;\n  }\n  public MergeIterator(CurrentIterator[] iters, Comparator cmp, Predicate p) {\n    this.iters = iters;\n    this.p = p;\n    this.cmp = cmp;\n    curIdx = leastIndex();\n  }\n  public boolean hasNext() {\n    return iters.length != 0;\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object next() {\n    Object rv = null;\n    do {\n      if(iters.length == 0) return null;\n      CurrentIterator iter = iters[curIdx];\n      rv = iter.current();\n      if(iter.hasNext()) {\n\titer.next();\n      } else {\n\tint ne = iters.length;\n\tCurrentIterator[] newIters = new CurrentIterator[ne-1];\n\tfor(int idx = 0; idx < ne; ++ idx) {\n\t  if(idx < curIdx) {\n\t    newIters[idx] = iters[idx];\n\t  } else if (idx > curIdx) {\n\t    newIters[idx-1] = iters[idx];\n\t  }\n\t}\n\titers = newIters;\n      }\n      curIdx = leastIndex();\n    } while(!p.test(rv));\n    return rv;\n  }\n  public static final Iterator emptyIter = new Iterator() {\n      public boolean hasNext() { return false; }\n      public Object next() { throw new java.util.NoSuchElementException(); }\n    };\n  public static class TwoWayMergeIterator implements Iterator {\n    CurrentIterator lhs;\n    CurrentIterator rhs;\n    Comparator cmp;\n    Predicate p;\n    boolean left;\n    @SuppressWarnings(\"unchecked\")\n    public TwoWayMergeIterator(CurrentIterator lhs, CurrentIterator rhs, Comparator cmp, Predicate p) {\n      this.lhs = lhs;\n      this.rhs = rhs;\n      this.cmp = cmp;\n      this.p = p;\n      this.left = cmp.compare(lhs.current(), rhs.current()) < 0 ? true : false;\n    }\n    public boolean hasNext() {\n      return lhs != null || rhs != null;\n    }\n    @SuppressWarnings(\"unchecked\")\n    public Object next() {\n      if(lhs == null && rhs == null)\n\tthrow new java.util.NoSuchElementException();\n      Object rv;\n      do {\n\tCurrentIterator update = left ? lhs : rhs;\n\tif(update == null) return null;\n\trv = update.current();\n\tif(update.hasNext()) {\n\t  update.next();\n\t} else {\n\t  if(left) lhs = null; else rhs = null;\n\t}\n\tif(lhs == null) left = false;\n\telse if (rhs == null) left = true;\n\telse left = cmp.compare(lhs.current(), rhs.current()) < 0 ? true : false;\n      } while(!p.test(rv));\n      return rv;\n    }\n    public static Iterator create(Iterator lhs, Iterator rhs, Comparator cmp) {\n      return new TwoWayMergeIterator(new CurrentIterator(lhs, lhs.next()),\n\t\t\t\t     new CurrentIterator(rhs, rhs.next()),\n\t\t\t\t     cmp, MergeIterator.alwaysTrue);\n    }\n  }\n  public static class PriorityQueueIterator implements Iterator {\n    PriorityQueue pq;\n    Predicate p;\n    public PriorityQueueIterator(PriorityQueue pq, Predicate p) {\n      this.pq = pq;\n      this.p = p;\n    }\n    public boolean hasNext() {\n      return !pq.isEmpty();\n    }\n    @SuppressWarnings(\"unchecked\")\n    public Object next() {\n      if(pq.isEmpty()) throw new NoSuchElementException();\n      while(true) {\n\tif(pq.isEmpty()) return null;\n\tfinal Object[] entry = (Object[])pq.poll();\n\tIterator iter = (Iterator)entry[0];\n\tObject rv = entry[1];\n\tif(iter.hasNext()) {\n\t  entry[1] = iter.next();\n\t  pq.offer(entry);\n\t}\n\tif(p.test(rv)) return rv;\n      }\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static Iterator create(Iterable<Iterator> srcIters, Comparator cmp, Predicate p) {\n      Comparator pqCmp = new Comparator() {\n\t  public int compare(Object lhs, Object rhs) {\n\t    return cmp.compare(((Object[])lhs)[1],((Object[])rhs)[1]);\n\t  }\n\t};\n      PriorityQueue pq = new PriorityQueue(pqCmp);\n      for(Iterator iter : srcIters) {\n\tif(iter != null && iter.hasNext())\n\t  pq.offer(new Object[] {iter, iter.next()});\n      }\n      return new PriorityQueueIterator(pq, p);\n    }\n    public static Iterator create(Iterable<Iterator> srcIters, Comparator cmp) {\n      return create(srcIters, cmp, alwaysTrue);\n    }\n  }\n  @SuppressWarnings(\"unchecked\")\n  public static final Iterator createMergeIterator(Iterable<Iterator> srcIters, Comparator cmp, Predicate p) {\n    ArrayList<Iterator> validIters = new ArrayList<Iterator>();\n    for(Iterator iter : srcIters) {\n      if(iter != null && iter.hasNext()) {\n\tvalidIters.add(iter);\n      }\n    }\n    if(validIters.isEmpty())\n      return emptyIter;\n    if(validIters.size() >= 8) {\n      return PriorityQueueIterator.create(validIters, cmp, p);\n    }\n    CurrentIterator[] iters = new CurrentIterator[validIters.size()];\n    for(int idx = 0; idx < iters.length; ++idx) {\n      Iterator iter = validIters.get(idx);\n      iters[idx] = new CurrentIterator(iter, iter.next());\n    }\n    if(validIters.size() == 2)\n      return new TwoWayMergeIterator(iters[0], iters[1], cmp, p);\n    else\n      return new MergeIterator(iters, cmp, p);\n  }\n  public static final Predicate alwaysTrue = new Predicate() { public boolean test(Object o){ return true; } };\n  public static Iterator createMergeIterator(Iterable<Iterator> srcIters, Comparator cmp) {\n    return createMergeIterator(srcIters, cmp, alwaysTrue);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/MethodImplCache.java",
    "content": "/**\n *   Copyright (c) Rich Hickey. All rights reserved.\n *   The use and distribution terms for this software are covered by the\n *   Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)\n *   which can be found in the file epl-v10.html at the root of this distribution.\n *   By using this software in any fashion, you are agreeing to be bound by\n * \t the terms of this license.\n *   You must not remove this notice, or any other, from this software.\n **/\n\n/* rich Nov 8, 2009 */\n/* Heavily modified by Chris Nuernberger - Dec 23, 2023 */\n\npackage ham_fisted;\n\nimport java.util.HashMap;\nimport java.util.Set;\nimport java.util.concurrent.locks.ReentrantLock;\nimport java.util.concurrent.ConcurrentHashMap;\nimport clojure.lang.IFn;\nimport clojure.lang.Keyword;\n\npublic final class MethodImplCache {\n  final ReentrantLock extLock = new ReentrantLock();\n  \n  //Sparse table of class to ifn.\n  //a lock-protected hashmap as we need to perform potentially many lookups\n  //in rapid succession.\n  final HashMap<Class,Object> extensions = new HashMap<Class,Object>();\n  volatile Object nullExtension = null;\n  \n  //Potentially dense table of resolved lookups.\n  final ConcurrentHashMap<Class,Object> lookupCache = new ConcurrentHashMap<Class,Object>();\n\n  public static final Object DEFAULT = new Object();\n  \n  public final Keyword methodk;\n  public final Keyword ns_methodk;\n  public final Class iface;\n  public final IFn ifaceFn;\n\n\n  public MethodImplCache(Keyword methodk, Keyword ns_methodk, Class iface, IFn ifaceFn) {\n    this.methodk = methodk;\n    this.ns_methodk = ns_methodk;\n    this.iface = iface;\n    this.ifaceFn = ifaceFn;\n    extensions.put(iface, ifaceFn);\n  }\n\n  public void extend(Class c, Object fn) {\n    extLock.lock();\n    try {\n      if(c == null)\n\tnullExtension = fn;\n      else {\n\tif(fn == null)\n\t  extensions.remove(c);\n\telse\n\t  extensions.put(c, fn);\n      }\n    } finally {\n      extLock.unlock();\n    }\n    lookupCache.clear();\n  }\n\n  public Set registeredClasses() { return extensions.keySet(); }\n  \n  @SuppressWarnings(\"unchecked\")\n  public Object recurCheckInterface(Set consideredSet, Class[] ifaces) {\n    final Object defVal = DEFAULT;\n    Object rv = defVal;\n    int ni = ifaces.length;\n    for(int idx = 0; idx < ni && rv == defVal; ++idx) {\n      Class iface = ifaces[idx];\n      if(consideredSet.add(iface)) {\n\trv = extensions.getOrDefault(iface, defVal);\n      }\n    }\n    //check derived interface in second pass so primary interfaces get first choice\n    if(rv == defVal) {\n      for(int idx = 0; idx < ni && rv == defVal; ++idx) {\n\tClass iface = ifaces[idx];\n\trv = recurCheckInterface(consideredSet, iface.getInterfaces());\n      }\n    }\n    return rv;\n  }\n  static final Class objAryCls = Object[].class;\n\n  @SuppressWarnings(\"unchecked\")\n  public Object findFnFor(Class c) {\n    if(c == null) return nullExtension;\n    final Object defVal = DEFAULT;\n    Object rv = lookupCache.getOrDefault(c, defVal);\n    //Include caching when lookup fails.\n    if(rv != defVal) return rv;\n    //rv is the default value at this point\n    if(iface.isAssignableFrom(c)) {\n      lookupCache.put(c, ifaceFn);\n      return ifaceFn;\n    }\n    extLock.lock();\n    try {\n      HashSet considered = new HashSet();\n      for(Class cc = c; cc != null && rv == defVal; cc = cc.getSuperclass()) {\n\trv = extensions.getOrDefault(cc, defVal);\n\tif(rv == defVal && cc == c && objAryCls.isAssignableFrom(cc))\n\t  rv = extensions.getOrDefault(objAryCls, defVal);\n\tif(rv == defVal)\n\t  rv = recurCheckInterface(considered, cc.getInterfaces());\n      }\n    } finally {\n      extLock.unlock();\n    }\n    if(rv != defVal)\n      lookupCache.put(c, rv);\n\n    return rv == defVal ? null : rv;\n  }\n\n}\n"
  },
  {
    "path": "java/ham_fisted/MutList.java",
    "content": "package ham_fisted;\n\nimport static ham_fisted.ChunkedList.*;\n\nimport java.util.List;\nimport java.util.Objects;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util.ListIterator;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport clojure.lang.Indexed;\nimport clojure.lang.RT;\nimport clojure.lang.IReduce;\nimport clojure.lang.Counted;\nimport clojure.lang.IKVReduce;\nimport clojure.lang.IFn;\nimport clojure.lang.IHashEq;\nimport clojure.lang.Seqable;\nimport clojure.lang.Reversible;\nimport clojure.lang.ISeq;\nimport clojure.lang.IObj;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientVector;\nimport clojure.lang.Util;\nimport clojure.lang.Counted;\nimport clojure.lang.IReduceInit;\n\n\npublic class MutList<E>\n  implements IMutList<E>, ChunkedListOwner, Cloneable, ITransientVector, UpdateValues\n{\n  final ChunkedList data;\n  public MutList() { data = new ChunkedList(); }\n  public MutList(int capacity) { data = new ChunkedList(capacity); }\n  public MutList(ChunkedList other) {\n    data = new ChunkedList(other, false);\n  }\n  //deep cloning constructor\n  public MutList(MutList<E> other) {\n    this(other.data.clone(0, other.data.nElems, 0, true));\n  }\n  @SafeVarargs\n  public static <E> MutList<E> create(boolean owning, IPersistentMap meta, E... data) {\n    return new MutList<E>(ChunkedList.create(owning, meta, data));\n  }\n  public final ChunkedListSection getChunkedList() {\n    return new ChunkedListSection(data.data, 0, data.nElems);\n  }\n  public final MutList<E> clone() { return new MutList<E>(this); }\n  public final MutList<E> cloneList() {\n    return clone();\n  }\n  public final boolean add(E v) { data.add(v); return true; }\n  public final void add(int idx, E v) { data.add(v,idx); }\n  public final boolean addAll(Collection<? extends E> c) {\n    return addAllReducible(c);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public final boolean addAllReducible(Object c) {\n    if( c instanceof Map)\n      c = ((Map)c).entrySet();\n    final int ssz = size();\n    if (c instanceof ChunkedListOwner) {\n      final ChunkedListSection section = ((ChunkedListOwner)c).getChunkedList();\n      int idx = data.nElems;\n      int oidx = section.startidx;\n      int one = section.endidx - oidx;\n      final int finalLen = idx + one;\n      data.enlarge(finalLen);\n      data.nElems = finalLen;\n      final Object[][] mdata = data.data;\n      final Object[][] odata = section.data;\n      while(idx < finalLen) {\n\tfinal int cidx = idx / 32;\n\tfinal int ocidx = oidx / 32;\n\tfinal int leftover = finalLen - idx;\n\tfinal int eidx = idx % 32;\n\tfinal int oeidx = oidx % 32;\n\tfinal int copyLen = Math.min(leftover, Math.min(32-eidx, 32-oeidx));\n\tSystem.arraycopy(odata[ocidx], oeidx, mdata[cidx], eidx, copyLen);\n\tidx += copyLen;\n\toidx += copyLen;\n      }\n    }\n    else if (c instanceof IReduceInit) {\n      final ChunkedList d = data;\n      if( c instanceof RandomAccess || c instanceof Counted) {\n\tfinal int cz = c instanceof RandomAccess ? ((List)c).size() : ((Counted)c).count();\n\tif (cz == 0) return false;\n\td.enlarge(ssz + cz);\n\td.nElems = ssz + cz;\n\td.fillRangeReduce(ssz, c);\n      }\n      else {\n\t((IReduceInit)c).reduce(new IFnDef() {\n\t    public Object invoke(Object lhs, Object rhs) {\n\t      d.add(rhs);\n\t      return this;\n\t    }\n\t  }, this);\n      }\n    }\n    else if (c instanceof RandomAccess) {\n      final List l = (List)c;\n      final int cs = l.size();\n      data.enlarge(cs + ssz);\n      int idx = ssz;\n      data.nElems = idx +  cs;\n      final Object[][] mdata = data.data;\n      int cidx = 0;\n      while(cidx < cs) {\n\tfinal Object[] chunk = mdata[idx/32];\n\tint eidx = idx % 32;\n\tfinal int groupLen = Math.min(chunk.length-eidx, cs - cidx);\n\tfor (int lidx = 0; lidx < groupLen; ++lidx, ++eidx, ++cidx) {\n\t  chunk[eidx] = l.get(cidx);\n\t}\n\tidx += groupLen;\n      }\n    } else {\n      if(! (c instanceof Iterable))\n\tthrow new RuntimeException(\"Object must either be instance of IReduceInit or java.util.Iterable\");\n      ((Iterable)c).forEach((v)->add((E)v));\n    }\n    return ssz != size();\n  }\n\n  public final boolean addAll(int idx, Collection<? extends E> c) {\n    if (c.isEmpty())\n      return false;\n    if (idx == data.nElems)\n      return addAll(c);\n\n    indexCheck(idx);\n    if (! (c instanceof RandomAccess)) {\n      ArrayList<E> al = new ArrayList<E>();\n      al.addAll(c);\n      c = al;\n    }\n\n    final int cs = c.size();\n    data.widen(idx, idx + cs);\n    for(E item: c) data.setValue(idx++, item);\n\n    return true;\n  }\n\n  public final void clear() { data.clear(); }\n\n  public final boolean contains(Object v) {\n    return data.contains(0, data.nElems, v);\n  }\n\n  public final boolean containsAll(Collection<?> c) {\n    return data.containsAll(0, data.nElems, c);\n  }\n\n  final int indexCheck(int idx) {\n    return ChunkedList.indexCheck(0, data.nElems, idx);\n  }\n\n  final int indexCheck(long idx) {\n    return ChunkedList.indexCheck(0, data.nElems, (int)idx);\n  }\n\n  final int wrapIndexCheck(int idx) {\n    return ChunkedList.wrapIndexCheck(0, data.nElems, idx);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public final E set(int idx, E e) {\n    return (E)data.setValueRV(indexCheck(idx), e);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public final E get(int idx) {\n    return (E)data.getValue(ChunkedList.indexCheck(data.nElems, idx));\n  }\n\n  public final int indexOf(Object o) {\n    return data.indexOf(0, data.nElems, o);\n  }\n\n  public final boolean isEmpty() { return data.nElems == 0; }\n\n  @SuppressWarnings(\"unchecked\")\n  public final Iterator<E> iterator() { return (Iterator<E>)data.iterator(); }\n\n  public static class SubMutList<E> implements IMutList<E>, ChunkedListOwner, Cloneable\n  {\n    final int startidx;\n    final int nElems;\n    final ChunkedList data;\n\n    SubMutList(int sidx, int eidx, ChunkedList d) {\n      startidx = sidx;\n      nElems = eidx - sidx;\n      data = d;\n    }\n\n    public final ChunkedListSection getChunkedList() {\n      return new ChunkedListSection(data.data, startidx, startidx+nElems);\n    }\n\n    public final MutList<E> clone() {\n      return new MutList<E>(data.clone(startidx, startidx+nElems));\n    }\n\n    public final MutList<E> cloneList() {\n      return clone();\n    }\n\n    final int indexCheck(int idx) {\n      return ChunkedList.indexCheck(startidx, nElems, idx);\n    }\n\n    final int wrapIndexCheck(int idx) {\n      return ChunkedList.wrapIndexCheck(startidx, nElems, idx);\n    }\n\n    public final int size() { return nElems; }\n    public final boolean isEmpty() { return nElems == 0; }\n    @SuppressWarnings(\"unchecked\")\n    public final E set(int idx, E e) {\n      return (E)data.setValueRV(indexCheck(idx), e);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public final E get(int idx) {\n      return (E)data.getValue(ChunkedList.indexCheck(startidx, nElems, idx));\n    }\n    public final int indexOf(Object obj) {\n      return data.indexOf(startidx, startidx+nElems, obj);\n    }\n    public final int lastIndexOf(Object obj) {\n      return data.lastIndexOf(startidx, startidx+nElems, obj);\n    }\n    public final boolean contains(Object obj) {\n      return data.contains(startidx, startidx+nElems, obj);\n    }\n    public final boolean containsAll(Collection<?> c) {\n      return data.containsAll(startidx, startidx+nElems, c);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public final Iterator<E> iterator() {\n      return (Iterator<E>)data.iterator(startidx, startidx + nElems);\n    }\n    public final ListIterator<E> listIterator(int idx) {\n      return data.listIterator(indexCheck(idx), startidx+nElems, (E)null);\n    }\n    public final ListIterator<E> listIterator() {\n      return listIterator(0);\n    }\n    public final IMutList<E> subList(int ssidx, int seidx) {\n      ChunkedList.sublistCheck(ssidx, seidx, nElems);\n      return new SubMutList<E>(ssidx + startidx, seidx + startidx, data);\n    }\n    public final Object[] toArray() {\n      return data.toArray(startidx, startidx + nElems);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public final <T> T[] toArray(T[] init) {\n      return (T[])data.fillArray(startidx, startidx + nElems, Arrays.copyOf(init, nElems));\n    }\n    public final Object nth(int idx) { return data.getValue(wrapIndexCheck(idx)); }\n    public final Object nth(int idx, Object notFound) {\n      if (idx < 0)\n\tidx = idx + data.nElems;\n\n      return idx < data.nElems && idx > -1 ? data.getValue(idx+startidx) : notFound;\n    }\n    public final Object invoke(Object idx) {\n      return nth(RT.intCast(idx));\n    }\n    public final Object invoke(Object idx, Object notFound) {\n      return nth(RT.intCast(idx), notFound);\n    }\n    public final int count() { return nElems; }\n\n    public final Object reduce(IFn f) {\n      return data.reduce(startidx, startidx+nElems, f);\n    }\n\n    public final Object reduce(IFn f, Object init) {\n      return data.reduce(startidx, startidx+nElems, f,init);\n    }\n\n    public final Object kvreduce(IFn f, Object init) {\n      return data.kvreduce(startidx, startidx+nElems, f, init);\n    }\n    public void fillRange(long sidx, long eidx, Object v) {\n      final int ssidx = indexCheck((int)sidx);\n      if (eidx < sidx || eidx > nElems)\n\tthrow new RuntimeException(\"End index out of range: \" + String.valueOf(eidx));\n      data.fillRange((int)ssidx, (int)(eidx + startidx), v);\n    }\n    public void fillRange(long sidx, List v) {\n      final int ssidx = indexCheck((int)sidx);\n      final int eidx = (int)sidx + v.size();\n      if (eidx > nElems)\n\tthrow new RuntimeException(\"End index out of range: \" + String.valueOf(eidx));\n      data.fillRangeReduce(ssidx, v);\n    }\n    public final int hashCode() {\n      return data.hasheq(startidx, startidx + nElems);\n    }\n    public final int hasheq() {\n      return hashCode();\n    }\n    public final String toString() {\n      return Transformables.sequenceToString(this);\n    }\n    public final boolean equals(Object other) {\n      return equiv(other);\n    }\n    public final boolean equiv(Object other) {\n      return data.equiv(startidx, startidx+nElems, other);\n    }\n    public final ISeq seq() { return data.seq(startidx, startidx+nElems); }\n    public final ISeq rseq() { return data.rseq(startidx, startidx+nElems); }\n    public IPersistentMap meta() { return data.meta(); }\n    public SubMutList<E> withMeta(IPersistentMap m) {\n      return new SubMutList<E>(startidx, startidx + nElems, data.withMeta(m));\n    }\n  }\n\n  public final IMutList<E> subList(int startidx, int endidx) {\n    ChunkedList.sublistCheck(startidx, endidx, size());\n    return new SubMutList<E>(startidx, endidx, data);\n  }\n\n  public final ListIterator<E> listIterator(int idx) {\n    return data.listIterator(idx, data.nElems, (E)null);\n  }\n  public final ListIterator<E> listIterator() { return listIterator(0); }\n\n  public final int lastIndexOf(Object obj) {\n    return data.lastIndexOf(0, data.nElems, obj);\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public final E remove(int idx) {\n    final E retval = (E)data.getValue(idx);\n    data.shorten(idx, idx+1);\n    return retval;\n  }\n\n  public void fillRange(int startidx, int endidx, Object v) {\n    indexCheck(startidx);\n    if(endidx < startidx || endidx > data.nElems)\n      throw new RuntimeException(\"End index out of range: \" + String.valueOf(endidx));\n    data.fillRange(startidx, endidx, v);\n  }\n\n  public void fillRange(int startidx, List v) {\n    indexCheck(startidx);\n    final int endidx = v.size();\n    if(endidx < startidx || endidx > data.nElems)\n      throw new RuntimeException(\"End index out of range: \" + String.valueOf(endidx));\n    data.fillRangeReduce(startidx, v);\n  }\n\n  public void addRange(int startidx, int endidx, Object v) {\n    indexCheck(startidx);\n    data.addRange(startidx, endidx, v);\n  }\n\n  public void removeRange(int startidx, int endidx) {\n    indexCheck(startidx);\n    if (endidx == startidx)\n      return;\n\n    if(endidx < startidx || endidx > data.nElems)\n      throw new RuntimeException(\"End index out of range: \" + String.valueOf(endidx));\n\n    data.shorten(startidx, endidx);\n  }\n\n  public final boolean remove(Object obj) {\n    final int idx = indexOf(obj);\n    if (idx != -1)\n      remove(idx);\n    return idx != -1;\n  }\n\n  public final boolean retainAll(Collection c) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n\n  public final boolean removeAll(Collection c) {\n    throw new RuntimeException(\"Unimplemented\");\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public final <T> T[] toArray(T[] typeMarker) {\n    return (T[])data.fillArray(Arrays.copyOf(typeMarker, data.nElems));\n  }\n\n  public final Object[] toArray() {\n    return data.toArray();\n  }\n\n  public final int size() { return data.nElems; }\n  public final int capacity() { return data.capacity; }\n\n  public final Object nth(int idx) { return data.getValue(wrapIndexCheck(idx)); }\n  public final Object nth(int idx, Object notFound) {\n    if (idx < 0)\n      idx = idx + data.nElems;\n\n    return idx < data.nElems && idx > -1 ? data.getValue(idx) : notFound;\n  }\n  public final Object invoke(Object idx) {\n    return nth(RT.intCast(idx));\n  }\n  public final Object invoke(Object idx, Object notFound) {\n    return nth(RT.intCast(idx), notFound);\n  }\n  public final int count() { return data.size(); }\n\n  public final Object reduce(IFn f) {\n    return data.reduce(0, data.nElems, f);\n  }\n\n  public final Object reduce(IFn f, Object init) {\n    return data.reduce(0, data.nElems, f,init);\n  }\n\n  public final Object kvreduce(IFn f, Object init) {\n    return data.kvreduce(0, data.nElems, f, init);\n  }\n\n  public final ISeq seq() { return data.seq(0, data.nElems); }\n  public final ISeq rseq() { return data.rseq(0, data.nElems); }\n\n  public final int hashCode() {\n    return data.hasheq(0, data.nElems);\n  }\n  public final int hasheq() {\n    return hashCode();\n  }\n  public final boolean equals(Object other) {\n    if (other == this)\n      return true;\n    return equiv(other);\n  }\n  public final boolean equiv(Object other) {\n    return data.equiv(0, data.nElems, other);\n  }\n  public final String toString() {\n    return Transformables.sequenceToString(this);\n  }\n  public IPersistentMap meta() { return data.meta(); }\n  public MutList<E> withMeta(IPersistentMap m) {\n    return new MutList<E>(data.withMeta(m));\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final MutList<E> assocN(int i, Object obj) {\n    if (i == data.nElems) add((E)obj);\n    set(indexCheck(i), (E)obj);\n    return this;\n  }\n  public final MutList<E> pop() {\n    if(data.nElems == 0)\n      throw new RuntimeException(\"Cannot pop empty vector.\");\n    remove(data.nElems-1);\n    return this;\n  }\n  public final MutList<E> assoc(Object i, Object obj) {\n    if(!Util.isInteger(i))\n      throw new RuntimeException(\"Vectors must have integer keys\");\n    return assocN(RT.intCast(i), obj);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public final MutList<E> conj(Object obj) {\n    add((E)obj);\n    return this;\n  }\n  public final Object valAt(Object key) {\n    return valAt(key, null);\n  }\n  public final Object valAt(Object key, Object notFound) {\n    if(Util.isInteger(key)) {\n      int k = RT.intCast(key);\n      if(k >= 0 && k < data.nElems)\n\treturn data.getValue(k);\n    }\n    return notFound;\n  }\n  public ImmutList persistent() { return new ImmutList(0, data.nElems, data); }\n  public ImmutList updateValues(BiFunction valueMap) {\n    return persistent().updateValues(valueMap);\n  }\n  public ImmutList updateValue(Object key, Function valueMap) {\n    return persistent().updateValue(key, valueMap);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/MutTreeList.java",
    "content": "package ham_fisted;\n\nimport java.util.Arrays;\nimport clojure.lang.Box;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientVector;\nimport clojure.lang.RT;\nimport clojure.lang.IPersistentVector;\n\npublic class MutTreeList extends TreeListBase implements ITransientVector {\n  int nTail;\n  boolean persistent = false;\n  final IPersistentMap meta;\n  public final Object sentinel = new Object();\n  public int nTail() { return nTail; }\n  public Object[] validTail() {\n    return nTail == tail.length ? tail : Arrays.copyOf(tail, nTail);\n  }\n  public MutTreeList(Object root, Object[] tail, IPersistentMap meta, int shift, int count) {\n    super(root, tail, shift, count);\n    this.meta = meta;\n  }\n  public MutTreeList() {\n    super(new Leaf(null, new Object[0][]), new Object[tailWidth], 0, 0);\n    this.nTail = 0;\n    this.meta = null;\n  }\n  public MutTreeList(TreeListBase other, IPersistentMap meta) {\n    super(other);\n    this.meta = meta;\n    nTail = tail.length;\n    this.tail = Arrays.copyOf(this.tail, tailWidth);\n  }\n  void consTail(Object[] tail) {\n    Object rv = shift == 0 ? ((Leaf)root).add(sentinel, tail) : ((Branch)root).add(sentinel, shift, tail);\n    if(rv instanceof Object[]) {\n      shift = shift+1;\n      root = new Branch(sentinel, (Object[])rv);\n    } else {\n      root = rv;\n    }\n  }\n  public boolean add(Object obj) {\n    final int tlen = nTail();\n    final int newCount = count+1;\n    if(tlen == 32) {\n      consTail(tail);\n      tail = new Object[tailWidth];\n      nTail = 0;\n    }\n    tail[nTail++] = obj;\n    this.count = newCount;\n    return true;\n  }\n  public Object set(int idx, Object obj) {\n    checkIndex(idx, count);\n    int cutoff = count - nTail();\n    if(idx < cutoff) {\n      Box b = new Box(null);\n      Object newRoot = shift == 1 ? ((Leaf)root).assocN(sentinel, idx, obj, b) :\n\t((Branch)root).assocN(sentinel, shift, idx, obj, b);\n      root = newRoot;\n      return b.val;\n    } else {\n      idx = idx - cutoff;\n      Object rv = tail[idx];\n      tail[idx] = obj;\n      return rv;\n    }\n  }\n  public void setObject(int idx, Object obj) {\n    checkIndex(idx, count);\n    int cutoff = count - nTail();\n    if(idx < cutoff) {\n      Object newRoot = shift == 1 ? ((Leaf)root).assocN(sentinel, idx, obj, null) :\n\t((Branch)root).assocN(sentinel, shift, idx, obj, null);\n      root = newRoot;\n    } else {\n      idx = idx - cutoff;\n      tail[idx] = obj;\n    }\n  }\n  public MutTreeList assocN(int i, Object val) {\n    if(i == count) add(val);\n    setObject(i, val);\n    return this;\n  }\n  public MutTreeList pop() {\n    if(count == 0) throw new IllegalStateException(\"Can't pop empty vector\");\n    if(nTail > 0) {\n      nTail--;\n    } else {\n      Object popResult = shift == 1 ? ((Leaf)root).pop(sentinel) : ((Branch)root).pop(sentinel, shift);\n      if(popResult instanceof SublistResult) {\n\tSublistResult r = (SublistResult)popResult;\n\tthis.root = r.node;\n\tnTail = tailWidth-1;\n\tSystem.arraycopy(tail, 0, r.tail, 0, nTail);\n      } else {\n\tthis.root = popResult;\n      }\n    }\n    count--;\n    return this;\n  }\n  public MutTreeList assoc(Object key, Object val) {\n    return assocN(RT.intCast(key), val);\n  }\n  public MutTreeList conj(Object val) { add(val); return this; }\n  public TreeList persistent() {\n    if(persistent == true)\n      throw new RuntimeException(\"Persistent called twice on transient vector\");\n    persistent = true;\n    return new TreeList( this, meta );\n  }\n  public IPersistentVector immut() { return persistent(); }\n  public static MutTreeList create(boolean owning, IPersistentMap meta, Object[] data) {\n    int nLeaves = (data.length  + tailWidth - 1) / tailWidth;\n    MutTreeList newList = new MutTreeList(new Leaf(null, new Object[0][]), new Object[tailWidth], meta, 0, 0);\n    for(int idx = 0; idx < nLeaves; ++idx) {\n      int dataOff = idx*32;\n      int dataEnd = Math.min(dataOff + 32, data.length);\n      if(idx == (nLeaves - 1)) {\n\tSystem.arraycopy(data, dataOff, newList.tail, 0, dataEnd - dataOff);\n\tnewList.nTail = dataEnd - dataOff;\n\tnewList.count += newList.nTail;\n      } else {\n\tnewList.consTail(Arrays.copyOfRange(data, dataOff, dataEnd));\n\tnewList.count += 32;\n      }\n    }\n    return newList;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/MutableMap.java",
    "content": "package ham_fisted;\n\n//Marker interface indicating that merge, compute, put, etc. are safe to use.\npublic interface MutableMap {}\n"
  },
  {
    "path": "java/ham_fisted/ObjArray.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.Iterator;\n\n\npublic class ObjArray {\n  public static final Object[] create() { return new Object[0]; }\n  public static final Object[] create(Object a) { return new Object[] {a}; }\n  public static final Object[] create(Object a, Object b) { return new Object[] {a, b}; }\n  public static final Object[] create(Object a, Object b, Object c) {\n    return new Object[] {a, b, c};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d) {\n    return new Object[] {a, b, c, d};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d, Object e) {\n    return new Object[] {a, b, c, d, e};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f) {\n    return new Object[] {a, b, c, d, e, f};\n  }\n  public static final Object[] createv(Object a, Object b, Object c, Object d,\n\t\t\t\t       Object e, Object f, Object[] extra) {\n    final int el = extra.length;\n    final int len = 6 + el;\n    Object[] retval = new Object[len];\n    retval[0] = a; retval[1] = b; retval[2] = c;\n    retval[3] = d; retval[4] = e; retval[5] = f;\n    System.arraycopy(extra, 0, retval, 6, el);\n    return retval;\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g) {\n    return new Object[] {a, b, c, d, e, f, g};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h) {\n    return new Object[] {a, b, c, d, e, f, g, h};\n  }\n  public static final Object[] createv(Object a, Object b, Object c, Object d,\n\t\t\t\t       Object e, Object f, Object g, Object h,\n\t\t\t\t       Object[] extra) {\n    final int el = extra.length;\n    final int len = 8 + el;\n    Object[] retval = new Object[len];\n    retval[0] = a; retval[1] = b; retval[2] = c;\n    retval[3] = d; retval[4] = e; retval[5] = f;\n    retval[6] = g; retval[7] = h;\n    System.arraycopy(extra, 0, retval, 8, el);\n    return retval;\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i) {\n    return new Object[] {a, b, c, d, e, f, g, h, i};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j, Object k) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j, k};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j, Object k, Object l) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j, k, l};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j, Object k, Object l,\n\t\t\t\t      Object m) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j, k, l, m};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j, Object k, Object l,\n\t\t\t\t      Object m, Object n) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j, k, l, m, n};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j, Object k, Object l,\n\t\t\t\t      Object m, Object n, Object o) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o};\n  }\n  public static final Object[] create(Object a, Object b, Object c, Object d,\n\t\t\t\t      Object e, Object f, Object g, Object h,\n\t\t\t\t      Object i, Object j, Object k, Object l,\n\t\t\t\t      Object m, Object n, Object o, Object p) {\n    return new Object[] {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p};\n  }\n  public static final Object[] createv(Object a, Object b, Object c, Object d,\n\t\t\t\t       Object e, Object f, Object g, Object h,\n\t\t\t\t       Object i, Object j, Object k, Object l,\n\t\t\t\t       Object m, Object n, Object o, Object p,\n\t\t\t\t       Object[] extra) {\n    final int el = extra.length;\n    final int len = 16 + el;\n    Object[] retval = new Object[len];\n    retval[0] = a; retval[1] = b; retval[2] = c;\n    retval[3] = d; retval[4] = e; retval[5] = f;\n    retval[6] = g; retval[7] = h; retval[8] = i;\n    retval[9] = j; retval[10] = k; retval[11] = l;\n    retval[12] = m; retval[13] = n; retval[14] = o;\n    retval[15] = p;\n    System.arraycopy(extra, 0, retval, 16, el);\n    return retval;\n  }\n\n\n  public static Object[] iterFill(Object[] data, int idx, Iterator iter) {\n    while(iter.hasNext())\n      data[idx++] = iter.next();\n    return data;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ParallelOptions.java",
    "content": "package ham_fisted;\n\n\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.ForkJoinPool;\n\n\npublic class ParallelOptions {\n  public final long minN;\n  public final int maxBatchSize;\n  public final boolean ordered;\n  public final ExecutorService pool;\n  public final int parallelism;\n  public final CatParallelism catParallelism;\n  public final int putTimeoutMs;\n  public final int nLookahead;\n  //In some cases users may want a sequence of unmerged results to do some\n  //other form of merge.\n  public final boolean unmergedResult;\n\n  public enum CatParallelism {\n    //Parallelize assuming catenation of large-N containers\n    ELEMWISE,\n    //Parallelize assuming large catenation of small-N containers -\n    //default parallelism.\n    SEQWISE,\n  }\n\n  public ParallelOptions(long _minN, int batchSize, boolean _ordered,\n\t\t\t ExecutorService _pool, int _parallelism,\n\t\t\t CatParallelism _catParallelism, int _putTimeoutMs,\n\t\t\t boolean unmergedResult, int nLookahead) {\n    minN = _minN;\n    maxBatchSize = batchSize;\n    ordered = _ordered;\n    pool = _pool;\n    parallelism = _parallelism;\n    catParallelism = _catParallelism;\n    putTimeoutMs = _putTimeoutMs;\n    this.unmergedResult = unmergedResult;\n    this.nLookahead = nLookahead;\n  }\n  public ParallelOptions(long minN, int batchSize, boolean ordered) {\n    this(minN, batchSize, ordered,\n\t ForkJoinPool.commonPool(), ForkJoinPool.getCommonPoolParallelism(),\n\t CatParallelism.SEQWISE, 5000, false, -1);\n  }\n  public ParallelOptions() {\n    this(1000, 64000, true);\n  }\n  public ParallelOptions minN(long newMinN) {\n    return new ParallelOptions(newMinN, maxBatchSize, ordered, pool, parallelism,\n\t\t\t       catParallelism, putTimeoutMs, false, -1);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/PartitionByInner.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.function.BiPredicate;\nimport clojure.lang.IFn;\nimport clojure.lang.Seqable;\nimport clojure.lang.ISeq;\nimport clojure.lang.IDeref;\nimport clojure.lang.Util;\nimport clojure.lang.IMeta;\nimport clojure.lang.RT;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.PersistentArrayMap;\nimport clojure.lang.Keyword;\n\n\n\npublic class PartitionByInner implements ITypedReduce, Iterator, Seqable, IDeref, IMeta {\n  public final Iterator iter;\n  public final IFn f;\n  public final Object fv;\n  public final BiPredicate pred;\n  boolean lastVValid;\n  Object lastV;\n  Object lastFV;\n\n  public PartitionByInner(Iterator i, IFn f, Object v, BiPredicate pred) {\n    this.iter = i;\n    this.f = f;\n    this.lastV = v;\n    this.lastVValid = true;\n    final Object fv = f.invoke(v);\n    this.fv = fv;\n    this.lastFV = fv;\n    this.pred = pred == null ? (x,y)->CljHash.equiv(x,y) : pred;\n  }\n\n  Object advance() {\n    Object rv = lastV;\n    if (iter.hasNext()) {\n      lastVValid = true;\n      Object vv= iter.next();\n      lastV = vv;\n      lastFV = f.invoke(vv);\n    } else {\n      lastVValid = false;\n      lastV = null;\n      lastFV = null;\n    }\n    return rv;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public Object reduce(IFn rfn, Object acc) {\n    final Iterator iter = this.iter;\n    final IFn ff = f;\n    final Object ffv = fv;\n    if(!hasNext()) return acc;\n    Object vv = lastV;\n    Object fvv = lastFV;\n    do {\n      acc = rfn.invoke(acc, vv);\n      if(RT.isReduced(acc)) {\n\tadvance();\n\treturn ((IDeref)acc).deref();\n      }\n      if(!iter.hasNext()) {\n\tadvance();\n\treturn acc;\n      }\n      vv = iter.next();\n      fvv = ff.invoke(vv);\n    } while(ffv == fvv || pred.test(ffv, fvv));\n    lastVValid = true;\n    lastV = vv;\n    lastFV = fvv;\n    return acc;\n  }\n\n  @SuppressWarnings(\"unchecked\")\n  public boolean hasNext() {\n    return lastVValid && (fv == lastFV || pred.test(fv, lastFV));\n  }\n  public Object next() {\n    if(!lastVValid) throw new NoSuchElementException();\n    return advance();\n  }\n  public ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(this); }\n  public Object deref() {\n    if(hasNext())\n      reduce(new IFnDef() { public Object invoke(Object acc, Object v) { return v; } }, null);\n    return lastVValid ? ImmutList.create(true, null, lastV, lastFV) : null;\n  }\n  public IPersistentMap meta() {\n    return new PersistentArrayMap(new Object[] { Keyword.intern(\"fv\"), fv });\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/PersistentHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Collection;\nimport java.util.function.BiFunction;\nimport java.util.function.Function;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.IObj;\nimport clojure.lang.Indexed;\n\n\npublic class PersistentHashMap\n  extends ROHashMap\n  implements IAPersistentMap, IObj {\n  public static final PersistentHashMap EMPTY = new PersistentHashMap(new HashMap());\n  int _hasheq = 0;\n\n  PersistentHashMap(HashMap data) {\n    super(data.loadFactor, data.capacity, data.length, data.data, data.meta);\n  }\n  public PersistentHashMap(HashMap data, boolean marker) {\n    super(data.loadFactor, data.capacity, data.length, data.data.clone(), data.meta);\n  }\n  PersistentHashMap(HashMap data, IPersistentMap m) {\n    super(data.loadFactor, data.capacity, data.length, data.data, m);\n  }\n\n  public int count() { return length; }\n  public int hasheq() {\n    if (_hasheq == 0)\n      _hasheq = super.hasheq();\n    return _hasheq;\n  }\n  public PersistentHashMap assoc(Object key, Object val) {\n    final int hashcode = hash(key);\n    final int idx = hashcode & mask;\n    HashNode e, init = data[idx];\n    Object k;\n    for(e = init; e != null && !((k = e.k) == key || equals(k, key)); e = e.nextNode);\n    if(e != null) {\n      if(e.v == val) return this;\n      PersistentHashMap rv = new PersistentHashMap(this, true);\n      // We use e.k here for identity short circuiting in HashNode assoc\n      rv.data[idx] = init.assoc(rv, e.k, hashcode, val);\n      return rv;\n    } else {\n      PersistentHashMap rv = new PersistentHashMap(this, true);\n      HashNode newNode = rv.newNode(key, hashcode, val);\n      rv.data[idx] = newNode;\n      newNode.nextNode = init;\n      rv.checkResize(null);\n      return rv;\n    }\n  }\n  public IPersistentMap without(Object key) {\n    final int hashcode = hash(key);\n    final int idx = hashcode & mask;\n    HashNode e, init = data[idx];\n    Object k;\n    for(e = init; e != null && !((k = e.k) == key || equals(k, key)); e = e.nextNode);\n    if(e == null) return this;\n    PersistentHashMap rv = new PersistentHashMap(this, true);\n    rv.data[idx] = init.dissoc(rv, key);\n    return rv;\n  }\n  public ITransientMap asTransient() {\n    return isEmpty() ? new UnsharedHashMap(meta) :\n      new TransientHashMap(this);\n  }\n  public PersistentHashMap withMeta(IPersistentMap m) {\n    return new PersistentHashMap(this, m);\n  }\n  public PersistentHashMap empty() { return EMPTY; }\n  public PersistentHashMap union(Map o, BiFunction bfn) {\n    return new PersistentHashMap(union(shallowClone(), o, bfn));\n  }\n  public PersistentHashMap intersection(Map o, BiFunction bfn) {\n    return new PersistentHashMap(intersection(shallowClone(), o, bfn));\n  }\n  public PersistentHashMap intersection(Set o) {\n    return new PersistentHashMap(intersection(shallowClone(), o));\n  }\n  public PersistentHashMap difference(Collection c) {\n    return new PersistentHashMap(difference(shallowClone(), c));\n  }\n  public PersistentHashMap updateValues(BiFunction valueMap) {\n    return new PersistentHashMap(updateValues(shallowClone(), valueMap));\n  }\n  public PersistentHashMap updateValue(Object k, Function fn) {\n    return new PersistentHashMap(updateValue(this, fn));\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/PersistentHashSet.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Set;\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientSet;\nimport clojure.lang.IObj;\n\n\npublic class PersistentHashSet extends ROHashSet implements IAPersistentSet, IObj {\n  public static final PersistentHashSet EMPTY = new PersistentHashSet();\n  public PersistentHashSet() { super(); }\n  public PersistentHashSet(HashBase hb) {\n    super(hb);\n  }\n  public PersistentHashSet(HashBase hb, IPersistentMap meta) {\n    super(hb,meta);\n  }\n  public PersistentHashSet withMeta(IPersistentMap m) {\n    return new PersistentHashSet(this, m);\n  }\n  public ITransientSet asTransient() {\n    return isEmpty() ?  new UnsharedHashSet(meta) : new TransientHashSet(this, meta);\n  }\n  public PersistentHashSet empty() { return EMPTY; }\n  public PersistentHashSet union(Collection rhs) {\n    return new PersistentHashSet(union(shallowClone(), rhs));\n  }\n  public PersistentHashSet intersection(Set rhs) {\n    return new PersistentHashSet(intersection(shallowClone(), rhs));\n  }\n  public PersistentHashSet difference(Set rhs) {\n    return new PersistentHashSet(difference(shallowClone(), rhs));\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/PersistentLongHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport java.util.Collection;\nimport java.util.Set;\nimport java.util.Map;\nimport clojure.lang.IEditableCollection;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.IObj;\nimport clojure.lang.Indexed;\n\npublic class PersistentLongHashMap\n  extends ROLongHashMap\n  implements IAPersistentMap, IObj {\n  public static final PersistentLongHashMap EMPTY = new PersistentLongHashMap(new LongHashMap());\n  int _hasheq = 0;\n\n  public PersistentLongHashMap(LongHashMap data) {\n    super(data.loadFactor, data.capacity, data.length, data.data, data.meta);\n  }\n  public PersistentLongHashMap(LongHashMap data, IPersistentMap m) {\n    super(data.loadFactor, data.capacity, data.length, data.data, m);\n  }\n  public int count() { return length; }\n  public int hasheq() {\n    if (_hasheq == 0)\n      _hasheq = super.hasheq();\n    return _hasheq;\n  }\n  public ITransientMap asTransient() {\n    return isEmpty() ? new UnsharedLongHashMap(meta) :\n      new TransientLongHashMap(this);\n  }\n  public PersistentLongHashMap withMeta(IPersistentMap m) {\n    return new PersistentLongHashMap(this, m);\n  }\n  public PersistentLongHashMap empty() { return EMPTY; }\n  public PersistentLongHashMap union(Map o, BiFunction bfn) {\n    return new PersistentLongHashMap(union(shallowClone(), o, bfn));\n  }\n  public PersistentLongHashMap intersection(Map o, BiFunction bfn) {\n    return new PersistentLongHashMap(intersection(shallowClone(), o, bfn));\n  }\n  public PersistentLongHashMap intersection(Set o) {\n    return new PersistentLongHashMap(intersection(shallowClone(), o));\n  }\n  public PersistentLongHashMap difference(Collection c) {\n    return new PersistentLongHashMap(difference(shallowClone(), c));\n  }\n  public PersistentLongHashMap updateValues(BiFunction valueMap) {\n    return new PersistentLongHashMap(updateValues(shallowClone(), valueMap));\n  }\n  public PersistentLongHashMap updateValue(Object k, Function fn) {\n    return new PersistentLongHashMap(updateValue(this, fn));\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/PersistentVector.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Arrays;\n\npublic class PersistentVector {\n\n}\n"
  },
  {
    "path": "java/ham_fisted/ROHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.MapEntry;\n\n\npublic class ROHashMap extends HashMap {\n  ROHashMap(float loadFactor, int initialCapacity,\n\t     int length, HashNode[] data,\n\t     IPersistentMap meta) {\n    super(loadFactor, initialCapacity, length, data, meta);\n  }\n  ROHashMap(HashMap other, IPersistentMap m) {\n    super(other, m);\n  }\n  public Object remove(Object k) {\n    throw new UnsupportedOperationException();\n  }\n  public Object put(Object key, Object value) {\n    throw new UnsupportedOperationException();\n  }\n  public void putAll(Map m) {\n    throw new UnsupportedOperationException();\n  }\n  public void clear() {\n    throw new UnsupportedOperationException();\n  }\n  public Object compute(Object key, BiFunction bfn) {\n    throw new UnsupportedOperationException();\n  }\n  public Object computeIfAbsent(Object key, Function mappingFunction) {\n    throw new UnsupportedOperationException();\n  }\n  public Object computeIfPresent(Object key, BiFunction remappingFunction) {\n    throw new UnsupportedOperationException();\n  }\n  public Object merge(Object key, Object value, BiFunction remappingFunction) {\n    throw new UnsupportedOperationException();\n  }\n  public void replaceAll(BiFunction function) {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ROHashSet.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\n\n\npublic class ROHashSet extends HashSet {\n  public ROHashSet() {\n    super();\n  }\n  public ROHashSet(HashBase hs) {\n    this(hs, null);\n  }\n  public ROHashSet(HashBase hs, IPersistentMap meta) {\n    super(hs, meta);\n  }\n  public boolean add(Object o) {\n    throw new UnsupportedOperationException();\n  }\n  public boolean addAll(Collection c) {\n    throw new UnsupportedOperationException();\n  }\n  public boolean remove(Object o) {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ROLongHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IMapEntry;\nimport clojure.lang.MapEntry;\n\n\npublic class ROLongHashMap extends LongHashMap {\n  ROLongHashMap(float loadFactor, int initialCapacity,\n\t\tint length, LongHashNode[] data,\n\t\tIPersistentMap meta) {\n    super(loadFactor, initialCapacity, length, data, meta);\n  }\n  ROLongHashMap(LongHashMap other, IPersistentMap m) {\n    super(other, m);\n  }\n  public Object remove(Object k) {\n    throw new UnsupportedOperationException();\n  }\n  public Object put(Object key, Object value) {\n    throw new UnsupportedOperationException();\n  }\n  public void putAll(Map m) {\n    throw new UnsupportedOperationException();\n  }\n  public void clear() {\n    throw new UnsupportedOperationException();\n  }\n  public Object compute(Object key, BiFunction bfn) {\n    throw new UnsupportedOperationException();\n  }\n  public Object computeIfAbsent(Object key, Function mappingFunction) {\n    throw new UnsupportedOperationException();\n  }\n  public Object computeIfPresent(Object key, BiFunction remappingFunction) {\n    throw new UnsupportedOperationException();\n  }\n  public Object merge(Object key, Object value, BiFunction remappingFunction) {\n    throw new UnsupportedOperationException();\n  }\n  public void replaceAll(BiFunction function) {\n    throw new UnsupportedOperationException();\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/RandomAccessSpliterator.java",
    "content": "package ham_fisted;\n\nimport java.util.Spliterator;\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\n\n\npublic class RandomAccessSpliterator<E> implements Spliterator<E> {\n\n  protected final List<E> list;\n  protected final int sidx;\n  protected int eidx;\n  int curIdx;\n\n  RandomAccessSpliterator(List<E> list, int sidx, int eidx) {\n    assert list instanceof RandomAccess;\n\n    this.list = list;\n    this.sidx = sidx;\n    this.eidx = eidx;\n    curIdx = sidx;\n  }\n\n  RandomAccessSpliterator(List<E> list) {\n    this(list, 0, list.size());\n  }\n\n  protected Spliterator<E> construct(List<E> list, int split, int eidx) {\n    return new RandomAccessSpliterator<E>(list, split, eidx);\n  }\n\n  protected Spliterator<E> doSplit() {\n    final int ne = eidx - sidx;\n    if(ne > 1) {\n      int split = sidx + (ne / 2);\n      int eeidx = eidx;\n      eidx = split;\n      return construct(list, split, eeidx);\n    }\n    return null;\n  }\n\n  public Spliterator<E> trySplit() {\n    return doSplit();\n  }\n\n  public long estimateSize() { return eidx - sidx; }\n\n  public boolean tryAdvance(Consumer<? super E> action) {\n    if (action == null)\n      throw new NullPointerException();\n    final boolean retval = curIdx < eidx;\n    if(retval) {\n      action.accept(list.get(curIdx));\n      ++curIdx;\n    }\n    return retval;\n  }\n\n  public void forEachRemaining(Consumer<? super E> c) {\n    final int ee = eidx;\n    if(list instanceof IMutList) {\n      final IMutList ll = (IMutList)list;\n      if(c instanceof DoubleConsumer) {\n\tfinal DoubleConsumer dc = (DoubleConsumer)c;\n\tfor(int cc = curIdx; cc < ee; ++cc) {\n\t  dc.accept(ll.getDouble(cc));\n\t}\n\tcurIdx = eidx;\n\treturn;\n      }\n      else if (c instanceof LongConsumer) {\n\tfinal LongConsumer dc = (LongConsumer)c;\n\tfor(int cc = curIdx; cc < ee; ++cc) {\n\t  dc.accept(ll.getLong(cc));\n\t}\n\tcurIdx = eidx;\n\treturn;\n      }\n    }\n    final List<E> ll = list;\n    for(int cc = curIdx; cc < ee; ++cc) {\n      c.accept(ll.get(cc));\n    }\n    curIdx = eidx;\n  }\n\n  public int characteristics() {\n    return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE;\n  }\n  public static class LongSpliterator extends RandomAccessSpliterator<Long> implements Spliterator.OfLong {\n    @SuppressWarnings(\"unchecked\")\n    public LongSpliterator(IMutList list, int sidx, int eidx) {\n      super(list, sidx, eidx);\n    }\n    protected Spliterator<Long> construct(List list, int sidx, int eidx) {\n      return new LongSpliterator((IMutList)list, sidx, eidx);\n    }\n    public Spliterator.OfLong trySplit() {\n      return (Spliterator.OfLong) doSplit();\n    }\n    public boolean tryAdvance(LongConsumer action) {\n      if (action == null)\n\tthrow new NullPointerException();\n      final boolean retval = curIdx < eidx;\n      if(retval) {\n\taction.accept(((IMutList)list).getLong(curIdx));\n\t++curIdx;\n      }\n      return retval;\n    }\n    public void forEachRemaining(LongConsumer dc) {\n      final int ee = eidx;\n      final IMutList ll = (IMutList)list;\n      for(int cc = curIdx; cc < ee; ++cc) {\n\tdc.accept(ll.getLong(cc));\n      }\n      curIdx = eidx;\n    }\n  }\n  public static class DoubleSpliterator extends RandomAccessSpliterator<Double> implements Spliterator.OfDouble {\n    @SuppressWarnings(\"unchecked\")\n    public DoubleSpliterator(IMutList list, int sidx, int eidx) {\n      super(list, sidx, eidx);\n    }\n    protected Spliterator<Double> construct(List list, int sidx, int eidx) {\n      return new DoubleSpliterator((IMutList)list, sidx, eidx);\n    }\n    public Spliterator.OfDouble trySplit() {\n      return (Spliterator.OfDouble) doSplit();\n    }\n    public boolean tryAdvance(DoubleConsumer action) {\n      if (action == null)\n\tthrow new NullPointerException();\n      final boolean retval = curIdx < eidx;\n      if(retval) {\n\taction.accept(((IMutList)list).getDouble(curIdx));\n\t++curIdx;\n      }\n      return retval;\n    }\n    public void forEachRemaining(DoubleConsumer dc) {\n      final int ee = eidx;\n      final IMutList ll = (IMutList)list;\n      for(int cc = curIdx; cc < ee; ++cc) {\n\tdc.accept(ll.getDouble(cc));\n      }\n      curIdx = eidx;\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/RangeList.java",
    "content": "package ham_fisted;\n\n\nimport java.util.List;\n\n\npublic interface RangeList {\n  public void fillRange(long startidx, long endidx, Object v);\n  default void fillRange(long startidx, List v) {\n    fillRangeReducible(startidx, v);\n  }\n  public void fillRangeReducible(long startidx, Object v);\n  public void removeRange(long startidx, long endidx);\n}\n"
  },
  {
    "path": "java/ham_fisted/Ranges.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Random;\nimport java.util.List;\nimport java.util.function.LongConsumer;\nimport java.util.function.LongBinaryOperator;\nimport clojure.lang.RT;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\nimport clojure.lang.IDeref;\nimport clojure.lang.Util;\nimport clojure.lang.Reduced;\nimport clojure.lang.ISeq;\n\n\n\npublic class Ranges {\n  public static class LongRange implements LongMutList, TypedList {\n    public final long start;\n    public final long end;\n    public final long step;\n    public final long nElems;\n    public final IPersistentMap meta;\n    int _hash = 0;\n    public LongRange(long s, long e, long _step, IPersistentMap m) {\n      start = s;\n      end = e;\n      step = _step;\n      nElems = (e - s)/_step;\n      if (nElems < 0)\n\tthrow new RuntimeException(\"Invalid Range - start: \" + String.valueOf(s)\n\t\t\t\t   + \" end: \" + String.valueOf(e) + \" step: \" +\n\t\t\t\t   String.valueOf(_step));\n      meta = m;\n    }\n    public IMutList cloneList() { return this; }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public int hasheq() {\n      if (_hash == 0) {\n\t_hash = LongMutList.super.hasheq();\n      }\n      return _hash;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public Class containedType() { return Long.TYPE; }\n    public int size() { return RT.intCast(nElems); }\n    public long lgetLong(long idx) {\n      final long sz = nElems;\n      if(idx < 0 || idx >= sz)\n\tthrow new IndexOutOfBoundsException(\"Index out of range: \" + String.valueOf(idx) +\n\t\t\t\t\t    \" size: \" + String.valueOf(sz));\n      return start + step*idx;\n    }\n    public long getLong(int idx) {\n      return lgetLong(idx);\n    }\n    public int[] toIntArray() {\n      return ArrayLists.iarange(RT.intCast(start), RT.intCast(end), RT.intCast(step));\n    }\n    public long[] toLongArray() {\n      return ArrayLists.larange(start, end, step);\n    }\n    public double[] toDoubleArray() {\n      return ArrayLists.darange(start, end, step);\n    }\n    public Object[] toArray() {\n      final int sz = size();\n      final Object[] retval = new Object[sz];\n      long st = start;\n      final long se = step;\n      for(int idx = 0; idx < sz; ++idx, st += se)\n\tretval[idx] = st;\n\n      return retval;\n    }\n    public LongMutList subList(long sidx, long eidx) {\n      ChunkedList.sublistCheck(sidx, eidx, nElems);\n      return new LongRange(start + sidx*step, start + eidx*step, step, meta);\n    }\n    public ISeq seq() { return inplaceSublistSeq(); }\n    public LongMutList subList(int sidx, int eidx) {\n      return subList((long)sidx, (long)eidx);\n    }\n    public Object reduce(final IFn fn, Object init) {\n      if(nElems == 0) return init;\n      Object acc = init;\n      long n = nElems;\n      long i = start;\n      if(!(fn instanceof IFn.OLO))\n\tdo {\n\t  acc = fn.invoke(acc, i);\n\t  if (RT.isReduced(acc)) return ((Reduced)acc).deref();\n\t  i += step;\n\t  n--;\n\t} while(n > 0);\n      else {\n\tfinal IFn.OLO ff = (IFn.OLO)fn;\n\tdo {\n\t  acc = ff.invokePrim(acc, i);\n\t  if (RT.isReduced(acc)) return ((Reduced)acc).deref();\n\t  i += step;\n\t  n--;\n\t} while(n > 0);\n      }\n      return acc;\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t     ParallelOptions options) {\n      return Reductions.parallelIndexGroupReduce(new IFnDef.LLO() {\n\t  public Object invokePrim(long sidx, long eidx) {\n\t    return Reductions.serialReduction(rfn, initValFn.invoke(), subList(sidx, eidx));\n\t  }\n\t}, nElems, mergeFn, options);\n    }\n    public Object lnth(long idx) {\n      final long sz = nElems;\n      if (idx < 0)\n\tidx = idx + sz;\n      return lgetLong(idx);\n    }\n    public Object lnth(long idx, Object notFound) {\n      final long sz = nElems;\n      if (idx < 0)\n\tidx = idx + sz;\n      return idx < sz && idx > -1 ? lgetLong(idx) : notFound;\n    }\n    public Object invoke(Object arg) {\n      return lnth(Casts.longCast(arg));\n    }\n    public Object invoke(Object arg, Object defVal) {\n      if(Util.isInteger(arg)) {\n\treturn lnth(Casts.longCast(arg), defVal);\n      } else {\n\treturn defVal;\n      }\n    }\n    public IPersistentMap meta() { return meta; }\n    public LongRange withMeta(IPersistentMap m) {\n      return new LongRange(start, end, step, m);\n    }\n  };\n\n  public static class DoubleRange implements DoubleMutList, TypedList {\n    public final double start;\n    public final double end;\n    public final double step;\n    public final long nElems;\n    public final IPersistentMap meta;\n    int _hash = 0;\n    public DoubleRange(double s, double e, double _step, IPersistentMap _meta) {\n      start = s;\n      end = e;\n      step = _step;\n      meta = _meta;\n      //Floor to long intentional\n      nElems = Math.max(0, (long)((e - s)/_step));\n      if (nElems < 0)\n\tthrow new IndexOutOfBoundsException(\"Invalid Range - start: \" + String.valueOf(s)\n\t\t\t\t   + \" end: \" + String.valueOf(e) + \" step: \" +\n\t\t\t\t   String.valueOf(_step));\n    }\n    public IMutList cloneList() { return this; }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public int hasheq() {\n      if (_hash == 0) {\n\t_hash = DoubleMutList.super.hasheq();\n      }\n      return _hash;\n    }\n    public String toString() { return Transformables.sequenceToString(this); }\n    public Class containedType() { return Double.TYPE; }\n    public int size() { return RT.intCast(nElems); }\n    public double lgetDouble(long idx) {\n      final long sz = nElems;\n      if(idx < 0)\n\tidx += sz;\n      if(idx < 0 || idx >= sz)\n\tthrow new IndexOutOfBoundsException(\"Index out of range: \" + String.valueOf(idx) +\n\t\t\t\t   \" size: \" + String.valueOf(sz));\n      return start + step*idx;\n    }\n    public ISeq seq() { return inplaceSublistSeq(); }\n    public double getDouble(int idx) { return lgetDouble(idx); }\n    public int[] toIntArray() {\n      final int st = RT.intCast(step);\n      if (st != 0)\n\treturn ArrayLists.iarange(RT.intCast(start), RT.intCast(end), RT.intCast(step));\n      throw new IndexOutOfBoundsException(\"Infinite range: \" + String.valueOf(step) + \" : \" + String.valueOf(st));\n    }\n    public long[] toLongArray() {\n      final long st = Casts.longCast(step);\n      if (st != 0)\n\treturn ArrayLists.larange(Casts.longCast(start), Casts.longCast(end), Casts.longCast(step));\n      throw new IndexOutOfBoundsException(\"Infinite range: \" + String.valueOf(step) + \" : \" + String.valueOf(st));\n    }\n    public double[] toDoubleArray() {\n      return ArrayLists.darange(start, end, step);\n    }\n    public DoubleMutList subList(long sidx, long eidx) {\n      ChunkedList.sublistCheck(sidx, eidx, size());\n      return new DoubleRange(start + sidx*step, start + eidx*step, step, meta);\n    }\n    public DoubleMutList subList(int sidx, int eidx) {\n      return subList((long)sidx, (long)eidx);\n    }\n    public Object reduce(final IFn fn, Object init) {\n      final IFn.ODO rrfn = fn instanceof IFn.ODO ? (IFn.ODO)fn : new IFn.ODO() {\n\t  public Object invokePrim(Object lhs, double v) {\n\t    return fn.invoke(lhs, v);\n\t  }\n\t};\n      return doubleReduction(rrfn, init);\n    }\n    public Object doubleReduction(IFn.ODO op, Object init) {\n      final long sz = nElems;\n      final double se = step;\n      final double st = start;\n      for(long idx = 0; idx < sz && !RT.isReduced(init); ++idx)\n\tinit = op.invokePrim(init, st + (se*idx));\n      return Reductions.unreduce(init);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t     ParallelOptions options) {\n      if(nElems > options.minN) {\n\treturn Reductions.parallelIndexGroupReduce(new IFnDef.LLO() {\n\t    public Object invokePrim(long sidx, long eidx) {\n\t      return Reductions.serialReduction(rfn, initValFn.invoke(), subList(sidx, eidx));\n\t    }\n\t  }, nElems, mergeFn, options);\n      } else {\n\treturn Reductions.serialReduction(rfn, initValFn.invoke(), this);\n      }\n    }\n    public Object lnth(long idx) {\n      final long sz = nElems;\n      if (idx < 0)\n\tidx = idx + sz;\n      return lgetDouble(idx);\n    }\n    public Object lnth(long idx, Object notFound) {\n      final long sz = nElems;\n      if (idx < 0)\n\tidx = idx + sz;\n      return idx < sz && idx > -1 ? lgetDouble(idx) : notFound;\n    }\n    public Object invoke(Object arg) {\n      return lnth(Casts.longCast(arg));\n    }\n    public Object invoke(Object arg, Object defVal) {\n      if(Util.isInteger(arg)) {\n\treturn lnth(Casts.longCast(arg), defVal);\n      } else {\n\treturn defVal;\n      }\n    }\n    public IPersistentMap meta() { return meta; }\n    public DoubleRange withMeta(IPersistentMap m) {\n      return new DoubleRange(start, end, step, m);\n    }\n  };\n}\n"
  },
  {
    "path": "java/ham_fisted/Reducible.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Iterator;\n\n\npublic interface Reducible\n{\n  default Reducible reduceIter(Iterator<Reducible> rest) {\n    Reducible retval = this;\n    while(rest.hasNext())\n      retval = retval.reduce(rest.next());\n    return retval;\n  }\n  Reducible reduce(Reducible rhs);\n}\n"
  },
  {
    "path": "java/ham_fisted/Reductions.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.IDeref;\nimport clojure.lang.Seqable;\nimport clojure.java.api.Clojure;\nimport clojure.lang.Delay;\nimport clojure.lang.AFn;\nimport clojure.lang.Util;\nimport java.util.RandomAccess;\nimport java.util.List;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.Spliterator;\nimport java.util.Collection;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.concurrent.Future;\nimport java.util.concurrent.ForkJoinPool;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ArrayBlockingQueue;\n\n\npublic class Reductions {\n\n  public static IFn ToStringPrint = new AFn() {\n      public Object invoke(Object target, Object ww) {\n\ttry {\n\t  ((java.io.Writer)ww).write(target.toString());\n\t}catch (java.io.IOException e) {\n\t  throw Util.sneakyThrow(e);\n\t}\n\treturn null;\n      }\n    };\n\n  public static Object unreduce(Object obj) {\n    return RT.isReduced(obj) ? ((IDeref)obj).deref() : obj;\n  }\n\n  public interface DoubleAccum extends IFnDef.ODO {}\n\n  public interface LongAccum extends IFnDef.OLO {}\n\n  public static Iterable toIterable(Object obj) {\n    if( obj == null) return null;\n    if( obj instanceof Iterable) return (Iterable)obj;\n    if( obj instanceof Map) return ((Map)obj).entrySet();\n    if( obj.getClass().isArray()) return ArrayLists.toList(obj);\n    if( obj instanceof String) return new StringCollection((String)obj);\n    return (Iterable)RT.seq(obj);\n  }\n\n  public static Object iterReduce(Object obj, IFn fn) {\n    if(obj == null) return fn.invoke();\n\n    final Iterator it = toIterable(obj).iterator();\n    Object init = it.hasNext() ? it.next() : null;\n    while(it.hasNext() && !RT.isReduced(init)) {\n      init = fn.invoke(init, it.next());\n    }\n    return unreduce(init);\n  }\n\n  public static Object iterReduce(Object obj, Object init, IFn fn) {\n    if(obj == null) return init;\n\n    final Iterator it = toIterable(obj).iterator();\n    while(it.hasNext() && !RT.isReduced(init)) {\n      init = fn.invoke(init, it.next());\n    }\n    return unreduce(init);\n  }\n\n  public static Reducible reduceReducibles(Iterable<Reducible> data) {\n    Iterator<Reducible> iter = data.iterator();\n    Reducible initial = iter.hasNext() ? iter.next() : null;\n    return initial.reduceIter(iter);\n  }\n\n  static final Delay collReducePtr = new Delay(new IFnDef() {\n      public Object invoke() {\n\treturn ((IDeref)Clojure.var(\"clojure.core.protocols\", \"coll-reduce\")).deref();\n      }\n    });\n  \n  public static Object serialReduction(IFn rfn, Object init, Object coll) {\n    if( coll == null) return init;\n    if( coll instanceof IReduceInit) {\n      return ((IReduceInit)coll).reduce(rfn, init);\n    }\n    return ((IFn)(collReducePtr.deref())).invoke(coll, rfn, init);\n  }\n  \n  @SuppressWarnings(\"unchecked\")\n  public static Consumer serialReduction(Consumer c, Object coll) {\n    serialReduction(new IFnDef() {\n\tpublic Object invoke(Object acc, Object v) {\n\t  c.accept(v);\n\t  return c;\n\t}\n      }, c, coll);\n    return c;\n  }\n\n  public static Object iterableMerge(ParallelOptions options, IFn mergeFn,\n\t\t\t\t     final Iterable groups) {\n    if(options.unmergedResult)\n      return groups;\n\n    final Iterator giter = groups.iterator();\n    Object initObj = giter.hasNext() ? giter.next() : null;\n    while(giter.hasNext())\n      initObj = mergeFn.invoke(initObj, giter.next());\n    return initObj;\n  }\n\n  public static Object parallelIndexGroupReduce(IFn groupFn, long nElems, IFn mergeFn,\n\t\t\t\t\t\tParallelOptions options) {\n    return iterableMerge(options, mergeFn,\n\t\t\t ForkJoinPatterns.parallelIndexGroups(nElems, groupFn, options));\n  }\n\n  public static Object parallelRandAccessReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t\t\t   List l, ParallelOptions options) {\n    return parallelIndexGroupReduce( new IFnDef.LLO() {\n\tpublic Object invokePrim(long sidx, long eidx) {\n\t  return serialReduction(rfn, initValFn.invoke(),\n\t\t\t\t l.subList(RT.intCast(sidx), RT.intCast(eidx)));\n\t}\n      }, l.size(), mergeFn, options);\n  }\n\n  public static class ReduceConsumer implements Consumer, IDeref {\n    Object init;\n    public final IFn rfn;\n\n    public static class DoubleReduceConsumer extends ReduceConsumer implements DoubleConsumer {\n      public final IFn.ODO dfn;\n      public DoubleReduceConsumer(Object in, IFn _rfn) {\n\tsuper(in, _rfn);\n\tdfn = (IFn.ODO)_rfn;\n      }\n      public void accept(Object obj) { accept(Casts.doubleCast(obj)); }\n      public void accept(double v) {\n\tif(!isReduced())\n\t  init = dfn.invokePrim(init, v);\n      }\n    }\n\n    public static class LongReduceConsumer extends ReduceConsumer implements LongConsumer {\n      public final IFn.OLO dfn;\n      public LongReduceConsumer(Object in, IFn _rfn) {\n\tsuper(in, _rfn);\n\tdfn = (IFn.OLO)_rfn;\n      }\n      public void accept(Object obj) { accept(Casts.longCast(obj)); }\n      public void accept(long v) {\n\tif(!isReduced())\n\t  init = dfn.invokePrim(init, v);\n      }\n    }\n\n    public ReduceConsumer(Object in, IFn _rfn) {\n      init = in;\n      rfn = _rfn;\n    }\n    public void accept(Object obj) {\n      if(!isReduced())\n\tinit = rfn.invoke(init, obj);\n    }\n    public boolean isReduced() {\n      return RT.isReduced(init);\n    }\n    public Object deref() { return init; }\n\n    public static ReduceConsumer create(Object init, IFn rfn) {\n      if(rfn instanceof IFn.ODO) {\n\treturn new DoubleReduceConsumer(init, rfn);\n      } else if (rfn instanceof IFn.OLO) {\n\treturn new LongReduceConsumer(init, rfn);\n      } else {\n\treturn new ReduceConsumer(init,rfn);\n      }\n    }\n  }\n\n  public static Object parallelCollectionReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t\t\t   Collection coll, ParallelOptions options ) {\n    if(coll.size() <= options.minN)\n      return serialReduction(rfn, initValFn.invoke(), coll);\n    return ForkJoinPatterns.parallelSpliteratorReduce(initValFn, rfn, mergeFn,\n\t\t\t\t\t\t      coll.spliterator(), options);\n  }\n\n  public static Delay preducePtr = new Delay( new IFnDef() {\n      public Object invoke() {\n\treturn ((IDeref)Clojure.var(\"ham-fisted.protocols\", \"preduce\")).deref();\n      }\n    });\n\n  public static Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t\t Object coll, ParallelOptions options) {\n    if(coll == null)\n      return options.unmergedResult ?\n\tArrayImmutList.create( true, null, initValFn.invoke() ) :\n\tinitValFn.invoke();\n\n    if(options.parallelism < 2) {\n      return serialParallelReduction(initValFn, rfn, options, coll);\n    }\n\n    //Delegate back to clojure here so we can use a protocol to dispatch the\n    //parallel reduction.\n    return ((IFn)preducePtr.deref()).invoke(coll, initValFn, rfn, mergeFn, options);\n  }\n\n  public static Object serialParallelReduction(IFn initValFn, IFn rfn,\n\t\t\t\t\t       ParallelOptions options,\n\t\t\t\t\t       Object coll) {\n    final Object retval = serialReduction(rfn, initValFn.invoke(), coll);\n    return options.unmergedResult ?\n      ArrayImmutList.create( true, null, retval ) :\n      retval;\n  }\n\n  public static class IndexedDoubleAccum implements IFnDef.ODO {\n    long idx;\n    final IFn.OLDO rfn;\n    public IndexedDoubleAccum(long sidx, IFn.OLDO rfn) {\n      this.rfn = rfn;\n      this.idx = sidx;\n    }\n    public IndexedDoubleAccum(IFn.OLDO rfn) {\n      this(0, rfn);\n    }\n    public Object invokePrim(Object acc, double v) {\n      return rfn.invokePrim(acc, idx++, v);\n    }\n  }\n  public static class IndexedLongAccum implements IFnDef.OLO {\n    long idx;\n    final IFn.OLLO rfn;\n    public IndexedLongAccum(long sidx, IFn.OLLO rfn) {\n      this.rfn = rfn;\n      this.idx = sidx;\n    }\n    public IndexedLongAccum(IFn.OLLO rfn) {\n      this(0, rfn);\n    }\n    public Object invokePrim(Object acc, long v) {\n      return rfn.invokePrim(acc, idx++, v);\n    }\n  }\n  public static class IndexedAccum implements IFnDef {\n    long idx;\n    final IFn.OLOO rfn;\n    public IndexedAccum(long sidx, IFn.OLOO rfn) {\n      this.rfn = rfn;\n      this.idx = sidx;\n    }\n    public IndexedAccum(IFn.OLOO rfn) {\n      this(0, rfn);\n    }\n    public Object invoke(Object acc, Object v) {\n      return rfn.invokePrim(acc, idx++, v);\n    }\n  }\n  static class LongCompose implements IFnDef.OLO {\n    final int nVals;\n    final IFn.OLO[] rfns;\n    public LongCompose(int nVals, Object[] rfns) {\n      this.nVals = nVals;\n      this.rfns = new IFn.OLO[rfns.length];\n      for(int idx = 0; idx < rfns.length; ++idx) {\n\tthis.rfns[idx] = Transformables.toLongReductionFn(rfns[idx]);\n      }\n    }\n    public Object invokePrim(Object acc, long val) {\n      final int nv = nVals;\n      final Object[] objs = (Object[])acc;\n      final IFn.OLO[] rfs = this.rfns;\n      for(int idx = 0; idx < nv; ++idx)\n\tobjs[idx] = rfs[idx].invokePrim(objs[idx], val);\n      return objs;\n    }\n  }\n\n  public static IFn longCompose(final int nVals, final Object[] rfns) {\n    return new LongCompose(nVals, rfns);\n  }\n\n  static class DoubleCompose implements IFnDef.ODO {\n    final int nVals;\n    final IFn.ODO[] rfns;\n    public DoubleCompose(int nVals, Object[] rfns) {\n      this.nVals = nVals;\n      this.rfns = new IFn.ODO[rfns.length];\n      for(int idx = 0; idx < rfns.length; ++idx) {\n\tthis.rfns[idx] = Transformables.toDoubleReductionFn(rfns[idx]);\n      }\n    }\n    public Object invokePrim(Object acc, double val) {\n      final int nv = nVals;\n      final Object[] objs = (Object[])acc;\n      final IFn.ODO[] rfs = this.rfns;\n      for(int idx = 0; idx < nv; ++idx)\n\tobjs[idx] = rfs[idx].invokePrim(objs[idx], val);\n      return objs;\n    }\n  }\n\n  public static IFn doubleCompose(final int nVals, final Object[] rfns) {\n    return new DoubleCompose(nVals, rfns);\n  }\n\n  static class ObjCompose implements IFnDef {\n    final int nVals;\n    final IFn[] rfns;\n    public ObjCompose(int nVals, Object[] rfns) {\n      this.nVals = nVals;\n      this.rfns = new IFn[rfns.length];\n      for(int idx = 0; idx < rfns.length; ++idx) {\n\tthis.rfns[idx] = (IFn)rfns[idx];\n      }\n    }\n    public Object invoke(Object acc, Object val) {\n      final int nv = nVals;\n      final Object[] objs = (Object[])acc;\n      final IFn[] rfs = this.rfns;\n      for(int idx = 0; idx < nv; ++idx)\n\tobjs[idx] = rfs[idx].invoke(objs[idx], val);\n      return objs;\n    }\n  }\n\n  public static IFn objCompose(final int nVals, final Object[] rfns) {\n    return new ObjCompose(nVals, rfns);\n  }\n\n  public static IFn mergeCompose(final int nVals, final Object[] mergeFns) {\n    return new IFnDef() {\n      public Object invoke(Object lhs, Object rhs) {\n\tfinal Object[] l = (Object[])lhs;\n\tfinal Object[] r = (Object[])rhs;\n\tfor(int idx = 0; idx < nVals; ++idx) {\n\t  l[idx] = ((IFn)mergeFns[idx]).invoke(l[idx], r[idx]);\n\t}\n\treturn l;\n      }\n    };\n  }\n  public static Object longSamplerReduction(IFn rfn, Object acc, IFn.LL sampler, long nElems) {\n    final IFn.OLO rrfn = Transformables.toLongReductionFn(rfn);\n    for(long idx = 0; idx < nElems; ++idx) {\n      acc = rrfn.invokePrim(acc, sampler.invokePrim(idx));\n      if(RT.isReduced(acc))\n\treturn ((IDeref)acc).deref();\n    }\n    return acc;\n  }\n\n  public static Object doubleSamplerReduction(IFn rfn, Object acc, IFn.LD sampler, long nElems) {\n    final IFn.ODO rrfn = Transformables.toDoubleReductionFn(rfn);\n    for(long idx = 0; idx < nElems; ++idx) {\n      acc = rrfn.invokePrim(acc, sampler.invokePrim(idx));\n      if(RT.isReduced(acc))\n\treturn ((IDeref)acc).deref();\n    }\n    return acc;\n  }\n  public static Object samplerReduction(IFn rfn, Object acc, IFn sampler, long nElems) {\n    for(long idx = 0; idx < nElems; ++idx) {\n      acc = rfn.invoke(acc, sampler.invoke(idx));\n      if(RT.isReduced(acc))\n\treturn ((IDeref)acc).deref();\n    }\n    return acc;\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ReindexList.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Arrays;\nimport java.util.List;\nimport java.util.Comparator;\nimport it.unimi.dsi.fastutil.ints.IntComparator;\nimport clojure.lang.IPersistentMap;\n\n\npublic class ReindexList implements IMutList, TypedList {\n  final int[] indexes;\n  final List data;\n  final IPersistentMap meta;\n\n  static int checkIndex(final int idx, final int dlen) {\n    if(idx < 0 || idx >= dlen)\n      throw new RuntimeException(\"Index out of range: \" + String.valueOf(idx));\n    return idx;\n  }\n\n  public static ReindexList create(int[] idx, List d, IPersistentMap m) {\n    if(d instanceof IMutList)\n      return new MutReindexList(idx, (IMutList)d, m);\n    return new ReindexList(idx, d, m);\n  }\n\n  public ReindexList(int[] idx, List d, IPersistentMap m) {\n    indexes = idx;\n    data = d;\n    meta = m;\n  }\n\n  public Class containedType() { return data instanceof TypedList ? ((TypedList)data).containedType() : null; }\n  public int size() { return indexes.length; }\n  public Object get(int idx) {\n    checkIndex(idx, indexes.length);\n    return data.get(indexes[idx]);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public Object set(int idx, Object nv) {\n    checkIndex(idx, indexes.length);\n    return data.set(indexes[idx], nv);\n  }\n  public ReindexList subList(int sidx, int eidx) {\n    return ReindexList.create(Arrays.copyOfRange(indexes, sidx, eidx), data, meta);\n  }\n  @SuppressWarnings(\"unchecked\")\n  public IntComparator indexComparator() {\n    if(data instanceof IMutList) {\n      final IMutList d = (IMutList)data;\n      IntComparator srcComparator = d.indexComparator();\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return srcComparator.compare(indexes[lidx], indexes[ridx]);\n\t}\n      };\n    }\n    return new IntComparator() {\n      public int compare(int lidx, int ridx) {\n\treturn ((Comparable)(data.get(indexes[lidx]))).compareTo(data.get(indexes[ridx]));\n      }\n    };\n  }\n  @SuppressWarnings(\"unchecked\")\n  public IntComparator indexComparator(Comparator comp) {\n    if (comp == null) return indexComparator();\n    if (data instanceof IMutList) {\n      final IMutList d = (IMutList)data;\n      IntComparator srcComparator = d.indexComparator(comp);\n      return new IntComparator() {\n\tpublic int compare(int lidx, int ridx) {\n\t  return srcComparator.compare(indexes[lidx], indexes[ridx]);\n\t}\n      };\n    }\n    return new IntComparator() {\n      public int compare(int lidx, int ridx) {\n\treturn comp.compare(data.get(indexes[lidx]), data.get(indexes[ridx]));\n      }\n    };\n  }\n  public IPersistentMap meta() { return meta; }\n  public ReindexList withMeta(IPersistentMap m) {\n    return ReindexList.create(indexes, data, m);\n  }\n  public List reindex(int[] newIndexes) {\n    final int nsz = newIndexes.length;\n    final int[] idxs = new int[nsz];\n    boolean inOrder = true;\n    for (int idx = 0; idx < nsz; ++idx) {\n      final int nidx = indexes[newIndexes[idx]];\n      inOrder = inOrder && nidx == idx;\n      idxs[idx] = nidx;\n    }\n    //If we are in-order, no new indexing is required.\n    if(inOrder) {\n      if (nsz == data.size())\n\treturn data;\n      else\n\treturn data.subList(0, nsz);\n    }\n    //Else create one new reindex with new indexes.  This keeps the cost\n    //of indirection to a the cost of 1 reindexing operation.\n    return ReindexList.create(idxs, data, meta);\n  }\n  public static class MutReindexList extends ReindexList {\n    IMutList mlist;\n    public MutReindexList(int[] indexes, IMutList ml, IPersistentMap meta) {\n      super(indexes, ml, meta);\n      mlist = ml;\n    }\n    public long getLong(int idx) {\n      checkIndex(idx, indexes.length);\n      return mlist.getLong(indexes[idx]);\n    }\n    public void setLong(int idx, long nv) {\n      checkIndex(idx, indexes.length);\n      mlist.setLong(indexes[idx], nv);\n    }\n    public double getDouble(int idx) {\n      checkIndex(idx, indexes.length);\n      return mlist.getDouble(indexes[idx]);\n    }\n    public void setDouble(int idx, double nv) {\n      checkIndex(idx, indexes.length);\n      mlist.setDouble(indexes[idx], nv);\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/ReverseList.java",
    "content": "package ham_fisted;\n\nimport java.util.List;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IObj;\n\n\npublic class ReverseList implements IMutList, TypedList {\n  final List data;\n  final IPersistentMap meta;\n  final int nElems;\n  final int nne;\n  int _hash = 0;\n\n\n  public ReverseList(List _data, IPersistentMap _meta) {\n    data = _data;\n    meta = _meta;\n    nElems = data.size();\n    nne = nElems - 1;\n  }\n\n  public static ReverseList create(List data, IPersistentMap meta) {\n    return data instanceof IMutList ? new MutReverseList((IMutList)data, meta) : new ReverseList(data, meta);\n  }\n\n  public String toString() { return Transformables.sequenceToString(this); }\n  public int hashCode() { return hasheq(); }\n  public int hasheq() {\n    if (_hash == 0) {\n      _hash = IMutList.super.hasheq();\n    }\n    return _hash;\n  }\n  public boolean equals(Object other) { return equiv(other); }\n  public Class containedType() { return data instanceof TypedList ? ((TypedList)data).containedType() : null; }\n  public int size() { return nElems; }\n  public Object get(int idx) { if(idx < 0) idx += nElems; return data.get(nne-idx); }\n  public ReverseList subList(int sidx, int eidx) {\n    sidx = nElems - sidx;\n    eidx = nElems - eidx;\n    return new ReverseList(data.subList(eidx, sidx), meta);\n  }\n  public List reverse() { return data instanceof IObj ? (List)((IObj)data).withMeta(meta) : data; }\n  public IPersistentMap meta() { return meta; }\n  public ReverseList withMeta(IPersistentMap m) { return new ReverseList(data, m); }\n\n\n  public static class MutReverseList extends ReverseList {\n    final IMutList mlist;\n    public MutReverseList(IMutList ml, IPersistentMap meta) {\n      super(ml, meta);\n      mlist = ml;\n    }\n    public long getLong(int idx) {\n      return mlist.getLong(nne - idx);\n    }\n    public double getDouble(int idx) {\n      return mlist.getDouble(nne - idx);\n    }\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/SetOps.java",
    "content": "package ham_fisted;\n\nimport java.util.Set;\nimport java.util.Collection;\n\npublic interface SetOps {\n  Set union(Collection rhs);\n  Set intersection(Set rhs);\n  Set difference(Set rhs);\n}\n"
  },
  {
    "path": "java/ham_fisted/StringCollection.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.RandomAccess;\nimport java.util.Iterator;\nimport java.util.ListIterator;\nimport java.util.Arrays;\nimport java.util.Objects;\nimport clojure.lang.IReduce;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport ham_fisted.Reductions;\n\n\npublic class StringCollection implements IMutList<Character> {\n  public final  String cs;\n  public StringCollection(String _cs) {\n    cs = _cs;\n  }\n  public final int size() { return cs.length(); }\n  public final Character get(int idx) { return cs.charAt(idx); }\n  public final IMutList<Character> subList(int startidx, int endidx) {\n    return new StringCollection((String)cs.subSequence(startidx, endidx));\n  }\n  public final Object[] fillArray(Object[] data) {\n    Reductions.serialReduction(new Reductions.IndexedAccum( new IFnDef.OLOO() {\n\tpublic Object invokePrim(Object acc, long idx, Object v) {\n\t  ((Object[])acc)[(int)idx] = v;\n\t  return acc;\n\t}\n      }),  data, this);\n    return data;\n  }\n  public Object reduce(IFn rfn) {\n    final int sz = size();\n    if (sz == 0) return rfn.invoke();\n    Object acc = null;\n    for( int idx = 0; idx < sz && !RT.isReduced(acc); ++idx)\n      acc = idx == 0 ? cs.charAt(idx) : rfn.invoke(acc, cs.charAt(idx));\n    return Reductions.unreduce(acc);\n  }\n\n  public Object reduce(IFn rfn, Object acc) {\n    final int sz = size();\n    for( int idx = 0; idx < sz && !RT.isReduced(acc); ++idx)\n      rfn.invoke(acc, cs.charAt(idx));\n    return Reductions.unreduce(acc);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/Sum.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.IDeref;\nimport clojure.lang.Keyword;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.PersistentArrayMap;\nimport java.util.function.DoubleConsumer;\nimport java.util.Collection;\n\n\n\npublic final class Sum implements Consumers.IDerefDoubleConsumer, Reducible\n{\n  public static final Keyword sumKwd = Keyword.intern(null, \"sum\");\n  public static final Keyword nElemsKwd = Keyword.intern(null, \"n-elems\");\n  //Low order summation bits\n  public double d0;\n  //High order summation bits\n  public double d1;\n  public double simpleSum;\n  public long nElems;\n  /**\n   * Incorporate a new double value using Kahan summation /\n   * compensation summation.\n   *\n   * High-order bits of the sum are in intermediateSum[0], low-order\n   * bits of the sum are in intermediateSum[1], any additional\n   * elements are application-specific.\n   *\n   * @param intermediateSum the high-order and low-order words of the intermediate sum\n   * @param value the name value to be included in the running sum\n   */\n  public void sumWithCompensation(double value) {\n    double tmp = value - d1;\n    double sum = d0;\n    double velvel = sum + tmp; // Little wolf of rounding error\n    d1 =  (velvel - sum) - tmp;\n    d0 = velvel;\n  }\n\n  public double computeFinalSum() {\n    // Better error bounds to add both terms as the final sum\n    double tmp = d0 + d1;\n    if (Double.isNaN(tmp) && Double.isInfinite(simpleSum))\n      return simpleSum;\n    else\n      return tmp;\n  }\n\n  public Sum(double _d0, double _d1, double _simpleSum, long _nElems) {\n    d0 = _d0;\n    d1 = _d1;\n    simpleSum = _simpleSum;\n    nElems = _nElems;\n  }\n  public Sum() {\n    this(0, 0, 0, 0);\n  }\n  public void acceptDouble(double data) {\n    sumWithCompensation(data);\n    simpleSum += data;\n    nElems++;\n  }\n\n  public void merge(Sum other) {\n    final long ne = nElems;\n    accept(other.computeFinalSum());\n    nElems = ne + other.nElems;\n  }\n\n  public Sum reduce(Reducible other) {\n    final Sum retval = new Sum(d0, d1, simpleSum, nElems);\n    retval.merge((Sum)other);\n    return retval;\n  }\n\n  public Object deref() {\n    return new PersistentArrayMap(new Object[] { sumKwd, computeFinalSum(), nElemsKwd, nElems });\n  }\n\n  public static class SimpleSum implements Consumers.IDerefDoubleConsumer, Reducible\n  {\n    double simpleSum;\n    public SimpleSum() { simpleSum = 0.0; }\n    public SimpleSum(SimpleSum o) { simpleSum = o.simpleSum; }\n    public void acceptDouble(double val) { simpleSum += val; }\n    public SimpleSum reduce(Reducible other) {\n      final SimpleSum retval = new SimpleSum(this);\n      retval.accept(((SimpleSum)other).simpleSum);\n      return retval;\n    }\n    public Object deref() {\n      return simpleSum;\n    }\n  };\n}\n"
  },
  {
    "path": "java/ham_fisted/Transformables.java",
    "content": "package ham_fisted;\n\nimport java.util.List;\nimport java.util.AbstractCollection;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.HashMap;\nimport java.util.Arrays;\nimport java.util.Map;\nimport java.util.Objects;\nimport java.util.RandomAccess;\nimport java.util.Collection;\nimport java.util.BitSet;\nimport java.util.concurrent.atomic.AtomicReference;\nimport java.util.function.UnaryOperator;\nimport java.util.function.BiFunction;\nimport java.util.function.Consumer;\nimport java.util.function.DoubleConsumer;\nimport java.util.function.LongConsumer;\nimport java.util.function.Predicate;\nimport java.util.function.LongPredicate;\nimport java.util.function.DoublePredicate;\nimport java.util.function.Supplier;\n\nimport clojure.lang.IFn;\nimport clojure.lang.ArraySeq;\nimport clojure.lang.Seqable;\nimport clojure.lang.RT;\nimport clojure.lang.IteratorSeq;\nimport clojure.lang.ISeq;\nimport clojure.lang.IObj;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IReduce;\nimport clojure.lang.IReduceInit;\nimport clojure.lang.IDeref;\nimport clojure.lang.Sequential;\nimport clojure.lang.Murmur3;\nimport clojure.lang.Util;\nimport clojure.lang.IHashEq;\nimport clojure.lang.IPersistentCollection;\nimport clojure.lang.PersistentList;\nimport clojure.lang.Reduced;\nimport clojure.lang.Delay;\nimport clojure.lang.Box;\nimport clojure.java.api.Clojure;\n\n\npublic class Transformables {\n\n  public static final Delay toIterableDelay = new Delay(new IFnDef() {\n      public Object invoke() {\n\treturn ((IDeref)Clojure.var(\"ham-fisted.protocols\", \"->iterable\")).deref();\n      }\n    } );\n\n  public static final Iterable toIterable(Object obj) {\n    if (obj instanceof Iterable)\n      return (Iterable) obj;\n    //else bail to protocol\n    return (Iterable)((IFn)toIterableDelay.deref()).invoke(obj);\n  }\n  public interface IMapable extends Iterable, IObj {\n    default IMapable map(IFn fn) {\n      return new MapIterable(fn, meta(), this);\n    }\n    default IMapable filter(IFn fn) {\n      return new FilterIterable(fn, meta(), this);\n    }\n    default IMapable cat(Iterable iters) {\n      return new CatIterable(meta(), new Iterable[]{ArrayLists.toList(new Iterable[] { this }), iters});\n    }\n  }\n  public static boolean truthy(final Object obj) {\n    return Casts.booleanCast(obj);\n  }\n  public static boolean not(final Object obj) {\n    return obj == null || obj == Boolean.FALSE;\n  }\n  public static boolean not(final boolean v) {\n    return !v;\n  }\n  public static IFn toReductionFn(Object rfn) {\n    if(rfn instanceof IFn) return (IFn)rfn;\n    if(rfn instanceof IFn.OLO) {\n      final IFn.OLO rrfn = (IFn.OLO)rfn;\n      return new IFnDef() {\n\tpublic Object invoke(Object lhs, Object rhs) {\n\t  return rrfn.invokePrim(lhs, Casts.longCast(rhs));\n\t}\n      };\n    }\n    if(rfn instanceof IFn.ODO) {\n      final IFn.ODO rrfn = (IFn.ODO)rfn;\n      return new IFnDef() {\n\tpublic Object invoke(Object lhs, Object rhs) {\n\t  return rrfn.invokePrim(lhs, Casts.doubleCast(rhs));\n\t}\n      };\n    }\n    else\n      throw new RuntimeException(\"Unrecognised function type: \" + String.valueOf(rfn.getClass()));\n  }\n\n  public static IFn.OLO toLongReductionFn(Object rfn) {\n    if(rfn instanceof IFn.OLO) {\n      return (IFn.OLO)rfn;\n    }\n    if(rfn instanceof IFnDef.ODO) {\n      final IFn.ODO rrfn = (IFn.ODO)rfn;\n      return new IFnDef.OLO() {\n\tpublic Object invokePrim(Object lhs, long rhs) {\n\t  return rrfn.invokePrim(lhs, (double)rhs);\n\t}\n      };\n    }\n    IFn rrfn = (IFn)rfn;\n    return new IFnDef.OLO() {\n      public Object invokePrim(Object lhs, long rhs) {\n\treturn rrfn.invoke(lhs, rhs);\n      }\n    };\n  }\n\n  public static IFn.ODO toDoubleReductionFn(Object rfn) {\n    if(rfn instanceof IFn.ODO) {\n      return (IFn.ODO)rfn;\n    }\n    if(rfn instanceof IFnDef.OLO) {\n      final IFn.OLO rrfn = (IFn.OLO)rfn;\n      return new IFnDef.ODO() {\n\tpublic Object invokePrim(Object lhs, double rhs) {\n\t  return rrfn.invokePrim(lhs, Casts.longCast(rhs));\n\t}\n      };\n    }\n    IFn rrfn = (IFn)rfn;\n    return new IFnDef.ODO() {\n      public Object invokePrim(Object lhs, double rhs) {\n\treturn rrfn.invoke(lhs, rhs);\n      }\n    };\n  }\n\n  public static int iterCount(Iterator iter) {\n    int c = 0;\n    while(iter.hasNext()) {\n      c++;\n      iter.next();\n    }\n    return c;\n  }\n  public static IFn mapReducer(final IFn rfn, final IFn mapFn) {\n    return new IFnDef() {\n      public Object invoke() { return rfn.invoke(); }\n      public Object invoke(Object res) { return rfn.invoke(res); }\n      public Object invoke(Object lhs, Object rhs) {\n\treturn rfn.invoke(lhs, mapFn.invoke(rhs));\n      }\n      public Object applyTo(Object arglist) {\n\treturn rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n      }\n    };\n  }\n  public static IFn longMapReducer(final IFn rfn, final IFn mapFn) {\n    final IFn.OLO rr = (IFn.OLO)rfn;\n    if (mapFn instanceof IFn.OL) {\n      final IFn.OL mfn = (IFn.OL)mapFn;\n      return new IFnDef() {\n\tpublic Object invoke() { return rfn.invoke(); }\n\tpublic Object invoke(Object res) { return rfn.invoke(res); }\n\tpublic Object invoke(Object lhs, Object v) {\n\t  return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t}\n\tpublic Object applyTo(Object arglist) {\n\t  return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t}\n      };\n    } else if (mapFn instanceof IFn.LL) {\n      final IFn.LL mfn = (IFn.LL)mapFn;\n      return new Reductions.LongAccum() {\n\tpublic Object invoke() { return rfn.invoke(); }\n\tpublic Object invoke(Object res) { return rfn.invoke(res); }\n\tpublic Object invokePrim(Object lhs, long v) {\n\t  return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t}\n\tpublic Object applyTo(Object arglist) {\n\t  return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t}\n      };\n    } else {\n      final IFn.DL mfn = (IFn.DL)mapFn;\n      return new Reductions.DoubleAccum() {\n\tpublic Object invoke() { return rfn.invoke(); }\n\tpublic Object invoke(Object res) { return rfn.invoke(res); }\n\tpublic Object invokePrim(Object lhs, double v) {\n\t  return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t}\n\tpublic Object applyTo(Object arglist) {\n\t  return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t}\n      };\n    }\n  }\n\n  final static HashMap<Class,BiFunction<IFn,IFn,IFn>> mappingReducer = new HashMap<Class,BiFunction<IFn,IFn,IFn>>();\n  static {\n    mappingReducer.put(IFn.LD.class, (IFn rfn, IFn mapFn)-> {\n\tfinal IFn.ODO rr = toDoubleReductionFn(rfn);\n\tfinal IFn.LD mfn = (IFn.LD)mapFn;\n\treturn new IFnDef.OLO() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, long v) {\n\t    return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t  }\n\t  public Object applyTo(Object arglist) {\n\t    return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t  }\n\t};\n      });\n    mappingReducer.put(IFnDef.LD.class, mappingReducer.get(IFn.LD.class));\n    mappingReducer.put(IFn.OD.class, (IFn rfn, IFn mapFn)->{\n\tfinal IFn.ODO rr = toDoubleReductionFn(rfn);\n\tfinal IFn.OD mfn = (IFn.OD)mapFn;\n\treturn new IFnDef.OOO() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invoke(Object lhs, Object v) {\n\t    return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t  }\n\t  public Object applyTo(Object arglist) {\n\t    return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t  }\n\t};\n      });\n    mappingReducer.put(IFnDef.OD.class, mappingReducer.get(IFn.OD.class));\n    mappingReducer.put(IFn.DD.class, (IFn rfn, IFn mapFn)-> {\n\tfinal IFn.ODO rr = toDoubleReductionFn(rfn);\n\tfinal IFn.DD mfn = (IFn.DD)mapFn;\n\treturn new IFnDef.ODO() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, double rhs) {\n\t    return rr.invokePrim(lhs, mfn.invokePrim(rhs));\n\t  }\n\t  public Object applyTo(Object arglist) {\n\t    return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t  }\n\t};\n      });\n    mappingReducer.put(IFnDef.DD.class, mappingReducer.get(IFn.DD.class));\n    mappingReducer.put(IFn.OL.class, (IFn rfn, IFn mapFn)-> {\n\tfinal IFn.OLO rr = toLongReductionFn(rfn);\n\tfinal IFn.OL mfn = (IFn.OL)mapFn;\n\treturn new IFnDef() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invoke(Object lhs, Object v) {\n\t    return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t  }\n\t  public Object applyTo(Object arglist) {\n\t    return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t  }\n\t};\n      });\n    mappingReducer.put(IFnDef.OL.class, mappingReducer.get(IFn.OL.class));\n    mappingReducer.put(IFn.DL.class, (IFn rfn, IFn mapFn)-> {\n\tfinal IFn.OLO rr = toLongReductionFn(rfn);\n\tfinal IFn.DL mfn = (IFn.DL)mapFn;\n\treturn new IFnDef.ODO() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, double v) {\n\t    return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t  }\n\t  public Object applyTo(Object arglist) {\n\t    return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t  }\n\t};\n      });\n    mappingReducer.put(IFnDef.DL.class, mappingReducer.get(IFn.DL.class));\n    mappingReducer.put(IFn.LL.class, (IFn rfn, IFn mapFn)-> {\n\tfinal IFn.OLO rr = toLongReductionFn(rfn);\n\tfinal IFn.LL mfn = (IFn.LL)mapFn;\n\treturn new IFnDef.OLO() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, long v) {\n\t    return rr.invokePrim(lhs, mfn.invokePrim(v));\n\t  }\n\t  public Object applyTo(Object arglist) {\n\t    return rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n\t  }\n\t};\n      });\n    mappingReducer.put(IFnDef.LL.class, mappingReducer.get(IFn.LL.class));\n  }\n\n  public static IFn typedMapReducer(IFn rfn, IFn mapFn) {\n    final Class[] ifaces = mapFn.getClass().getInterfaces();\n    final int il = ifaces.length;\n    for(int idx = 0; idx < il; ++idx) {\n      final BiFunction<IFn, IFn, IFn> ff = mappingReducer.get(ifaces[idx]);\n      if(ff != null)\n\treturn ff.apply(rfn, mapFn);\n    }\n    return new IFnDef() {\n      public Object invoke() { return rfn.invoke(); }\n      public Object invoke(Object res) { return rfn.invoke(res); }\n      public Object invoke(Object lhs, Object v) {\n\treturn rfn.invoke(lhs, mapFn.invoke(v));\n      }\n      public Object applyTo(Object arglist) {\n\treturn rfn.invoke(RT.first(arglist), mapFn.applyTo(RT.next(arglist)));\n      }\n    };\n  }\n  public static Object singleMapReduce(final Object item, final IFn rfn,\n\t\t\t\t       final IFn mapFn, Object init) {\n    return Reductions.serialReduction(typedMapReducer(rfn, mapFn), init, item);\n  }\n\n  public static boolean seqEquiv(Seqable ss, Object o){\n\tISeq s = ss.seq();\n\tif(s != null)\n\t  return s.equiv(o);\n\telse\n\t  return (o instanceof Sequential || o instanceof List) && RT.seq(o) == null;\n  }\n\n  public static int seqHashCode(Seqable ss) {\n    ISeq s = ss.seq();\n    if(s == null)\n      return 1;\n    return Util.hash(s);\n  }\n\n  public interface IterableSeq extends Collection, Seqable, IMapable, ITypedReduce,\n\t\t\t\t       IHashEq, Sequential, IPersistentCollection {\n    default int hasheq() { return Murmur3.hashOrdered(this); }\n    default boolean equiv(Object o) { return seqEquiv(this, o); }\n    default int count() {\n      long retval = 0;\n      final Iterator iter = iterator();\n      while(iter.hasNext()) {\n\t++retval;\n\titer.next();\n      }\n      return RT.intCast(retval);\n    }\n    default IPersistentCollection cons(Object o) {\n      return RT.cons(o, seq());\n    }\n    default IPersistentCollection empty() {\n      return PersistentList.EMPTY;\n    }\n    @SuppressWarnings(\"unchecked\")\n    default void forEach(Consumer c) {\n      ITypedReduce.super.forEach(c);\n    }\n    default ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(iterator()); }\n  }\n\n  public static class MapIterable\n    extends AbstractCollection\n    implements IterableSeq {\n    final Object[] iterables;\n    final IFn fn;\n    final IPersistentMap meta;\n    public MapIterable(IFn _fn, IPersistentMap _meta, Object... _its) {\n      fn = _fn;\n      meta = _meta;\n      iterables = _its;\n    }\n    public static MapIterable createSingle(IFn fn, IPersistentMap meta, Object single) {\n      return new MapIterable(fn, meta, new Object[] { single });\n    }\n    public MapIterable(MapIterable o, IPersistentMap m) {\n      fn = o.fn;\n      iterables = o.iterables;\n      meta = m;\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean isEmpty() {\n      return iterator().hasNext() == false;\n    }\n    public int size() {\n      return iterCount(iterator());\n    }\n    static class SingleIterator implements Iterator {\n      final Iterator iter;\n      final IFn fn;\n      public SingleIterator(IFn _fn, Iterator it) {\n\titer = it;\n\tfn = _fn;\n      }\n      public boolean hasNext() { return iter.hasNext(); }\n      public Object next() { return fn.invoke(iter.next()); }\n    }\n\n    static class DualIterator implements Iterator {\n      final Iterator lhs;\n      final Iterator rhs;\n      final IFn fn;\n      public DualIterator(IFn f, Iterator l, Iterator r) {\n\tlhs = l;\n\trhs = r;\n\tfn = f;\n      }\n      public boolean hasNext() { return lhs.hasNext() && rhs.hasNext(); }\n      public Object next() {\n\treturn fn.invoke(lhs.next(), rhs.next());\n      }\n    }\n\n    public Iterator iterator() {\n      final int ss = iterables.length;\n      switch(ss) {\n      case 1: return new SingleIterator(fn, toIterable(iterables[0]).iterator());\n      case 2: return new DualIterator(fn, toIterable(iterables[0]).iterator(),\n\t\t\t\t      toIterable(iterables[1]).iterator());\n      default:\n\tfinal Iterator[] iterators = new Iterator[ss];\n\tfor(int idx = 0; idx < ss; ++idx) {\n\t  iterators[idx] = toIterable(iterables[idx]).iterator();\n\t}\n\treturn new Iterator() {\n\t  public boolean hasNext() {\n\t    for(int idx = 0; idx < ss; ++idx)\n\t      if( iterators[idx].hasNext() == false)\n\t\treturn false;\n\t    return true;\n\t  }\n\t  public Object next() {\n\t    switch(ss) {\n\t    case 3: return fn.invoke(iterators[0].next(), iterators[1].next(), iterators[2].next());\n\t    case 4: return fn.invoke(iterators[0].next(), iterators[1].next(), iterators[2].next(), iterators[3].next());\n\t    default:\n\t      Object[] args = new Object[ss];\n\t      for (int idx = 0; idx < ss; ++idx)\n\t\targs[idx] = iterators[idx].next();\n\t      return fn.applyTo(ArraySeq.create(args));\n\t    }\n\t  }\n\t};\n      }\n    }\n    public ISeq seq() {\n      return LazyChunkedSeq.chunkIteratorSeq(iterator());\n    }\n    public boolean equals(Object o) { return equiv(o); }\n    public int hashCode(){ return hasheq(); }\n\n    public MapIterable map(IFn nfn) {\n      return new MapIterable(MapFn.create(fn, nfn), meta(), iterables);\n    }\n    public IPersistentMap meta() { return meta; }\n    public MapIterable withMeta(IPersistentMap m) {\n      return new MapIterable(this, m);\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      final int nLists = iterables.length;\n      if(nLists == 1) {\n\treturn singleMapReduce(iterables[0], rfn, fn, acc);\n      } else {\n\tfinal Iterator[] iterators = new Iterator[nLists];\n\tfor(int idx = 0; idx < nLists; ++idx)\n\t  iterators[idx] = toIterable(iterables[idx]).iterator();\n\tswitch(iterables.length) {\n\tcase 2: {\n\t  final Iterator l = iterators[0];\n\t  final Iterator r = iterators[1];\n\t  while(l.hasNext() && r.hasNext()) {\n\t    acc = rfn.invoke(acc, fn.invoke(l.next(), r.next()));\n\t    if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t  }\n\t  break;\n\t}\n\tcase 3: {\n\t  final Iterator x = iterators[0];\n\t  final Iterator y = iterators[1];\n\t  final Iterator z = iterators[2];\n\t  while(x.hasNext() && y.hasNext() && z.hasNext()) {\n\t    acc = rfn.invoke(acc, fn.invoke(x.next(), y.next(), z.next()));\n\t    if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t  }\n\t  break;\n\t}\n\tcase 4: {\n\t  final Iterator x = iterators[0];\n\t  final Iterator y = iterators[1];\n\t  final Iterator z = iterators[2];\n\t  final Iterator w = iterators[3];\n\t  while(x.hasNext() && y.hasNext() && z.hasNext() && w.hasNext()) {\n\t    acc = rfn.invoke(acc, fn.invoke(x.next(), y.next(), z.next(), w.next()));\n\t    if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t  }\n\t  break;\n\t}\n\tdefault: {\n\t  boolean hn = true;\n\t  for(int idx = 0; idx < nLists && hn; ++idx) {\n\t    hn = hn && iterators[idx].hasNext();\n\t  }\n\t  if(hn) {\n\t    final Object[] args = new Object[nLists];\n\t    final ISeq argSeq = ArraySeq.create(args);\n\t    while(hn) {\n\t      for(int idx = 0; idx < nLists && hn; ++idx) {\n\t\targs[idx] = iterators[idx].next();\n\t      }\n\t      acc = rfn.invoke(acc, fn.applyTo(argSeq));\n\t      if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t      for(int idx = 0; idx < nLists && hn; ++idx) {\n\t\thn = hn && iterators[idx].hasNext();\n\t      }\n\t    }\n\t  }\n\t}\n\t}\n      }\n      return acc;\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t    ParallelOptions options) {\n      if(iterables.length == 1) {\n\treturn Reductions.parallelReduction(initValFn, typedMapReducer(rfn, fn), mergeFn,\n\t\t\t\t\t    iterables[0], options);\n      } else {\n\treturn Reductions.serialParallelReduction(initValFn, rfn, options, this);\n      }\n    }\n    public Object[] toArray() {\n      return ArrayLists.toArray(this);\n    }\n  }\n  public static class PredFn implements IFnDef {\n    static IFn create(IFn src, IFn dst) {\n      if ((src instanceof LongPredicate) && (dst instanceof LongPredicate)) {\n\tfinal LongPredicate ss = (LongPredicate)src;\n\tfinal LongPredicate dd = (LongPredicate)dst;\n\treturn new IFnDef.LongPredicate() {\n\t  public boolean test(long v) {\n\t    return ss.test(v) && dd.test(v);\n\t  }\n\t};\n      } else if((src instanceof IFn.LO) && (dst instanceof IFn.LO)) {\n\tfinal IFn.LO ss = (IFn.LO)src;\n\tfinal IFn.LO dd = (IFn.LO)dst;\n\treturn new IFnDef.LO() {\n\t  public Object invokePrim(long v) {\n\t    return truthy(ss.invokePrim(v)) && truthy(dd.invokePrim(v));\n\t  }\n\t};\n      } else if ((src instanceof DoublePredicate) && (dst instanceof DoublePredicate)) {\n\tfinal DoublePredicate ss = (DoublePredicate)src;\n\tfinal DoublePredicate dd = (DoublePredicate)dst;\n\treturn new IFnDef.DoublePredicate() {\n\t  public boolean test(double v) {\n\t    return ss.test(v) && dd.test(v);\n\t  }\n\t};\n      } else if((src instanceof IFn.DO) && (dst instanceof IFn.DO)) {\n\tfinal IFn.DO ss = (IFn.DO)src;\n\tfinal IFn.DO dd = (IFn.DO)dst;\n\treturn new IFnDef.DO() {\n\t  public Object invokePrim(double v) {\n\t    return truthy(ss.invokePrim(v)) && truthy(dd.invokePrim(v));\n\t  }\n\t};\n      } else if ((src instanceof Predicate) && (dst instanceof Predicate)) {\n\tfinal Predicate ss = (Predicate)src;\n\tfinal Predicate dd = (Predicate)dst;\n\treturn new IFnDef.Predicate() {\n\t  @SuppressWarnings(\"unchecked\")\n\t  public boolean test(Object v) {\n\t    return ss.test(v) && dd.test(v);\n\t  }\n\t};\n      } else {\n\treturn new PredFn(src,dst);\n      }\n    }\n\n    final IFn srcPred;\n    final IFn dstPred;\n    public PredFn(IFn sp, IFn dp) {\n      srcPred = sp;\n      dstPred = dp;\n    }\n    public Object invoke(Object v) {\n      return truthy(srcPred.invoke(v)) && truthy(dstPred.invoke(v));\n    }\n  };\n  public static class FilterIterable\n    extends AbstractCollection\n    implements IterableSeq {\n    final IFn pred;\n    final Object src;\n    final IPersistentMap meta;\n    public FilterIterable(IFn _p, IPersistentMap _meta, Object _i) {\n      pred = _p;\n      src = _i;\n      meta = _meta;\n    }\n    public FilterIterable(FilterIterable o, IPersistentMap m) {\n      pred = o.pred;\n      src = o.src;\n      meta = m;\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean isEmpty() {\n      return seq() == null;\n    }\n    public int size() { return iterCount(iterator()); }\n    static class FilterIterator implements Iterator {\n      final Iterator iter;\n      final IFn pred;\n      Box nextObj = new Box(null);\n      public FilterIterator(Iterator _i, IFn p) {\n\titer = _i;\n\tpred = p;\n\tadvance();\n      }\n      void advance() {\n\twhile(iter.hasNext()) {\n\t  final Object nobj = iter.next();\n\t  if (truthy(pred.invoke(nobj))) {\n\t    nextObj.val = nobj;\n\t    return;\n\t  }\n\t}\n\tnextObj = null;\n      }\n      public boolean hasNext() { return nextObj != null; }\n      public Object next() {\n\tif (nextObj == null)\n\t  throw new NoSuchElementException();\n\tfinal Object retval = nextObj.val;\n\tadvance();\n\treturn retval;\n      }\n    }\n    public Iterator iterator() {\n      return new FilterIterator(toIterable(src).iterator(), pred);\n    }\n\n    public int hashCode(){ return hasheq(); }\n    public boolean equals(Object o) { return equiv(o); }\n    public ISeq seq() {\n      return LazyChunkedSeq.chunkIteratorSeq(iterator());\n    }\n    public IMapable filter(IFn nfn) {\n      return new FilterIterable(PredFn.create(pred, nfn), meta(), src);\n    }\n    public IPersistentMap meta() { return meta; }\n    public FilterIterable withMeta(IPersistentMap m) {\n      return new FilterIterable(this, m);\n    }\n    @SuppressWarnings(\"unchecked\")\n    public static IFn typedReducer(final IFn rfn, final IFn pred) {\n      if(pred instanceof LongPredicate) {\n\tfinal LongPredicate pfn = (LongPredicate)pred;\n\tfinal IFn.OLO rrfn = toLongReductionFn(rfn);\n\treturn new Reductions.LongAccum() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, long v) {\n\t    return pfn.test(v) ? rrfn.invokePrim(lhs, v) : lhs;\n\t  }\n\t};\n      } else if(pred instanceof IFn.LO) {\n\tfinal IFn.LO pfn = (IFn.LO)pred;\n\tfinal IFn.OLO rrfn = toLongReductionFn(rfn);\n\treturn new Reductions.LongAccum() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, long v) {\n\t    return truthy(pfn.invokePrim(v)) ? rrfn.invokePrim(lhs, v) : lhs;\n\t  }\n\t};\n      } else if (pred instanceof DoublePredicate) {\n\tfinal DoublePredicate pfn = (DoublePredicate)pred;\n\tfinal IFn.ODO rrfn = toDoubleReductionFn(rfn);\n\treturn new Reductions.DoubleAccum() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, double v) {\n\t    return pfn.test(v) ? rrfn.invokePrim(lhs, v) : lhs;\n\t  }\n\t};\n      } else if (pred instanceof IFn.DO) {\n\tfinal IFn.DO pfn = (IFn.DO)pred;\n\tfinal IFn.ODO rrfn = toDoubleReductionFn(rfn);\n\treturn new Reductions.DoubleAccum() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invokePrim(Object lhs, double v) {\n\t    return truthy(pfn.invokePrim(v)) ? rrfn.invokePrim(lhs, v) : lhs;\n\t  }\n\t};\n      } else if (pred instanceof Predicate) {\n\tfinal Predicate pfn = (Predicate)pred;\n\treturn new IFnDef() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invoke(Object lhs, Object v) {\n\t    return pfn.test(v) ? rfn.invoke(lhs, v) : lhs;\n\t  }\n\t};\n      } else {\n\treturn new IFnDef() {\n\t  public Object invoke() { return rfn.invoke(); }\n\t  public Object invoke(Object res) { return rfn.invoke(res); }\n\t  public Object invoke(Object lhs, Object v) {\n\t    return truthy(pred.invoke(v)) ? rfn.invoke(lhs, v) : lhs;\n\t  }\n\t};\n      }\n    }\n    public Object reduce(final IFn rfn, final Object init) {\n      return Reductions.serialReduction(typedReducer(rfn,pred), init, src);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t    ParallelOptions options) {\n      return Reductions.parallelReduction(initValFn, typedReducer(rfn, pred), mergeFn,\n\t\t\t\t\t  src, options);\n    }\n    public Object[] toArray() {\n      return ArrayLists.toArray(this);\n    }\n  }\n\n  public static class CatIterable\n    extends AbstractCollection\n    implements IterableSeq {\n    //this is an array of iterables of iterables.\n    final Iterable[] data;\n    public final IPersistentMap meta;\n    public final ParallelOptions.CatParallelism parallelism;\n    public CatIterable(IPersistentMap _meta, ParallelOptions.CatParallelism parallelism, Iterable arglist) {\n      this.data = new Iterable[] {arglist};\n      this.meta = _meta;\n      this.parallelism = parallelism;\n    }\n    public CatIterable(IPersistentMap _meta, Iterable[] f) {\n      this.data = f;\n      this.meta = _meta;\n      this.parallelism = null;\n    }\n    public CatIterable(Iterable arglist) {\n      data = new Iterable[]{arglist};\n      meta = null;\n      parallelism = null;\n    }\n    public CatIterable(CatIterable other, IPersistentMap m) {\n      data = other.data;\n      meta = m;\n      parallelism = other.parallelism;\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean equals(Object o) { return equiv(o); }\n    public int hashCode() { return hasheq(); }\n    public int size() { return iterCount(iterator()); }\n    public boolean isEmpty() {\n      return iterator().hasNext() == false;\n    }\n    static class CatIteratorCtx implements CtxIter.Ctx {\n      public final Iterator gpIter;\n      public final Iterator parentIter;\n      public final Iterator curIter;\n      public CatIteratorCtx(Iterator gpIter, Iterator parentIter, Iterator curIter) {\n\tthis.gpIter = gpIter;\n\tthis.parentIter = parentIter;\n\tthis.curIter = curIter;\n      }\n      public CatIteratorCtx update() {\n\tif(curIter != null && curIter.hasNext()) return this;\n\tIterator curIter = this.curIter;\n\tIterator parentIter = this.parentIter;\n\tdo {\n\t  if(parentIter != null && parentIter.hasNext()) {\n\t    Iterable pp = toIterable(parentIter.next());\n\t    curIter = pp != null ? pp.iterator() : null;\n\t  } else {\n\t    if(gpIter.hasNext()) {\n\t      Iterable gg = toIterable(gpIter.next());\n\t      parentIter = gg != null ? gg.iterator() : null;\n\t    } else {\n\t      return new CatIteratorCtx(gpIter, null, null);\n\t    }\n\t  }\n\t  if(curIter != null && curIter.hasNext()) return new CatIteratorCtx(gpIter, parentIter, curIter);\n\t} while(true);\n      }\n      public boolean valid() {\n\treturn curIter != null && curIter.hasNext();\n      }\n      public Object val() {\n\treturn curIter.next();\n      }\n    }\n    public Iterator iterator() {\n      return new CtxIter(new Supplier<CtxIter.Ctx>() {\n\t  public CtxIter.Ctx get() {\n\t    return new CatIteratorCtx(ArrayLists.toList(data).iterator(), null, null).update();\n\t  }\n\t});\n    }\n    public IMapable cat(Iterable _iters) {\n      final int dlen = data.length;\n      final Iterable[] newd = Arrays.copyOf(data, dlen+1);\n      newd[dlen] = _iters;\n      return new CatIterable(meta(), newd);\n    }\n    public ISeq seq() { return LazyChunkedSeq.chunkIteratorSeq(iterator()); }\n    public IPersistentMap meta() { return meta; }\n    public CatIterable withMeta(IPersistentMap m) {\n      return new CatIterable(this, m);\n    }\n    public Object reduce(IFn fn) {\n      return Reductions.iterReduce(this, fn);\n    }\n    public static IFn catReducer(IFn rfn) {\n      if(rfn instanceof IFn.OLO) {\n\tfinal IFn.OLO ff = (IFn.OLO)rfn;\n\treturn new IFnDef.OLO() {\n\t  public Object invokePrim(Object acc, long v) {\n\t    acc = ff.invokePrim(acc, v);\n\t    return RT.isReduced(acc) ? new Reduced(acc) : acc;\n\t  }\n\t};\n      } else if (rfn instanceof IFn.ODO) {\n\tfinal IFn.ODO ff = (IFn.ODO)rfn;\n\treturn new IFnDef.ODO() {\n\t  public Object invokePrim(Object acc, double v) {\n\t    acc = ff.invokePrim(acc, v);\n\t    return RT.isReduced(acc) ? new Reduced(acc) : acc;\n\t  }\n\t};\n      } else {\n\treturn new IFnDef() {\n\t  public Object invoke(Object acc, Object v) {\n\t    acc = rfn.invoke(acc,v);\n\t    return RT.isReduced(acc) ? new Reduced(acc) : acc;\n\t  }\n\t};\n      }\n    }\n    public Object reduce(IFn rfn, Object init) {\n      final int nData = data.length;\n      final Iterable[] d = data;\n      final IFn rf = catReducer(rfn);\n      for(int idx = 0; idx < nData && !RT.isReduced(init); ++idx) {\n\tfinal Iterable item = d[idx];\n\tfinal Iterator iter = item != null ? item.iterator() : null;\n\tif (iter != null) {\n\t  for(; iter.hasNext() && !RT.isReduced(init);)\n\t    init = Reductions.serialReduction(rf, init, iter.next());\n\t}\n      }\n      return Reductions.unreduce(init);\n    }\n    static class CatIterIter implements Iterator {\n      Iterator gpIter;\n      Iterator parentIter;\n      public CatIterIter(Iterator _gpIter) {\n\tgpIter = _gpIter;\n\tparentIter = null;\n\tadvance();\n      }\n      public boolean hasNext() { return parentIter != null && parentIter.hasNext(); }\n      public Object next() {\n\tfinal Object rv = parentIter.next();\n\tif(!parentIter.hasNext())\n\t  advance();\n\treturn rv;\n      }\n      void advance() {\n\tif(hasNext()) { return; }\n\twhile(gpIter != null && gpIter.hasNext()) {\n\t  parentIter = null;\n\t  final Iterable parent = (Iterable)gpIter.next();\n\t  if(parent != null) {\n\t    parentIter = parent.iterator();\n\t  }\n\t  if(hasNext())\n\t    return;\n\t}\n\tgpIter = null;\n\tparentIter = null;\n      }\n    }\n    public Iterator containerIter() { return new CatIterIter(ArrayLists.toList(data).iterator()); }\n    Object preduceSeqwise(IFn initValFn, IFn rfn, IFn mergeFn, Object init,\n\t\t\t\t ParallelOptions options) {\n      final Iterable initSequence = new Iterable() {\n\t  public Iterator iterator() {\n\t    return containerIter();\n\t  }\n\t};\n\n      final Iterable partiallyReduced = ForkJoinPatterns.pmap(options, new IFnDef() {\n\t  public Object invoke(Object arg) {\n\t    return Reductions.serialReduction(rfn, initValFn.invoke(), arg);\n\t  }\n\t}, ArrayLists.toList(new Object[] { initSequence }));\n      if(options.unmergedResult)\n\treturn partiallyReduced;\n      return Reductions.serialReduction(mergeFn, init, partiallyReduced);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn,\n\t\t\t\t    ParallelOptions options) {\n      final int nData = data.length;\n      final Iterable[] d = data;\n      Object init = initValFn.invoke();\n      final IFn rf = catReducer(rfn);\n      ParallelOptions.CatParallelism catP = this.parallelism != null ? this.parallelism : options.catParallelism;\n      switch (catP) {\n      case ELEMWISE: {\n\tfinal Iterable initSequence = new Iterable() {\n\t    public Iterator iterator() {\n\t      return new CatIterIter(ArrayLists.toList(data).iterator());\n\t    }\n\t  };\n\tfinal Iterable mapped = new MapIterable(new IFnDef() {\n\t    public Object invoke(Object data) {\n\t      return Reductions.parallelReduction(initValFn, rf, mergeFn, data, options);\n\t    }\n\t  }, null, initSequence);\n\n\tif(options.unmergedResult) {\n\t  init = new CatIterable(mapped);\n\t} else {\n\t  init = Reductions.iterableMerge(options, mergeFn, mapped);\n\t}\n\tbreak;\n      }\n      case SEQWISE: {\n\tinit = preduceSeqwise(initValFn, rf, mergeFn, init, options);\n\tbreak;\n      }\n      };\n      return Reductions.unreduce(init);\n    }\n    public Object[] toArray() {\n      return ArrayLists.toArray(this);\n    }\n  }\n\n  public static class SingleMapList implements IMutList, IMapable {\n    final int nElems;\n    final List list;\n    final IFn fn;\n    final IPersistentMap meta;\n    public SingleMapList(IFn _fn, IPersistentMap m, List l) {\n      nElems = l.size();\n      list = l;\n      fn = _fn;\n      meta = m;\n    }\n    public SingleMapList(SingleMapList o, IPersistentMap m) {\n      nElems = o.nElems;\n      list = o.list;\n      fn = o.fn;\n      meta = m;\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public int size() { return nElems; }\n    public Object get(int idx) { return fn.invoke(list.get(idx)); }\n    public SingleMapList subList(int sidx, int eidx) {\n      return new SingleMapList(fn, meta, list.subList(sidx, eidx));\n    }\n    public IPersistentMap meta() { return meta; }\n    public SingleMapList withMeta(IPersistentMap m) {\n      return new SingleMapList(this, m);\n    }\n    public SingleMapList map(IFn nfn) {\n      return new SingleMapList(MapFn.create(fn, nfn), meta, list);\n    }\n    public Object reduce(IFn rfn, Object init) {\n      return singleMapReduce(list, rfn, fn, init);\n    }\n    public Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn, ParallelOptions options) {\n      return Reductions.parallelReduction(initValFn, typedMapReducer(rfn, fn), mergeFn,\n\t\t\t\t\t  list, options);\n    }\n  }\n\n  public static class DualMapList implements IMutList, IMapable {\n    final int nElems;\n    final List lhs;\n    final List rhs;\n    final IFn fn;\n    final IPersistentMap meta;\n    public DualMapList(IFn _fn, IPersistentMap m, List l, List r) {\n      nElems = Math.min(l.size(), r.size());\n      lhs = l;\n      rhs = r;\n      fn = _fn;\n      meta = m;\n    }\n    public DualMapList(DualMapList o, IPersistentMap m) {\n      nElems = o.nElems;\n      lhs = o.lhs;\n      rhs = o.rhs;\n      fn = o.fn;\n      meta = m;\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public int size() { return nElems; }\n    public Object get(int idx) { return fn.invoke(lhs.get(idx), rhs.get(idx)); }\n    public DualMapList subList(int sidx, int eidx) {\n      return new DualMapList(fn, meta, lhs.subList(sidx, eidx), rhs.subList(sidx, eidx));\n    }\n    public IPersistentMap meta() { return meta; }\n    public DualMapList withMeta(IPersistentMap m) {\n      return new DualMapList(this, m);\n    }\n    public DualMapList map(IFn nfn) {\n      return new DualMapList(MapFn.create(fn, nfn), meta, lhs, rhs);\n    }\n  }\n\n  public static class MapList implements IMutList, IMapable {\n    final int nElems;\n    final List[] lists;\n    final IFn fn;\n    final IPersistentMap meta;\n    final IFn.LO getter;\n    public MapList(IFn _fn, IPersistentMap _meta, List... _lists) {\n      final int nLists = _lists.length;\n      if(nLists == 0)\n\tnElems = 0;\n      else {\n\tint ne = _lists[0].size();\n\tfor(int idx = 1; idx < nLists; ++idx)\n\t  ne = Math.min(ne, _lists[idx].size());\n\tnElems = ne;\n      }\n      lists = _lists;\n      fn = _fn;\n      meta = _meta;\n      IFn.LO getter = null;\n      final List[] ll = lists;\n      switch(nLists) {\n      case 1: getter = new IFnDef.LO() {\n\t  public Object invokePrim(long idx) { return fn.invoke(ll[0].get((int)idx));\n\t  } };\n\tbreak;\n      case 2:  getter = new IFnDef.LO() {\n\t  public Object invokePrim(long idx) { return fn.invoke(ll[0].get((int)idx), ll[1].get((int)idx));\n\t  } };\n\tbreak;\n      case 3:  getter = new IFnDef.LO() {\n\t  public Object invokePrim(long lidx) { final int idx = (int)lidx; return fn.invoke(ll[0].get(idx), ll[1].get(idx), ll[2].get(idx));\n\t  } };\n\tbreak;\n      case 4:\n\tgetter = new IFnDef.LO() {\n\t  public Object invokePrim(long lidx) { final int idx = (int)lidx; return fn.invoke(ll[0].get(idx),\n\t\t\t\t\t\t\t\t\t\t\t    ll[1].get(idx),\n\t\t\t\t\t\t\t\t\t\t\t    ll[2].get(idx),\n\t\t\t\t\t\t\t\t\t\t\t    ll[3].get(idx));\n\t  } };\n\tbreak;\n      default:\n\tgetter = new IFnDef.LO() {\n\t    public Object invokePrim(long lidx) {\n\t      final int idx = (int)lidx;\n\t      Object[] args = new Object[nLists];\n\t      for (int aidx = 0; aidx < nLists; ++aidx)\n\t\targs[aidx] = lists[aidx].get(idx);\n\t      return fn.applyTo(ArraySeq.create(args));\n\t    }\n\t  };\n      }\n      this.getter = getter;\n    }\n    public MapList(MapList other, IPersistentMap m) {\n      nElems = other.nElems;\n      lists = other.lists;\n      fn = other.fn;\n      getter = other.getter;\n      meta = m;\n    }\n    public static IMutList create(IFn fn, IPersistentMap meta, List... lists) {\n      if (lists.length == 1)\n\treturn new SingleMapList(fn, meta, lists[0]);\n      else if (lists.length == 2)\n\treturn new DualMapList(fn, meta, lists[0], lists[1]);\n      else\n\treturn new MapList(fn, meta, lists);\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public int hashCode() { return hasheq(); }\n    public int size() { return nElems; }\n    public Object get(int idx) {\n      if(idx < 0)\n\tidx += nElems;\n      if(idx < 0 || idx >= nElems)\n\tthrow new RuntimeException(\"Index out of range.\");\n      return getter.invokePrim(idx);\n\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      final int ne = nElems;\n      final List[] ll = lists;\n      final int ls = ll.length;\n      switch(ls) {\n      case 1: return Reductions.serialReduction( mapReducer(rfn, this.fn), acc, ll[0] );\n      case 2:\n\tfor (int idx = 0; idx < ne; ++idx) {\n\t  acc = rfn.invoke(acc, fn.invoke(lists[0].get(idx), lists[1].get(idx)));\n\t  if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t}\n\treturn acc;\n      case 3:\n\tfor (int idx = 0; idx < ne; ++idx) {\n\t  acc = rfn.invoke(acc, fn.invoke(lists[0].get(idx), lists[1].get(idx), lists[2].get(idx)));\n\t  if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t}\n\treturn acc;\n      case 4:\n\tfor (int idx = 0; idx < ne; ++idx) {\n\t  acc = rfn.invoke(acc, fn.invoke(lists[0].get(idx), lists[1].get(idx),\n\t\t\t\t\t  lists[2].get(idx), lists[3].get(idx)));\n\t  if(RT.isReduced(acc)) return ((IDeref)acc).deref();\n\t}\n\treturn acc;\n      }\n      //fallthrough\n      final Object[] args = new Object[ls];\n      final ISeq arglist = ArraySeq.create(args);\n      for(int oidx = 0; oidx < ne; ++oidx) {\n\tfor (int aidx = 0; aidx < ls; ++aidx)\n\t  args[aidx] = lists[aidx].get(oidx);\n\tacc = rfn.invoke(acc, fn.applyTo(arglist));\n\tif(RT.isReduced(acc))\n\t  return ((IDeref)acc).deref();\n      }\n      return acc;\n    }\n    public IMutList subList(int sidx, int eidx) {\n      final int sz = size();\n      if (sidx < 0 || sidx >= sz)\n\tthrow new RuntimeException(\"Start index out of range.\");\n      if (eidx < sidx || eidx > sz)\n\tthrow new RuntimeException(\"End index out of range.\");\n      final int ll = lists.length;\n      List[] newLists = new List[ll];\n      for(int idx = 0; idx < ll; ++idx)\n\tnewLists[idx] = lists[idx].subList(sidx, eidx);\n      return new MapList(fn, meta(), newLists);\n    }\n    public MapList map(IFn nfn) {\n      return new MapList(MapFn.create(fn, nfn), meta(), lists);\n    }\n    public IPersistentMap meta() { return meta; }\n    public MapList withMeta(IPersistentMap m) {\n      return new MapList(this, m);\n    }\n  }\n\n  public static class IndexedMapper extends AbstractCollection\n    implements IterableSeq {\n    final IFn mapFn;\n    final Object src;\n    final IPersistentMap meta;\n    public IndexedMapper(IFn mapFn, Object src, IPersistentMap m) {\n      this.mapFn = mapFn;\n      this.src = src;\n      this.meta = m;\n    }\n    public String toString() { return sequenceToString(this); }\n    public boolean equals(Object other) { return equiv(other); }\n    public int hashCode() { return hasheq(); }\n    public boolean isEmpty() { return iterator().hasNext() == false; }\n    public int size() { return iterCount(toIterable(src).iterator()); }\n    public static class CountingFn implements IFnDef {\n      long cnt;\n      final IFn mapFn;\n      public CountingFn(IFn mapFn) { cnt = 0; this.mapFn = mapFn; }\n      public Object invoke(Object arg) {\n\treturn mapFn.invoke(cnt++, arg);\n      }\n    }\n    MapIterable mapper() { return new MapIterable(new CountingFn(mapFn), meta, new Object[] { src }); }\n    public Iterator iterator() {\n      return mapper().iterator();\n    }\n    public Object reduce(IFn rfn, Object init) {\n      return mapper().reduce(rfn, init);\n    }\n    public IMapable map(IFn fn) {\n      final IFn srcFn = mapFn;\n      return new IndexedMapper(new IFnDef() {\n\t  public Object invoke(Object idx, Object arg) {\n\t    return fn.invoke(srcFn.invoke(idx,arg));\n\t  }\n\t}, src, meta);\n    }\n    public IPersistentMap meta() { return meta; }\n    public IObj withMeta(IPersistentMap m) { return new IndexedMapper(mapFn, src, meta); }\n  }\n\n  public static class CachingIterable extends AbstractCollection\n    implements Seqable {\n    final Iterable src;\n    final IPersistentMap meta;\n    AtomicReference<ISeq> seq;\n    public CachingIterable(Iterable _src, IPersistentMap _meta) {\n      src = _src;\n      meta = _meta;\n      seq = new AtomicReference<ISeq>();\n    }\n    CachingIterable(CachingIterable other, IPersistentMap m) {\n      src = other.src;\n      meta = m;\n      seq = other.seq;\n    }\n    public ISeq seq() {\n      return seq.updateAndGet(new UnaryOperator<ISeq>() {\n\t  public ISeq apply(ISeq v) {\n\t    if(v != null) return v;\n\t    return src instanceof Seqable ? ((Seqable)src).seq() : LazyChunkedSeq.chunkIteratorSeq(src.iterator());\n\t  }\n\t});\n    }\n    public Iterator iterator() { return ((Collection)seq()).iterator(); }\n    public int size() { return ((Collection)seq()).size(); }\n    public IPersistentMap meta() { return meta; }\n    public CachingIterable withMeta(IPersistentMap m) { return new CachingIterable(src, m); }\n  }\n  public static class CachingList implements IMutList {\n    final List src;\n    final Object[] dataCache;\n    final BitSet cachedIndexes;\n    final IPersistentMap meta;\n    int _hash;\n    public CachingList(List srcData, IPersistentMap _meta) {\n      src = srcData;\n      meta = _meta;\n      dataCache = new Object[srcData.size()];\n      cachedIndexes = new BitSet();\n    }\n    CachingList(CachingList other, IPersistentMap _meta) {\n      src = other.src;\n      dataCache = other.dataCache;\n      cachedIndexes = other.cachedIndexes;\n      meta = _meta;\n    }\n    public int hashCode() {\n      return hasheq();\n    }\n    public int hasheq() {\n      if (_hash == 0)\n\t_hash = IMutList.super.hasheq();\n      return _hash;\n    }\n    public boolean equals(Object other) {\n      return equiv(other);\n    }\n    public String toString() { return sequenceToString(this); }\n    public Object get(final int idx) {\n      synchronized(cachedIndexes) {\n\tif(cachedIndexes.get(idx))\n\t  return dataCache[idx];\n\tfinal Object retval = src.get(idx);\n\tdataCache[idx] = retval;\n\tcachedIndexes.set(idx);\n\treturn retval;\n      }\n    }\n    public int size() { return src.size(); }\n    public CachingList withMeta(IPersistentMap m) {\n      return new CachingList(this, m);\n    }\n  }\n\n  static void appendObjects(StringBuilder sb, Collection data) {\n    boolean first = true;\n    for(Object o: data) {\n      if(!first)\n\tsb.append(\" \");\n      first = false;\n      sb.append(o == null ? \"nil\" : o.toString());\n    }\n  }\n\n  public static String sequenceToString(Iterable data) {\n    StringBuilder sb = new StringBuilder();\n    if(data instanceof RandomAccess) {\n      final List ra = (List) data;\n      final int sz = ra.size();\n      sb.append(\"[\");\n      if(sz < 50) {\n\tappendObjects(sb, ra);\n      } else {\n\tappendObjects(sb, ra.subList(0, 20));\n\tsb.append(\" ... \");\n\tappendObjects(sb, ra.subList(sz-20, sz));\n      }\n      sb.append(\"]\");\n    } else {\n      sb.append(\"(\");\n      if (data != null) {\n\tint idx = 0;\n\tfor(Object o: data) {\n\t  if(idx >= 50) {\n\t    sb.append(\" ...\");\n\t    break;\n\t  }\n\t  if (idx > 0)\n\t    sb.append(\" \");\n\t  sb.append(o == null ? \"nil\" : o.toString());\n\t  ++idx;\n\t}\n      }\n      sb.append(\")\");\n    }\n    return sb.toString();\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/TransientHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.function.BiFunction;\nimport java.util.Map;\nimport clojure.lang.Indexed;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.ITransientAssociative2;\nimport clojure.lang.IObj;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\n\npublic class TransientHashMap\n  extends ROHashMap\n  implements IATransientMap, IObj\n{\n  public TransientHashMap(HashMap data) {\n    super(data.loadFactor, data.capacity, data.length, data.data.clone(), data.meta);\n  }\n  public TransientHashMap(TransientHashMap data, IPersistentMap m) {\n    super(data.loadFactor, data.capacity, data.length, data.data, m);\n  }\n  public TransientHashMap conj(Object val) {\n    if(val instanceof Map) {\n      return (TransientHashMap)union((Map)val, BiFunctions.rhsWins);\n    } else {\n      return (TransientHashMap)IATransientMap.super.conjVal(val);\n    }\n  }\n  public TransientHashMap assoc(Object key, Object val) {\n    int hc = hash(key);\n    int idx = hc & mask;\n    HashNode e = data[idx];\n    data[idx] = e != null ? e.assoc(this, key, hc, val) : newNode(key, hc, val);\n    return this;\n  }\n  public TransientHashMap without(Object key) {\n    int hc = hash(key);\n    int idx = hc & mask;\n    HashNode e = data[idx];\n    if(e!=null)\n      data[idx] = e.dissoc(this, key);\n    return this;\n  }\n  public PersistentHashMap persistent() {\n    return new PersistentHashMap(this);\n  }\n  public TransientHashMap withMeta(IPersistentMap m) {\n    return new TransientHashMap(this, m);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/TransientHashSet.java",
    "content": "package ham_fisted;\n\nimport clojure.lang.IPersistentMap;\n\npublic class TransientHashSet extends ROHashSet implements IATransientSet {\n  public TransientHashSet(HashBase hb, IPersistentMap meta) { super(hb, meta); }\n  public TransientHashSet conj(Object key) {\n    int hc = hash(key);\n    int idx = hc & mask;\n    HashNode e = data[idx];\n    data[idx] = e != null ? e.assoc(this, key, hc, VALUE) : newNode(key, hc, VALUE);\n    return this;\n  }\n  public TransientHashSet disjoin(Object key) {\n    int hc = hash(key);\n    int idx = hc & mask;\n    HashNode e = data[idx];\n    if(e != null)\n      data[idx] = e.dissoc(this, key);\n    return this;\n  }\n  public PersistentHashSet persistent() { return new PersistentHashSet(this, meta); }\n}\n"
  },
  {
    "path": "java/ham_fisted/TransientList.java",
    "content": "package ham_fisted;\n\nimport static ham_fisted.IntegerOps.*;\n\nimport clojure.lang.ITransientVector;\nimport clojure.lang.RT;\nimport clojure.lang.Util;\nimport java.util.BitSet;\nimport java.util.Arrays;\n\n\npublic class TransientList implements ITransientVector, IFnDef {\n  final ChunkedList data;\n  final BitSet ownedChunks;\n  //Note there is no startidx.  We cannot share structure with sub-lists so startidx is\n  //always 0.  Thus calling transient on a subvector results\n  int nElems;\n  public TransientList(ChunkedList _data, int _nElems, boolean _ownsEverything) {\n    data = _data;\n    nElems = _nElems;\n    ownedChunks = new BitSet();\n    if( _ownsEverything) {\n      final int nChunks = ChunkedList.numChunks(nElems);\n      for(int idx = 0; idx < nChunks; ++idx)\n\townedChunks.set(idx);\n    }\n  }\n  final int indexCheck(int idx) {\n    return ChunkedList.indexCheck(0, nElems, idx);\n  }\n  final int wrapIndexCheck(int idx) {\n    return ChunkedList.wrapIndexCheck(0, nElems, idx);\n  }\n  public final int count() { return nElems; }\n  public final int size() { return nElems; }\n  public final int length() { return nElems; }\n  public final Object nth(int idx) {\n    return nth(idx, null);\n  }\n  public final Object nth(int idx, Object notFound) {\n    if (idx < 0)\n      idx += nElems;\n    if (idx >= 0 && idx < nElems)\n      return data.getValue(idx);\n    return notFound;\n  }\n  public final Object invoke(Object idx) {\n    return nth(RT.intCast(idx));\n  }\n  public final Object invoke(Object idx, Object nf) {\n    return nth(RT.intCast(idx), nf);\n  }\n  public final Object valAt(Object idx) {\n    if (Util.isInteger(idx))\n      return nth(RT.intCast(idx));\n    return null;\n  }\n  public final Object valAt(Object idx, Object notFound) {\n    if (Util.isInteger(idx))\n      return nth(RT.intCast(idx), notFound);\n    return notFound;\n  }\n  public final TransientList assocN(int idx, Object v) {\n    if (idx == nElems)\n      return conj(v);\n    indexCheck(idx);\n    int cidx = idx/32;\n    int eidx = idx%32;\n    final Object[][] mdata = data.data;\n    Object[] chunk = mdata[cidx];\n    if (!ownedChunks.get(cidx)) {\n      ownedChunks.set(cidx);\n      chunk = chunk.clone();\n      mdata[cidx] = chunk;\n    }\n    chunk[eidx] = v;\n    return this;\n  }\n  public final TransientList assoc(Object obj, Object v) {\n    if (!Util.isInteger(obj))\n      throw new RuntimeException(\"Vectors must have integer indexes: \" + String.valueOf(obj));\n    return assocN(RT.intCast(obj), v);\n  }\n  public final TransientList conj(Object v) {\n    final int idx = nElems++;\n    final int cidx = idx / 32;\n    final int eidx = idx % 32;\n    Object[][] mdata = data.data;\n    Object[] chunk;\n    if (cidx == mdata.length) {\n      mdata = Arrays.copyOf(mdata, cidx+1);\n      chunk = new Object[4];\n      mdata[cidx] = chunk;\n      ownedChunks.set(cidx);\n    } else {\n      chunk = mdata[cidx];\n      if ((!ownedChunks.get(cidx)) || chunk.length <= eidx) {\n\tchunk = Arrays.copyOf(chunk, nextPow2(eidx+1));\n\tmdata[cidx] = chunk;\n\townedChunks.set(cidx);\n      }\n    }\n    chunk[eidx] = v;\n    return this;\n  }\n  public final TransientList pop() {\n    if(nElems == 0)\n      throw new RuntimeException(\"Attempt to pop empty vector\");\n    final int idx = --nElems;\n    final int cidx = idx / 32;\n    final int eidx = idx % 32;\n    Object[][] mdata = data.data;\n    Object[] chunk = mdata[cidx];\n    if (!ownedChunks.get(cidx)) {\n      chunk = chunk.clone();\n      ownedChunks.set(cidx);\n      mdata[cidx] = chunk;\n    }\n    //Release any outstanding references.\n    chunk[eidx] = null;\n    return this;\n  }\n  public final ImmutList persistent() {\n    return new ImmutList(0, nElems, data);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/TransientLongHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.Map;\nimport clojure.lang.Indexed;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.ITransientAssociative2;\nimport clojure.lang.IObj;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IFn;\n\npublic class TransientLongHashMap\n  extends ROLongHashMap\n  implements IATransientMap, IObj\n{\n  public TransientLongHashMap(LongHashMap data) {\n    super(data.loadFactor, data.capacity, data.length, data.data.clone(), data.meta);\n  }\n  public TransientLongHashMap(TransientLongHashMap data, IPersistentMap m) {\n    super(data.loadFactor, data.capacity, data.length, data.data, m);\n  }\n  public TransientLongHashMap assoc(Object kk, Object val) {\n    long key = Casts.longCast(kk);\n    int hc = hash(key);\n    int idx = hc & mask;\n    LongHashNode e = data[idx];\n    data[idx] = e != null ? e.assoc(this, key, hc, val) : newNode(key, hc, val);\n    return this;\n  }\n  public TransientLongHashMap without(Object kk) {\n    long key = Casts.longCast(kk);\n    int hc = hash(key);\n    int idx = hc & mask;\n    LongHashNode e = data[idx];\n    if(e!=null)\n      data[idx] = e.dissoc(this, key);\n    return this;\n  }\n  public PersistentLongHashMap persistent() {\n    return new PersistentLongHashMap(this);\n  }\n  public TransientLongHashMap withMeta(IPersistentMap m) {\n    return new TransientLongHashMap(this, m);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/TreeList.java",
    "content": "package ham_fisted;\nimport java.util.Arrays;\nimport java.util.BitSet;\nimport java.util.List;\nimport java.util.Comparator;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\nimport java.util.function.BiFunction;\nimport java.util.ArrayList;\nimport clojure.lang.IPersistentVector;\nimport clojure.lang.IFn;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.Util;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.IEditableCollection;\n\npublic class TreeList extends TreeListBase implements IPersistentVector, IEditableCollection {\n  final IPersistentMap meta;\n  int _hash = 0;\n  public TreeList(Object root, Object[] tail, IPersistentMap meta, int shift, int count) {\n    super(root, tail, shift, count);\n    this.meta = meta;\n  }\n  public TreeList(IPersistentMap meta) {\n    this(new Leaf(), new Object[0], meta, 0, 0);\n  }\n  public TreeList() {\n    this(null);\n  }\n  public TreeList(TreeListBase other, IPersistentMap meta) {\n    super(other);\n    this.meta = meta;\n  }\n  public static TreeList EMPTY = new TreeList();\n  public TreeList cons(Object d) {\n    final int tlen = tail.length;\n    final int newCount = count+1;\n    if(tlen == 32) {\n      Object rv = shift == 0 ? ((Leaf)root).cons(tail) : ((Branch)root).cons(shift, tail);\n      if(rv instanceof Object[]) {\n\treturn new TreeList(new Branch(null, (Object[])rv), new Object[]{d}, meta, shift+1, newCount);\n      } else {\n\treturn new TreeList(rv, new Object[]{d}, meta, shift, newCount);\n      }\n    } else {\n      Object[] newTail = new Object[tlen+1];\n      System.arraycopy(tail, 0, newTail, 0, tail.length);\n      newTail[tlen] = d;\n      return new TreeList(root, newTail, meta, shift, newCount);\n    }\n  }\n  public int hasheq() {\n    if(_hash == 0) _hash = CljHash.listHasheq(this);\n    return _hash;\n  }\n  public int hashCode() { return hasheq(); }\n  public TreeList consAll(Iter data) {\n    int tlen = tail.length;\n    Object[] newTail = Arrays.copyOf(tail, tailWidth);\n    while(data != null && tlen < tailWidth) {\n      newTail[tlen++] = data.get();\n      data = data.next();\n    }\n    if(data == null)\n      return new TreeList(root, Arrays.copyOf(newTail, tlen), meta, shift, count);\n    Object newRoot = root;\n    int newShift = shift;\n    int newCount = count;\n    final int numSiblings = branchWidth-1;\n    data = Iter.prepend(newTail, data);\n    do {\n      ConsAllResult res = shift == 0 ?\n\t((Leaf)newRoot).consAll(null, numSiblings, data) :\n\t((Branch)newRoot).consAll(null, numSiblings, shift, data);\n      data = res.nextData;\n      newCount += res.added;\n      newTail = res.tail;\n      Object[] nodes = res.nodes;\n      if(nodes.length == 1) {\n\tnewRoot = nodes[0];\n      } else {\n\tnewRoot = new Branch(null, res.nodes);\n\tnewShift += 1;\n      }\n      //should assert here that data is null of tail is nonempty\n    } while(data != null);\n    return new TreeList(newRoot, newTail, meta, newShift, newCount);    \n  }\n\n  public TreeList withMeta(IPersistentMap newMeta) {\n    return new TreeList(root, tail, newMeta, shift, count);\n  }\n  public IPersistentMap meta() { return meta; }\n\n  public TreeList empty() { return EMPTY; }\n\n  public TreeList assocN(int idx, Object obj) {\n    if(idx == count)\n      return cons(obj);\n    checkIndex(idx, count);\n    int cutoff = count - tail.length;\n    if( idx < cutoff) {\n      return new TreeList(shift == 0 ? ((Leaf)root).assocN(null, idx, obj, null)\n\t\t\t  : ((Branch)root).assocN(null, shift,idx,obj, null),\n\t\t\t  tail, meta, shift, count);\n    } else {\n      Object[] newTail = Arrays.copyOf(tail, tail.length);\n      newTail[idx % tailWidth] = obj;\n      return new TreeList(root, newTail, meta, shift, count);\n    }\n  }\n  public TreeList assoc(Object idx, Object o) {\n    return assocN(RT.intCast(idx), o);\n  }\n  public TreeList pop() {\n    if (count == 0)\n      throw new IllegalStateException(\"Can't pop empty vector\");\n    if (count == 1)\n      return EMPTY;\n    Object[] newTail;\n    Object newRoot;\n    int newShift = shift;\n    if(tail.length != 0) {\n      newRoot = root;\n      newShift = shift;\n      newTail = Arrays.copyOf(tail, tail.length-1);\n    } else {\n      SublistResult res = shift == 0 ? ((Leaf)root).pop(null) : ((Branch)root).pop(null, shift);\n      newRoot = res.node;\n      newTail = Arrays.copyOf(res.tail, tailWidth-1);\n      while(shift > 0) {\n\tBranch newBranch = (Branch)newRoot;\n\tif(newBranch.data.length > 1)\n\t  break;\n\t\n\tnewRoot = newBranch.data[0];\n\tnewShift--;\n      }\n    }\n    return new TreeList(newRoot, newTail, meta, newShift, count-1);\n  }\n  public Object peek() {\n    if (count == 0)\n      return null;\n    return get(count-1);\n  }\n  public MutTreeList asTransient() {\n    return new MutTreeList(this, meta());\n  }\n  public IPersistentVector immut() { return this; }\n  public static TreeList create(boolean owning, IPersistentMap meta, Object[] data) {\n    int nTails = (data.length + tailWidth - 1) / tailWidth;\n    if(nTails == 1) {\n      return new TreeList(Leaf.EMPTY, owning ? data : data.clone(), meta, 0, data.length);\n    }\n    return MutTreeList.create(owning, meta, data).persistent();\n  }\n  public static TreeList create(IPersistentMap meta, Object[] tail, Object obj) {\n    if(tail.length != tailWidth)\n      throw new RuntimeException(\"Tail must be exactly 32 len\");\n    return new TreeList(new Leaf(null, new Object[][] { tail }), new Object[] { obj }, meta, 0, 33);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/TreeListBase.java",
    "content": "package ham_fisted;\n\nimport java.util.Iterator;\nimport java.util.Arrays;\nimport java.util.ArrayList;\nimport java.util.Spliterator;\nimport java.util.NoSuchElementException;\nimport java.util.function.BiFunction;\nimport java.util.function.Consumer;\nimport clojure.lang.RT;\nimport clojure.lang.IDeref;\nimport clojure.lang.IFn;\nimport clojure.lang.IPersistentVector;\nimport clojure.lang.Box;\n\n\n\npublic class TreeListBase implements IMutList {\n  public static final int branchWidth = 32;\n  public static final int leafWidth = branchWidth;\n  public static final int tailWidth = branchWidth;\n  public static final int shiftWidth = Integer.numberOfTrailingZeros(branchWidth);\n\n  public static class SublistResult {\n    public final Object node;\n    public final Object[] tail;\n    public SublistResult(Object node, Object[] tail) {\n      this.node = node;\n      this.tail = tail;\n    }\n  }\n  public static int checkIndex(int idx, int nElems) {\n    if (idx < 0 || idx >= nElems)\n      throw new IndexOutOfBoundsException(\"Index: \" + String.valueOf(idx) + \" is out of range 0-\" + String.valueOf(nElems));\n    return idx;\n  }\n\n  public static final void sublistCheck(long sidx, long eidx, long nElems) {\n    if(sidx < 0 || sidx > nElems)\n      throw new IndexOutOfBoundsException(\"Start index out of range: start-index(\"\n\t\t\t\t\t  + String.valueOf(sidx) +\"), n-elems(\"\n\t\t\t\t\t  + String.valueOf(nElems) + \")\");\n    if(eidx < 0 || eidx > nElems)\n      throw new IndexOutOfBoundsException(\"End index out of range: end-index(\"\n\t\t\t\t\t  + String.valueOf(eidx) +\"), n-elems(\"\n\t\t\t\t\t  + String.valueOf(nElems) + \")\");\n    if(eidx < sidx)\n      throw new IndexOutOfBoundsException(\"End index underflow: end-index(\"\n\t\t\t\t\t  + String.valueOf(eidx) +\") < start-index(\"\n\t\t\t\t\t  + String.valueOf(sidx) + \")\");\n  }\n  public static final Object[][] emptyObjAryAry = new Object[0][];\n  public static final Object[] emptyObjAry = new Object[0];\n  public static class ConsAllResult {\n    public final Object[] nodes;\n    public final Iter nextData;\n    public final Object[] tail;\n    public final int added;\n    public ConsAllResult(Object[] nodes, Iter nextData, Object[] tail, int added) {\n      this.nodes = nodes;\n      this.nextData = nextData;\n      this.tail = tail;\n      this.added = added;\n    }\n  }\n  public static interface INode {\n    public void forEachRemaining(int shift, int sidx, int eidx, Consumer cc);\n    public Object reduce(int shift, int sidx, int eidx, IFn rfn, Object acc);\n  }\n  public static int outerEidxSpan(int sidx, int eidx, int level) {\n    if(sidx == eidx)\n      return 0;\n    int ssidx = sidx/level;\n    int eeidx = (eidx-1)/level;\n    return ((eeidx - ssidx) + 1);\n  }\n  public static int localEidx(int aryIdx, int eidx, int level) {\n    return Math.min(level, eidx - (aryIdx * level));\n  }\n  public static class Leaf implements INode {\n    final Object owner;\n    Object[][] data;\n    public Object[][] data() { return this.data; }\n    public Leaf() { this.owner = null; this.data = emptyObjAryAry; }\n    public Leaf(Object owner, Object[][] data) { this.owner = owner; this.data = data; }\n    public Leaf(Object[][] data) { this(null, data); }\n    public Leaf(Object[] tail) { this.owner = null; this.data = new Object[][]{ tail }; }\n    public Object cons(Object owner, Object[] tail) {\n      boolean force = owner == null || this.owner != owner;\n      if(data.length == leafWidth) {\n\treturn new Object[]{this, new Leaf(owner, new Object[][] { tail })};\n      } else {\n\tObject[][] newData = Arrays.copyOf(data, data.length+1);\n\tnewData[data.length]=tail;\n\tif(force)\n\t  return new Leaf(owner, newData);\n\telse {\n\t  this.data = newData;\n\t  return this;\n\t}\n      }\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void forEachRemaining(int shift, int sidx, int eidx, Consumer cc) {\n      int aryIdx = sidx / leafWidth;\n      int aryEnd = aryIdx + outerEidxSpan(sidx, eidx, leafWidth);\n      int aryOffset = sidx % leafWidth;\n      // System.out.println(\"leaf sidx \" + String.valueOf(sidx) +\n      // \t\t\t \" eidx \" + String.valueOf(eidx) +\n      // \t\t\t \" aryIdx \" + String.valueOf(aryIdx) +\n      // \t\t\t \" aryEnd \" + String.valueOf(aryEnd) +\n      // \t\t\t \" aryOffset \" + String.valueOf(aryOffset)\n      // \t\t\t );\n      for(; aryIdx < aryEnd; ++aryIdx) {\n\tint localEnd = localEidx(aryIdx, eidx, leafWidth);\n\t// System.out.println(\"Local End: \" + String.valueOf(localEnd));\n\tObject[] localData = data()[aryIdx];\n\tfor(; aryOffset < localEnd; ++aryOffset) cc.accept(localData[aryOffset]);\n\taryOffset = 0;\n      }\n    }\n    public Object reduce(int shift, int sidx, int eidx, IFn rfn, Object acc) {\n      int aryIdx = sidx / leafWidth;\n      int aryEnd = aryIdx + outerEidxSpan(sidx, eidx, leafWidth);\n      int aryOffset = sidx % leafWidth;\n      // System.out.println(\"leaf sidx \" + String.valueOf(sidx) +\n      // \t\t\t \" eidx \" + String.valueOf(eidx) +\n      // \t\t\t \" aryIdx \" + String.valueOf(aryIdx) +\n      // \t\t\t \" aryEnd \" + String.valueOf(aryEnd) +\n      // \t\t\t \" aryOffset \" + String.valueOf(aryOffset)\n      // \t\t\t );\n      for(; aryIdx < aryEnd; ++aryIdx) {\n\tint localEnd = localEidx(aryIdx, eidx, leafWidth);\n\t// System.out.println(\"Local End: \" + String.valueOf(localEnd));\n\tObject[] localData = data()[aryIdx];\n\tfor(; aryOffset < localEnd; ++aryOffset) {\n\t  acc = rfn.invoke(acc, localData[aryOffset]);\n\t  if(RT.isReduced(acc)) return acc;\n\t}\n\taryOffset = 0;\n      }\n      return acc;\n    }\n    public Object cons(Object[] tail) {\n      return cons(null, tail);\n    }\n    public Object add(Object owner, Object[] tail) {\n      return cons(owner, tail);\n    }\n    public ConsAllResult consAll(Object owner, int maxSiblings, Iter dataIter) {\n      int maxTails = leafWidth  - data.length + leafWidth * maxSiblings;\n      ArrayList<Object[]> tails = new ArrayList<Object[]>();\n      Object[] tail = new Object[32];\n      int nTail = 0;\n      int added = 0;\n      while(tails.size() < maxTails && dataIter != null) {\n\tif(nTail == tailWidth)\n\t  tails.add(tail.clone());\n\tfor(nTail = 0; nTail < tailWidth && dataIter != null; ++nTail) {\n\t  tail[nTail++] = dataIter.get();\n\t  dataIter = dataIter.next();\n\t  ++added;\n\t}\n\tnTail = 0;\n      }\n      //Rectify tail\n      if(nTail == 0)\n\ttail = new Object[0];\n      else if (nTail != tailWidth)\n\ttail = Arrays.copyOf(tail, nTail);\n\n      if(tails.isEmpty())\n\treturn new ConsAllResult(new Object[]{this}, dataIter, tail, added);\n      int totalTails = tails.size();\n      int nLocalTails = Math.min(leafWidth - data.length, totalTails);\n      Object[][] newData = Arrays.copyOf(data, nLocalTails);\n      for(int idx = data.length; idx < nLocalTails; ++idx)\n\tnewData[idx] = tails.get(idx-data.length);\n\n      int nOtherLeaves = (totalTails - nLocalTails + leafWidth - 1) / leafWidth;\n      Object[] leaves = new Object[1 + nOtherLeaves];\n      leaves[0] = new Leaf(owner, newData);\n      int leafIdx = 1;\n      for(int idx = nLocalTails; idx < totalTails; idx += leafWidth) {\n\tint nextIdx = Math.min(totalTails, idx + leafWidth);\n\tint nLeafTails = nextIdx - idx;\n\tleaves[leafIdx++] = new Leaf(owner, tails.subList(idx, nextIdx).toArray(emptyObjAryAry));\n      }\n      return new ConsAllResult(leaves, dataIter, tail, added);\n    }\n    public Object[] getArray(int idx) { return data[idx/leafWidth]; }\n    public Leaf assocN(Object owner, int idx, Object obj, Box oldVal) {\n      boolean force = owner == null || this.owner != owner;\n      int localIdx = idx/leafWidth;\n      Object[] entry = force ? Arrays.copyOf(data[localIdx], tailWidth) : data[localIdx];\n      int objIdx = idx % tailWidth;\n      if(oldVal != null) oldVal.val = entry[objIdx];\n      entry[objIdx] = obj;\n      if(force) {\n\tObject[][] newData = Arrays.copyOf(data, data.length);\n\tnewData[localIdx] = entry;\n\treturn new Leaf(owner, newData);\n      } else {\n\treturn this;\n      }\n    }\n    public SublistResult pop(Object owner) {\n      int dlen = data.length;\n      Object[] lastTail = data[dlen-1];\n      Object[][] newD;\n      if(dlen-1 == 0) {\n\tnewD = new Object[0][];\n      } else {\n\tnewD = Arrays.copyOf(data, dlen-1);\n      }\n      boolean force = owner == null || this.owner != owner;\n      Leaf newLeaf;\n      if(force) {\n\tnewLeaf = new Leaf(owner, newD);\n      } else {\n\tthis.data = newD;\n\tnewLeaf = this;\n      }\n      return new SublistResult(newLeaf, lastTail);\n    }\n    public boolean isEmpty() { return data.length == 0; }\n    //Assumption here is that sidx lies exactly on a tailWidth boundary.\n    public SublistResult subList(int sidx, int eidx) {\n      int dataSidx = sidx / tailWidth;\n      int numTails = ((eidx - sidx) + (tailWidth-1))/tailWidth;\n      int dataEidx = dataSidx + numTails;\n      int len = eidx - sidx;\n      int leftover = len % tailWidth;\n      /* System.out.println(\"Leaf SubList sidx \" + String.valueOf(sidx) + \" eidx \" + String.valueOf(eidx) */\n      /* \t\t\t + \" dataSidx \" + String.valueOf(dataSidx) + \" dataEidx \" + String.valueOf(dataEidx) */\n      /* \t\t\t + \" leftover \" + leftover); */\n      if(sidx == 0 && eidx == (data.length * tailWidth))\n\treturn new SublistResult(this, new Object[0]);\n      if(leftover == 0) {\n\treturn new SublistResult(new Leaf(Arrays.copyOfRange(data, dataSidx, dataEidx)), new Object[0]);\n      } else {\n\n\tObject[] tail = data[dataEidx-1];\n\treturn new SublistResult(new Leaf(Arrays.copyOfRange(data, dataSidx, dataEidx-1))\n\t\t\t\t , Arrays.copyOf(tail, leftover));\n      }\n    }\n    public static final Leaf EMPTY = new Leaf();\n  }\n  public static class Branch implements INode {\n    final Object owner;\n    Object[] data; //either branch or leaf\n    public Object[] data() { return this.data; }\n    public Branch() { this.owner = null; data = new Object[0]; }\n    public Branch(Object owner, Object[] data) { this.owner = owner; this.data = data; }\n    public Branch(Leaf leaf) { this.owner = null; this.data = new Object[]{leaf}; }\n    public Branch(Branch branch) { this.owner = null; this.data = new Object[]{branch}; }\n    public Branch(Object owner, int shift, Object[] tail) {\n      this(owner, new Object[] { shift == 1 ? new Leaf(tail) : new Branch(shift-1, tail) } );\n    }\n    @SuppressWarnings(\"unchecked\")\n    public void forEachRemaining(int shift, int sidx, int eidx, Consumer cc) {\n      /* System.out.println(\"brach sidx \" + String.valueOf(sidx) + */\n      /* \t\t\t \" eidx \" + String.valueOf(eidx)); */\n      int shiftAmt = shift * shiftWidth;\n      int level = branchWidth << shiftAmt;\n      int aryIdx = sidx / level;\n      int aryEnd = aryIdx + outerEidxSpan(sidx, eidx, level);\n      int aryOffset = sidx % level;\n      for(; aryIdx < aryEnd; ++aryIdx) {\n\tint localEnd = localEidx(aryIdx, eidx, level);\n\t((INode)data[aryIdx]).forEachRemaining(shift-1, aryOffset, localEnd, cc);\n\taryOffset = 0;\n      }\n    }\n    public Object reduce(int shift, int sidx, int eidx, IFn rfn, Object acc) {\n      /* System.out.println(\"brach sidx \" + String.valueOf(sidx) + */\n      /* \t\t\t \" eidx \" + String.valueOf(eidx)); */\n      int shiftAmt = shift * shiftWidth;\n      int level = branchWidth << shiftAmt;\n      int aryIdx = sidx / level;\n      int aryEnd = aryIdx + outerEidxSpan(sidx, eidx, level);\n      int aryOffset = sidx % level;\n      for(; aryIdx < aryEnd; ++aryIdx) {\n\tint localEnd = localEidx(aryIdx, eidx, level);\n\tacc = ((INode)data[aryIdx]).reduce(shift-1, aryOffset, localEnd, rfn, acc);\n\tif(RT.isReduced(acc)) return acc;\n\taryOffset = 0;\n      }\n      return acc;\n    }\n    public Object cons(Object owner, int shift, Object[] tail) {\n      if(data.length == 0)\n\treturn new Branch(owner, shift, tail);\n      int lastIdx = data.length-1;\n      Object last = data[lastIdx];\n      boolean force = owner == null || this.owner != owner;\n      Object res = shift == 1 ? ((Leaf)last).cons(owner, tail) : ((Branch)last).cons(owner, shift-1, tail);\n      if(res instanceof Object[]) {\n\tObject newNode = ((Object[])res)[1];\n\tif(data.length == branchWidth) {\n\t  return new Object[] { this, new Branch( owner, new Object[] { newNode } ) };\n\t} else {\n\t  Object[] newData = Arrays.copyOf(data, data.length+1);\n\t  newData[data.length] = newNode;\n\t  if(force) {\n\t    return new Branch(owner, newData);\n\t  } else {\n\t    data = newData;\n\t    return this;\n\t  }\n\t}\n      }\n      Object[] newData = force ? data.clone() : data;\n      newData[newData.length-1] = res;\n      if(force) {\n\treturn new Branch(owner, newData);\n      } else {\n\treturn this;\n      }\n    }\n    public Object cons(int shift, Object[] tail) {\n      return cons(null, shift, tail);\n    }\n    public Object add(Object owner, int shift, Object[] tail) {\n      return cons(owner, shift, tail);\n    }\n    public ConsAllResult consAll(Object owner, int shift, int maxSiblings, Iter dataIter) {\n      int maxChildren = branchWidth - data.length + branchWidth * maxSiblings;\n      Object lastNode = data[data.length-1];\n      ConsAllResult res = shift == 1 ?\n\t((Leaf)lastNode).consAll(owner, maxChildren, dataIter) :\n\t((Branch)lastNode).consAll(owner, shift-1, maxChildren, dataIter);\n      int numChildren = res.nodes.length;\n      Object[] tail = res.tail;\n      dataIter = res.nextData;\n      int added = res.added;\n      if(res.nodes.length == 1 && res.nodes[0] == lastNode)\n\treturn new ConsAllResult(new Object[]{this}, dataIter, tail, added);\n      int nLocalNodes = Math.min(numChildren, branchWidth - data.length);\n      Object[] newData = Arrays.copyOf(data, data.length + nLocalNodes);\n      int nNewBranches = (numChildren - nLocalNodes + branchWidth -1)/branchWidth;\n      Object[] rv = new Object[1 + nNewBranches];\n      rv[0] = new Branch(owner, newData);\n      for(int idx = 0; idx < nNewBranches; ++idx) {\n\tint copyBegin = nLocalNodes + (idx * branchWidth);\n\tint copyEnd = Math.min(copyBegin + branchWidth, numChildren);\n\trv[idx+1] = new Branch(owner, Arrays.copyOfRange(data, copyBegin, copyEnd));\n      }\n      return new ConsAllResult(rv, dataIter, tail, added);\n    }\n    public Object getNode(int shift, int idx) {\n      int shiftAmt = shift * shiftWidth;\n      int level = branchWidth << shiftAmt;\n      int localIdx = idx / level;\n      return data[localIdx];\n    }\n    public Object[] getArray(int shift, int idx) {\n      int shiftAmt = shift * shiftWidth;\n      int level = branchWidth << shiftAmt;\n      int localIdx = idx / level;\n      int leftover = idx % level;\n      Object item = data[localIdx];\n      return shift == 1 ? ((Leaf)item).getArray(leftover) : ((Branch)item).getArray(shift-1, leftover);\n    }\n    public Branch assocN(Object owner, int shift, int idx, Object obj, Box oldVal) {\n      boolean force = owner == null || this.owner != owner;\n      int shiftAmt = shift * shiftWidth;\n      int level = branchWidth << shiftAmt;\n      int localIdx = idx / level;\n      int leftover = idx % level;\n      Object item = data[localIdx];\n      Object newItem = shift == 1 ? ((Leaf)item).assocN(owner, leftover, obj, oldVal)\n\t: ((Branch)item).assocN(owner, shift-1, leftover, obj, oldVal);\n      Object[] newData = force ? Arrays.copyOf(data, data.length) : data;\n      if(newItem != item) {\n\tnewData[localIdx] = newItem;\n      }\n      return force ? new Branch(owner, newData) : this;\n    }\n    public boolean isEmpty() { return data.length == 0; }\n    public SublistResult pop(Object owner, int shift) {\n      boolean force = owner == null || owner != this.owner;\n      int dlen = data.length;\n      Object lastObj = data[dlen-1];\n      SublistResult res = shift == 1 ? ((Leaf)lastObj).pop(owner) : ((Branch)lastObj).pop(owner, shift-1);\n      Object node = res.node;\n      Object[] newTail = res.tail;\n      boolean empty = shift == 1 ? ((Leaf)node).isEmpty() : ((Branch)node).isEmpty();\n      Object[] newD;\n      if(empty) {\n\tif(dlen-1 == 0) {\n\t  newD = new Object[0];\n\t} else {\n\t  newD = Arrays.copyOf(data, dlen-1);\n\t}\n      }else {\n\tnewD = force ? data.clone() : data;\n      }\n      int newLen = newD.length;\n      if(!empty)\n\tnewD[newLen-1] = node;\n\n      Branch newBranch;\n      if(force) {\n\tnewBranch = new Branch(owner, newD);\n      } else {\n\tthis.data = newD;\n\tnewBranch = this;\n      }\n      return new SublistResult(newBranch, newTail);\n    }\n    public static final BiFunction leafMergeRight = new BiFunction() {\n\tpublic Object apply(Object lhs, Object rhs) {\n\t  Leaf ll = (Leaf)lhs;\n\t  Leaf rr = (Leaf)rhs;\n\t  // System.out.println(\"ll \" + String.valueOf(ll.data.length) + \" rr \" + String.valueOf(rr.data.length));\n\t  if(ll.data.length < leafWidth) {\n\t    int totalWidth = ll.data.length + rr.data.length;\n\t    int newLen = Math.min(leafWidth, ll.data.length + rr.data.length);\n\t    Object[][] newLeafData = Arrays.copyOf(ll.data, newLen);\n\t    System.arraycopy(rr.data, 0, newLeafData, ll.data.length, newLen - ll.data.length);\n\t    ll = new Leaf(newLeafData);\n\t    int newRightLen = totalWidth - newLen;\n\t    if(newRightLen > 0)\n\t      rr = new Leaf(Arrays.copyOfRange(rr.data, rr.data.length-newRightLen, rr.data.length));\n\t    else\n\t      rr = null;\n\t  }\n\t  return rr == null ? ll : new Object[] {ll, rr};\n\t}\n      };\n    @SuppressWarnings(\"unchecked\")\n    public static final BiFunction branchMergeRight = new BiFunction() {\n\tpublic Object apply(Object lhs, Object rhs) {\n\t  Branch ll = (Branch)lhs;\n\t  Branch rr = (Branch)rhs;\n\t  int totalWidth = ll.data.length + rr.data.length;\n\t  int newLen = Math.min(branchWidth, ll.data.length + rr.data.length);\n\t  ArrayList newBranchData = new ArrayList(newLen);\n\t  newBranchData.addAll(Arrays.asList(ll.data));\n\t  Object lastObj = newBranchData.get(newBranchData.size()-1);\n\t  BiFunction mergeFn = lastObj instanceof Leaf ? leafMergeRight : branchMergeRight;\n\t  for(int idx = 0; idx < rr.data.length; ++idx) {\n\t    Object merged = mergeFn.apply(lastObj, rr.data[idx]);\n\t    int lastidx = newBranchData.size()-1;\n\t    if(merged instanceof Object[]) {\n\t      final Object[] mm = (Object[])merged;\n\t      newBranchData.set(lastidx, mm[0]);\n\t      newBranchData.add(mm[1]);\n\t      lastObj = mm[1];\n\t    } else {\n\t      newBranchData.set(lastidx, merged);\n\t      lastObj = merged;\n\t    }\n\t  }\n\t  int newDataSize = newBranchData.size();\n\t  int llen = Math.min(branchWidth, newDataSize);\n\t  ll = new Branch(null, newBranchData.subList(0, llen).toArray());\n\t  if(llen < newDataSize) {\n\t    rr = new Branch(null, newBranchData.subList(llen, newDataSize).toArray());\n\t  } else {\n\t    rr = null;\n\t  }\n\t  return rr == null ? ll : new Object[] {ll, rr};\n\t}\n      };\n\n    @SuppressWarnings(\"unchecked\")\n    public SublistResult subList(int shift, int sidx, int eidx) {\n      int shiftAmt = shift * shiftWidth;\n      int level = branchWidth << shiftAmt;\n      int localSidx = sidx / level;\n      int numNodes = (eidx - (localSidx * level) + (level - 1)) / level;\n      int localEidx = localSidx + numNodes;\n      ArrayList newData = new ArrayList(numNodes);\n      Object[] newTail = null;\n      final BiFunction mergeFunction = shift == 1 ? leafMergeRight : branchMergeRight;\n      for(int nodeIdx = 0; nodeIdx < numNodes; ++nodeIdx) {\n\tint dataIdx = localSidx + nodeIdx;\n\tint nodeStart = dataIdx * level;\n\tint nodeEnd = nodeStart + level;\n\tint nodeSidx = Math.max(nodeStart, sidx);\n\tint nodeEidx = Math.min(nodeEnd, eidx);\n\tObject dataNode = data[dataIdx];\n\tif(nodeStart == nodeSidx && nodeEnd == nodeEidx) {\n\t  newData.add(dataNode);\n\t} else {\n\t  int subSidx = nodeSidx - nodeStart;\n\t  int subEidx = nodeEidx - nodeStart;\n\t  SublistResult res = shift == 1 ?\n\t    ((Leaf)dataNode).subList(subSidx, subEidx) :\n\t    ((Branch)dataNode).subList(shift-1, subSidx, subEidx);\n\t  newData.add(res.node);\n\t  newTail = res.tail;\n\t}\n\tint sz = newData.size();\n\tif(sz > 1 ) {\n\t  Object merged = mergeFunction.apply(newData.get(sz-2), newData.get(sz-1));\n\t  if(merged instanceof Object[]) {\n\t    Object[] mm = (Object[])merged;\n\t    newData.set(sz-2, mm[0]);\n\t    newData.set(sz-1, mm[1]);\n\t  } else {\n\t    newData.set(sz-2, merged);\n\t    //right node was completely consumed by left\n\t    newData.remove(sz-1);\n\t  }\n\t}\n      }\n      return new SublistResult(new Branch(owner, newData.toArray()), newTail);\n    }\n  };\n\n  Object[] tail;\n  Object root;\n  int count;\n  int shift;\n  public Object[] tail() { return tail; }\n  public Object[] validTail() { return tail; }\n  public Object root() { return root; }\n  public int length() { return count; }\n  public int count() { return count; }\n  public int size() { return count; }\n  public int shift() { return shift; }\n  public int nTail() { return tail.length; }\n\n  public TreeListBase(Object root, Object[] tail, int shift, int count) {\n    this.tail = tail;\n    this.root = root;\n    this.count = count;\n    this.shift = shift;\n  }\n  public TreeListBase() {\n    this.tail = new Object[0];\n    this.root = new Leaf();\n    this.count = 0;\n    this.shift = 0;\n  }\n  public TreeListBase(TreeListBase other) {\n    this.tail = other.validTail();\n    this.root = other.root;\n    this.count = other.count;\n    this.shift = other.shift;\n  }\n  public static class ArrayIterator implements Iterator<Object[]> {\n    final TreeListBase data;\n    int arySidx;\n    final int aryEidx;\n    public ArrayIterator(TreeListBase data, int arySidx, int aryEidx) {\n      this.data = data;\n      this.arySidx = arySidx;\n      this.aryEidx = aryEidx;\n    }\n    public boolean hasNext() { return arySidx < aryEidx; }\n    public Object[] next() {\n      if(arySidx >= aryEidx) throw new NoSuchElementException();\n      Object[] rv = data.getArray(arySidx * tailWidth);\n      ++arySidx;\n      return rv;\n    }\n  }\n  public Iterator<Object[]> arrayIterator(int sidx, int eidx) {\n    int arySidx = sidx / tailWidth;\n    int nArrays = (eidx - (arySidx * tailWidth) + (tailWidth - 1))/tailWidth;\n    int aryEidx = arySidx + nArrays;\n    return new ArrayIterator(this, arySidx, aryEidx);\n  }\n  public Object[] getArray(int idx) {\n    int cutoff = count - nTail();\n    return (idx < cutoff)\n      ? (shift == 0)\n      ? ((Leaf)root).getArray(idx) : ((Branch)root).getArray(shift, idx)\n      : tail;\n  }\n  public Object get(int idx) {\n    checkIndex(idx, count);\n    return getArray(idx)[idx % 32];\n  }\n  @SuppressWarnings(\"unchecked\")\n  public void forEachRemaining(int sidx, int eidx, Consumer cc) {\n    sublistCheck(sidx, eidx, size());\n    int cutoff = count - nTail();\n    if(sidx < cutoff)\n      ((INode)root).forEachRemaining(shift, sidx, Math.min(eidx, cutoff), cc);\n    if(eidx > cutoff) {\n      int cidx = eidx - cutoff;\n      for(int idx = Math.max(sidx, cutoff) - cutoff; idx < cidx; ++idx)\n\tcc.accept(tail[idx]);\n    }\n  }\n  public Object reduce(int sidx, int eidx, IFn rfn, Object acc) {\n    sublistCheck(sidx, eidx, size());\n    int cutoff = count - nTail();\n    if(sidx < cutoff)\n      acc = ((INode)root).reduce(shift, sidx, Math.min(eidx, cutoff), rfn, acc);\n    if (RT.isReduced(acc)) return ((IDeref)acc).deref();\n    if(eidx > cutoff) {\n      int cidx = eidx - cutoff;\n      for(int idx = Math.max(sidx, cutoff) - cutoff; idx < cidx; ++idx) {\n\tacc = rfn.invoke(acc, tail[idx]);\n\tif (RT.isReduced(acc)) return acc;\n      }\n    }\n    return acc;\n  }\n\n  public Object reduce(IFn rfn, Object acc) {\n    return reduce(0, count, rfn, acc);\n  }\n  public Object[] fillArray(int sidx, int eidx, Object[] data) {\n    Iterator<Object[]> iter = arrayIterator(sidx, eidx);\n    int arySidx = sidx - (sidx % tailWidth);\n    int writeOff = 0;\n    while(iter.hasNext()) {\n      int startoff = Math.max(sidx, arySidx);\n      int endoff = Math.min(eidx, arySidx + tailWidth);\n      int copyLen = endoff - startoff;\n      System.arraycopy(iter.next(), startoff % 32, data, writeOff, copyLen);\n      writeOff += copyLen;\n      arySidx += tailWidth;\n    }\n    return data;\n  }\n  public Object[] fillArray(Object[] data) {\n    return fillArray(0, count, data);\n  }\n  public static class TreeListSpliterator implements Spliterator {\n    public final TreeListBase data;\n    int sidx;\n    int eidx;\n\n    public TreeListSpliterator(TreeListBase data, int sidx, int eidx) {\n      this.data = data;\n      this.sidx = sidx;\n      this.eidx = eidx;\n    }\n    public int characteristics() {\n      return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED | Spliterator.IMMUTABLE;\n    }\n    public Spliterator trySplit() {\n      int ne = (eidx - sidx);\n      if ( ne > 2) {\n\tint middle = sidx + (ne / 2);\n\tint eeidx = eidx;\n\teidx = middle;\n\treturn new TreeListSpliterator(data, middle, eeidx);\n      }\n      return null;\n    }\n    public long estimateSize() { return eidx - sidx; }\n    @SuppressWarnings(\"unchecked\")\n    public boolean tryAdvance(Consumer c) {\n      if(sidx < eidx) {\n\tc.accept(data.get(sidx));\n\t++sidx;\n\treturn true;\n      }\n      return false;\n    }\n    public void forEachRemaining(Consumer c) {\n      data.forEachRemaining(sidx, eidx, c);\n      sidx = eidx;\n    }\n  }\n  public Spliterator spliterator(int sidx, int eidx) {\n    sublistCheck(sidx, eidx, size());\n    return new TreeListSpliterator(this, sidx, eidx);\n  }\n  public Spliterator spliterator() { return spliterator(0, size()); }\n  public static class SubList implements IMutList, IPersistentVector {\n    int offset; //<= 32\n    TreeList data;\n    public SubList(int offset, TreeList data) {\n      this.offset = offset;\n      this.data = data;\n    }\n    public int offset() { return offset; }\n    public TreeList data() { return data; }\n    public int count() { return data.count() - offset; }\n    public int size() { return data.count() - offset; }\n    public int length() { return data.count() - offset; }\n    public Object get(int idx) {\n      checkIndex(idx, count());\n      return data.get(idx + offset);\n    }\n    public SubList cons(Object a) {\n      return new SubList(offset, data.cons(a));\n    }\n    public SubList assocN(int idx, Object a) {\n      return new SubList(offset, data.assocN(idx, a));\n    }\n    public IPersistentVector pop() {\n      int cnt = count();\n      if ( cnt == 0 ) throw new UnsupportedOperationException(\"Underflow\");\n      if ( cnt == 1 ) return TreeList.EMPTY;\n      return new SubList(offset, data.pop());\n    }\n    public Object peek() { return data.peek(); }\n    public IMutList subList(int sidx, int eidx) {\n      sublistCheck(sidx, eidx, size());\n      return data.subList(sidx+offset, eidx+offset);\n    }\n    public Object[] fillArray(Object[] ary) {\n      return data.fillArray(offset, data.count(), ary);\n    }\n    public Object reduce(IFn rfn, Object acc) {\n      return data.reduce(offset, data.count(), rfn, acc);\n    }\n    public Spliterator spliterator() {\n      return data.spliterator(offset, data.count());\n    }\n    public static IMutList create(int offset, TreeList data) {\n      if(offset == 0)\n\treturn data;\n      return new SubList(offset, data);\n    }\n  }\n  public static Object[] nonNull(Object[] data) {\n    return data == null ? emptyObjAry : data;\n  }\n  public IMutList subList(int sidx, int eidx) {\n    sublistCheck(sidx, eidx, size());\n    int tlen = nTail();\n    int cutoff = count - nTail();\n    if(sidx == 0 && eidx == count)\n      return this;\n    if(sidx == eidx)\n      return TreeList.EMPTY;\n    Object[] tailPart = null;\n    if(eidx > cutoff) {\n      int tailSidx = Math.max(sidx, cutoff);\n      tailPart = Arrays.copyOfRange(tail, tailSidx - cutoff, eidx - cutoff);\n    }\n    int newShift = shift;\n    Object newNode = null;\n    Object[] treeTail = null;\n    int offset = sidx % tailWidth;\n    int roundedSidx = sidx - offset;\n    if(sidx < cutoff) {\n      int treeEidx = Math.min(eidx, cutoff);\n      SublistResult treePart = shift==0\n\t? ((Leaf)root).subList(roundedSidx, treeEidx)\n\t: ((Branch)root).subList(shift, roundedSidx, treeEidx);\n      newNode = treePart.node;\n      treeTail = treePart.tail;\n      while(newShift > 0) {\n\tBranch b = (Branch)newNode;\n\tif(b.data.length == 1) {\n\t  newNode = b.data[0];\n\t  newShift--;\n\t} else {\n\t  break;\n\t}\n      }\n    }\n    if(newNode == null)\n      return new TreeList(new Leaf(), tailPart, meta(), 0, tailPart.length);\n    TreeList newList = new TreeList(newNode, nonNull(tailPart == null ? treeTail : tailPart),\n\t\t\t\t    meta(), newShift, eidx-roundedSidx);\n    return SubList.create(offset, newList);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/TypedList.java",
    "content": "package ham_fisted;\n\n\npublic interface TypedList {\n  default Class containedType() { return Object.class; }\n}\n"
  },
  {
    "path": "java/ham_fisted/TypedNth.java",
    "content": "package ham_fisted;\n\n\nimport clojure.lang.RT;\n\n\npublic class TypedNth {\n  public static double dnth(Object v, long idx) {    \n    return (v instanceof double[]) ? dnth((double[])v, idx) : Casts.doubleCast(RT.nth(v, (int)idx));\n  }\n  public static double dnth(double[] v, long idx) {\n    return v[(int)idx];\n  }\n  public static float fnth(Object v, long idx) {    \n    return (v instanceof float[]) ? fnth((float[])v, idx) : Casts.floatCast(RT.nth(v, (int)idx));\n  }\n  public static float fnth(float[] v, long idx) {\n    return v[(int)idx];\n  }\n  public static long lnth(Object v, long idx) {\n    return (v instanceof long[]) ? lnth((long[])v, idx) : Casts.longCast(RT.nth(v, (int)idx));\n  }\n  public static long lnth(long[] v, long idx) {\n    return v[(int)idx];\n  }\n  public static int inth(Object v, long idx) {\n    return (v instanceof int[]) ? inth((int[])v, idx) : Casts.intCast(RT.nth(v, (int)idx));\n  }\n  public static int inth(int[] v, long idx) {\n    return v[(int)idx];\n  }\n}\n  \n"
  },
  {
    "path": "java/ham_fisted/UnsharedHashMap.java",
    "content": "package ham_fisted;\n\n\nimport java.util.List;\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.ITransientAssociative2;\nimport clojure.lang.Indexed;\n\n\npublic class UnsharedHashMap\n  extends HashMap\n  implements MutableMap, IATransientMap {\n  public UnsharedHashMap() {\n    super(null);\n  }\n  public UnsharedHashMap(IPersistentMap meta) {\n    super(meta);\n  }\n  public UnsharedHashMap(IPersistentMap meta, int capacity) {\n    super(0.75f, Math.max(4, IntegerOps.nextPow2((int)(capacity/0.75f))),\n\t  0, null, meta);\n  }\n  public static UnsharedHashMap create(Object[] data) {\n    final int l = data.length;\n    if((l%2) != 0)\n      throw new RuntimeException(\"Data length not evenly divisible by 2\");\n    final UnsharedHashMap rv = new UnsharedHashMap(null, l/2);\n    final HashNode[] d = rv.data;\n    final int m = rv.mask;\n    for(int idx = 0; idx < l; idx += 2) {\n      final Object k = data[idx];\n      final Object v = data[idx+1];\n      final int hc = rv.hash(k);\n      final int didx = hc & m;\n      HashNode lf, init = d[didx];\n      for(lf = init; lf != null && !(lf.k == k || rv.equals(lf.k, k)); lf = lf.nextNode);\n      if(lf != null) {\n\tlf.v = v;\n      } else {\n\tfinal HashNode newNode = rv.newNode(k, hc, v);\n\tnewNode.nextNode = d[didx];\n\td[didx] = newNode;\n      }\n    }\n    return rv;\n  }\n  public static UnsharedHashMap createInterleaved(List data) {\n    final int l = data.size();\n    if((l%2) != 0)\n      throw new RuntimeException(\"Data length not evenly divisible by 2\");\n    final UnsharedHashMap rv = new UnsharedHashMap(null, l/2);\n    final HashNode[] d = rv.data;\n    final int m = rv.mask;\n    for(int idx = 0; idx < l; idx += 2) {\n      final Object k = data.get(idx);\n      final Object v = data.get(idx+1);\n      final int hc = rv.hash(k);\n      final int didx = hc & m;\n      HashNode lf, init = d[didx];\n      for(lf = init; lf != null && !(lf.k == k || rv.equals(lf.k, k)); lf = lf.nextNode);\n      if(lf != null) {\n\tlf.v = v;\n      } else {\n\tfinal HashNode newNode = rv.newNode(k, hc, v);\n\tnewNode.nextNode = d[didx];\n\td[didx] = newNode;\n      }\n    }\n    return rv;\n  }\n  public UnsharedHashMap assoc(Object key, Object val) {\n    put(key,val);\n    return this;\n  }\n  public UnsharedHashMap without(Object key) {\n    remove(key);\n    return this;\n  }\n  public PersistentHashMap persistent() {\n    return new PersistentHashMap(this);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/UnsharedHashSet.java",
    "content": "package ham_fisted;\n\n\nimport java.util.Collection;\nimport clojure.lang.IPersistentMap;\n\n\npublic class UnsharedHashSet extends HashSet implements IATransientSet {\n  public UnsharedHashSet(IPersistentMap meta) {\n    super(meta);\n  }\n  public UnsharedHashSet conj(Object key) {\n    add(key);\n    return this;\n  }\n  public UnsharedHashSet disjoin(Object key) {\n    remove(key);\n    return this;\n  }\n  public HashSet union(Collection rhs) {\n    addAll(rhs);\n    return this;\n  }\n  public PersistentHashSet persistent() { return new PersistentHashSet(this, meta); }\n}\n"
  },
  {
    "path": "java/ham_fisted/UnsharedLongHashMap.java",
    "content": "package ham_fisted;\n\nimport java.util.List;\nimport java.util.Map;\nimport clojure.lang.IPersistentMap;\nimport clojure.lang.ITransientMap;\nimport clojure.lang.ITransientAssociative2;\nimport clojure.lang.Indexed;\n\n\npublic class UnsharedLongHashMap\n  extends LongHashMap\n  implements MutableMap, IATransientMap {\n  public UnsharedLongHashMap() {\n    super(null);\n  }\n  public UnsharedLongHashMap(IPersistentMap meta) {\n    super(meta);\n  }\n  public UnsharedLongHashMap(IPersistentMap meta, int capacity) {\n    super(0.75f, Math.max(4, IntegerOps.nextPow2((int)(capacity/0.75f))),\n\t  0, null, meta);\n  }\n  public static UnsharedLongHashMap create(Object[] data) {\n    final int l = data.length;\n    if((l%2) != 0)\n      throw new RuntimeException(\"Data length not evenly divisible by 2\");\n    final UnsharedLongHashMap rv = new UnsharedLongHashMap(null, l/2);\n    final LongHashNode[] d = rv.data;\n    final int m = rv.mask;\n    for(int idx = 0; idx < l; idx += 2) {\n      final long k = Casts.longCast(data[idx]);\n      final Object v = data[idx+1];\n      final int hc = rv.hash(k);\n      final int didx = hc & m;\n      LongHashNode lf, init = d[didx];\n      for(lf = init; lf != null && !(lf.k == k); lf = lf.nextNode);\n      if(lf != null) {\n\tlf.v = v;\n      } else {\n\tfinal LongHashNode newNode = rv.newNode(k, hc, v);\n\tnewNode.nextNode = d[didx];\n\td[didx] = newNode;\n      }\n    }\n    return rv;\n  }\n  public static UnsharedLongHashMap createInterleaved(List data) {\n    final int l = data.size();\n    if((l%2) != 0)\n      throw new RuntimeException(\"Data length not evenly divisible by 2\");\n    final UnsharedLongHashMap rv = new UnsharedLongHashMap(null, l/2);\n    final LongHashNode[] d = rv.data;\n    final int m = rv.mask;\n    for(int idx = 0; idx < l; idx += 2) {\n      final long k = Casts.longCast(data.get(idx));\n      final Object v = data.get(idx+1);\n      final int hc = rv.hash(k);\n      final int didx = hc & m;\n      LongHashNode lf, init = d[didx];\n      for(lf = init; lf != null && !(lf.k == k); lf = lf.nextNode);\n      if(lf != null) {\n\tlf.v = v;\n      } else {\n\tfinal LongHashNode newNode = rv.newNode(k, hc, v);\n\tnewNode.nextNode = d[didx];\n\td[didx] = newNode;\n      }\n    }\n    return rv;\n  }\n  public UnsharedLongHashMap assoc(Object key, Object val) {\n    put(key,val);\n    return this;\n  }\n  public UnsharedLongHashMap without(Object key) {\n    remove(key);\n    return this;\n  }\n  public PersistentLongHashMap persistent() {\n    return new PersistentLongHashMap(this);\n  }\n}\n"
  },
  {
    "path": "java/ham_fisted/UpdateValues.java",
    "content": "package ham_fisted;\n\nimport java.util.function.Function;\nimport java.util.function.BiFunction;\nimport clojure.lang.IFn;\nimport clojure.lang.ITransientCollection;\n\npublic interface UpdateValues {\n  public UpdateValues updateValues(BiFunction valueMap);\n  public UpdateValues updateValue(Object key, Function fn);\n}\n"
  },
  {
    "path": "resources/clj-kondo.exports/cnuernber/ham-fisted/config.edn",
    "content": "{:lint-as {ham-fisted.defprotocol/defprotocol clojure.core/defprotocol\n           ham-fisted.defprotocol/extend-protocol clojure.core/extend-protocol\n           ham-fisted.defprotocol/extend-type clojure.core/extend-type}\n :hooks {:analyze-call {ham-fisted.hlet/let hooks.ham-fisted/analyze-hlet-macro\n                        ham-fisted.function/function hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/long-predicate hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/long-unary-operator hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/double-predicate hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/double-unary-operator hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/obj->long hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/long->double hooks.ham-fisted/analyze-1-arg-fn-macro\n                        ham-fisted.function/bi-function hooks.ham-fisted/analyze-2-arg-fn-macro\n                        ham-fisted.function/binary-predicate hooks.ham-fisted/analyze-2-arg-fn-macro\n                        ham-fisted.function/long-binary-operator hooks.ham-fisted/analyze-2-arg-fn-macro\n                        ham-fisted.function/double-binary-operator hooks.ham-fisted/analyze-2-arg-fn-macro\n                        ham-fisted.reduce/long-accumulator hooks.ham-fisted/analyze-2-arg-fn-macro\n                        ham-fisted.reduce/double-accumulator hooks.ham-fisted/analyze-2-arg-fn-macro\n                        ham-fisted.reduce/indexed-accum hooks.ham-fisted/analyze-indexed-reduce-fn-macro\n                        ham-fisted.alists/make-prim-array-list hooks.ham-fisted/analyze-make-prim-array-list-macro\n                        ham-fisted.lazy-noncaching/make-readonly-list hooks.ham-fisted/analyze-indexed-make-list-macro}}}\n"
  },
  {
    "path": "resources/clj-kondo.exports/cnuernber/ham-fisted/hooks/ham_fisted.clj_kondo",
    "content": "(ns hooks.ham-fisted\n  (:require [clj-kondo.hooks-api :as api]))\n\n(defn node-value\n  [node]\n  (when node\n    (api/sexpr node)))\n\n(defn analyze-hlet-macro\n  [{:keys [:node]}]\n  (let [[bindings & body] (rest (:children node))\n        new-node (api/list-node\n                  (list*\n                   (api/token-node 'clojure.core/let)\n                   (api/vector-node\n                    (concat\n                      [(api/token-node 'dbls)\n                       (api/token-node 'clojure.core/vec)\n                       (api/token-node 'lngs)\n                       (api/token-node 'clojure.core/vec)\n                       (api/token-node 'lng-fns)\n                       (api/token-node 'clojure.core/vec)\n                       (api/token-node 'dbl-fns)\n                       (api/token-node 'clojure.core/vec)\n                       (api/token-node 'obj-fns)\n                       (api/token-node 'clojure.core/vec)]\n                      (:children bindings)))\n                   body))]\n    {:node new-node}))\n\n(defn analyze-1-arg-fn-macro\n  [{:keys [:node]}]\n  (let [[arg1 & body] (rest (:children node))\n        new-node (api/list-node\n                  (list*\n                   (api/token-node 'clojure.core/fn)\n                   (api/vector-node [arg1])\n                   body))]\n    {:node new-node}))\n\n(defn analyze-2-arg-fn-macro\n  [{:keys [:node]}]\n  (let [[arg1 arg2 & body] (rest (:children node))\n        new-node (api/list-node\n                  (list*\n                   (api/token-node 'clojure.core/fn)\n                   (api/vector-node [arg1 arg2])\n                   body))]\n    {:node new-node}))\n\n(defn analyze-indexed-reduce-fn-macro\n  [{:keys [:node]}]\n  (let [[acc-arg idx-arg obj-arg & body] (rest (:children node))\n        new-node (api/list-node\n                  (list*\n                   (api/token-node 'clojure.core/fn)\n                   (api/vector-node [acc-arg\n                                     (api/vector-node [idx-arg obj-arg])])\n                   body))]\n    {:node new-node}))\n\n(defn analyze-indexed-make-list-macro\n  [{:keys [:node]}]\n  (let [children (rest (:children node))\n        _input-args (drop-last 3 children)\n        [nel-arg idx-arg & body] (take-last 3 children)\n        new-node (api/list-node\n                  (list\n                   (api/token-node 'clojure.core/map)\n                   (api/list-node\n                    (list*\n                     (api/token-node 'clojure.core/fn)\n                     (api/vector-node [idx-arg])\n                     body))\n                   (api/list-node\n                    (list\n                     (api/token-node 'clojure.core/range)\n                     (api/token-node nel-arg)))))]\n    {:node new-node}))\n\n(defn analyze-make-prim-array-list-macro\n  [{:keys [:node]}]\n  (let [[lname ary-tag iface getname setname addname set-cast-fn get-cast-fn obj-cast-fn add-all-reduce] (rest (:children node))\n        new-node (api/list-node\n                  (list\n                   (api/token-node 'clojure.core/deftype)\n                   (vary-meta lname assoc :tag (node-value ary-tag))\n                   (api/vector-node\n                    [(api/token-node 'data)\n                     (api/token-node 'n-elems)\n                     (api/token-node 'm)])\n                   iface\n                   (api/list-node\n                    (list\n                     getname\n                     (api/vector-node\n                      [(api/token-node '_)\n                       (api/token-node 'idx)])\n                     (api/list-node\n                      (list\n                       get-cast-fn\n                       (api/list-node\n                        (list\n                         (api/token-node 'clojure.core/aget)\n                         (api/token-node 'data)\n                         (api/token-node 'idx)))))))\n                   (api/list-node\n                    (list\n                     setname\n                     (api/vector-node\n                      [(api/token-node '_)\n                       (api/token-node 'idx)\n                       (api/token-node 'v)])\n                     (api/list-node\n                      (list\n                       (api/token-node 'clojure.core/aset)\n                       (api/token-node 'data)\n                       (api/token-node 'idx)\n                       (api/list-node\n                        (list\n                         set-cast-fn\n                         (api/token-node 'v)))))))\n                   (api/list-node\n                    (list\n                     addname\n                     (api/vector-node\n                      [(api/token-node '_)\n                       (api/token-node 'v)])\n                     (api/list-node\n                      (list\n                       (api/token-node 'clojure.core/aset)\n                       (api/token-node 'data)\n                       (api/token-node 'n-elems)\n                       (api/list-node\n                        (list\n                         obj-cast-fn\n                         (api/token-node 'v)))))))\n                   (api/list-node\n                    (list\n                     (api/token-node 'addAllReducible)\n                     (api/vector-node\n                      [(api/token-node 'this)\n                       (api/token-node 'coll)])\n                     (api/list-node\n                      (list\n                       add-all-reduce\n                       (api/token-node 'this)\n                       (api/token-node 'coll)))))))]\n    {:node new-node}))\n"
  },
  {
    "path": "results/.keepme",
    "content": ""
  },
  {
    "path": "results/concatv.edn",
    "content": "[{:clj {:mean-μs 0.24780844090292262, :variance-μs 3.764414164768287E-12}, :hamf {:mean-μs 0.43340971203396683, :variance-μs 9.387848181317607E-11}, :hamf-objarry {:mean-μs 0.2547612418625813, :variance-μs 3.302995262400414E-13}, :n-elems 4, :test :concatv, :numeric? true} {:clj {:mean-μs 0.8037494984097233, :variance-μs 2.709700728020432E-11}, :hamf {:mean-μs 0.9090962224550908, :variance-μs 5.7322329447778246E-11}, :hamf-objarry {:mean-μs 0.4451537483364495, :variance-μs 6.103257970014966E-12}, :n-elems 10, :test :concatv, :numeric? true} {:clj {:mean-μs 7.795815362657326, :variance-μs 6.281494043817672E-10}, :hamf {:mean-μs 3.394483066467648, :variance-μs 9.411949111627164E-11}, :hamf-objarry {:mean-μs 2.9224988649698935, :variance-μs 2.8498563089823355E-10}, :n-elems 100, :test :concatv, :numeric? true} {:clj {:mean-μs 81.0860135891287, :variance-μs 1.6596268671685533E-7}, :hamf {:mean-μs 37.53904281118535, :variance-μs 8.261923640048913E-8}, :hamf-objarry {:mean-μs 33.72946273712737, :variance-μs 9.40292705667369E-8}, :n-elems 1000, :test :concatv, :numeric? true} {:clj {:mean-μs 828.644979338843, :variance-μs 2.7044209184254263E-5}, :hamf {:mean-μs 339.2093104026846, :variance-μs 7.96549948444661E-6}, :hamf-objarry {:mean-μs 299.8918443443444, :variance-μs 1.0650090238108979E-6}, :n-elems 10000, :test :concatv, :numeric? true} {:clj {:mean-μs 8368.874025641026, :variance-μs 2.1625008937376858E-4}, :hamf {:mean-μs 3364.718911111111, :variance-μs 3.514570640074054E-5}, :hamf-objarry {:mean-μs 3320.8981935483876, :variance-μs 9.131112745088487E-5}, :n-elems 100000, :test :concatv, :numeric? true} {:clj {:mean-μs 84957.22483333333, :variance-μs 0.011313175909666845}, :hamf {:mean-μs 37388.642611111114, :variance-μs 0.0026630569333667073}, :hamf-objarry {:mean-μs 77076.09787499999, :variance-μs 223.1233904054363}, :n-elems 1000000, :test :concatv, :numeric? true}]"
  },
  {
    "path": "results/d00905c-chrisn-lt3-jdk-1.8.0_312.edn",
    "content": "{:machine-name \"chrisn-lt3\",\n :git-sha \"d00905c\",\n :jdk-version \"1.8.0_312\",\n :dataset\n [{:n-elems 5,\n   :norm-factor-μs 0.2737073007766444,\n   :hamf 0.8009695217828876,\n   :clj 1.0,\n   :test :assoc-in}\n  {:n-elems 5,\n   :norm-factor-μs 0.141872438402895,\n   :hamf 0.2750157164152516,\n   :clj 1.0,\n   :test :assoc-in-nil}\n  {:n-elems 100,\n   :norm-factor-μs 6.810420269594472,\n   :hamf 0.12045202287580566,\n   :clj 1.0,\n   :test :concatv}\n  {:n-elems 10000,\n   :norm-factor-μs 960.7099828660438,\n   :hamf 0.4206960080303668,\n   :clj 1.0,\n   :test :frequencies}\n  {:n-elems 5,\n   :norm-factor-μs 0.12507571383882654,\n   :hamf 0.5976826789421495,\n   :clj 1.0,\n   :test :get-in}\n  {:n-elems 10000,\n   :norm-factor-μs 1410.6903333333335,\n   :hamf 0.33488278384032505,\n   :clj 1.0,\n   :test :group-by}\n  {:n-elems 10000,\n   :norm-factor-μs 1433.528372685185,\n   :hamf 0.2931361354483846,\n   :clj 1.0,\n   :test :group-by-reduce}\n  {:n-elems 10000,\n   :java 0.8174789938125867,\n   :norm-factor-μs 541.5395810810811,\n   :hamf 1.0463362481300715,\n   :clj 1.0,\n   :test :hashmap-access}\n  {:n-elems 10,\n   :java 0.7914018884239628,\n   :norm-factor-μs 0.4022970885136924,\n   :hamf 0.903954075168239,\n   :clj 1.0,\n   :test :hashmap-access}\n  {:n-elems 4,\n   :norm-factor-μs 0.4067259476382922,\n   :hamf 0.3981553073808861,\n   :clj 1.0,\n   :test :hashmap-cons-obj-ary}\n  {:n-elems 10,\n   :norm-factor-μs 0.6818907494639115,\n   :hamf 0.6957442339286233,\n   :clj 1.0,\n   :test :hashmap-cons-obj-ary}\n  {:n-elems 1000,\n   :norm-factor-μs 130.4228752688172,\n   :hamf 0.44926071566559916,\n   :clj 1.0,\n   :test :hashmap-cons-obj-ary}\n  {:n-elems 10000,\n   :java 0.5859413067880584,\n   :norm-factor-μs 1281.3707827004218,\n   :hamf 0.9270037369029654,\n   :clj 1.0,\n   :test :hashmap-construction}\n  {:n-elems 10,\n   :java 0.27785938738153243,\n   :norm-factor-μs 2.237653573625657,\n   :hamf 0.4006274017339368,\n   :clj 1.0,\n   :test :hashmap-construction}\n  {:n-elems 10000,\n   :java 0.6249505770784523,\n   :norm-factor-μs 321.2954284963197,\n   :hamf 0.7035802166713964,\n   :clj 1.0,\n   :test :hashmap-reduce}\n  {:n-elems 10,\n   :java 0.7135037003851468,\n   :norm-factor-μs 0.3117122182140018,\n   :hamf 0.8615676280736668,\n   :clj 1.0,\n   :test :hashmap-reduce}\n  {:n-elems 20000,\n   :java 1.0,\n   :norm-factor-μs 497.4922640264026,\n   :hamf 1.0172281545633246,\n   :test :int-list}\n  {:n-elems 1000,\n   :norm-factor-μs 226.51757317073174,\n   :hamf 0.3251372917848312,\n   :clj 1.0,\n   :test :mapmap}\n  {:n-elems 20000,\n   :norm-factor-μs 1374.724713963964,\n   :hamf 0.3910982420215109,\n   :clj 1.0,\n   :test :object-array}\n  {:n-elems 20000,\n   :java 1.0,\n   :norm-factor-μs 493.7951913875599,\n   :hamf 0.981178195595189,\n   :test :object-list}\n  {:n-elems 20000,\n   :norm-factor-μs 1342.562408888889,\n   :eduction 0.370245588501266,\n   :hamf 0.22739722394427567,\n   :clj 1.0,\n   :test :sequence-summation}\n  {:n-elems 10000,\n   :norm-factor-μs 286.4782659980898,\n   :hamf 0.4295476338444791,\n   :clj 1.0,\n   :test :shuffle}\n  {:n-elems 10000,\n   :norm-factor-μs 2839.5518425925925,\n   :hamf 0.28388161547650165,\n   :clj 1.0,\n   :test :sort}\n  {:n-elems 10000,\n   :norm-factor-μs 2485.0578412698414,\n   :hamf 0.4238762907271986,\n   :clj 1.0,\n   :test :sort-doubles}\n  {:n-elems 10000,\n   :norm-factor-μs 2885.107268518519,\n   :hamf 0.27927387790535163,\n   :clj 1.0,\n   :test :sort-ints}\n  {:n-elems 10,\n   :java 0.1465288671905732,\n   :norm-factor-μs 1.9384014094753692,\n   :hamf 0.09261922329193109,\n   :clj 1.0,\n   :test :union}\n  {:n-elems 10000,\n   :java 0.2776789952954786,\n   :norm-factor-μs 1446.9220880952382,\n   :hamf 0.19769322238863848,\n   :clj 1.0,\n   :test :union}\n  {:n-elems 10,\n   :java 0.14352703285934437,\n   :norm-factor-μs 1.9376540425154556,\n   :hamf 0.09116729205903847,\n   :clj 1.0,\n   :test :union-disj}\n  {:n-elems 10000,\n   :java 0.2852826007683308,\n   :norm-factor-μs 1440.7768595238097,\n   :hamf 0.19795254491423378,\n   :clj 1.0,\n   :test :union-disj}\n  {:n-elems 10,\n   :java 0.11367177685883537,\n   :norm-factor-μs 25.724485906709905,\n   :hamf 0.22980816916533875,\n   :clj 1.0,\n   :test :union-reduce}\n  {:n-elems 10000,\n   :java 0.08078332979789488,\n   :norm-factor-μs 37008.01033333334,\n   :hamf 0.15897321364597183,\n   :clj 1.0,\n   :test :union-reduce}\n  {:n-elems 5,\n   :norm-factor-μs 0.29246851947534236,\n   :hamf 1.4007771267102096,\n   :clj 1.0,\n   :test :update-in}\n  {:n-elems 5,\n   :norm-factor-μs 0.1382874667400807,\n   :hamf 0.2889718087035753,\n   :clj 1.0,\n   :test :update-in-nil}\n  {:n-elems 1000,\n   :norm-factor-μs 166.7942376344086,\n   :hamf 0.08320271790164209,\n   :clj 1.0,\n   :test :update-values}\n  {:n-elems 10,\n   :java 1.5628249973091581,\n   :norm-factor-μs 86.02279933938894,\n   :hamf 1.1306972837725195,\n   :clj 1.0,\n   :test :vector-access}\n  {:n-elems 10000,\n   :java 0.9449218717052008,\n   :norm-factor-μs 139.99571786042242,\n   :hamf 1.0471455082754746,\n   :clj 1.0,\n   :test :vector-access}\n  {:n-elems 10,\n   :java 1.1497535407399773,\n   :norm-factor-μs 0.07540932086272897,\n   :hamf 0.36451148371515757,\n   :clj 1.0,\n   :test :vector-cons-obj-array}\n  {:n-elems 10000,\n   :java 0.06613494382317181,\n   :norm-factor-μs 103.369319416499,\n   :hamf 0.04042520509271698,\n   :clj 1.0,\n   :test :vector-cons-obj-array}\n  {:n-elems 10,\n   :java 0.507751745430425,\n   :norm-factor-μs 0.07268104518100771,\n   :hamf 1.1191943841960355,\n   :clj 1.0,\n   :test :vector-construction}\n  {:n-elems 10000,\n   :java 0.06228636275785186,\n   :norm-factor-μs 109.04036126126128,\n   :hamf 0.0700779992253449,\n   :clj 1.0,\n   :test :vector-construction}\n  {:n-elems 10,\n   :java 2.040987879747724,\n   :norm-factor-μs 0.1518468919073785,\n   :hamf 1.0314119616036046,\n   :clj 1.0,\n   :test :vector-reduce}\n  {:n-elems 10000,\n   :java 1.3918010263064262,\n   :norm-factor-μs 146.63559051094893,\n   :hamf 1.0263336595466455,\n   :clj 1.0,\n   :test :vector-reduce}\n  {:n-elems 10,\n   :java 0.284477780527412,\n   :norm-factor-μs 0.03607406265851366,\n   :hamf 0.5691549470684795,\n   :clj 1.0,\n   :test :vector-to-array}\n  {:n-elems 10000,\n   :java 0.05191814884413698,\n   :norm-factor-μs 65.94629079634464,\n   :hamf 0.06834408666272451,\n   :clj 1.0,\n   :test :vector-to-array}]}\n"
  },
  {
    "path": "results/d00905c-chrisn-lt3-jdk-17.0.1.edn",
    "content": "{:machine-name \"chrisn-lt3\",\n :git-sha \"d00905c\",\n :jdk-version \"17.0.1\",\n :dataset\n [{:n-elems 5,\n   :norm-factor-μs 0.2454300764363296,\n   :hamf 0.645561999028018,\n   :clj 1.0,\n   :test :assoc-in}\n  {:n-elems 5,\n   :norm-factor-μs 0.11989653723540485,\n   :hamf 0.3710010211170179,\n   :clj 1.0,\n   :test :assoc-in-nil}\n  {:n-elems 100,\n   :norm-factor-μs 9.826760791689058,\n   :hamf 0.0987601947642363,\n   :clj 1.0,\n   :test :concatv}\n  {:n-elems 10000,\n   :norm-factor-μs 966.1539672897197,\n   :hamf 0.4117709827331045,\n   :clj 1.0,\n   :test :frequencies}\n  {:n-elems 5,\n   :norm-factor-μs 0.12388659038983477,\n   :hamf 0.5635429524984066,\n   :clj 1.0,\n   :test :get-in}\n  {:n-elems 10000,\n   :norm-factor-μs 1414.4795533333333,\n   :hamf 0.33263526123149856,\n   :clj 1.0,\n   :test :group-by}\n  {:n-elems 10000,\n   :norm-factor-μs 1408.0276894977171,\n   :hamf 0.3133028742380794,\n   :clj 1.0,\n   :test :group-by-reduce}\n  {:n-elems 10000,\n   :java 0.700098540194207,\n   :norm-factor-μs 549.4677786885246,\n   :hamf 0.9885904403596032,\n   :clj 1.0,\n   :test :hashmap-access}\n  {:n-elems 10,\n   :java 0.8371851640462842,\n   :norm-factor-μs 0.39970161594433823,\n   :hamf 0.8257697710235989,\n   :clj 1.0,\n   :test :hashmap-access}\n  {:n-elems 4,\n   :norm-factor-μs 0.39154649377328343,\n   :hamf 0.35532562182772665,\n   :clj 1.0,\n   :test :hashmap-cons-obj-ary}\n  {:n-elems 10,\n   :norm-factor-μs 0.863606395306321,\n   :hamf 0.5840580056224318,\n   :clj 1.0,\n   :test :hashmap-cons-obj-ary}\n  {:n-elems 1000,\n   :norm-factor-μs 124.81141047503047,\n   :hamf 0.5406815136043169,\n   :clj 1.0,\n   :test :hashmap-cons-obj-ary}\n  {:n-elems 10000,\n   :java 0.5630691816953767,\n   :norm-factor-μs 1331.1297402597404,\n   :hamf 0.9227125798469248,\n   :clj 1.0,\n   :test :hashmap-construction}\n  {:n-elems 10,\n   :java 0.24035557617165446,\n   :norm-factor-μs 2.337265181606312,\n   :hamf 0.3573060003056217,\n   :clj 1.0,\n   :test :hashmap-construction}\n  {:n-elems 10000,\n   :java 0.7919820197723015,\n   :norm-factor-μs 316.4332277777778,\n   :hamf 0.8600438031678125,\n   :clj 1.0,\n   :test :hashmap-reduce}\n  {:n-elems 10,\n   :java 0.7025734210457583,\n   :norm-factor-μs 0.36049310535635243,\n   :hamf 0.7353545091164955,\n   :clj 1.0,\n   :test :hashmap-reduce}\n  {:n-elems 20000,\n   :java 1.0,\n   :norm-factor-μs 467.99419967793887,\n   :hamf 1.1472402345498847,\n   :test :int-list}\n  {:n-elems 1000,\n   :norm-factor-μs 275.7863779026218,\n   :hamf 0.27598576781699885,\n   :clj 1.0,\n   :test :mapmap}\n  {:n-elems 20000,\n   :norm-factor-μs 1560.9749201877935,\n   :hamf 0.24042373091680067,\n   :clj 1.0,\n   :test :object-array}\n  {:n-elems 20000,\n   :java 1.0,\n   :norm-factor-μs 518.8781770833334,\n   :hamf 0.9872361136470196,\n   :test :object-list}\n  {:n-elems 20000,\n   :norm-factor-μs 1380.4963036529682,\n   :eduction 0.29022715840409075,\n   :hamf 0.40938478721051513,\n   :clj 1.0,\n   :test :sequence-summation}\n  {:n-elems 10000,\n   :norm-factor-μs 329.70861211211206,\n   :hamf 0.35256060031168274,\n   :clj 1.0,\n   :test :shuffle}\n  {:n-elems 10000,\n   :norm-factor-μs 2418.306638888889,\n   :hamf 0.3365951985310685,\n   :clj 1.0,\n   :test :sort}\n  {:n-elems 10000,\n   :norm-factor-μs 2272.1426259259265,\n   :hamf 0.3744829531086446,\n   :clj 1.0,\n   :test :sort-doubles}\n  {:n-elems 10000,\n   :norm-factor-μs 2514.7790203252034,\n   :hamf 0.29084489524894996,\n   :clj 1.0,\n   :test :sort-ints}\n  {:n-elems 10,\n   :java 0.1547125872471658,\n   :norm-factor-μs 1.785352472507342,\n   :hamf 0.08782960760507862,\n   :clj 1.0,\n   :test :union}\n  {:n-elems 10000,\n   :java 0.27530353772534377,\n   :norm-factor-μs 1664.8231730769232,\n   :hamf 0.17444121772551566,\n   :clj 1.0,\n   :test :union}\n  {:n-elems 10,\n   :java 0.1563929390039218,\n   :norm-factor-μs 1.7984273753995366,\n   :hamf 0.08496556764141062,\n   :clj 1.0,\n   :test :union-disj}\n  {:n-elems 10000,\n   :java 0.27923401245084806,\n   :norm-factor-μs 1641.3437692307693,\n   :hamf 0.17765049653015624,\n   :clj 1.0,\n   :test :union-disj}\n  {:n-elems 10,\n   :java 0.13905790023136533,\n   :norm-factor-μs 23.95422292622533,\n   :hamf 0.22028258205545878,\n   :clj 1.0,\n   :test :union-reduce}\n  {:n-elems 10000,\n   :java 0.09975903561943682,\n   :norm-factor-μs 41261.662833333336,\n   :hamf 0.15873443329519718,\n   :clj 1.0,\n   :test :union-reduce}\n  {:n-elems 5,\n   :norm-factor-μs 0.27596133989884,\n   :hamf 1.153192661309212,\n   :clj 1.0,\n   :test :update-in}\n  {:n-elems 5,\n   :norm-factor-μs 0.15777840704317916,\n   :hamf 0.27633859337368183,\n   :clj 1.0,\n   :test :update-in-nil}\n  {:n-elems 1000,\n   :norm-factor-μs 158.99377192982456,\n   :hamf 0.09024145341863514,\n   :clj 1.0,\n   :test :update-values}\n  {:n-elems 10,\n   :java 1.5677072712878053,\n   :norm-factor-μs 77.9446561934316,\n   :hamf 1.0084726623021274,\n   :clj 1.0,\n   :test :vector-access}\n  {:n-elems 10000,\n   :java 0.9569459740380856,\n   :norm-factor-μs 125.77780037546934,\n   :hamf 1.026870193252271,\n   :clj 1.0,\n   :test :vector-access}\n  {:n-elems 10,\n   :java 1.1844251995426458,\n   :norm-factor-μs 0.0711508365312022,\n   :hamf 0.3555518514949478,\n   :clj 1.0,\n   :test :vector-cons-obj-array}\n  {:n-elems 10000,\n   :java 0.08315298066928496,\n   :norm-factor-μs 112.19156870229008,\n   :hamf 0.04848307511571774,\n   :clj 1.0,\n   :test :vector-cons-obj-array}\n  {:n-elems 10,\n   :java 0.4598551977815668,\n   :norm-factor-μs 0.07780193981548053,\n   :hamf 1.1235255104314212,\n   :clj 1.0,\n   :test :vector-construction}\n  {:n-elems 10000,\n   :java 0.08238350984081357,\n   :norm-factor-μs 117.43194285714287,\n   :hamf 0.07759581065745061,\n   :clj 1.0,\n   :test :vector-construction}\n  {:n-elems 10,\n   :java 1.9959541201348796,\n   :norm-factor-μs 0.15045886766676977,\n   :hamf 1.0879851619448582,\n   :clj 1.0,\n   :test :vector-reduce}\n  {:n-elems 10000,\n   :java 1.227779861025791,\n   :norm-factor-μs 194.19370060606062,\n   :hamf 0.8632717352503987,\n   :clj 1.0,\n   :test :vector-reduce}\n  {:n-elems 10,\n   :java 0.25632023563227685,\n   :norm-factor-μs 0.040976120084999255,\n   :hamf 0.5032633746096943,\n   :clj 1.0,\n   :test :vector-to-array}\n  {:n-elems 10000,\n   :java 0.0626329260162031,\n   :norm-factor-μs 69.5895701754386,\n   :hamf 0.12397017888135678,\n   :clj 1.0,\n   :test :vector-to-array}]}\n"
  },
  {
    "path": "results/general-hashmap.edn",
    "content": "[{:hamf-trie {:mean-μs 0.12737612204503088, :variance-μs 6.396591659858203E-11}, :java {:mean-μs 0.15931202460367855, :variance-μs 2.1921699693937754E-11}, :hamf-hashmap {:mean-μs 0.07082310724719383, :variance-μs 1.2468831270368505E-12}, :clj-int-map {:mean-μs 0.18253536926477196, :variance-μs 7.2435025867869124E-12}, :n-elems 4, :clj {:mean-μs 0.12660375158571427, :variance-μs 1.2129316208769813E-11}, :test :hashmap-construction, :hamf-long-map {:mean-μs 0.07933024944444202, :variance-μs 2.1311067935557158E-11}, :numeric? true} {:hamf-trie {:mean-μs 0.03881749141608742, :variance-μs 4.287722865119336E-15}, :java {:mean-μs 0.032855244414518744, :variance-μs 1.9405992798749638E-14}, :hamf-hashmap {:mean-μs 0.0385735657127411, :variance-μs 4.514740863848797E-15}, :clj-int-map {:mean-μs 0.037798297858484826, :variance-μs 4.1147004931921244E-14}, :n-elems 4, :clj {:mean-μs 0.05715286326051579, :variance-μs 8.809370228294369E-14}, :test :hashmap-access, :hamf-long-map {:mean-μs 0.03226057214308612, :variance-μs 3.566550010133413E-16}, :numeric? true} {:hamf-trie {:mean-μs 0.0024384717786416405, :variance-μs 5.803862412065768E-16}, :java {:mean-μs 0.0024378755410881777, :variance-μs 4.295888301027563E-16}, :hamf-hashmap {:mean-μs 0.0024450730662496133, :variance-μs 5.927874716218362E-16}, :clj-int-map {:mean-μs 0.002448551632772595, :variance-μs 1.8980594912551673E-15}, :n-elems 4, :clj {:mean-μs 0.002443443341831773, :variance-μs 5.170177435378848E-16}, :test :hashmap-reduction, :hamf-long-map {:mean-μs 0.002446382918059421, :variance-μs 1.3007366485730063E-16}, :numeric? true} {:hamf-trie 360, :java 320, :hamf-hashmap 360, :clj-int-map 632, :n-elems 4, :clj 176, :test :hashmap-bytes, :hamf-long-map 368, :numeric? true} {:hamf-trie {:mean-μs 0.13929403993989783, :variance-μs 5.450456700957539E-11}, :java {:mean-μs 0.17365940942022098, :variance-μs 1.064268216077601E-11}, :hamf-hashmap {:mean-μs 0.14058743431243464, :variance-μs 2.676404093792181E-12}, :n-elems 4, :clj {:mean-μs 0.11750402207956963, :variance-μs 1.579265281707213E-11}, :test :hashmap-construction, :numeric? false} {:hamf-trie {:mean-μs 0.06118565145565695, :variance-μs 1.396593610771331E-12}, :java {:mean-μs 0.042190656717632995, :variance-μs 2.427847078325523E-13}, :hamf-hashmap {:mean-μs 0.05205594394946113, :variance-μs 8.952374773511257E-15}, :n-elems 4, :clj {:mean-μs 0.05765036235868071, :variance-μs 1.6251377628408275E-13}, :test :hashmap-access, :numeric? false} {:hamf-trie {:mean-μs 0.00437183284375, :variance-μs 3.1404750788561035E-13}, :java {:mean-μs 0.004161787729166666, :variance-μs 1.8177328862022605E-13}, :hamf-hashmap {:mean-μs 0.0039667416278950105, :variance-μs 5.139588061720048E-15}, :n-elems 4, :clj {:mean-μs 0.003965322427083334, :variance-μs 2.6684162672671795E-15}, :test :hashmap-reduction, :numeric? false} {:hamf-trie 744, :java 704, :hamf-hashmap 744, :n-elems 4, :clj 560, :test :hashmap-bytes, :numeric? false} {:hamf-trie {:mean-μs 0.38881422524809084, :variance-μs 3.6784587621633865E-10}, :java {:mean-μs 0.36307100852637253, :variance-μs 7.394271419902345E-12}, :hamf-hashmap {:mean-μs 0.36328345928985556, :variance-μs 3.4678105142504224E-10}, :clj-int-map {:mean-μs 0.4495605552493311, :variance-μs 5.1607456622082824E-12}, :n-elems 10, :clj {:mean-μs 0.7369809755058884, :variance-μs 8.22757863590052E-11}, :test :hashmap-construction, :hamf-long-map {:mean-μs 0.2043492727775039, :variance-μs 3.475441861833042E-12}, :numeric? true} {:hamf-trie {:mean-μs 0.15733376615602068, :variance-μs 4.5775990120545246E-14}, :java {:mean-μs 0.08919611977324254, :variance-μs 8.578982120055384E-15}, :hamf-hashmap {:mean-μs 0.1495159480779122, :variance-μs 1.006378675606183E-13}, :clj-int-map {:mean-μs 0.1841453176041887, :variance-μs 7.026963173788516E-13}, :n-elems 10, :clj {:mean-μs 0.19522919080707185, :variance-μs 2.748861772918758E-13}, :test :hashmap-access, :hamf-long-map {:mean-μs 0.11958588080443483, :variance-μs 1.5187104739401225E-13}, :numeric? true} {:hamf-trie {:mean-μs 0.003928673499708508, :variance-μs 2.616775725543735E-16}, :java {:mean-μs 0.004396966968750001, :variance-μs 3.2373918098896885E-13}, :hamf-hashmap {:mean-μs 0.003949708881970929, :variance-μs 5.623070317493453E-15}, :clj-int-map {:mean-μs 0.004160355885416666, :variance-μs 1.816701020857573E-13}, :n-elems 10, :clj {:mean-μs 0.003922125917744089, :variance-μs 3.6482420051809284E-16}, :test :hashmap-reduction, :hamf-long-map {:mean-μs 0.003958190197175222, :variance-μs 6.327717781092918E-15}, :numeric? true} {:hamf-trie 808, :java 688, :hamf-hashmap 728, :clj-int-map 1328, :n-elems 10, :clj 520, :test :hashmap-bytes, :hamf-long-map 784, :numeric? true} {:hamf-trie {:mean-μs 0.391980719710974, :variance-μs 3.177861567297025E-11}, :java {:mean-μs 0.38384906786499706, :variance-μs 3.0062228263010584E-11}, :hamf-hashmap {:mean-μs 0.3834914961636829, :variance-μs 7.277915431714698E-11}, :n-elems 10, :clj {:mean-μs 0.5766033379083687, :variance-μs 1.3677833136358415E-10}, :test :hashmap-construction, :numeric? false} {:hamf-trie {:mean-μs 0.17896307771287526, :variance-μs 3.6676289532947006E-14}, :java {:mean-μs 0.09507845899989242, :variance-μs 3.1564077823872248E-15}, :hamf-hashmap {:mean-μs 0.18408497814128674, :variance-μs 6.220949136009276E-13}, :n-elems 10, :clj {:mean-μs 0.17937706624420582, :variance-μs 1.1963169589385688E-12}, :test :hashmap-access, :numeric? false} {:hamf-trie {:mean-μs 0.004129701467313691, :variance-μs 1.6406977366772879E-13}, :java {:mean-μs 0.00432857203125, :variance-μs 2.665194658832183E-13}, :hamf-hashmap {:mean-μs 0.004333073760416668, :variance-μs 2.564274172463116E-13}, :n-elems 10, :clj {:mean-μs 0.0039509407069990825, :variance-μs 3.876332490476048E-15}, :test :hashmap-reduction, :numeric? false} {:hamf-trie 1800, :java 1648, :hamf-hashmap 1688, :n-elems 10, :clj 1520, :test :hashmap-bytes, :numeric? false} {:hamf-trie {:mean-μs 5.042265099729212, :variance-μs 1.3019750130568536E-8}, :java {:mean-μs 3.4682698136391563, :variance-μs 1.2106259218308585E-8}, :hamf-hashmap {:mean-μs 3.5239084320573406, :variance-μs 2.0592874264445192E-8}, :clj-int-map {:mean-μs 5.915345205184009, :variance-μs 4.7514044719016145E-8}, :n-elems 100, :clj {:mean-μs 6.099257853377101, :variance-μs 1.1957982711306617E-8}, :test :hashmap-construction, :hamf-long-map {:mean-μs 3.254834293394778, :variance-μs 3.344082683701172E-8}, :numeric? true} {:hamf-trie {:mean-μs 2.355782991225383, :variance-μs 4.963674628469898E-11}, :java {:mean-μs 1.0801430070155806, :variance-μs 1.239219438258746E-10}, :hamf-hashmap {:mean-μs 1.583093910520642, :variance-μs 6.989749612367083E-12}, :clj-int-map {:mean-μs 1.9407344024362587, :variance-μs 5.510222310760512E-11}, :n-elems 100, :clj {:mean-μs 2.1451822321434926, :variance-μs 8.73402096040883E-11}, :test :hashmap-access, :hamf-long-map {:mean-μs 1.3615756260343472, :variance-μs 1.4378168868528625E-12}, :numeric? true} {:hamf-trie {:mean-μs 0.004355775583333334, :variance-μs 2.5841190649951006E-13}, :java {:mean-μs 0.004387476104166667, :variance-μs 3.0479993250641736E-13}, :hamf-hashmap {:mean-μs 0.00435306115625, :variance-μs 2.478671626520929E-13}, :clj-int-map {:mean-μs 0.004169804656250001, :variance-μs 1.6719513991090373E-13}, :n-elems 100, :clj {:mean-μs 0.003979964347546555, :variance-μs 7.126219212697998E-15}, :test :hashmap-reduction, :hamf-long-map {:mean-μs 0.0044084813125, :variance-μs 2.386154550975209E-13}, :numeric? true} {:hamf-trie 7864, :java 6688, :hamf-hashmap 6728, :clj-int-map 9320, :n-elems 100, :clj 5336, :test :hashmap-bytes, :hamf-long-map 7504, :numeric? true} {:hamf-trie {:mean-μs 4.81606174028822, :variance-μs 1.5665166480985434E-8}, :java {:mean-μs 3.461359238004145, :variance-μs 9.702443215715173E-9}, :hamf-hashmap {:mean-μs 3.614230712634013, :variance-μs 1.7439344392895864E-8}, :n-elems 100, :clj {:mean-μs 5.523413217039427, :variance-μs 2.78643894449881E-9}, :test :hashmap-construction, :numeric? false} {:hamf-trie {:mean-μs 1.8320056480580593, :variance-μs 5.881840598643257E-12}, :java {:mean-μs 1.0945387262778477, :variance-μs 7.725902442750274E-11}, :hamf-hashmap {:mean-μs 1.4730817014619413, :variance-μs 1.5386189994280872E-11}, :n-elems 100, :clj {:mean-μs 1.5674547419073985, :variance-μs 7.080508559610851E-11}, :test :hashmap-access, :numeric? false} {:hamf-trie {:mean-μs 0.003951741768835076, :variance-μs 4.2801113306202835E-15}, :java {:mean-μs 0.003961767246033917, :variance-μs 4.840416100237032E-15}, :hamf-hashmap {:mean-μs 0.003956974679443984, :variance-μs 5.597973639323671E-15}, :n-elems 100, :clj {:mean-μs 0.004327536010416667, :variance-μs 2.8151414833665384E-13}, :test :hashmap-reduction, :numeric? false} {:hamf-trie 17496, :java 16288, :hamf-hashmap 16328, :n-elems 100, :clj 14720, :test :hashmap-bytes, :numeric? false} {:hamf-trie {:mean-μs 65.21449017094018, :variance-μs 1.557468688019957E-6}, :java {:mean-μs 31.095526593585063, :variance-μs 7.841178970421217E-7}, :hamf-hashmap {:mean-μs 32.726058785529716, :variance-μs 6.724550020819318E-7}, :clj-int-map {:mean-μs 84.05662559374127, :variance-μs 1.2379705027684346E-7}, :n-elems 1000, :clj {:mean-μs 81.44535906763677, :variance-μs 6.374716214979322E-7}, :test :hashmap-construction, :hamf-long-map {:mean-μs 30.260220216962523, :variance-μs 1.256291216552317E-6}, :numeric? true} {:hamf-trie {:mean-μs 33.017372240437155, :variance-μs 8.592611669121406E-10}, :java {:mean-μs 11.837676194405155, :variance-μs 2.6374858885184383E-9}, :hamf-hashmap {:mean-μs 14.619642228739002, :variance-μs 8.053497666657927E-10}, :clj-int-map {:mean-μs 21.25854047472045, :variance-μs 3.1670463383734034E-7}, :n-elems 1000, :clj {:mean-μs 23.59308321507411, :variance-μs 1.2759146241946811E-8}, :test :hashmap-access, :hamf-long-map {:mean-μs 13.930387806688003, :variance-μs 1.391420621113504E-8}, :numeric? true} {:hamf-trie {:mean-μs 0.0041704717604166665, :variance-μs 2.2728670616887456E-13}, :java {:mean-μs 0.0040447757319230625, :variance-μs 2.564157454177168E-15}, :hamf-hashmap {:mean-μs 0.004120246500000001, :variance-μs 1.6619460616093238E-13}, :clj-int-map {:mean-μs 0.0039059910822086116, :variance-μs 7.498891755475981E-17}, :n-elems 1000, :clj {:mean-μs 0.003944085134378271, :variance-μs 9.088481049851367E-15}, :test :hashmap-reduction, :hamf-long-map {:mean-μs 0.003939165355000591, :variance-μs 4.414282841383754E-15}, :numeric? true} {:hamf-trie 79592, :java 64064, :hamf-hashmap 64104, :clj-int-map 97928, :n-elems 1000, :clj 72952, :test :hashmap-bytes, :hamf-long-map 71888, :numeric? true} {:hamf-trie {:mean-μs 63.17735462510189, :variance-μs 2.4447571117536376E-6}, :java {:mean-μs 33.135304131054134, :variance-μs 7.444925057237155E-7}, :hamf-hashmap {:mean-μs 35.32318542519327, :variance-μs 1.9787499436824814E-6}, :n-elems 1000, :clj {:mean-μs 73.98949730392157, :variance-μs 1.80198847544197E-6}, :test :hashmap-construction, :numeric? false} {:hamf-trie {:mean-μs 30.22536841308298, :variance-μs 6.50870367110682E-8}, :java {:mean-μs 14.414018979748537, :variance-μs 2.985518123790603E-10}, :hamf-hashmap {:mean-μs 16.950012444971218, :variance-μs 1.200396719638997E-9}, :n-elems 1000, :clj {:mean-μs 19.26251062532101, :variance-μs 8.503871035654129E-10}, :test :hashmap-access, :numeric? false} {:hamf-trie {:mean-μs 0.004413220885416667, :variance-μs 3.423062424479693E-13}, :java {:mean-μs 0.00422049603125, :variance-μs 2.9761742065081937E-13}, :hamf-hashmap {:mean-μs 0.004361120625, :variance-μs 2.406070972460215E-13}, :n-elems 1000, :clj {:mean-μs 0.0043975624687500004, :variance-μs 2.551046772970641E-13}, :test :hashmap-reduction, :numeric? false} {:hamf-trie 174824, :java 159344, :hamf-hashmap 159384, :n-elems 1000, :clj 166520, :test :hashmap-bytes, :numeric? false} {:hamf-trie {:mean-μs 780.8485737913487, :variance-μs 3.477543096084737E-5}, :java {:mean-μs 375.0044652014653, :variance-μs 7.39986466736043E-5}, :hamf-hashmap {:mean-μs 398.6921731770833, :variance-μs 8.205242788379923E-5}, :clj-int-map {:mean-μs 1154.6796074074075, :variance-μs 0.0033827290231506968}, :n-elems 10000, :clj {:mean-μs 719.7024083333334, :variance-μs 1.9683084659932206E-6}, :test :hashmap-construction, :hamf-long-map {:mean-μs 375.4870214460784, :variance-μs 3.450134214371576E-5}, :numeric? true} {:hamf-trie {:mean-μs 350.05588395904437, :variance-μs 2.774934875777946E-7}, :java {:mean-μs 147.08369096209915, :variance-μs 9.402568656767165E-9}, :hamf-hashmap {:mean-μs 193.4745440797941, :variance-μs 1.602035297694827E-7}, :clj-int-map {:mean-μs 290.3997015281758, :variance-μs 2.4641816378847545E-6}, :n-elems 10000, :clj {:mean-μs 317.73844761904763, :variance-μs 1.875548994856781E-7}, :test :hashmap-access, :hamf-long-map {:mean-μs 159.55805785562634, :variance-μs 1.9641160542432423E-8}, :numeric? true} {:hamf-trie {:mean-μs 0.004174307697916667, :variance-μs 1.8470619277218825E-13}, :java {:mean-μs 0.003958018485899186, :variance-μs 5.7057823918703085E-15}, :hamf-hashmap {:mean-μs 0.003925685516701463, :variance-μs 6.551914226599447E-17}, :clj-int-map {:mean-μs 0.003964951132591866, :variance-μs 5.682124489389675E-15}, :n-elems 10000, :clj {:mean-μs 0.003933888226433571, :variance-μs 6.4640969317443285E-15}, :test :hashmap-reduction, :hamf-long-map {:mean-μs 0.004351605875, :variance-μs 2.897003492924412E-13}, :numeric? true} {:hamf-trie 700664, :java 609184, :hamf-hashmap 609224, :clj-int-map 906416, :n-elems 10000, :clj 450320, :test :hashmap-bytes, :hamf-long-map 673552, :numeric? true} {:hamf-trie {:mean-μs 778.6050628205129, :variance-μs 1.2085644687352968E-5}, :java {:mean-μs 429.3114950564971, :variance-μs 6.238034878090834E-5}, :hamf-hashmap {:mean-μs 424.7148458856347, :variance-μs 5.306066205877626E-5}, :n-elems 10000, :clj {:mean-μs 681.7886047297299, :variance-μs 6.529311888673321E-6}, :test :hashmap-construction, :numeric? false} {:hamf-trie {:mean-μs 348.9691128472223, :variance-μs 1.271805725039338E-7}, :java {:mean-μs 174.46373507246378, :variance-μs 2.238383134084509E-8}, :hamf-hashmap {:mean-μs 193.144, :variance-μs 7.086958663804234E-8}, :n-elems 10000, :clj {:mean-μs 248.72084791666668, :variance-μs 1.1873965896110325E-6}, :test :hashmap-access, :numeric? false} {:hamf-trie {:mean-μs 0.003924769680303962, :variance-μs 6.171628630039009E-16}, :java {:mean-μs 0.00395765214327313, :variance-μs 6.60370363918879E-15}, :hamf-hashmap {:mean-μs 0.003940098602889401, :variance-μs 5.231695887552283E-15}, :n-elems 10000, :clj {:mean-μs 0.003953429604374496, :variance-μs 6.284615802717058E-15}, :test :hashmap-reduction, :numeric? false} {:hamf-trie 1626208, :java 1514008, :hamf-hashmap 1514048, :n-elems 10000, :clj 1357408, :test :hashmap-bytes, :numeric? false} {:hamf-trie {:mean-μs 105631.582, :variance-μs 0.41091841103706755}, :java {:mean-μs 34421.373666666674, :variance-μs 0.006783515112774007}, :hamf-hashmap {:mean-μs 41940.65366666667, :variance-μs 1.6065800330680753}, :clj-int-map {:mean-μs 228662.874, :variance-μs 143.98871654502028}, :n-elems 1000000, :clj {:mean-μs 87141.36675, :variance-μs 0.152704115646775}, :test :hashmap-construction, :hamf-long-map {:mean-μs 30214.13570833333, :variance-μs 0.08636392782682523}, :numeric? true} {:hamf-trie {:mean-μs 55755.943, :variance-μs 0.1451732910962674}, :java {:mean-μs 20863.527666666665, :variance-μs 0.0191632000882306}, :hamf-hashmap {:mean-μs 25654.37004166667, :variance-μs 0.021320091008268795}, :clj-int-map {:mean-μs 29977.67216666667, :variance-μs 0.110571280534535}, :n-elems 1000000, :clj {:mean-μs 49993.6235, :variance-μs 0.11235685551394138}, :test :hashmap-access, :hamf-long-map {:mean-μs 13560.8405, :variance-μs 0.00883170116229789}, :numeric? true} {:hamf-trie {:mean-μs 0.004350175133233413, :variance-μs 7.167683862078651E-13}, :java {:mean-μs 0.004548510938421815, :variance-μs 5.243753524294015E-13}, :hamf-hashmap {:mean-μs 0.004439494431695403, :variance-μs 5.254081712185421E-13}, :clj-int-map {:mean-μs 0.0045442266764172835, :variance-μs 6.287656824822641E-13}, :n-elems 1000000, :clj {:mean-μs 0.0045736030637335045, :variance-μs 6.517934758604611E-13}, :test :hashmap-reduction, :hamf-long-map {:mean-μs 0.004243031342943516, :variance-μs 3.7924330277669446E-13}, :numeric? true} {:hamf-trie 10278800, :java 9044184, :hamf-hashmap 9044224, :clj-int-map 5706776, :n-elems 1000000, :clj 7729992, :test :hashmap-bytes, :hamf-long-map 7448336, :numeric? true} {:hamf-trie {:mean-μs 111861.846, :variance-μs 0.20176143255576712}, :java {:mean-μs 47607.29483333334, :variance-μs 0.03152497361291819}, :hamf-hashmap {:mean-μs 48172.75788888889, :variance-μs 0.8034428813259324}, :n-elems 1000000, :clj {:mean-μs 77178.77258333334, :variance-μs 0.3013717195992401}, :test :hashmap-construction, :numeric? false} {:hamf-trie {:mean-μs 57660.383916666666, :variance-μs 0.8521034262750425}, :java {:mean-μs 24973.350916666666, :variance-μs 0.027276928168641783}, :hamf-hashmap {:mean-μs 26249.08016666667, :variance-μs 0.027534862330441803}, :n-elems 1000000, :clj {:mean-μs 37368.78800000001, :variance-μs 0.5087530702252877}, :test :hashmap-access, :numeric? false} {:hamf-trie {:mean-μs 0.004623724218752654, :variance-μs 6.257277938746783E-13}, :java {:mean-μs 0.0044721586994317195, :variance-μs 6.955546061472555E-13}, :hamf-hashmap {:mean-μs 0.004641498543766695, :variance-μs 7.014826910761973E-13}, :n-elems 1000000, :clj {:mean-μs 0.004608290065270957, :variance-μs 6.565473543067006E-13}, :test :hashmap-reduction, :numeric? false} {:hamf-trie 17460312, :java 16248032, :hamf-hashmap 16248072, :n-elems 1000000, :clj 14934288, :test :hashmap-bytes, :numeric? false}]"
  },
  {
    "path": "results/persistent-vector.edn",
    "content": "[{:java {:mean-μs 0.08404675313017497, :variance-μs 5.070139825243536E-14}, :n-elems 4, :clj {:mean-μs 0.04981935796635717, :variance-μs 1.527546946548401E-14}, :hamf {:mean-μs 0.10138344871884107, :variance-μs 7.973542842854269E-12}, :hamf-objary {:mean-μs 0.06318031677331305, :variance-μs 2.598610965473221E-12}, :test :vector-construction, :numeric? true} {:java {:mean-μs 0.014702250662715712, :variance-μs 4.403565754201952E-15}, :n-elems 4, :clj {:mean-μs 0.004808472835989959, :variance-μs 3.737505647466913E-16}, :hamf {:mean-μs 0.008112511943890463, :variance-μs 1.8442921728131405E-15}, :hamf-objary {:mean-μs 0.009619735097717748, :variance-μs 3.1724185102195438E-15}, :test :vector-access, :numeric? true} {:java {:mean-μs 0.005695914429490561, :variance-μs 2.0902311808272606E-14}, :n-elems 4, :clj {:mean-μs 0.00776486082290484, :variance-μs 4.729924999826533E-15}, :hamf {:mean-μs 0.01769129811981235, :variance-μs 2.0548635015740677E-12}, :hamf-objary {:mean-μs 0.010831710108628032, :variance-μs 7.570628868297045E-13}, :test :to-object-array, :numeric? true} {:java {:mean-μs 0.028725450802097346, :variance-μs 4.037289482015303E-14}, :n-elems 4, :clj {:mean-μs 0.03379246923815769, :variance-μs 7.104242855584067E-14}, :hamf {:mean-μs 0.032029540930047055, :variance-μs 4.248883565775089E-14}, :hamf-objary {:mean-μs 0.020358696845172882, :variance-μs 5.860664163959884E-14}, :test :from-double-array, :numeric? true} {:java {:mean-μs 0.1487238615157873, :variance-μs 1.3721503855042793E-12}, :n-elems 10, :clj {:mean-μs 0.08704663779104119, :variance-μs 4.175072297684551E-13}, :hamf {:mean-μs 0.14848439116805284, :variance-μs 3.357253148697639E-12}, :hamf-objary {:mean-μs 0.10886955594743827, :variance-μs 4.2233835999981864E-13}, :test :vector-construction, :numeric? true} {:java {:mean-μs 0.03597425499167559, :variance-μs 2.6517529741054524E-14}, :n-elems 10, :clj {:mean-μs 0.11066612996848661, :variance-μs 7.029107461479434E-13}, :hamf {:mean-μs 0.11329646938881383, :variance-μs 6.947066673472629E-13}, :hamf-objary {:mean-μs 0.10995136747021847, :variance-μs 5.183236466763794E-13}, :test :vector-access, :numeric? true} {:java {:mean-μs 0.012149834599900317, :variance-μs 2.589810189123974E-13}, :n-elems 10, :clj {:mean-μs 0.024358550404403795, :variance-μs 2.4834812156200304E-14}, :hamf {:mean-μs 0.017184634020573464, :variance-μs 7.0867003136786735E-15}, :hamf-objary {:mean-μs 0.01577686322847378, :variance-μs 2.0433189381845226E-14}, :test :to-object-array, :numeric? true} {:java {:mean-μs 0.04061378096300939, :variance-μs 4.9328568972788055E-14}, :n-elems 10, :clj {:mean-μs 0.05603033873642637, :variance-μs 1.065685429898049E-13}, :hamf {:mean-μs 0.04428793121614028, :variance-μs 1.0837386012847952E-13}, :hamf-objary {:mean-μs 0.03017124637986729, :variance-μs 1.9094853556729642E-14}, :test :from-double-array, :numeric? true} {:java {:mean-μs 0.7238227166843572, :variance-μs 8.746766611199866E-11}, :n-elems 100, :clj {:mean-μs 0.669717836801407, :variance-μs 1.2046035303641108E-10}, :hamf {:mean-μs 0.7232141750175776, :variance-μs 1.9085735524452754E-11}, :hamf-objary {:mean-μs 0.7000264403840255, :variance-μs 3.706183440159025E-11}, :test :vector-construction, :numeric? true} {:java {:mean-μs 0.3369278672420447, :variance-μs 1.751101196182606E-12}, :n-elems 100, :clj {:mean-μs 1.1870847861316134, :variance-μs 1.1862836974336482E-10}, :hamf {:mean-μs 1.060780160333358, :variance-μs 2.0927760194106986E-11}, :hamf-objary {:mean-μs 1.0629402511446575, :variance-μs 3.9832535419879046E-11}, :test :vector-access, :numeric? true} {:java {:mean-μs 0.015744159900351568, :variance-μs 9.977632866593663E-15}, :n-elems 100, :clj {:mean-μs 0.301215325717709, :variance-μs 2.1863556829924976E-13}, :hamf {:mean-μs 0.028260030657313435, :variance-μs 5.3671690610719224E-14}, :hamf-objary {:mean-μs 0.029411523935848838, :variance-μs 1.0968228427509516E-13}, :test :to-object-array, :numeric? true} {:java {:mean-μs 0.19336313799634125, :variance-μs 4.616392765668418E-13}, :n-elems 100, :clj {:mean-μs 0.88769464015771, :variance-μs 5.515768626056941E-11}, :hamf {:mean-μs 0.2263363410352146, :variance-μs 4.286090259626298E-12}, :hamf-objary {:mean-μs 0.20145931600120642, :variance-μs 1.3368500155474601E-12}, :test :from-double-array, :numeric? true} {:java {:mean-μs 7.419557924794185, :variance-μs 1.2063035500434223E-8}, :n-elems 1000, :clj {:mean-μs 6.551940577285984, :variance-μs 1.670104537251088E-9}, :hamf {:mean-μs 8.659981221466104, :variance-μs 1.2136700217014222E-8}, :hamf-objary {:mean-μs 7.445694670246351, :variance-μs 4.794667855844152E-9}, :test :vector-construction, :numeric? true} {:java {:mean-μs 3.2820573543971894, :variance-μs 4.8871499264651275E-11}, :n-elems 1000, :clj {:mean-μs 12.008160149419806, :variance-μs 9.799471756836892E-9}, :hamf {:mean-μs 10.798925809988683, :variance-μs 2.93748693952479E-9}, :hamf-objary {:mean-μs 10.704891635720601, :variance-μs 8.803949393371953E-9}, :test :vector-access, :numeric? true} {:java {:mean-μs 0.09855071867068062, :variance-μs 1.5382695957145455E-12}, :n-elems 1000, :clj {:mean-μs 2.829761194657988, :variance-μs 4.1680271617923245E-10}, :hamf {:mean-μs 0.23507436086672542, :variance-μs 3.156679760555342E-13}, :hamf-objary {:mean-μs 0.23330618642337395, :variance-μs 6.041367107732296E-12}, :test :to-object-array, :numeric? true} {:java {:mean-μs 1.9964637136988383, :variance-μs 8.286981727511509E-11}, :n-elems 1000, :clj {:mean-μs 8.903504789442467, :variance-μs 3.6010833975361855E-9}, :hamf {:mean-μs 2.2681713998193977, :variance-μs 2.345768658599516E-10}, :hamf-objary {:mean-μs 2.007464888095474, :variance-μs 1.3151750052769603E-10}, :test :from-double-array, :numeric? true} {:java {:mean-μs 41.81280116959065, :variance-μs 4.669333383154487E-8}, :n-elems 10000, :clj {:mean-μs 58.775339348079164, :variance-μs 8.901106506383374E-8}, :hamf {:mean-μs 34.812974452133794, :variance-μs 1.2146728637284742E-8}, :hamf-objary {:mean-μs 41.273131874071076, :variance-μs 7.998453376619444E-8}, :test :vector-construction, :numeric? true} {:java {:mean-μs 32.731771024464834, :variance-μs 2.170938246869297E-9}, :n-elems 10000, :clj {:mean-μs 124.72057712657714, :variance-μs 6.02334215414936E-6}, :hamf {:mean-μs 108.5272948164147, :variance-μs 7.06933875418284E-7}, :hamf-objary {:mean-μs 109.04531914893619, :variance-μs 1.2206286177146486E-6}, :test :vector-access, :numeric? true} {:java {:mean-μs 1.0006702248436885, :variance-μs 2.25595187105329E-11}, :n-elems 10000, :clj {:mean-μs 32.716528118939884, :variance-μs 1.7027873521302094E-8}, :hamf {:mean-μs 2.0961830192765865, :variance-μs 2.683216214040755E-10}, :hamf-objary {:mean-μs 2.148982849912814, :variance-μs 2.572704097985616E-10}, :test :to-object-array, :numeric? true} {:java {:mean-μs 17.91259518328316, :variance-μs 6.391510938463997E-9}, :n-elems 10000, :clj {:mean-μs 88.85198008849558, :variance-μs 6.306972398300558E-8}, :hamf {:mean-μs 20.598280486139558, :variance-μs 1.1740308329333441E-8}, :hamf-objary {:mean-μs 18.39746522515863, :variance-μs 4.176210746495778E-9}, :test :from-double-array, :numeric? true} {:java {:mean-μs 422.5867705718271, :variance-μs 1.072367608569531E-6}, :n-elems 100000, :clj {:mean-μs 637.8606199575372, :variance-μs 2.130866992003682E-6}, :hamf {:mean-μs 491.11614297385626, :variance-μs 3.786868092401166E-6}, :hamf-objary {:mean-μs 416.1541419753087, :variance-μs 9.662979704333655E-6}, :test :vector-construction, :numeric? true} {:java {:mean-μs 328.0229678649238, :variance-μs 3.3761939922963616E-7}, :n-elems 100000, :clj {:mean-μs 1326.2433640350878, :variance-μs 1.369539381780244E-4}, :hamf {:mean-μs 1104.4642857142858, :variance-μs 2.857838456217471E-5}, :hamf-objary {:mean-μs 1102.6335494505495, :variance-μs 1.366624956250049E-4}, :test :vector-access, :numeric? true} {:java {:mean-μs 7.509156500308072, :variance-μs 8.881072727459943E-8}, :n-elems 100000, :clj {:mean-μs 383.44464385297846, :variance-μs 2.1643609267547677E-6}, :hamf {:mean-μs 20.868715710637126, :variance-μs 1.049428804842173E-8}, :hamf-objary {:mean-μs 21.167191438141096, :variance-μs 3.245508258023865E-9}, :test :to-object-array, :numeric? true} {:java {:mean-μs 168.67022895622898, :variance-μs 3.924779705292658E-8}, :n-elems 100000, :clj {:mean-μs 895.1254880952381, :variance-μs 1.294896278180783E-6}, :hamf {:mean-μs 193.2052230769231, :variance-μs 4.994959728464088E-8}, :hamf-objary {:mean-μs 173.36318457538997, :variance-μs 9.811368580988553E-9}, :test :from-double-array, :numeric? true}]"
  },
  {
    "path": "results/random-update.edn",
    "content": "[{:hamf-trie {:mean-μs 7.473810371306137, :variance-μs 6.636768315602025E-9}, :java {:mean-μs 5.722913191296465, :variance-μs 2.7712356095487855E-9}, :hamf-hashmap {:mean-μs 6.7346819509476035, :variance-μs 2.6547603007155143E-9}, :clj-int-map {:mean-μs 28.61158458542015, :variance-μs 3.21139535674694E-7}, :n-elems 4, :clj {:mean-μs 29.315022571484526, :variance-μs 5.278260531630705E-8}, :test :random-update, :hamf-long-map {:mean-μs 4.727335746415519, :variance-μs 7.605068686913684E-10}, :numeric? true} {:hamf-trie {:mean-μs 8.249470905172416, :variance-μs 6.806187947226365E-9}, :java {:mean-μs 8.727563394056169, :variance-μs 1.4505477240971553E-9}, :hamf-hashmap {:mean-μs 11.482808723169011, :variance-μs 3.19167505795684E-9}, :n-elems 4, :clj {:mean-μs 19.57993421306107, :variance-μs 9.927578023551844E-8}, :test :random-update, :numeric? false} {:hamf-trie {:mean-μs 14.490477033168942, :variance-μs 1.6814016212846286E-8}, :java {:mean-μs 6.474124965105541, :variance-μs 2.0802148324619174E-9}, :hamf-hashmap {:mean-μs 10.617591625338537, :variance-μs 1.1670278774147662E-10}, :clj-int-map {:mean-μs 40.61000130157491, :variance-μs 3.718157660320322E-6}, :n-elems 10, :clj {:mean-μs 35.440350803142216, :variance-μs 7.336263662612312E-8}, :test :random-update, :hamf-long-map {:mean-μs 7.769649753048311, :variance-μs 1.4072701621324273E-9}, :numeric? true} {:hamf-trie {:mean-μs 16.489329767977623, :variance-μs 2.2739911162825837E-8}, :java {:mean-μs 11.329024095702461, :variance-μs 7.207390845879511E-9}, :hamf-hashmap {:mean-μs 17.204908985062758, :variance-μs 2.5615310976489953E-8}, :n-elems 10, :clj {:mean-μs 43.703390000000006, :variance-μs 4.846730085373682E-8}, :test :random-update, :numeric? false} {:hamf-trie {:mean-μs 17.366044789498034, :variance-μs 7.307864496441526E-9}, :java {:mean-μs 6.700638444548558, :variance-μs 2.891177537915405E-9}, :hamf-hashmap {:mean-μs 11.688231641721234, :variance-μs 8.932985936148656E-9}, :clj-int-map {:mean-μs 60.34284659433394, :variance-μs 4.6594863030114697E-7}, :n-elems 100, :clj {:mean-μs 47.221551500789886, :variance-μs 3.719528358275888E-8}, :test :random-update, :hamf-long-map {:mean-μs 10.178484621529858, :variance-μs 1.042940939679223E-8}, :numeric? true} {:hamf-trie {:mean-μs 23.103045288197624, :variance-μs 2.5081767176541172E-9}, :java {:mean-μs 11.483072079253018, :variance-μs 6.479275579587933E-9}, :hamf-hashmap {:mean-μs 14.500872780203787, :variance-μs 2.423372330838471E-8}, :n-elems 100, :clj {:mean-μs 41.491602569444446, :variance-μs 6.222481117254631E-8}, :test :random-update, :numeric? false} {:hamf-trie {:mean-μs 26.771196961524634, :variance-μs 9.903000450981743E-9}, :java {:mean-μs 9.280695548028806, :variance-μs 4.165138181087952E-10}, :hamf-hashmap {:mean-μs 14.475852591844586, :variance-μs 3.4677079839386018E-9}, :clj-int-map {:mean-μs 59.20099134982901, :variance-μs 8.297331301308577E-7}, :n-elems 1000, :clj {:mean-μs 77.1033328290469, :variance-μs 9.214075297517732E-9}, :test :random-update, :hamf-long-map {:mean-μs 8.895876164699619, :variance-μs 9.478380693292846E-11}, :numeric? true} {:hamf-trie {:mean-μs 37.93254213413115, :variance-μs 1.5721684133185825E-8}, :java {:mean-μs 14.728724891362727, :variance-μs 4.2628079865109866E-8}, :hamf-hashmap {:mean-μs 16.268459005810197, :variance-μs 2.1882211372855838E-8}, :n-elems 1000, :clj {:mean-μs 68.5770062742414, :variance-μs 1.2239030273183371E-6}, :test :random-update, :numeric? false} {:hamf-trie {:mean-μs 270.5718541666667, :variance-μs 5.09299341655838E-6}, :java {:mean-μs 99.79422464486292, :variance-μs 2.671491481155907E-7}, :hamf-hashmap {:mean-μs 146.36228659990462, :variance-μs 4.3048047936489657E-7}, :clj-int-map {:mean-μs 784.6103664021165, :variance-μs 5.9642458623448635E-5}, :n-elems 10000, :clj {:mean-μs 663.2450320088301, :variance-μs 2.758626783028814E-5}, :test :random-update, :hamf-long-map {:mean-μs 88.61613315618541, :variance-μs 2.5562978815447094E-8}, :numeric? true} {:hamf-trie {:mean-μs 386.008633974359, :variance-μs 1.6235898638785035E-5}, :java {:mean-μs 150.50318778280544, :variance-μs 8.595231344923378E-8}, :hamf-hashmap {:mean-μs 157.8658671421025, :variance-μs 7.728062207237752E-7}, :n-elems 10000, :clj {:mean-μs 521.2739136752136, :variance-μs 1.0895932142197636E-5}, :test :random-update, :numeric? false} {:hamf-trie {:mean-μs 27840.1305, :variance-μs 0.004096132211343695}, :java {:mean-μs 10149.956166666669, :variance-μs 0.0010089984839960011}, :hamf-hashmap {:mean-μs 14959.376523809524, :variance-μs 0.01870731796338507}, :clj-int-map {:mean-μs 70253.72091666667, :variance-μs 2.3498522960982005}, :n-elems 1000000, :clj {:mean-μs 73434.18241666668, :variance-μs 0.23153408453337476}, :test :random-update, :hamf-long-map {:mean-μs 8934.935416666667, :variance-μs 4.084387226111203E-5}, :numeric? true} {:hamf-trie {:mean-μs 38235.67222222222, :variance-μs 0.19408606879502188}, :java {:mean-μs 15777.87157142857, :variance-μs 0.001808629869948285}, :hamf-hashmap {:mean-μs 16273.244619047618, :variance-μs 2.682036882564654E-4}, :n-elems 1000000, :clj {:mean-μs 60807.11641666667, :variance-μs 0.5310154552200417}, :test :random-update, :numeric? false}]"
  },
  {
    "path": "results/sort-by.edn",
    "content": "[{:clj {:mean-μs 0.09368354713973853, :variance-μs 3.4749205456213755E-13}, :hamf {:mean-μs 0.14596828192467412, :variance-μs 5.984064042814943E-12}, :hamf-typed {:mean-μs 0.18029647307999264, :variance-μs 1.431082943304768E-11}, :n-elems 4, :test :sort-by, :numeric? true} {:clj {:mean-μs 0.3346017224491346, :variance-μs 2.7625131964102243E-12}, :hamf {:mean-μs 0.2159108130775009, :variance-μs 4.255235551841957E-12}, :hamf-typed {:mean-μs 0.2323090567932432, :variance-μs 4.03787766814031E-12}, :n-elems 10, :test :sort-by, :numeric? true} {:clj {:mean-μs 7.842569624343959, :variance-μs 1.971383294271551E-9}, :hamf {:mean-μs 2.118178162835768, :variance-μs 2.0992895696266137E-11}, :hamf-typed {:mean-μs 1.8497657610202387, :variance-μs 3.242863273800923E-10}, :n-elems 100, :test :sort-by, :numeric? true} {:clj {:mean-μs 148.49643230694036, :variance-μs 1.0612311214254018E-6}, :hamf {:mean-μs 38.419489832169546, :variance-μs 4.743966092745893E-6}, :hamf-typed {:mean-μs 32.32202215649647, :variance-μs 2.375869025074426E-6}, :n-elems 1000, :test :sort-by, :numeric? true} {:clj {:mean-μs 2282.277214814815, :variance-μs 1.0071167063558871E-4}, :hamf {:mean-μs 570.5418945386065, :variance-μs 6.974032847926867E-6}, :hamf-typed {:mean-μs 466.0654403100776, :variance-μs 1.58677409917289E-5}, :n-elems 10000, :test :sort-by, :numeric? true} {:clj {:mean-μs 31241.091, :variance-μs 0.017035503393293683}, :hamf {:mean-μs 3290.2144731182802, :variance-μs 1.0871166837450611E-4}, :hamf-typed {:mean-μs 2683.9532894736844, :variance-μs 6.081506563538577E-4}, :n-elems 100000, :test :sort-by, :numeric? true} {:clj {:mean-μs 556215.5891666667, :variance-μs 8.178382644753714}, :hamf {:mean-μs 37757.84622222223, :variance-μs 0.2343899319752739}, :hamf-typed {:mean-μs 28849.764583333334, :variance-μs 0.43991080556205003}, :n-elems 1000000, :test :sort-by, :numeric? true}]"
  },
  {
    "path": "results/typed-parallel-reductions.edn",
    "content": "[{:clj {:mean-μs 6.109750675343813, :variance-μs 6.1388779737180735E-9}, :hamf-untyped {:mean-μs 19.804417360560404, :variance-μs 1.4171681970281903E-8}, :hamf-typed {:mean-μs 15.336961038961041, :variance-μs 3.6832920022683177E-9}, :hamf-consumer {:mean-μs 14.204317738380002, :variance-μs 1.848603195751864E-9}, :n-elems 1000, :numeric? true, :test :typed-parallel-reductions} {:clj {:mean-μs 5610.183491228071, :variance-μs 0.006643800428007367}, :hamf-untyped {:mean-μs 1071.3932925531915, :variance-μs 1.0762994372732568E-5}, :hamf-typed {:mean-μs 448.69007812499996, :variance-μs 2.867989318426488E-6}, :hamf-consumer {:mean-μs 392.8345065359478, :variance-μs 1.0494138131426487E-6}, :n-elems 1000000, :numeric? true, :test :typed-parallel-reductions} {:clj {:mean-μs 572202.5613333334, :variance-μs 8.731098992905238}, :hamf-untyped {:mean-μs 86518.08233333332, :variance-μs 0.02604559385406698}, :hamf-typed {:mean-μs 34243.37627777778, :variance-μs 0.21671453178828554}, :hamf-consumer {:mean-μs 28208.393125000002, :variance-μs 0.007329199036216756}, :n-elems 100000000, :numeric? true, :test :typed-parallel-reductions}]"
  },
  {
    "path": "results/typed-reductions-intel.edn",
    "content": "[{:clj {:mean-μs 0.08083155079773072, :variance-μs 2.607437776221788E-13}, :clj-typed {:mean-μs 0.1103805778248939, :variance-μs 2.439651290536169E-13}, :hamf-partial {:mean-μs 0.13004735309677243, :variance-μs 5.784854897254039E-13}, :hamf-deftype-consumer {:mean-μs 0.1953989385738267, :variance-μs 4.9865286056145706E-12}, :hamf-java-consumer {:mean-μs 0.23984735686088046, :variance-μs 4.554884450446967E-12}, :n-elems 4, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 0.23319472260485014, :variance-μs 6.504487014189002E-11}, :clj-typed {:mean-μs 0.2648384502886857, :variance-μs 3.0752725590709146E-12}, :hamf-partial {:mean-μs 0.46332126574765975, :variance-μs 1.3427220642780956E-11}, :hamf-deftype-consumer {:mean-μs 0.4394848976129789, :variance-μs 2.3559917416110998E-11}, :hamf-java-consumer {:mean-μs 0.44066994734026077, :variance-μs 6.5227574804474215E-12}, :n-elems 10, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 1.8098834931427243, :variance-μs 3.6875297161309607E-10}, :clj-typed {:mean-μs 2.213904877494819, :variance-μs 5.903275495642295E-10}, :hamf-partial {:mean-μs 2.985199862782352, :variance-μs 6.654646560983587E-10}, :hamf-deftype-consumer {:mean-μs 2.3535886494121936, :variance-μs 4.873315280030986E-10}, :hamf-java-consumer {:mean-μs 2.3654510956687145, :variance-μs 1.6598586638706686E-10}, :n-elems 100, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 19.3617035337454, :variance-μs 1.738537575972473E-8}, :clj-typed {:mean-μs 23.88976932840988, :variance-μs 4.096933742156692E-8}, :hamf-partial {:mean-μs 29.751869933712126, :variance-μs 8.461874211572359E-9}, :hamf-deftype-consumer {:mean-μs 21.85484181492208, :variance-μs 6.944969205156315E-9}, :hamf-java-consumer {:mean-μs 21.694217533635513, :variance-μs 1.8892073846351382E-8}, :n-elems 1000, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 194.30773903508774, :variance-μs 4.764487843415978E-6}, :clj-typed {:mean-μs 239.42507523148151, :variance-μs 1.3964075214313341E-6}, :hamf-partial {:mean-μs 297.6285317002882, :variance-μs 1.3538777855842707E-5}, :hamf-deftype-consumer {:mean-μs 213.80862943989075, :variance-μs 3.4080759030627283E-6}, :hamf-java-consumer {:mean-μs 211.8145369220152, :variance-μs 5.458272351473067E-6}, :n-elems 10000, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 19653.14427777778, :variance-μs 0.31501798511343293}, :clj-typed {:mean-μs 23928.633933333334, :variance-μs 0.07455115523551598}, :hamf-partial {:mean-μs 28838.906708333336, :variance-μs 0.03931331868764148}, :hamf-deftype-consumer {:mean-μs 20856.439233333334, :variance-μs 0.024563788894250656}, :hamf-java-consumer {:mean-μs 20685.577366666665, :variance-μs 0.01255119205303075}, :n-elems 1000000, :numeric? true, :test :typed-reductions}]"
  },
  {
    "path": "results/typed-reductions.edn",
    "content": "[{:clj {:mean-μs 0.020973830885365856, :variance-μs 1.5389297939653883E-13}, :clj-typed {:mean-μs 0.03145851381475773, :variance-μs 5.903242517478972E-14}, :hamf-partial {:mean-μs 0.059273714740684255, :variance-μs 1.2371784565925692E-11}, :hamf-deftype-consumer {:mean-μs 0.04533951706819582, :variance-μs 1.9485949331172755E-14}, :hamf-java-consumer {:mean-μs 0.05566604482153488, :variance-μs 2.610345084081093E-12}, :n-elems 4, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 0.047609480990502294, :variance-μs 2.1159911315394183E-13}, :clj-typed {:mean-μs 0.05651426818074108, :variance-μs 1.3201867191062258E-12}, :hamf-partial {:mean-μs 0.15300628831607596, :variance-μs 3.9885298864863E-12}, :hamf-deftype-consumer {:mean-μs 0.14999821983221245, :variance-μs 9.846322079703306E-13}, :hamf-java-consumer {:mean-μs 0.14961160653301617, :variance-μs 5.251461002222532E-13}, :n-elems 10, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 0.45921288628482243, :variance-μs 4.125427462132233E-11}, :clj-typed {:mean-μs 0.40030021051129266, :variance-μs 1.978201113004833E-12}, :hamf-partial {:mean-μs 1.162238944524843, :variance-μs 7.024705635842096E-11}, :hamf-deftype-consumer {:mean-μs 1.0722720725926402, :variance-μs 3.840528539811712E-11}, :hamf-java-consumer {:mean-μs 1.0578596457127247, :variance-μs 1.8860351768678773E-11}, :n-elems 100, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 5.057716056512496, :variance-μs 5.441775028540305E-10}, :clj-typed {:mean-μs 5.1675323381853, :variance-μs 1.7268263670282741E-9}, :hamf-partial {:mean-μs 11.075325958213787, :variance-μs 4.197215172769934E-9}, :hamf-deftype-consumer {:mean-μs 10.362469034236076, :variance-μs 1.4804452994402536E-9}, :hamf-java-consumer {:mean-μs 10.182020976041988, :variance-μs 1.3093141731145295E-9}, :n-elems 1000, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 50.798319254763115, :variance-μs 4.745629116433968E-8}, :clj-typed {:mean-μs 51.5585498403093, :variance-μs 7.521515048479323E-7}, :hamf-partial {:mean-μs 110.28216556169428, :variance-μs 1.0787136356440518E-6}, :hamf-deftype-consumer {:mean-μs 103.50167146282973, :variance-μs 1.9744936828106858E-7}, :hamf-java-consumer {:mean-μs 102.26325822312648, :variance-μs 3.310837696169239E-7}, :n-elems 10000, :numeric? true, :test :typed-reductions} {:clj {:mean-μs 5108.328216666667, :variance-μs 8.538736042629945E-4}, :clj-typed {:mean-μs 5187.716408333334, :variance-μs 0.005420315139756417}, :hamf-partial {:mean-μs 11014.015766666667, :variance-μs 0.014137288650498668}, :hamf-deftype-consumer {:mean-μs 10451.190766666667, :variance-μs 0.0034926461597226547}, :hamf-java-consumer {:mean-μs 10335.650483333333, :variance-μs 0.003020790403802994}, :n-elems 1000000, :numeric? true, :test :typed-reductions}]"
  },
  {
    "path": "results/union-disj.edn",
    "content": "[{:hamf-trie {:mean-μs 0.05387404263091655, :variance-μs 7.601879123779283E-12}, :java {:mean-μs 0.07206509120153398, :variance-μs 8.814124155631456E-13}, :hamf-hashmap {:mean-μs 0.06297155107772515, :variance-μs 3.568340166695999E-11}, :clj-int-map {:mean-μs 0.14015141141420245, :variance-μs 7.080369007861796E-12}, :n-elems 4, :clj {:mean-μs 0.1943523048384093, :variance-μs 1.443176048149449E-11}, :test :union-disj, :hamf-long-map {:mean-μs 0.035919899195097624, :variance-μs 4.73272322792755E-14}, :numeric? true} {:hamf-trie {:mean-μs 0.05586932456545242, :variance-μs 7.648525495599117E-12}, :java {:mean-μs 0.08033694721122178, :variance-μs 3.698528623414985E-11}, :hamf-hashmap {:mean-μs 0.05333671496349147, :variance-μs 3.939069448801596E-12}, :n-elems 4, :clj {:mean-μs 0.16365682288915165, :variance-μs 9.850253772814097E-12}, :test :union-disj, :numeric? false} {:hamf-trie {:mean-μs 0.09101537476401057, :variance-μs 2.3126389658731673E-12}, :java {:mean-μs 0.18305658882513484, :variance-μs 4.8930132832954695E-12}, :hamf-hashmap {:mean-μs 0.08930336189814504, :variance-μs 2.638454874290202E-13}, :clj-int-map {:mean-μs 0.385461959718345, :variance-μs 1.8691699696931915E-12}, :n-elems 10, :clj {:mean-μs 0.8336979928326932, :variance-μs 1.0026382184343124E-9}, :test :union-disj, :hamf-long-map {:mean-μs 0.07489276761384404, :variance-μs 4.839374073933964E-13}, :numeric? true} {:hamf-trie {:mean-μs 0.10764307121408206, :variance-μs 2.8894234351012996E-13}, :java {:mean-μs 0.18663758329506372, :variance-μs 3.439659031376218E-11}, :hamf-hashmap {:mean-μs 0.10605252259190305, :variance-μs 1.9719122525819353E-13}, :n-elems 10, :clj {:mean-μs 0.5302580652648192, :variance-μs 1.4528192279555148E-11}, :test :union-disj, :numeric? false} {:hamf-trie {:mean-μs 0.8610978648948328, :variance-μs 1.5299490300003772E-11}, :java {:mean-μs 1.6728428883700135, :variance-μs 3.6640709814869684E-9}, :hamf-hashmap {:mean-μs 0.6602829319211199, :variance-μs 1.3741791219221696E-11}, :clj-int-map {:mean-μs 4.26644650450757, :variance-μs 8.993285462112174E-11}, :n-elems 100, :clj {:mean-μs 5.057957208341729, :variance-μs 3.130108371957946E-9}, :test :union-disj, :hamf-long-map {:mean-μs 0.6505923338527289, :variance-μs 1.2013612366560051E-11}, :numeric? true} {:hamf-trie {:mean-μs 0.9934630280303927, :variance-μs 2.697913343778186E-9}, :java {:mean-μs 1.7003467974121873, :variance-μs 2.2301722095663205E-9}, :hamf-hashmap {:mean-μs 1.2105747917688385, :variance-μs 2.352238409535548E-9}, :n-elems 100, :clj {:mean-μs 4.703321511573859, :variance-μs 3.214922306780342E-9}, :test :union-disj, :numeric? false} {:hamf-trie {:mean-μs 10.033796019202594, :variance-μs 4.0936306117393106E-7}, :java {:mean-μs 18.62291703310126, :variance-μs 3.303296668707903E-7}, :hamf-hashmap {:mean-μs 6.708932768398129, :variance-μs 2.834718174727148E-7}, :clj-int-map {:mean-μs 77.57473166666666, :variance-μs 3.4202783716722863E-6}, :n-elems 1000, :clj {:mean-μs 65.11077131526768, :variance-μs 5.809813435720986E-7}, :test :union-disj, :hamf-long-map {:mean-μs 5.567049100929166, :variance-μs 2.172001389597534E-9}, :numeric? true} {:hamf-trie {:mean-μs 9.541903893978027, :variance-μs 2.025414018716051E-8}, :java {:mean-μs 21.034355885817227, :variance-μs 2.7239025039167727E-7}, :hamf-hashmap {:mean-μs 11.213639267605636, :variance-μs 3.100144207897286E-8}, :n-elems 1000, :clj {:mean-μs 61.512498178506384, :variance-μs 2.0769263334273362E-7}, :test :union-disj, :numeric? false} {:hamf-trie {:mean-μs 157.52274583333332, :variance-μs 1.1360718520883453E-5}, :java {:mean-μs 286.98687321937325, :variance-μs 1.0208708642513169E-5}, :hamf-hashmap {:mean-μs 149.84130009298002, :variance-μs 8.020519742463194E-5}, :clj-int-map {:mean-μs 962.540546474359, :variance-μs 8.667281439737801E-4}, :n-elems 10000, :clj {:mean-μs 650.8663758169935, :variance-μs 2.8210312846365386E-5}, :test :union-disj, :hamf-long-map {:mean-μs 124.9529899052328, :variance-μs 5.3337277789910735E-6}, :numeric? true} {:hamf-trie {:mean-μs 162.7947814814815, :variance-μs 8.707301176213405E-6}, :java {:mean-μs 328.07865468409585, :variance-μs 9.621875320371119E-6}, :hamf-hashmap {:mean-μs 191.68460606060606, :variance-μs 1.8009645296775687E-6}, :n-elems 10000, :clj {:mean-μs 599.7976074297188, :variance-μs 1.1665058423438299E-5}, :test :union-disj, :numeric? false} {:hamf-trie {:mean-μs 5174.599858333333, :variance-μs 0.01487523512920403}, :java {:mean-μs 4691.425795454546, :variance-μs 0.011931599349578487}, :hamf-hashmap {:mean-μs 2661.0065875, :variance-μs 0.013205702558121592}, :clj-int-map {:mean-μs 22581.566633333336, :variance-μs 1.3293161128934872}, :n-elems 1000000, :clj {:mean-μs 21840.236100000002, :variance-μs 3.8839211955426007}, :test :union-disj, :hamf-long-map {:mean-μs 1795.5331338797819, :variance-μs 0.011691181337103302}, :numeric? true} {:hamf-trie {:mean-μs 4984.485531746032, :variance-μs 0.029493650615204557}, :java {:mean-μs 8145.096730769231, :variance-μs 0.03162908116503202}, :hamf-hashmap {:mean-μs 3729.94931547619, :variance-μs 0.016524662754384047}, :n-elems 1000000, :clj {:mean-μs 20441.775111111117, :variance-μs 2.594552115168829}, :test :union-disj, :numeric? false}]"
  },
  {
    "path": "results/union-overlapping.edn",
    "content": "[{:hamf-trie {:mean-μs 0.10502638201374732, :variance-μs 9.426261585611141E-14}, :java {:mean-μs 0.1791063653635941, :variance-μs 7.260687089336133E-11}, :hamf-hashmap {:mean-μs 0.07032127191331726, :variance-μs 3.592262253795875E-11}, :clj-int-map {:mean-μs 0.3143601710680975, :variance-μs 3.0287656017762097E-12}, :n-elems 4, :clj {:mean-μs 0.3608711911743155, :variance-μs 1.8110786849075344E-11}, :test :union-overlapping, :hamf-long-map {:mean-μs 0.04893065959274923, :variance-μs 1.73764889882564E-13}, :numeric? true} {:hamf-trie {:mean-μs 0.1220632807960718, :variance-μs 1.0108794962904816E-13}, :java {:mean-μs 0.14789828961326076, :variance-μs 3.2273257527005675E-13}, :hamf-hashmap {:mean-μs 0.06324700870921762, :variance-μs 2.2726279112956253E-13}, :n-elems 4, :clj {:mean-μs 0.22202906084300278, :variance-μs 2.962560488187324E-11}, :test :union-overlapping, :numeric? false} {:hamf-trie {:mean-μs 0.21233526842619083, :variance-μs 9.390680559258845E-14}, :java {:mean-μs 0.33055351628735746, :variance-μs 1.826352668823769E-10}, :hamf-hashmap {:mean-μs 0.16288825709471177, :variance-μs 2.038690774759388E-12}, :clj-int-map {:mean-μs 0.7167336882052902, :variance-μs 9.729527522057529E-12}, :n-elems 10, :clj {:mean-μs 0.9405646974483907, :variance-μs 7.987818630075633E-11}, :test :union-overlapping, :hamf-long-map {:mean-μs 0.12042608814025262, :variance-μs 6.23845724318453E-13}, :numeric? true} {:hamf-trie {:mean-μs 0.2298904471968627, :variance-μs 1.1131540307538773E-12}, :java {:mean-μs 0.33493803425830315, :variance-μs 2.9542118566664694E-10}, :hamf-hashmap {:mean-μs 0.20690905870206056, :variance-μs 7.298883883877252E-12}, :n-elems 10, :clj {:mean-μs 0.8966828136432882, :variance-μs 1.887251153815189E-10}, :test :union-overlapping, :numeric? false} {:hamf-trie {:mean-μs 2.176490849349662, :variance-μs 5.502495993107607E-10}, :java {:mean-μs 3.2023792385301286, :variance-μs 2.4673814200821513E-8}, :hamf-hashmap {:mean-μs 1.5024097582103233, :variance-μs 3.392305513102097E-10}, :clj-int-map {:mean-μs 10.345330417781437, :variance-μs 4.901126268291725E-9}, :n-elems 100, :clj {:mean-μs 10.41371986549405, :variance-μs 1.7435177975930493E-9}, :test :union-overlapping, :hamf-long-map {:mean-μs 0.9984897507617002, :variance-μs 1.9496814931296483E-10}, :numeric? true} {:hamf-trie {:mean-μs 2.324429762964032, :variance-μs 7.540512787524547E-10}, :java {:mean-μs 3.3033282678013465, :variance-μs 2.7080255603092382E-8}, :hamf-hashmap {:mean-μs 1.5853071883611523, :variance-μs 3.103971504267881E-10}, :n-elems 100, :clj {:mean-μs 9.487314385333839, :variance-μs 4.117894545524918E-9}, :test :union-overlapping, :numeric? false} {:hamf-trie {:mean-μs 25.501163470434857, :variance-μs 4.711786482155854E-7}, :java {:mean-μs 37.90233383252215, :variance-μs 1.878993769774089E-8}, :hamf-hashmap {:mean-μs 16.578812079054877, :variance-μs 3.721841769265016E-8}, :clj-int-map {:mean-μs 154.41381233386497, :variance-μs 1.4142949825301602E-6}, :n-elems 1000, :clj {:mean-μs 130.17339845474615, :variance-μs 1.715224953583912E-6}, :test :union-overlapping, :hamf-long-map {:mean-μs 11.311622755505365, :variance-μs 1.0237344636433006E-8}, :numeric? true} {:hamf-trie {:mean-μs 25.732278143459922, :variance-μs 5.6240939353385624E-8}, :java {:mean-μs 44.371754378219286, :variance-μs 6.51773073340733E-7}, :hamf-hashmap {:mean-μs 19.644183598937587, :variance-μs 6.408836539021094E-8}, :n-elems 1000, :clj {:mean-μs 119.1047305882353, :variance-μs 8.702885259979214E-7}, :test :union-overlapping, :numeric? false} {:hamf-trie {:mean-μs 321.54726411075615, :variance-μs 2.7314817905134994E-5}, :java {:mean-μs 484.5736138211382, :variance-μs 7.312125421957086E-5}, :hamf-hashmap {:mean-μs 246.8647060240964, :variance-μs 1.0172197986893092E-5}, :clj-int-map {:mean-μs 1984.1942533333338, :variance-μs 0.008893258581366043}, :n-elems 10000, :clj {:mean-μs 1285.800107594937, :variance-μs 6.861328450502594E-5}, :test :union-overlapping, :hamf-long-map {:mean-μs 167.27258664459163, :variance-μs 1.208741398739636E-5}, :numeric? true} {:hamf-trie {:mean-μs 348.9733344827586, :variance-μs 5.533058293016269E-6}, :java {:mean-μs 516.8418498349835, :variance-μs 2.1618437770980092E-5}, :hamf-hashmap {:mean-μs 288.0162975517891, :variance-μs 2.2954193152688092E-5}, :n-elems 10000, :clj {:mean-μs 1189.4219392156863, :variance-μs 2.4065541122703955E-4}, :test :union-overlapping, :numeric? false} {:hamf-trie {:mean-μs 2911.2336171171173, :variance-μs 0.019254886931371996}, :java {:mean-μs 3602.4680000000003, :variance-μs 0.0035377872634102313}, :hamf-hashmap {:mean-μs 1783.2670134408604, :variance-μs 0.016966164123158312}, :clj-int-map {:mean-μs 20299.600333333336, :variance-μs 2.2236462300057527}, :n-elems 1000000, :clj {:mean-μs 18774.30525, :variance-μs 2.4784938356067845}, :test :union-overlapping, :hamf-long-map {:mean-μs 1287.4669568627453, :variance-μs 0.0011637377945428373}, :numeric? true} {:hamf-trie {:mean-μs 4279.03372, :variance-μs 0.020357493386886187}, :java {:mean-μs 6655.074855555556, :variance-μs 0.010340817931078538}, :hamf-hashmap {:mean-μs 3435.771166666667, :variance-μs 0.005673278505370591}, :n-elems 1000000, :clj {:mean-μs 20370.107333333333, :variance-μs 3.2669529107933153}, :test :union-overlapping, :numeric? false}]"
  },
  {
    "path": "results/union-reduce-transient.edn",
    "content": "[{:hamf-trans-long-map {:mean-μs 0.7412825333830333, :variance-μs 3.170731692172204E-10}, :hamf-hashmap {:mean-μs 0.8866651053184513, :variance-μs 3.484445195766126E-12}, :n-elems 4, :test :union-reduce-transient, :hamf-long-map {:mean-μs 0.8786651060075851, :variance-μs 1.153713343546831E-11}, :numeric? true, :hamf-trans-hashmap {:mean-μs 0.7622947671498717, :variance-μs 1.879670822353778E-10}} {:hamf-trans-long-map {:mean-μs 2.2578933011538433, :variance-μs 1.1912266153907903E-9}, :hamf-hashmap {:mean-μs 2.12513856186766, :variance-μs 3.44592015940261E-10}, :n-elems 10, :test :union-reduce-transient, :hamf-long-map {:mean-μs 2.1200784115269724, :variance-μs 1.3821808227797617E-10}, :numeric? true, :hamf-trans-hashmap {:mean-μs 2.2487650346317354, :variance-μs 1.12960205996829E-9}} {:hamf-trans-long-map {:mean-μs 20.318177081213108, :variance-μs 9.360366853700005E-8}, :hamf-hashmap {:mean-μs 18.764085931700073, :variance-μs 1.828781314253933E-8}, :n-elems 100, :test :union-reduce-transient, :hamf-long-map {:mean-μs 18.831902556409773, :variance-μs 5.1392113031581955E-9}, :numeric? true, :hamf-trans-hashmap {:mean-μs 21.68933647589471, :variance-μs 1.743532937661252E-7}} {:hamf-trans-long-map {:mean-μs 224.48590850417614, :variance-μs 1.0103915961737732E-4}, :hamf-hashmap {:mean-μs 219.95389528985507, :variance-μs 1.0649025456953546E-5}, :n-elems 1000, :test :union-reduce-transient, :hamf-long-map {:mean-μs 218.86707522123893, :variance-μs 3.0514713995301176E-5}, :numeric? true, :hamf-trans-hashmap {:mean-μs 225.72055139833714, :variance-μs 7.644137395932283E-6}} {:hamf-trans-long-map {:mean-μs 2679.216245614035, :variance-μs 3.578130407433292E-4}, :hamf-hashmap {:mean-μs 2798.3279594594596, :variance-μs 0.001752698461439497}, :n-elems 10000, :test :union-reduce-transient, :hamf-long-map {:mean-μs 2778.5944864864864, :variance-μs 0.0011648177035861703}, :numeric? true, :hamf-trans-hashmap {:mean-μs 2681.1084166666665, :variance-μs 7.942134300416677E-4}} {:hamf-trans-long-map {:mean-μs 15799.275738095239, :variance-μs 0.002852110740338103}, :hamf-hashmap {:mean-μs 17891.047555555557, :variance-μs 0.025927661871208384}, :n-elems 1000000, :test :union-reduce-transient, :hamf-long-map {:mean-μs 18630.76869444445, :variance-μs 0.0395750146766083}, :numeric? true, :hamf-trans-hashmap {:mean-μs 15486.036642857143, :variance-μs 0.046683416241262723}}]"
  },
  {
    "path": "results/union-reduce.edn",
    "content": "[{:hamf-trie {:mean-μs 1.7252145524853624, :variance-μs 2.011615888905509E-10}, :java {:mean-μs 38.32988724387806, :variance-μs 1.8803434110405448E-6}, :hamf-hashmap {:mean-μs 1.2381281025521231, :variance-μs 7.209768527187194E-9}, :clj-int-map {:mean-μs 5.861840907242486, :variance-μs 1.9579476680473757E-9}, :n-elems 4, :clj {:mean-μs 7.42634866750487, :variance-μs 7.627804021594806E-9}, :test :union-reduce, :hamf-long-map {:mean-μs 1.106631402508452, :variance-μs 6.2822972924059196E-9}, :numeric? true} {:hamf-trie {:mean-μs 2.17823404331, :variance-μs 1.2554786716603527E-9}, :java {:mean-μs 38.116079696273616, :variance-μs 2.067486699868819E-8}, :hamf-hashmap {:mean-μs 1.4451719973078556, :variance-μs 4.191455542888255E-10}, :n-elems 4, :clj {:mean-μs 5.422725345839924, :variance-μs 3.0843970332480513E-9}, :test :union-reduce, :numeric? false} {:hamf-trie {:mean-μs 6.059379510739388, :variance-μs 3.148597844167285E-9}, :java {:mean-μs 93.98164679911702, :variance-μs 7.586405510284673E-8}, :hamf-hashmap {:mean-μs 2.3757701729699483, :variance-μs 2.534243076758045E-10}, :clj-int-map {:mean-μs 15.311703172085648, :variance-μs 4.910261252366723E-9}, :n-elems 10, :clj {:mean-μs 18.259924595233763, :variance-μs 1.8242569414470183E-8}, :test :union-reduce, :hamf-long-map {:mean-μs 1.9576182610238315, :variance-μs 6.291706049500769E-11}, :numeric? true} {:hamf-trie {:mean-μs 3.9894582821518676, :variance-μs 1.1492966005754426E-8}, :java {:mean-μs 94.84054833647205, :variance-μs 1.5161304455261573E-7}, :hamf-hashmap {:mean-μs 2.6381999444324946, :variance-μs 3.6644632694290616E-8}, :n-elems 10, :clj {:mean-μs 13.594286938534278, :variance-μs 1.511480975985681E-8}, :test :union-reduce, :numeric? false} {:hamf-trie {:mean-μs 53.18793429744689, :variance-μs 1.4319146246254403E-7}, :java {:mean-μs 943.35361682243, :variance-μs 2.764350354297334E-5}, :hamf-hashmap {:mean-μs 24.15856529495719, :variance-μs 4.097383320823301E-6}, :clj-int-map {:mean-μs 217.43048051948054, :variance-μs 4.965510566066485E-6}, :n-elems 100, :clj {:mean-μs 179.73787843488654, :variance-μs 3.777078889569355E-6}, :test :union-reduce, :hamf-long-map {:mean-μs 17.67657798219235, :variance-μs 8.757207605184863E-9}, :numeric? true} {:hamf-trie {:mean-μs 51.102250000000005, :variance-μs 3.838505344378272E-7}, :java {:mean-μs 942.6637720125786, :variance-μs 1.2386850963142328E-5}, :hamf-hashmap {:mean-μs 27.14281319669184, :variance-μs 2.467018502603686E-7}, :n-elems 100, :clj {:mean-μs 162.32703961748635, :variance-μs 1.1839934684263025E-4}, :test :union-reduce, :numeric? false} {:hamf-trie {:mean-μs 524.5056842105263, :variance-μs 1.0863700809083028E-5}, :java {:mean-μs 9408.903106060607, :variance-μs 0.002817331073447118}, :hamf-hashmap {:mean-μs 314.069758744856, :variance-μs 5.1753992843360013E-5}, :clj-int-map {:mean-μs 2980.940348484849, :variance-μs 0.02232584565807595}, :n-elems 1000, :clj {:mean-μs 2220.5140111111114, :variance-μs 5.021514807700558E-4}, :test :union-reduce, :hamf-long-map {:mean-μs 246.04637132352943, :variance-μs 1.2300311707203191E-5}, :numeric? true} {:hamf-trie {:mean-μs 542.4614453405019, :variance-μs 5.173914501500367E-5}, :java {:mean-μs 9467.722575757574, :variance-μs 0.0029632205643559035}, :hamf-hashmap {:mean-μs 379.6645031210986, :variance-μs 2.5376491541213855E-5}, :n-elems 1000, :clj {:mean-μs 2071.348385416667, :variance-μs 0.020338011925833777}, :test :union-reduce, :numeric? false} {:hamf-trie {:mean-μs 5917.341805555556, :variance-μs 0.009515687917660094}, :java {:mean-μs 99796.31791666668, :variance-μs 11.563507553274604}, :hamf-hashmap {:mean-μs 3659.8134107142855, :variance-μs 0.001547409551530098}, :clj-int-map {:mean-μs 36213.265, :variance-μs 0.3727468710440302}, :n-elems 10000, :clj {:mean-μs 22785.483366666667, :variance-μs 0.05900913628111442}, :test :union-reduce, :hamf-long-map {:mean-μs 3027.809068627451, :variance-μs 4.251032741093422E-4}, :numeric? true} {:hamf-trie {:mean-μs 6372.496270833333, :variance-μs 0.0057097176436725116}, :java {:mean-μs 103640.92316666667, :variance-μs 58.24561118563865}, :hamf-hashmap {:mean-μs 4942.851936507937, :variance-μs 0.034681454680306936}, :n-elems 10000, :clj {:mean-μs 22197.684250000002, :variance-μs 3.0316012223332187}, :test :union-reduce, :numeric? false} {:hamf-trie {:mean-μs 58398.40116666667, :variance-μs 1.754406274143675}, :java {:mean-μs 1096804.0131666667, :variance-μs 251.4701104954116}, :hamf-hashmap {:mean-μs 25968.265233333335, :variance-μs 0.13249291644170835}, :clj-int-map {:mean-μs 410986.65883333335, :variance-μs 428.0071516463167}, :n-elems 1000000, :clj {:mean-μs 365097.666, :variance-μs 562.6211510776219}, :test :union-reduce, :hamf-long-map {:mean-μs 24091.087466666668, :variance-μs 4.293764864312841}, :numeric? true} {:hamf-trie {:mean-μs 75765.96383333334, :variance-μs 3.399043885345373}, :java {:mean-μs 1219823.3045, :variance-μs 552.5941588752235}, :hamf-hashmap {:mean-μs 59915.99491666666, :variance-μs 16.822256157834293}, :n-elems 1000000, :clj {:mean-μs 407285.2278333333, :variance-μs 1188.415009698171}, :test :union-reduce, :numeric? false}]"
  },
  {
    "path": "results/update-values.edn",
    "content": "[{:hamf-trie {:mean-μs 0.02327796051118421, :variance-μs 1.529798206229456E-12}, :java {:mean-μs 0.07847960494396915, :variance-μs 6.967239475562219E-11}, :hamf-hashmap {:mean-μs 0.04177343050693086, :variance-μs 2.793246669872514E-11}, :clj-int-map {:mean-μs 0.2140203792702577, :variance-μs 1.7091480124142276E-9}, :n-elems 4, :clj {:mean-μs 0.16000777451163323, :variance-μs 1.6225888151827234E-11}, :test :update-values, :hamf-long-map {:mean-μs 0.031042283155488796, :variance-μs 3.667389465617035E-14}, :numeric? true} {:hamf-trie {:mean-μs 0.14682536268574706, :variance-μs 1.1720200400734721E-8}, :java {:mean-μs 0.07505282953979409, :variance-μs 1.958352763068874E-12}, :hamf-hashmap {:mean-μs 0.07620133611255923, :variance-μs 1.9538818411170063E-10}, :n-elems 4, :clj {:mean-μs 0.12028106134618147, :variance-μs 8.664968021466646E-12}, :test :update-values, :numeric? false} {:hamf-trie {:mean-μs 0.11711380170394013, :variance-μs 1.1120362518620985E-12}, :java {:mean-μs 0.1426209117711911, :variance-μs 1.9768546530060133E-13}, :hamf-hashmap {:mean-μs 0.08490383296119978, :variance-μs 1.4406649195760521E-11}, :clj-int-map {:mean-μs 0.37913624174515115, :variance-μs 6.846181047401567E-10}, :n-elems 10, :clj {:mean-μs 0.26714631887493423, :variance-μs 1.6715492379382318E-10}, :test :update-values, :hamf-long-map {:mean-μs 0.08867522080370929, :variance-μs 9.029038656283934E-14}, :numeric? true} {:hamf-trie {:mean-μs 0.11227565937962775, :variance-μs 1.008375961266171E-11}, :java {:mean-μs 0.15195437993096086, :variance-μs 1.241621304105891E-10}, :hamf-hashmap {:mean-μs 0.08544332713548886, :variance-μs 2.136955811180962E-11}, :n-elems 10, :clj {:mean-μs 0.2590125967719688, :variance-μs 1.6083054235535771E-10}, :test :update-values, :numeric? false} {:hamf-trie {:mean-μs 1.0189347159156787, :variance-μs 8.936932055536869E-9}, :java {:mean-μs 1.424921812796662, :variance-μs 2.892741965050164E-10}, :hamf-hashmap {:mean-μs 0.5425087975874657, :variance-μs 1.201778885326809E-10}, :clj-int-map {:mean-μs 5.351526782685392, :variance-μs 1.6986481748803361E-7}, :n-elems 100, :clj {:mean-μs 2.9119777834452663, :variance-μs 1.385181291203484E-8}, :test :update-values, :hamf-long-map {:mean-μs 0.5636471016724729, :variance-μs 7.935041214888953E-10}, :numeric? true} {:hamf-trie {:mean-μs 0.963894393494081, :variance-μs 8.554152614780146E-11}, :java {:mean-μs 1.5376735663532985, :variance-μs 1.9142271267603622E-10}, :hamf-hashmap {:mean-μs 0.5565060917111692, :variance-μs 1.1399854927089318E-11}, :n-elems 100, :clj {:mean-μs 2.693525257887008, :variance-μs 4.527435201244143E-9}, :test :update-values, :numeric? false} {:hamf-trie {:mean-μs 8.083828863188979, :variance-μs 5.203264679292682E-9}, :java {:mean-μs 16.096294095665172, :variance-μs 6.799347545588575E-8}, :hamf-hashmap {:mean-μs 6.190307065890513, :variance-μs 1.8338285552011452E-9}, :clj-int-map {:mean-μs 79.01754469345698, :variance-μs 3.2383455777678053E-6}, :n-elems 1000, :clj {:mean-μs 40.62912088923967, :variance-μs 3.0511749788563086E-6}, :test :update-values, :hamf-long-map {:mean-μs 5.960749848570888, :variance-μs 9.004788710038562E-8}, :numeric? true} {:hamf-trie {:mean-μs 8.645071313757573, :variance-μs 3.9951935857527376E-8}, :java {:mean-μs 19.83810250313718, :variance-μs 5.6948459817578805E-8}, :hamf-hashmap {:mean-μs 6.33829362877976, :variance-μs 4.9963727298931594E-9}, :n-elems 1000, :clj {:mean-μs 36.64484267523503, :variance-μs 3.1799669320644587E-6}, :test :update-values, :numeric? false} {:hamf-trie {:mean-μs 89.64856090314913, :variance-μs 9.184094334200789E-7}, :java {:mean-μs 288.5613842857143, :variance-μs 4.1490216851221805E-6}, :hamf-hashmap {:mean-μs 122.14282939322301, :variance-μs 1.89917898117354E-5}, :clj-int-map {:mean-μs 1042.6436542553192, :variance-μs 4.244495402500743E-5}, :n-elems 10000, :clj {:mean-μs 326.7029265175719, :variance-μs 6.44053470881768E-5}, :test :update-values, :hamf-long-map {:mean-μs 103.01725053078556, :variance-μs 2.033621312486714E-6}, :numeric? true} {:hamf-trie {:mean-μs 94.21875124378109, :variance-μs 2.475502125683672E-7}, :java {:mean-μs 315.3385751840168, :variance-μs 9.47068701674807E-6}, :hamf-hashmap {:mean-μs 123.19073616089209, :variance-μs 1.1321857119797999E-5}, :n-elems 10000, :clj {:mean-μs 279.60671802054156, :variance-μs 1.987768575559929E-5}, :test :update-values, :numeric? false} {:hamf-trie {:mean-μs 875.124011494253, :variance-μs 2.3593347263788428E-4}, :java {:mean-μs 1883.3649781420768, :variance-μs 0.047683306558661744}, :hamf-hashmap {:mean-μs 663.4260704761905, :variance-μs 0.009436127874248483}, :clj-int-map {:mean-μs 10616.249916666668, :variance-μs 0.07341608083279194}, :n-elems 1000000, :clj {:mean-μs 3817.3415246913587, :variance-μs 0.002413966098376224}, :test :update-values, :hamf-long-map {:mean-μs 625.1630857843138, :variance-μs 6.884754374434351E-4}, :numeric? true} {:hamf-trie {:mean-μs 1664.7518924731185, :variance-μs 6.001581389875809E-4}, :java {:mean-μs 4386.828270833334, :variance-μs 0.005613395971719895}, :hamf-hashmap {:mean-μs 1365.4537822222223, :variance-μs 2.3271949921746955E-4}, :n-elems 1000000, :clj {:mean-μs 3986.0304679487176, :variance-μs 0.00559609015678013}, :test :update-values, :numeric? false}]"
  },
  {
    "path": "results/vec-equals.edn",
    "content": "[{:clj {:mean-μs 0.013114838133872559, :variance-μs 8.516910019923821E-16}, :hamf {:mean-μs 0.013453478507802178, :variance-μs 5.500406624628508E-16}, :n-elems 4, :test :equals, :numeric? true} {:clj {:mean-μs 0.014078313993473786, :variance-μs 4.1520987302137574E-16}, :hamf {:mean-μs 0.014942907668277137, :variance-μs 1.1622913418498456E-15}, :n-elems 4, :test :equals, :numeric? false} {:clj {:mean-μs 0.02200595405762387, :variance-μs 1.6248563316139666E-16}, :hamf {:mean-μs 0.020377683927085583, :variance-μs 4.896998172086728E-15}, :n-elems 10, :test :equals, :numeric? true} {:clj {:mean-μs 0.021947801236497873, :variance-μs 4.8453164092927975E-15}, :hamf {:mean-μs 0.020389919756287723, :variance-μs 5.517379878526508E-15}, :n-elems 10, :test :equals, :numeric? false} {:clj {:mean-μs 0.4129872683330938, :variance-μs 3.4952275396514294E-12}, :hamf {:mean-μs 0.12356661450685098, :variance-μs 6.762682580051647E-13}, :n-elems 100, :test :equals, :numeric? true} {:clj {:mean-μs 0.41086788497176263, :variance-μs 7.9542700263153E-12}, :hamf {:mean-μs 0.12288005640342069, :variance-μs 3.705936325434058E-13}, :n-elems 100, :test :equals, :numeric? false} {:clj {:mean-μs 7.628584670906521, :variance-μs 2.031587087069574E-9}, :hamf {:mean-μs 1.5920195382633124, :variance-μs 7.833875350922081E-11}, :n-elems 1000, :test :equals, :numeric? true} {:clj {:mean-μs 3.9882135278514594, :variance-μs 2.26510125976812E-10}, :hamf {:mean-μs 1.2153155253505414, :variance-μs 1.946881781725304E-11}, :n-elems 1000, :test :equals, :numeric? false} {:clj {:mean-μs 96.19576477199743, :variance-μs 6.078162864496903E-7}, :hamf {:mean-μs 17.308249798642272, :variance-μs 1.119495552027586E-8}, :n-elems 10000, :test :equals, :numeric? true} {:clj {:mean-μs 53.58084915102771, :variance-μs 1.5045705978512028E-7}, :hamf {:mean-μs 12.022921093470218, :variance-μs 1.6352125401067207E-9}, :n-elems 10000, :test :equals, :numeric? false} {:clj {:mean-μs 1105.8278095238097, :variance-μs 5.674031963247992E-5}, :hamf {:mean-μs 175.21224855324076, :variance-μs 9.207391310371014E-7}, :n-elems 100000, :test :equals, :numeric? true} {:clj {:mean-μs 678.9248702460852, :variance-μs 1.4946960727416105E-5}, :hamf {:mean-μs 121.41390271035598, :variance-μs 4.593320347574881E-7}, :n-elems 100000, :test :equals, :numeric? false}]"
  },
  {
    "path": "scripts/benchmark",
    "content": "#!/bin/bash\n\necho \"Building uberjar\"\nrm -rf target\nclj -T:build perftest\njava -Djdk.attach.allowAttachSelf -jar target/uber-ham-fisted.jar\n"
  },
  {
    "path": "scripts/compile",
    "content": "#!/bin/bash\n\nrm -rf target/classes\nclojure -T:build compile\n"
  },
  {
    "path": "scripts/deploy",
    "content": "#!/bin/bash\n\nset -e\n\nscripts/run-tests\nrm -f pom.xml\nclj -T:build jar\ncp target/classes/META-INF/maven/com.cnuernber/ham-fisted/pom.xml .\nclj -X:codox\nscripts/reformat\nclj -X:deploy\n"
  },
  {
    "path": "scripts/enable-jdk17",
    "content": "#!/bin/bash\n\nif [ ! -e jdk-17.0.1 ]; then\n    wget https://download.java.net/java/GA/jdk17.0.1/2a2082e5a09d4267845be086888add4f/12/GPL/openjdk-17.0.1_linux-x64_bin.tar.gz\n    tar -xvzf openjdk-17.0.1_linux-x64_bin.tar.gz\n    rm openjdk-17.0.1_linux-x64_bin.tar.gz\nfi\n\nexport PATH=$(pwd)/jdk-17.0.1/bin:$PATH\nexport JAVA_HOME=$(pwd)/jdk-17.0.1/\n"
  },
  {
    "path": "scripts/install",
    "content": "#!/bin/bash\n\nset -e\n\nscripts/run-tests\nclj -T:build jar\ncp target/classes/META-INF/maven/com.cnuernber/ham-fisted/pom.xml .\nclj -X:install\n"
  },
  {
    "path": "scripts/koacha-test",
    "content": "#!/bin/bash\n\nscripts/compile\nclojure -M:dev:kaocha-test\n"
  },
  {
    "path": "scripts/lint",
    "content": "#!/bin/bash\n\nscripts/compile\nclojure -M:dev:test:clj-kondo --copy-configs --dependencies --parallel --lint \"$(clojure -A:dev:test -Spath)\"\nclojure -M:dev:test:clj-kondo --lint \"src:test\" --fail-level \"error\"\n"
  },
  {
    "path": "scripts/reformat",
    "content": "#!/bin/bash\n\npushd src\nreformat\npopd\n\npushd test\nreformat\npopd\n"
  },
  {
    "path": "scripts/run-tests",
    "content": "#!/bin/bash\n\nscripts/compile\nclojure -M:dev:test\n"
  },
  {
    "path": "src/ham_fisted/alists.clj",
    "content": "(ns ham-fisted.alists\n  \"Generic primitive array backed array-lists.  The pure clojure implementations are a bit\n  slower than the java ones but *far* less code so these are used for the\n  less-frequently-used primive datatypes - byte, short, char, and float.\"\n  (:require [ham-fisted.iterator :as iterator]\n            [ham-fisted.protocols :as protocols]\n            [ham-fisted.defprotocol :refer [extend extend-type extend-protocol]])\n  (:import [ham_fisted ArrayLists ArrayLists$ILongArrayList ArrayLists$IDoubleArrayList\n            Transformables ArrayHelpers Casts IMutList IFnDef$OLO IFnDef$ODO\n            ArrayLists$ObjectArrayList ArrayLists$ObjectArraySubList\n            ArrayLists$ByteArraySubList ArrayLists$ShortArraySubList ArrayLists$CharArraySubList\n            ArrayLists$IntArraySubList ArrayLists$IntArrayList\n            ArrayLists$LongArraySubList ArrayLists$LongArrayList\n            ArrayLists$FloatArraySubList ArrayLists$BooleanArraySubList\n            ArrayLists$DoubleArraySubList ArrayLists$DoubleArrayList\n            ArrayLists$IArrayList ChunkedList Reductions]\n           [clojure.lang IPersistentMap IReduceInit RT]\n           [java.util Arrays RandomAccess List])\n  (:refer-clojure :exclude [extend extend-type extend-protocol]))\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* true)\n\n(defmacro implement-tostring-print\n  [tname]\n  (require '[ham-fisted.print])\n  `(ham-fisted.print/implement-tostring-print ~tname))\n\n\n(defn- add-long-reduce\n  [list c]\n  (Reductions/serialReduction\n   (reify IFnDef$OLO\n     (invokePrim [this acc v]\n       (.addLong ^IMutList acc v)\n       acc))\n   list\n   c))\n\n(defn- add-double-reduce\n  [list c]\n  (Reductions/serialReduction\n   (reify IFnDef$ODO\n     (invokePrim [this acc v]\n       (.addDouble ^IMutList acc v)\n       acc))\n   list\n   c))\n\n(defmacro make-prim-array-list\n  [lname ary-tag iface getname setname addname set-cast-fn get-cast-fn obj-cast-fn\n   add-all-reduce]\n  `(deftype ~lname [~(with-meta 'data {:unsynchronized-mutable true\n                                       :tag ary-tag})\n                    ~(with-meta 'n-elems {:unsynchronized-mutable true\n                                          :tag 'long})\n                    ~(with-meta 'm {:tag 'IPersistentMap})]\n     ~'Object\n     (hashCode [this#] (.hasheq this#))\n     (equals [this# other#] (.equiv this# other#))\n     (toString [this#] (Transformables/sequenceToString this#))\n     ~iface\n     (meta [this#] ~'m)\n     (withMeta [this# newm#] (with-meta (.subList this# 0 ~'n-elems) newm#))\n     (cloneList [this#] (~(symbol (str (name lname) \".\")) (.copyOf this# ~'n-elems)\n                         ~'n-elems ~'m))\n     (clone [this#] (.cloneList this#))\n     (clear [this#] (set! ~'n-elems 0))\n     (setSize [this# sz#] (set! ~'n-elems (unchecked-long sz#)))\n     (size [this#] (unchecked-int ~'n-elems))\n     (~getname [this# idx#] (~get-cast-fn (aget ~'data (ArrayLists/checkIndex idx# ~'n-elems))))\n     (get [this# idx#] (aget ~'data (ArrayLists/checkIndex idx# ~'n-elems)))\n     (~setname [this# idx# v#] (ArrayHelpers/aset ~'data (ArrayLists/checkIndex idx# ~'n-elems) (~set-cast-fn v#)))\n     (set [this# idx# val#]\n       (let [idx# (ArrayLists/checkIndex idx# ~'n-elems)\n             rv# (aget ~'data idx#)]\n         (ArrayHelpers/aset ~'data idx# (~set-cast-fn val#))\n         rv#))\n     (subList [this# sidx# eidx#]\n       (ChunkedList/sublistCheck sidx# eidx# ~'n-elems)\n       (ArrayLists/toList ~'data sidx# eidx# ~'m))\n     (ensureCapacity [this# newlen#]\n       (when (> newlen# (alength ~'data))\n         (set! ~'data (.copyOf this# (ArrayLists/newArrayLen newlen#))))\n       ~'data)\n     (~addname [this# v#]\n      (let [curlen# ~'n-elems\n            newlen# (unchecked-inc ~'n-elems)\n            ~(with-meta 'b {:tag ary-tag}) (.ensureCapacity this# newlen#)]\n        (ArrayHelpers/aset ~'b curlen# (~set-cast-fn v#))\n        (set! ~'n-elems newlen#)))\n     (add [this# idx# obj#]\n       (ArrayLists/checkIndex idx# ~'n-elems)\n       (if (== idx# ~'n-elems)\n         (.add this# obj#)\n         (let [bval# (~set-cast-fn (~obj-cast-fn obj#))\n               curlen# ~'n-elems\n               newlen# (unchecked-inc curlen#)\n               ~(with-meta 'd {:tag ary-tag}) (.ensureCapacity this# newlen#)]\n           (System/arraycopy ~'d idx# ~'d (unchecked-inc idx#) (- curlen# idx#))\n           (ArrayHelpers/aset ~'d idx# bval#)\n           (set! ~'n-elems newlen#))))\n     (addAllReducible [this# c#]\n       (let [sz# (.size this#)]\n         (if (instance? RandomAccess c#)\n           (do\n             (when-not (== 0 (.size ^List c#))\n               (let [~(with-meta 'c {:tag 'List}) c#\n                     curlen# ~'n-elems\n                     newlen# (+ curlen# (.size ~'c))]\n                 (.ensureCapacity this# newlen#)\n                 (set! ~'n-elems newlen#)\n                 (.fillRangeReducible this# curlen# ~'c))))\n           (~add-all-reduce this# c#))\n         (not (== sz# ~'n-elems))))\n     (fillRangeReducible [this# sidx# c#]\n       (.fillRangeReducible (.subList this# 0 (.size this#)) sidx# c#))\n     (removeRange [this# sidx# eidx#]\n       (ArrayLists/checkIndexRange ~'n-elems (long sidx#) (long eidx#))\n       (System/arraycopy ~'data sidx# ~'data eidx# (- ~'n-elems eidx#))\n       (set! ~'n-elems (- ~'n-elems (- eidx# sidx#))))\n     (sort [~'this c#] (.sort ~(with-meta '(.subList this 0 n-elems)  {:tag 'IMutList}) c#))\n     (sortIndirect [~'this c#] (.sortIndirect ~(with-meta '(.subList this 0 n-elems) {:tag 'IMutList}) c#))\n     (shuffle [~'this r#] (.shuffle ~(with-meta '(.subList this 0 n-elems) {:tag 'IMutList}) r#))\n     (reduce [this# rfn# init#]\n       (reduce rfn# init# (.subList this# 0 ~'n-elems)))\n     (binarySearch [~'this v# c#] (.binarySearch ~(with-meta '(.subList this 0 n-elems) {:tag 'IMutList}) v# c#))\n     (move [this# sidx# eidx# count#]\n       (ArrayLists/checkIndexRange ~'n-elems (long eidx#) (+ (long eidx#) count#))\n       (System/arraycopy ~'data sidx# ~'data eidx# count#))\n     (fill [this# sidx# eidx# v#]\n       (ArrayLists/checkIndexRange ~'n-elems (long sidx#) (long eidx#))\n       (Arrays/fill ~'data sidx# eidx# (~set-cast-fn (~obj-cast-fn v#))))\n     (copyOfRange [this# sidx# eidx#]\n       (Arrays/copyOfRange ~'data sidx# eidx#))\n     (copyOf [this# len#]\n       (Arrays/copyOf ~'data len#))\n     (getArraySection [this#]\n       (ham_fisted.ArraySection. ~'data 0 ~'n-elems))))\n\n\n(make-prim-array-list ByteArrayList bytes ArrayLists$ILongArrayList getLong setLong addLong\n                      RT/byteCast unchecked-long Casts/longCast add-long-reduce)\n(make-prim-array-list ShortArrayList shorts ArrayLists$ILongArrayList getLong setLong addLong\n                      RT/shortCast unchecked-long Casts/longCast add-long-reduce)\n(make-prim-array-list CharArrayList chars ArrayLists$ILongArrayList getLong setLong addLong\n                      Casts/charCast Casts/charLongCast Casts/charLongCast add-long-reduce)\n(make-prim-array-list FloatArrayList floats ArrayLists$IDoubleArrayList getDouble setDouble\n                      addDouble float unchecked-double Casts/doubleCast add-double-reduce)\n\n\n(deftype BooleanArrayList [^{:unsynchronized-mutable true\n                             :tag booleans} data\n                           ^{:unsynchronized-mutable true\n                             :tag long} n-elems\n                           ^IPersistentMap m]\n  Object\n  (hashCode [this] (.hasheq this))\n  (equals [this other] (.equiv this other))\n  (toString [this] (Transformables/sequenceToString this))\n  ArrayLists$IArrayList\n  (cloneList [this] (BooleanArrayList. (.copyOf this n-elems) n-elems m))\n  (meta [this] m)\n  (withMeta [this newm] (with-meta (.subList this 0 n-elems) newm))\n  (setSize [this sz] (set! n-elems (unchecked-long sz)))\n  (size [this] (unchecked-int n-elems))\n  (clear [this] (set! n-elems 0))\n  (get [this idx] (aget data (ArrayLists/checkIndex idx n-elems)))\n  (set [this idx v]\n    (let [retval (.get this idx)]\n      (ArrayHelpers/aset data (ArrayLists/checkIndex idx n-elems)\n                         (Casts/booleanCast v))\n      retval))\n  (subList [this sidx eidx]\n    (ChunkedList/sublistCheck sidx eidx n-elems)\n    (ArrayLists/toList data sidx eidx m))\n  (ensureCapacity [this newlen]\n    (when (> newlen (alength data))\n      (set! data ^booleans (.copyOf this (ArrayLists/newArrayLen newlen))))\n    data)\n  (add [this v]\n    (let [curlen n-elems\n          newlen (unchecked-inc n-elems)\n          ^booleans b (.ensureCapacity this newlen)]\n      (ArrayHelpers/aset b curlen (Casts/booleanCast v))\n      (set! n-elems newlen)\n      true))\n  (add [this idx obj]\n    (if (== idx n-elems)\n      (.add this obj)\n      (do\n        (ArrayLists/checkIndex idx n-elems)\n        (let [bval (Casts/booleanCast obj)\n              curlen n-elems\n              newlen (unchecked-inc curlen)\n              ^booleans d (.ensureCapacity this newlen)]\n          (System/arraycopy d idx d (unchecked-inc idx) (- curlen idx))\n          (ArrayHelpers/aset d idx bval)\n          (set! n-elems newlen)))))\n  (addAllReducible [this c]\n    (let [sz (.size this)]\n      (if (instance? RandomAccess c)\n        (let [^List c c\n              curlen n-elems\n              newlen (+ curlen (.size c))]\n          (.ensureCapacity this newlen)\n          (set! n-elems newlen)\n          (.fillRangeReducible this curlen c))\n        (Reductions/serialReduction (fn [acc v]\n                                      (.add ^List acc v)\n                                      acc)\n                                    this\n                                    c))\n      (not (== sz n-elems))))\n  (fillRangeReducible [this sidx c]\n    (.fillRangeReducible (.subList this 0 (.size this)) sidx c))\n  (removeRange [this sidx eidx]\n    (ArrayLists/checkIndexRange n-elems sidx eidx)\n    (System/arraycopy data sidx data eidx (- n-elems eidx))\n    (set! n-elems (- n-elems (- eidx sidx))))\n  (sort [this c] (.sort (.subList this 0 n-elems) c))\n  (sortIndirect [this c] (.sortIndirect ^IMutList (.subList this 0 n-elems) c))\n  (shuffle [this r] (.shuffle ^IMutList (.subList this 0 n-elems) r))\n  (binarySearch [this v c] (.binarySearch ^IMutList (.subList this 0 n-elems) v c))\n  (move [this sidx eidx ct]\n    (ArrayLists/checkIndexRange n-elems (long eidx) (+ (long eidx) ct))\n    (System/arraycopy data sidx data eidx ct))\n  (fill [this sidx eidx v]\n    (ArrayLists/checkIndexRange n-elems (long sidx) (long eidx))\n    (Arrays/fill data sidx eidx (Casts/booleanCast v)))\n  (copyOfRange [this sidx eidx]\n    (Arrays/copyOfRange data sidx eidx))\n  (copyOf [this len]\n    (Arrays/copyOf data len))\n  (getArraySection [this]\n    (ham_fisted.ArraySection. data 0 n-elems)))\n\n\n(implement-tostring-print ByteArrayList)\n(implement-tostring-print ShortArrayList)\n(implement-tostring-print CharArrayList)\n(implement-tostring-print FloatArrayList)\n(implement-tostring-print BooleanArrayList)\n\n\n(defn- ladd\n  [^IMutList m v]\n  (.add m v)\n  m)\n\n(defn- lmerge\n  [^IMutList l v]\n  (.addAllReducible l v)\n  l)\n\n\n#_(extend-protocol protocols/Reducer\n    ArrayLists$ObjectArrayList\n    (->init-val-fn [item] #(ArrayLists$ObjectArrayList.))\n    (->rfn [item] ladd)\n    ArrayLists$IntArrayList\n    (->init-val-fn [item] #(ArrayLists$IntArrayList.))\n    (->rfn [item] ladd)\n    ArrayLists$LongArrayList\n    (->init-val-fn [item] #(ArrayLists$LongArrayList.))\n    (->rfn [item] ladd)\n    ArrayLists$DoubleArrayList\n    (->init-val-fn [item] #(ArrayLists$DoubleArrayList.))\n    (->rfn [item] ladd))\n\n\n#_(extend-protocol protocols/ParallelReducer\n    ArrayLists$ObjectArrayList\n    (->merge-fn [l] lmerge)\n    ArrayLists$IntArrayList\n    (->merge-fn [l] lmerge)\n    ArrayLists$LongArrayList\n    (->merge-fn [l] lmerge)\n    ArrayLists$DoubleArrayList\n    (->merge-fn [l] lmerge))\n\n\n\n(defmacro extend-array-types\n  []\n  `(do\n     ~@(->>\n        {'(Class/forName \"[Z\") ['bytes 'BooleanArrayList.]\n         '(Class/forName \"[B\") ['bytes 'ByteArrayList.]\n         '(Class/forName \"[S\") ['shorts 'ShortArrayList.]\n         '(Class/forName \"[C\") ['chars 'CharArrayList.]\n         '(Class/forName \"[I\") ['ints 'ArrayLists$IntArrayList.]\n         '(Class/forName \"[J\") ['longs 'ArrayLists$LongArrayList.]\n         '(Class/forName \"[F\") ['floats 'FloatArrayList.]\n         '(Class/forName \"[D\") ['doubles 'ArrayLists$DoubleArrayList.]\n         '(Class/forName \"[Ljava.lang.Object;\") ['objects 'ArrayLists$ObjectArrayList.]}\n        (map (fn [[cls-type [hint growable-cons]]]\n               `(extend ~cls-type\n                  protocols/WrapArray\n                  {:wrap-array (fn [~(with-meta (symbol \"ary\") {:tag hint})]\n                                 (ArrayLists/toList ~'ary))\n                   :wrap-array-growable (fn [~(with-meta (symbol \"ary\") {:tag hint})\n                                             ~(with-meta (symbol \"ptr\") {:tag 'long})]\n                                          (~growable-cons ~'ary ~'ptr nil))}))))))\n\n\n(extend-array-types)\n\n(def ^:private obj-ary-cls (Class/forName \"[Ljava.lang.Object;\"))\n\n(defn wrap-array\n  \"Wrap an array with an implementation of IMutList\"\n  ^IMutList [ary]\n  (if (instance? obj-ary-cls ary)\n    (ArrayLists/toList ^objects ary)\n    (protocols/wrap-array ary)))\n\n\n(defn wrap-array-growable\n  \"Wrap an array with an implementation of IMutList that supports add and addAllReducible.\n  'ptr is the numeric put ptr, defaults to the array length.  Pass in zero for a preallocated\n  but empty growable wrapper.\"\n  (^IMutList [ary ptr]\n   (if (instance? obj-ary-cls ary)\n     (ArrayLists$ObjectArrayList. ary ptr nil)\n     (protocols/wrap-array-growable ary ptr)))\n  (^IMutList [ary] (wrap-array-growable ary (java.lang.reflect.Array/getLength ary))))\n\n(def array-list-types [:int8 :int16 :int32 :int64 :float32 :float64 :char :boolean :object])\n\n(defn growable-array-list\n  (^IMutList [dtype]\n   (case dtype\n     :int8 (ByteArrayList. (byte-array 8) 0 {})\n     :int16 (ShortArrayList. (short-array 8) 0 {})\n     :int32 (ArrayLists$IntArrayList. (int-array 8) 0 {})\n     :int64 (ArrayLists$LongArrayList. (long-array 4) 0 {})\n     :float32 (FloatArrayList. (float-array 8) 0 {})\n     :float64 (ArrayLists$DoubleArrayList. (double-array 4) 0 {})\n     :char (CharArrayList. (char-array 8) 0 {})\n     :boolean (BooleanArrayList. (boolean-array 8) 0 {})\n     :object (ArrayLists$ObjectArrayList. (object-array 8) 0 {})))\n  (^IMutList [dtype data]\n   (let [rv (growable-array-list dtype)]\n     (.addAllReducible rv data)\n     rv)))\n"
  },
  {
    "path": "src/ham_fisted/api.clj",
    "content": "(ns ham-fisted.api\n  \"Fast mutable and immutable associative data structures based on bitmap trie\n  hashmaps. Mutable pathways implement the `java.util.Map` or `Set` interfaces\n  including in-place update features such as compute or computeIfPresent.\n\n  Mutable maps or sets can be turned into their immutable counterparts via the\n  Clojure `persistent!` call. This allows working in a mutable space for\n  convenience and performance then switching to an immutable pathway when\n  necessary. Note: after `persistent!` one should never backdoor mutate map or\n  set again as this will break the contract of immutability.  Immutable\n  data structures also support conversion to transient via `transient`.\n\n  Map keysets (`.keySet`) are full `PersistentHashSet`s of keys.\n\n  Maps and sets support metadata but setting the metadata on mutable objects\n  returns a new mutable object that shares the backing store leading to possible\n  issues. Metadata is transferred to the persistent versions of the\n  mutable/transient objects upon `persistent!`.\n\n  Very fast versions of union, difference and intersection are provided for maps\n  and sets with the map version of union and difference requiring an extra\n  argument, a `java.util.BiFunction` or an `IFn` taking 2 arguments to merge the\n  left and right sides into the final map. These implementations of union,\n  difference, and intersection are the fastest implementation of these\n  operations we know of on the JVM.\n\n  Additionally a fast value update pathway is provided, enabling quickly\n  updating all the values in a given map. Additionally, a new map primitive\n  - [[mapmap]] - allows transforming a given map into a new map quickly by\n  mapping across all the entries.\n\n  Unlike the standard Java objects, mutation-via-iterator is not supported.\"\n  (:require [ham-fisted.iterator :as iterator]\n            [ham-fisted.function :refer [bi-function ->bi-function function bi-consumer obj->long]\n             :as hamf-fn]\n            [ham-fisted.lazy-noncaching\n             :refer [map concat filter repeatedly]\n             :as lznc]\n            [ham-fisted.caffeine :as hamf-caffeine]\n            [ham-fisted.lazy-caching :as lzc]\n            [ham-fisted.alists :as alists]\n            [ham-fisted.impl :as impl]\n            [ham-fisted.reduce :refer [reduce-reducer preduce options->parallel-options preduce-reducer\n                                       long-accumulator double-accumulator double-consumer-accumulator\n                                       long-consumer-accumulator]\n             :as hamf-rf]\n            [ham-fisted.language :as hamf-language]\n            [ham-fisted.protocols :as protocols]\n            [ham-fisted.defprotocol :refer [extend extend-type extend-protocol]])\n  (:import [ham_fisted UnsharedHashMap UnsharedLongHashMap UnsharedHashSet\n            PersistentHashSet PersistentHashMap PersistentLongHashMap\n            ArrayLists$ArrayOwner MergeIterator\n            HashProvider MapSetOps SetOps ObjArray UpdateValues\n            MutList ImmutList StringCollection ArrayImmutList ArrayLists\n            ImmutSort IMutList Ranges$LongRange ArrayHelpers\n            Ranges$DoubleRange IFnDef Transformables$MapIterable\n            Transformables$FilterIterable Transformables$CatIterable\n            Transformables$MapList Transformables$IMapable Transformables\n            ReindexList ConstList ArrayLists$ObjectArrayList Transformables$SingleMapList\n            ArrayLists$IntArrayList ArrayLists$LongArrayList ArrayLists$DoubleArrayList\n            ReverseList TypedList DoubleMutList LongMutList\n            Consumers Sum Sum$SimpleSum Casts Reducible IndexedDoubleConsumer\n            IndexedLongConsumer IndexedConsumer ITypedReduce ParallelOptions Reductions\n            IFnDef$LO IFnDef$LL IFnDef$DO IFnDef$DD IFnDef$DDD\n            IFnDef$LLL ParallelOptions$CatParallelism IFnDef$OO IFnDef$OOO IFnDef$ODO\n            IFnDef$OLO IFnDef$OD IFnDef$OL IFnDef$LD IFnDef$DL IFnDef$OLOO IFnDef$OLDO\n            IFnDef$OLLO IFnDef$LongPredicate IFnDef$DoublePredicate IFnDef$Predicate\n            Consumers$IncConsumer Reductions$IndexedDoubleAccum Reductions$IndexedLongAccum\n            Reductions$IndexedAccum MutableMap IAMapEntry MapForward TypedNth\n            TreeList MutTreeList]\n           [ham_fisted.alists ByteArrayList ShortArrayList CharArrayList FloatArrayList\n            BooleanArrayList]\n           [clojure.lang ITransientAssociative2 ITransientCollection Indexed\n            IEditableCollection RT IPersistentMap Associative Util IFn ArraySeq\n            Reversible IReduce IReduceInit IFn$DD IFn$DL IFn$DO IFn$LD IFn$LL IFn$LO\n            IFn$OD IFn$OL IFn$OLO IFn$ODO IObj Util IReduceInit Seqable IteratorSeq\n            ITransientMap Counted Box]\n           [java.util Map Map$Entry List RandomAccess Set Collection ArrayList Arrays\n            Comparator Random Collections Iterator PriorityQueue LinkedHashMap LongSummaryStatistics\n            DoubleSummaryStatistics]\n           [java.lang.reflect Array]\n           [java.util.function Function BiFunction BiConsumer Consumer\n            DoubleBinaryOperator LongBinaryOperator LongFunction IntFunction\n            DoubleConsumer DoublePredicate DoubleUnaryOperator LongPredicate\n            LongUnaryOperator LongConsumer Predicate UnaryOperator]\n           [java.util.concurrent ForkJoinPool ExecutorService Callable Future\n            ConcurrentHashMap ForkJoinTask ArrayBlockingQueue]\n           [it.unimi.dsi.fastutil.ints IntComparator IntArrays]\n           [it.unimi.dsi.fastutil.longs LongComparator]\n           [it.unimi.dsi.fastutil.floats FloatComparator]\n           [it.unimi.dsi.fastutil.doubles DoubleComparator DoubleArrays]\n           [it.unimi.dsi.fastutil.objects ObjectArrays]\n           [com.github.benmanes.caffeine.cache Caffeine LoadingCache CacheLoader Cache\n            RemovalCause]\n           [com.github.benmanes.caffeine.cache.stats CacheStats]\n           [java.time Duration]\n           [java.util.logging Logger]\n           [java.util.stream IntStream DoubleStream])\n  (:refer-clojure :exclude [assoc! conj! frequencies merge merge-with memoize cond\n                            into hash-map not\n                            group-by subvec group-by mapv vec vector object-array\n                            sort int-array long-array double-array float-array\n                            range map concat filter filterv first last pmap take take-last drop\n                            drop-last sort-by repeat repeatedly shuffle into-array\n                            empty? reverse byte-array short-array char-array boolean-array\n                            keys vals persistent! rest transient update-vals\n                            re-matches complement count extend extend-type extend-protocol\n                            constantly]))\n\n(comment\n  (require '[clj-java-decompiler.core :refer [disassemble]])\n  )\n\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n(declare assoc! conj! vec mapv vector object-array range first take drop into-array shuffle\n         object-array-list int-array-list long-array-list double-array-list\n         int-array argsort byte-array short-array char-array boolean-array repeat\n         persistent! rest immut-map keys vals group-by-reduce\n         reindex group-by-consumer\n         merge constant-count mutable-map?\n         transient update-vals apply-concat)\n\n(defn constantly\n  [x]\n  (hamf-language/constantly x))\n\n(defn not\n  \"Returns boolean opposite of passed in value\"\n  {:inline (fn [x] `(Transformables/not ~x))\n   :inline-arities #{1}}\n  [a]\n  (Transformables/not a))\n\n(defn complement\n  \"Like clojure core complement but avoids var lookup on 'not'\"\n  [f]\n  (lznc/complement f))\n\n(defn count \"hamf protocol extensible count\" ^long [m] (protocols/count m))\n\n(defn ->collection\n  \"Ensure item is an implementation of java.util.Collection.\"\n  ^Collection [item]\n  (lznc/->collection item))\n\n\n(defn ->random-access\n  \"Ensure item is derived from java.util.List and java.util.RandomAccess and\n  thus supports constant time random addressing.\"\n  ^List [item]\n  (lznc/->random-access item))\n\n\n(defn ->reducible\n  \"Ensure item either implements IReduceInit or java.util.Collection.  For arrays\n  this will return an object that has a much more efficient reduction pathway\n  than the base Clojure reducer.\"\n  [item]\n  (lznc/->reducible item))\n\n\n\n(defn- check-deprecated-provider\n  [options]\n  (when (:hash-provider options)\n    (.warning (Logger/getGlobal) \"Hash providers have been deprecated\")))\n\n\n(def ^{:tag PersistentHashMap\n       :doc \"Constant persistent empty map\"} empty-map PersistentHashMap/EMPTY)\n(def ^{:tag PersistentHashSet\n       :doc \"Constant persistent empty set\"} empty-set PersistentHashSet/EMPTY)\n(def ^{:tag ArrayImmutList\n       :doc \"Constant persistent empty vec\"} empty-vec ArrayImmutList/EMPTY)\n\n\n(defn- empty-map?\n  [m]\n  (or (nil? m)\n      (and (instance? Map m)\n           (== 0 (.size ^Map m)))))\n\n\n\n(def ^:private empty-objs (clojure.core/object-array 0))\n\n\n(def ^{:doc \"As quickly as possible, produce an object array from these inputs.  Very fast for arities\n  <= 16.\"\n       :arglists '([]\n                   [v0]\n                   [v0 v1]\n                   [v0 v1 v2]\n                   [v0 v1 v2 v3]\n                   [v0 v1 v2 v3 v4]\n                   [v0 v1 v2 v3 v4 v5]\n                   [v0 v1 v2 v3 v4 v5 v6]\n                   [v0 v1 v2 v3 v4 v5 v6 v7]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14]\n                   [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15])}\n  obj-ary hamf-language/obj-ary)\n\n(defmacro cond\n  \"Similar to `core/cond` except it supports true else clauses as opposed to always\n  returning nil on else.  The last clause of an odd number of clauses will be used as\n  the else branch similar to case.  Additional if the last predicate is the constant\n  'true' or ':else' it will be used as the else clause.  If no else is provided then\n  returns nil same as `core/cond`.\n\n  Important! - in order to get correct type hinting on both branches of the if they\n  both must return an explicit long or double:\n\n  * Sill Boxed\n\n```clojure\n  (defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (.length ^String a) ;;string.length returns integer not long\n      ))\n\n(defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (alength ^longs a)\n      ))\n```\n  * Correctly Unboxed\n\n```clojure\n(defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (long (.length ^String a))\n      ))\n\n(defn memory-size\n    ^long [a]\n    (cond\n      (instance? Long a) 24\n      :else (long (alength ^longs a))\n      ))\n```\"\n  [& clauses]\n  `(lznc/cond ~@clauses))\n\n(defn into\n  \"Like clojure.core/into, but also designed to handle editable collections,\n  transients, and base java.util.Map, List and Set containers.\"\n  ([container data]\n   (cond\n     (instance? IEditableCollection container)\n     (-> (reduce conj! (transient container) data)\n         (persistent!))\n     (instance? ITransientCollection container)\n     (reduce conj! container data)\n     (instance? Map container)\n     (if (instance? Map data)\n       (do (.putAll ^Map container ^Map data) container)\n       (reduce conj! container data))\n     (instance? Collection container)\n     (cond\n       (instance? Collection data)\n       (do (.addAll ^Collection container ^Collection data) container)\n       (instance? CharSequence data)\n       (do (.addAll ^Collection container (StringCollection. data)) container)\n       :else\n       (reduce conj! container data))\n     :else\n     (throw (Exception. (str \"Unable to ascertain container type: \" (type container))))))\n  ([container xform data]\n   (into container (eduction xform data))))\n\n\n(defonce ^:private obj-ary-cls (type (clojure.core/object-array 0)))\n\n\n(defn mut-map-rf\n  ([cons-fn] (mut-map-rf cons-fn nil))\n  ([cons-fn finalize-fn]\n   (fn\n     ([] (cons-fn))\n     ([acc] (if finalize-fn (finalize-fn acc) acc))\n     ([^Map m d]\n      (cond\n        (instance? Map$Entry d)\n        (.put m (.getKey ^Map$Entry d) (.getValue ^Map$Entry d))\n        (instance? Indexed d)\n        (.put m (.nth ^Indexed d 0) (.nth ^Indexed d 1))\n        :else\n        (throw (Exception. (str \"Unrecognized map input: \" (type d)))))\n      m))))\n\n\n(defn transient-map-rf\n  ([cons-fn] (transient-map-rf cons-fn nil))\n  ([cons-fn finalize-fn]\n   (fn\n     ([] (cons-fn))\n     ([acc] (if finalize-fn (finalize-fn acc) acc))\n     ([^ITransientCollection m d] (.conj m d)))))\n\n\n(defn- tduce\n  [xform rf data]\n  (if xform\n    (transduce xform rf data)\n    (rf (reduce rf (rf) data))))\n\n\n(defn mut-hashtable-map\n  \"Create a mutable implementation of java.util.Map.  This object efficiently implements\n  ITransient map so you can use assoc! and persistent! on it but you can additionally use\n  the various members of the java.util.Map interface such as put, compute, computeIfAbsent,\n  replaceAll and merge.\n\n  If data is an object array it is treated as a flat key-value list which is distinctly\n  different than how conj! treats object arrays.  You have been warned.\"\n  (^UnsharedHashMap [] (UnsharedHashMap. nil))\n  (^UnsharedHashMap [data] (mut-hashtable-map nil nil data))\n  (^UnsharedHashMap [xform data] (mut-hashtable-map xform nil data))\n  (^UnsharedHashMap [xform options data]\n   (cond\n     (number? data)\n     (UnsharedHashMap. nil (int data))\n     (nil? xform)\n     (cond\n       (instance? obj-ary-cls data)\n       (UnsharedHashMap/create data)\n       (instance? Map data)\n       (doto (UnsharedHashMap. nil (.size ^Map data))\n         (.putAll data))\n       :else\n       (into (UnsharedHashMap. nil) data))\n     :else\n     (into (UnsharedHashMap. nil) xform data))))\n\n\n(defn mut-long-hashtable-map\n  \"Create a mutable implementation of java.util.Map.  This object efficiently implements\n  ITransient map so you can use assoc! and persistent! on it but you can additionally use\n  the various members of the java.util.Map interface such as put, compute, computeIfAbsent,\n  replaceAll and merge.\n\n  If data is an object array it is treated as a flat key-value list which is distinctly\n  different than how conj! treats object arrays.  You have been warned.\"\n  (^UnsharedLongHashMap [] (UnsharedLongHashMap. nil))\n  (^UnsharedLongHashMap [data] (mut-long-hashtable-map nil nil data))\n  (^UnsharedLongHashMap [xform data] (mut-long-hashtable-map xform nil data))\n  (^UnsharedLongHashMap [xform options data]\n   (cond\n     (number? data)\n     (UnsharedLongHashMap. nil (int data))\n     (nil? xform)\n     (cond\n       (instance? obj-ary-cls data)\n       (UnsharedLongHashMap/create data)\n       (instance? Map data)\n       (doto (UnsharedLongHashMap. nil (.size ^Map data))\n         (.putAll data))\n       :else\n       (into (UnsharedLongHashMap. nil) data))\n     :else\n     (into (UnsharedLongHashMap. nil) xform data))))\n\n\n(defn mut-map\n  \"Create a mutable implementation of java.util.Map.  This object efficiently implements\n  ITransient map so you can use assoc! and persistent! on it but you can additionally use\n  the various members of the java.util.Map interface such as put, compute, computeIfAbsent,\n  replaceAll and merge.\n\n  If data is an object array it is treated as a flat key-value list which is distinctly\n  different than how conj! treats object arrays.  You have been warned.\"\n  (^UnsharedHashMap [] (mut-hashtable-map))\n  (^UnsharedHashMap [data] (mut-hashtable-map data))\n  (^UnsharedHashMap [xform data] (mut-hashtable-map xform data))\n  (^UnsharedHashMap [xform options data] (mut-hashtable-map xform options data)))\n\n\n(defn mut-long-map\n  \"Create a mutable implementation of java.util.Map specialized to long keys.  This object\n  efficiently implements ITransient map so you can use assoc! and persistent! on it but you can additionally use\n  the various members of the java.util.Map interface such as put, compute, computeIfAbsent,\n  replaceAll and merge.  Attempting to store any non-numeric value will result in an exception.\n\n  If data is an object array it is treated as a flat key-value list which is distinctly\n  different than how conj! treats object arrays.  You have been warned.\"\n  (^UnsharedLongHashMap [] (mut-long-hashtable-map))\n  (^UnsharedLongHashMap [data] (mut-long-hashtable-map data))\n  (^UnsharedLongHashMap [xform data] (mut-long-hashtable-map xform data))\n  (^UnsharedLongHashMap [xform options data] (mut-long-hashtable-map xform options data)))\n\n\n(defn constant-countable?\n  \"Return true if data has a constant time count.\"\n  [data]\n  (lznc/constant-countable? data))\n\n\n(defn constant-count\n  \"Constant time count.  Returns nil if input doesn't have a constant time count.\"\n  [data]\n  (lznc/constant-count data))\n\n\n(defn immut-map\n  \"Create an immutable map.  This object supports conversion to a transient map via\n  Clojure's `transient` function.  Duplicate keys are treated as if by assoc.\n\n  If data is an object array it is treated as a flat key-value list which is distinctly\n  different than how conj! treats object arrays.  You have been warned.\n\n  If you know you will have consistently more key/val pairs than 8 you should just\n  use `(persistent! (mut-map data))` as that avoids the transition from an arraymap\n  to a persistent hashmap.\n\n  Examples:\n\n  ```clojure\nham-fisted.api> (immut-map (obj-ary :a 1 :b 2 :c 3 :d 4))\n{:a 1, :b 2, :c 3, :d 4}\nham-fisted.api> (type *1)\nham_fisted.PersistentArrayMap\nham-fisted.api> (immut-map (obj-ary :a 1 :b 2 :c 3 :d 4 :e 5))\n{:d 4, :b 2, :c 3, :a 1, :e 5}\nham-fisted.api> (type *1)\nham_fisted.PersistentHashMap\nham-fisted.api> (immut-map [[:a 1][:b 2][:c 3][:d 4][:e 5]])\n{:d 4, :b 2, :c 3, :a 1, :e 5}\nham-fisted.api> (type *1)\nham_fisted.PersistentHashMap\n```\"\n  (^PersistentHashMap [] empty-map)\n  (^PersistentHashMap [data]\n   (immut-map nil data))\n  (^PersistentHashMap [options data]\n   (-> (mut-map options data)\n       (persistent!))))\n\n\n(defn hash-map\n  \"Drop-in replacement to Clojure's hash-map function.\"\n  ([] empty-map)\n  ([a b]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b))))\n  ([a b c d]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d))))\n  ([a b c d e f]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d)\n                  (.put e f))))\n  ([a b c d e f g h]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d)\n                  (.put e f)\n                  (.put g h))))\n  ([a b c d e f g h i j]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d)\n                  (.put e f)\n                  (.put g h)\n                  (.put i j))))\n  ([a b c d e f g h i j k l]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d)\n                  (.put e f)\n                  (.put g h)\n                  (.put i j)\n                  (.put k l))))\n  ([a b c d e f g h i j k l m n]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d)\n                  (.put e f)\n                  (.put g h)\n                  (.put i j)\n                  (.put k l)\n                  (.put m n))))\n  ([a b c d e f g h i j k l m n o p]\n   (persistent! (doto (mut-hashtable-map)\n                  (.put a b)\n                  (.put c d)\n                  (.put e f)\n                  (.put g h)\n                  (.put i j)\n                  (.put k l)\n                  (.put m n)\n                  (.put o p))))\n  ([a b c d e f g h i j k l m n o p & args]\n   (persistent! (UnsharedHashMap/create\n                 (ObjArray/createv a b c d e f g h i j k l m n o p (object-array args))))))\n\n\n(defn java-hashmap\n  \"Create a java.util.HashMap.  Duplicate keys are treated as if map was created by assoc.\"\n  (^java.util.HashMap [] (java.util.HashMap.))\n  (^java.util.HashMap [data] (java-hashmap nil nil data))\n  (^java.util.HashMap [xform data] (java-hashmap xform nil data))\n  (^java.util.HashMap [xform options data]\n   (cond\n     (number? data)\n     (java.util.HashMap. (int data))\n     (and (nil? xform) (instance? Map data))\n     (if (instance? java.util.HashMap data)\n       (.clone ^java.util.HashMap data)\n       (java.util.HashMap. ^Map data))\n     :else\n     (tduce xform\n            (mut-map-rf #(java.util.HashMap. (long (get options :init-size 0))))\n            data))))\n\n\n(defn java-linked-hashmap\n  \"Linked hash maps perform identically or very nearly so to java.util.HashMaps\n  but they retain the order of insertion and modification.\"\n  (^java.util.LinkedHashMap [] (java.util.LinkedHashMap.))\n  (^java.util.LinkedHashMap [data]\n   (cond\n     (instance? java.util.LinkedHashMap data) data\n     (number? data) (java.util.LinkedHashMap. (int data))\n     (instance? java.util.LinkedHashMap data)\n     (.clone ^java.util.LinkedHashMap data)\n     (instance? Map data)\n     (java.util.LinkedHashMap. ^Map data)\n     :else\n     (tduce nil (mut-map-rf #(java.util.LinkedHashMap.)) data))))\n\n\n(defn linked-hashmap\n  \"Linked hash map using clojure's equiv pathways.  At this time the node link order reflects\n  insertion order.  Modification and access do not affect the node link order.\"\n  (^ham_fisted.LinkedHashMap [] (ham_fisted.LinkedHashMap.))\n  (^ham_fisted.LinkedHashMap [data]\n   (let [rv (ham_fisted.LinkedHashMap.)]\n     (if (instance? Map data)\n       (do (.putAll rv data) rv)\n       (tduce nil (mut-map-rf (constantly rv)) data)))))\n\n\n(defn java-concurrent-hashmap\n  \"Create a java concurrent hashmap which is still the fastest possible way to solve a\n  few concurrent problems.\"\n  (^ConcurrentHashMap [] (ConcurrentHashMap.))\n  (^ConcurrentHashMap [data]\n   (cond\n     (instance? ConcurrentHashMap data) data\n     (number? data) (ConcurrentHashMap. (int data))\n     (instance? Map data)\n     (ConcurrentHashMap. ^Map data)\n     :else\n     (tduce nil (mut-map-rf #(ConcurrentHashMap.)) data))))\n\n\n(defn mut-set\n  \"Create a mutable hashset based on the hashtable. You can create a persistent hashset via\n  the clojure `persistent!` call.\n\n  Options:\n\n  * `:hash-provider` - An implementation of `BitmapTrieCommon$HashProvider`.  Defaults to\n  the [[default-hash-provider]].\"\n  (^UnsharedHashSet [] (UnsharedHashSet. nil))\n  (^UnsharedHashSet [data] (into (UnsharedHashSet. nil) data))\n  (^UnsharedHashSet [options data] (into (UnsharedHashSet. nil) data)))\n\n\n(defn immut-set\n  \"Create an immutable hashset based on a hash table.  This object supports conversion\n  to transients via `transient`.\n\n  Options:\n\n  * `:hash-provider` - An implementation of `BitmapTrieCommon$HashProvider`.  Defaults to\n  the [[default-hash-provider]].\"\n  (^PersistentHashSet [] empty-set)\n  (^PersistentHashSet [data] (into empty-set data))\n  (^PersistentHashSet [options data] (into empty-set data)))\n\n\n(defn java-hashset\n  \"Create a java hashset which is still the fastest possible way to solve a few problems.\"\n  (^java.util.HashSet [] (java.util.HashSet.))\n  (^java.util.HashSet [data] (into (java.util.HashSet.) data)))\n\n\n(defn mut-list\n  \"Create a mutable java list that is in-place convertible to a persistent list\"\n  (^MutTreeList [] (MutTreeList.))\n  (^MutTreeList [data]\n   (cond\n     (nil? data) (MutTreeList.)\n     (instance? obj-ary-cls data)\n     (MutTreeList/create false nil ^objects data)\n     (or (instance? IReduceInit data) (instance? Collection data))\n     (doto (MutTreeList.) (.addAllReducible data))\n     (string? data)\n     (doto (MutTreeList.) (.addAll (StringCollection. data)))\n     (.isArray (.getClass ^Object data))\n     (MutTreeList/create false nil  ^objects data)\n     :else\n     (into (MutTreeList.) data))))\n\n\n(defn immut-list\n  \"Create a persistent list.  Object arrays will be treated as if this new object owns them.\"\n  (^TreeList [] empty-vec)\n  (^TreeList [data]\n   (if (instance? obj-ary-cls data)\n     (ArrayImmutList/create true nil data)\n     (persistent! (mut-list data)))))\n\n\n(defn array-list\n  \"Create an implementation of java.util.ArrayList.\"\n  (^ArrayList [data]\n   (if (instance? Collection data)\n     (doto (ArrayList.) (.addAll (->collection data)))\n     (into (ArrayList.) data)))\n  (^ArrayList [] (ArrayList.)))\n\n\n(defn assoc!\n  \"assoc! that works on transient collections, implementations of java.util.Map and\n  RandomAccess java.util.List implementations.  Be sure to keep track of return value\n  as some implementations return a different return value than the first argument.\"\n  [obj k v]\n  (cond\n    (instance? ITransientAssociative2 obj)\n    (.assoc ^ITransientAssociative2 obj k v)\n    (instance? Map obj)\n    (do (.put ^Map obj k v) obj)\n    (instance? RandomAccess obj)\n    (do (.set ^List obj (int k) v) obj)\n    :else\n    (throw (Exception. \"Item cannot be assoc!'d\"))))\n\n\n(defn conj!\n  \"conj! that works on transient collections, implementations of java.util.Set and\n  RandomAccess java.util.List implementations.  Be sure to keep track of return value\n  as some implementations return a different return value than the first argument.\"\n  [obj val]\n  (cond\n    (instance? ITransientCollection obj)\n    (.conj ^ITransientCollection obj val)\n    (instance? Collection obj)\n    (do (.add ^Collection obj val) obj)\n    (instance? Map obj)\n    (do (cond\n          (instance? Indexed val)\n          (let [^Indexed val val]\n            (.put ^Map obj (.nth val 0) (.nth val 1))\n            obj)\n          (instance? Map$Entry val)\n          (let [^Map$Entry val val]\n            (.put ^Map obj (.getKey val) (.getValue val))\n            obj)\n          :else\n          (throw (RuntimeException. (str \"Cannot conj \" val \" to a map.\")))))\n    :else\n    (throw (Exception. \"Item cannot be conj!'d\"))))\n\n\n(defn add-all!\n  \"Add all items from l2 to l1.  l1 is expected to be a java.util.List implementation.\n  Returns l1.\"\n  [l1 l2]\n  (if (instance? IMutList l1)\n    (.addAllReducible ^IMutList l1 l2)\n    (.addAll (->collection l1) l2))\n  l1)\n\n\n\n(defn clear!\n  \"Mutably clear a map, set, list or implementation of java.util.Collection.\"\n  [map-or-coll]\n  (cond\n    (instance? Map map-or-coll)\n    (.clear ^Map map-or-coll)\n    (instance? Collection map-or-coll)\n    (.clear ^Collection map-or-coll)\n    (instance? LoadingCache map-or-coll)\n    (.invalidateAll ^LoadingCache map-or-coll)\n    :else\n    (throw (Exception. (str \"Unrecognized type for clear!: \" map-or-coll))))\n  map-or-coll)\n\n\n(defn ^:no-doc map-set?\n  [item]\n  (instance? MapSetOps item))\n\n(defn ^:no-doc as-map-set\n  ^MapSetOps [item] item)\n\n(defn- ->set\n  ^Set [item]\n  (cond\n    (instance? Set item)\n    item\n    (instance? Map item)\n    (.keySet ^Map item)\n    :else\n    (immut-set item)))\n\n\n(defn keys\n  \"Return the keys of a map.  This version allows parallel reduction operations on\n  the returned sequence.\"\n  [m]\n  (map key m))\n\n\n(defn vals\n  \"Return the values of a map.  This version allows parallel reduction operations on\n  the returned sequence.  Returned sequence is in same order as `(keys m)`.\"\n  [m]\n  (map val m))\n\n(defmacro make-map-entry\n  \"Create a dynamic implementation of clojure's IMapEntry class.\"\n  [k-code v-code]\n  `(reify IAMapEntry\n     (getKey [this#] ~k-code)\n     (getValue [this#] ~v-code)))\n\n\n(defn map-union\n  \"Take the union of two maps returning a new map.  bfn is a function that takes 2 arguments,\n  map1-val and map2-val and returns a new value.  Has fallback if map1 and map2 aren't backed\n  by bitmap tries.\n\n   * `bfn` - A function taking two arguments and returning one.  `+` is a fine choice.\n   * `map1` - the lhs of the union.\n   * `map2` - the rhs of the union.\n\n  Returns a persistent map if input is a persistent map else if map1 is a mutable map\n  map1 is returned with overlapping entries merged.  In this way you can pass in a\n  normal java hashmap, a linked java hashmap, or a persistent map and get back a result that\n  matches the input.\n\n  If map1 and map2 are the same returns map1.\"\n  [bfn map1 map2]\n  (cond\n    (nil? map1) map2\n    (nil? map2) map1\n    (identical? map1 map2) map1\n    :else\n    (let [bfn (->bi-function bfn)]\n      (if (map-set? map1)\n        (.union (as-map-set map1) map2 bfn)\n        (let [map1 (if (mutable-map? map1)\n                     map1\n                     (mut-map map1))]\n          (reduce (fn [acc kv]\n                    (.merge ^Map map1 (key kv) (val kv) bfn))\n                  nil\n                  map2)\n          map1)))))\n\n\n(defn map-union-java-hashmap\n  \"Take the union of two maps returning a new map.  See documentation for [map-union].\n  Returns a java.util.HashMap.\"\n  ^java.util.HashMap [bfn ^Map lhs ^Map rhs]\n  (map-union bfn (java-hashmap lhs) rhs))\n\n(def ^:no-doc rhs-wins (hamf-fn/bi-function l r r))\n\n\n(defn ^:no-doc map-set-union-fallback\n  [m m2]\n  (-> (reduce (fn [^ITransientMap l e]\n                (.conj l e))\n              (mut-hashtable-map m)\n              m2)\n      (persistent!)))\n\n\n(defn ^:no-doc set-union-fallback\n  [m m2]\n  (-> (reduce (fn [^UnsharedHashSet l e]\n                (.conj l e))\n              (mut-set m)\n              m2)\n      (persistent!)))\n\n\n(defn mutable-map?\n  [m]\n  (or (instance? MutableMap m)\n      (and (instance? Map m)\n           (not (instance? IPersistentMap m))\n           (not (instance? ITransientMap m)))))\n\n\n(defn union\n  \"Union of two sets or two maps.  When two maps are provided the right hand side\n  wins in the case of an intersection - same as merge.\n\n  Result is either a set or a map, depending on if s1 is a set or map.\"\n  [s1 s2]\n  (cond\n    (nil? s1) s2\n    (nil? s2) s1\n    (identical? s1 s2) s1\n    (and (instance? Map s1) (instance? Map s2))\n    (cond\n      (mutable-map? s1)\n      (do (.putAll ^Map s1 s2) s1)\n      (map-set? s1)\n      (.union (as-map-set s1) ^Map s2 rhs-wins)\n      :else\n      (persistent!\n       (reduce-kv (fn [acc k v]\n                    (assoc! acc k v))\n                  (transient s1)\n                  s2)))\n    (instance? SetOps s1)\n    (.union ^SetOps s1 s2)\n    :else\n    (set-union-fallback s1 s2)))\n\n\n(defn union-reduce-maps\n  \"Do an efficient union reduction across many maps using bfn to update values.\n  If the first map is mutable the union is done mutably into the first map and it is\n  returned.\"\n  ([bfn maps]\n   (let [bfn (->bi-function bfn)]\n     (-> (reduce #(map-union bfn %1 %2) maps)\n         (persistent!)))))\n\n\n(defn ^:no-doc union-reduce-java-hashmap\n  \"Do an efficient union of many maps into a single java.util.HashMap.\"\n  (^java.util.HashMap [bfn maps options]\n   (let [maps (->reducible maps)]\n     (if (nil? maps)\n       nil\n       (let [bfn (->bi-function bfn)]\n         (reduce (fn [acc v]\n                   (map-union bfn acc v))\n                 (java-hashmap (first maps))\n                 (rest maps))))))\n  (^java.util.HashMap [bfn maps]\n   (union-reduce-java-hashmap bfn maps nil)))\n\n\n(defn difference\n  \"Take the difference of two maps (or sets) returning a new map.  Return value is a map1\n  (or set1) without the keys present in map2.\"\n  [map1 map2]\n  (cond\n    (or (nil? map1) (nil? map2))\n    map1\n    (map-set? map1)\n    (if (instance? Map map2)\n      (.difference (as-map-set map1) ^Map map2)\n      (.difference (as-map-set map1) (->set map2)))\n    (instance? SetOps map1)\n    (.difference ^SetOps map1 (->set map2))\n    (instance? Set map1)\n    (let [map2 (->set map2)]\n      (-> (reduce (fn [^Set acc v]\n                    (when-not (.contains map2 v)\n                      (.add acc v))\n                    acc)\n                  (mut-set)\n                  map1)\n          (persistent!)))\n    (instance? Map map1)\n    (let [map2 (->set map2)]\n      (-> (reduce (fn [^Map acc kv]\n                    (when-not (.contains map2 (key kv))\n                      (.put acc (key kv) (val kv)))\n                    acc)\n                  (mut-map)\n                  map1)\n          (persistent!)))))\n\n\n(defn map-intersection\n  \"Intersect the keyspace of map1 and map2 returning a new map.  Each value is the result\n  of bfn applied to the map1-value and map2-value, respectively.  See documentation for\n  [[map-union]].\n\n  Clojure's `merge` functionality can be duplicate via:\n\n  ```clojure\n  (map-intersection (fn [lhs rhs] rhs) map1 map2)\n  ```\"\n  [bfn map1 map2]\n  (if (or (nil? map2) (nil? map2))\n    empty-map\n    (let [bfn (->bi-function bfn)]\n      (if (map-set? map1)\n        (if (instance? Map map2)\n          (.intersection (as-map-set map1) ^Map map2 bfn)\n          (.intersection (as-map-set map1) (->set map2)))\n        (let [retval (mut-map)]\n          (.forEach ^Map map1 (reify BiConsumer\n                                (accept [this k v]\n                                  (let [vv (.getOrDefault ^Map map2 k ::failure)]\n                                    (when-not (identical? vv ::failure)\n                                      (.put ^Map retval k (.apply bfn v vv)))))))\n          (persistent! retval))))))\n\n\n(defn intersection\n  \"Intersect the keyspace of set1 and set2 returning a new set.  Also works if s1 is a\n  map and s2 is a set - the map is trimmed to the intersecting keyspace of s1 and s2.\"\n  [s1 s2]\n  (cond\n    (or (nil? s1) (nil? s2)) empty-set\n    (instance? SetOps s1)\n    (.intersection ^SetOps s1 (if (instance? Map s2)\n                                (.keySet ^Map s2)\n                                (->set s2)))\n    (instance? Map s1)\n    (map-intersection rhs-wins s1 s2)\n    :else\n    (let [retval (mut-set)\n          [s1 s2] (if (< (count s1) (count s2))\n                    [s1 s2]\n                    [s2 s1])\n          s2 (->set s2)]\n      (-> (reduce (fn [rv v]\n                    (when (.contains s2 v)\n                      (.add ^Set rv v))\n                    rv)\n                  (mut-set)\n                  s1)\n          (persistent!)))))\n\n\n(defn update-values\n  \"Immutably (or mutably) update all values in the map returning a new map.\n  bfn takes 2 arguments, k,v and returns a new v. Returning nil removes the key from the map.\n  When passed a vector the keys are indexes and no nil-removal is done.\"\n  [map bfn]\n  (let [bfn (->bi-function bfn)]\n    (cond\n      (instance? UpdateValues map)\n      (.updateValues ^UpdateValues map bfn)\n      (or (instance? ITransientMap map) (instance? IPersistentMap map))\n      (-> (reduce (fn [^Map acc kv]\n                    (let [v (.apply bfn (key kv) (val kv))]\n                      (when-not (nil? v)\n                        (.put acc (key kv) v)))\n                    acc)\n                  (mut-map)\n                  map)\n          (persistent!))\n      (instance? Map map)\n      (let [iter (.iterator (.entrySet ^Map map))]\n        (loop [continue? (.hasNext iter)]\n          (if continue?\n            (let [kv (.next iter)]\n              (let [v (.apply bfn (key kv) (val kv))]\n                (if-not (nil? v)\n                  (.setValue ^Map$Entry kv v)\n                  (.remove iter)))\n              (recur (.hasNext iter)))\n            map)))\n      (instance? RandomAccess map)\n      (mut-list (lznc/map-indexed #(.apply bfn %1 %2) map))\n      :else\n      (map-indexed #(.apply bfn %1 %2) map))))\n\n\n(defn update-vals\n  [data f]\n  (update-values data (bi-function k v (f v))))\n\n\n(defn mapmap\n  \"Clojure's missing piece. Map over the data in src-map, which must be a map or\n  sequence of pairs, using map-fn. map-fn must return either a new key-value\n  pair or nil. Then, remove nil pairs, and return a new map. If map-fn returns\n  more than one pair with the same key later pair will overwrite the earlier\n  pair.\n\n  Logically the same as:\n\n  ```clojure\n  (into {} (comp (map map-fn) (remove nil?)) src-map)\n  ```\"\n  [map-fn src-map]\n  (-> (reduce (fn [^Map m entry]\n                (let [^Indexed result (map-fn entry)]\n                  (when result\n                    (.put m (.nth result 0) (.nth result 1)))\n                  m))\n              (mut-map nil {:init-size (or (constant-count src-map) 16)} nil)\n              src-map)\n      (persistent!)))\n\n\n(defn in-fork-join-task?\n  \"True if you are currently running in a fork-join task\"\n  []\n  (ForkJoinTask/inForkJoinPool))\n\n\n(def ^:private default-pgroup-opts (options->parallel-options {:ordered? true}))\n\n\n(defn pgroups\n  \"Run y index groups across n-elems.   Y is common pool parallelism.\n\n  body-fn gets passed two longs, startidx and endidx.\n\n  Returns a sequence of the results of body-fn applied to each group of indexes.\n\n  Before using this primitive please see if [[ham-fisted.reduce/preduce]] will work.\n\n  You *must* wrap this in something that realizes the results if you need the parallelization\n  to finish by a particular point in the program - `(dorun (hamf/pgroups ...))`.\n\n  Options:\n\n  * `:pgroup-min` - when provided n-elems must be more than this value for the computation\n    to be parallelized.\n  * `:batch-size` - max batch size.  Defaults to 64000.\"\n  ([n-elems body-fn options]\n   (impl/pgroups n-elems body-fn (options->parallel-options (assoc options :ordered? true))))\n  ([n-elems body-fn]\n   (impl/pgroups n-elems body-fn default-pgroup-opts)))\n\n\n(def ^:private default-upgroup-opts (options->parallel-options {:ordered? false}))\n\n\n(defn upgroups\n  \"Run y index groups across n-elems.   Y is common pool parallelism.\n\n  body-fn gets passed two longs, startidx and endidx.\n\n  Returns a sequence of the results of body-fn applied to each group of indexes.\n\n  Before using this primitive please see if [[ham-fisted.reduce/preduce]] will work.\n\n  You *must* wrap this in something that realizes the results if you need the parallelization\n  to finish by a particular point in the program - `(dorun (hamf/upgroups ...))`.\n\n  Options:\n\n  * `:pgroup-min` - when provided n-elems must be more than this value for the computation\n    to be parallelized.\n  * `:batch-size` - max batch size.  Defaults to 64000.\"\n  ([n-elems body-fn options]\n   (impl/pgroups n-elems body-fn (options->parallel-options (assoc options :ordered? false))))\n  ([n-elems body-fn]\n   (impl/pgroups n-elems body-fn default-upgroup-opts)))\n\n\n(defn pmap\n  \"pmap using the commonPool.  This is useful for interacting with other primitives, namely\n  [[pgroups]] which are also based on this pool.  This is a change from Clojure's base\n  pmap in that it uses the ForkJoinPool/commonPool for parallelism as opposed to the\n  agent pool - this makes it compose with pgroups and dtype-next's parallelism system.\n\n    Before using this primitive please see if [[ham-fisted.reduce/preduce]] will work.\n\n  Is guaranteed to *not* trigger the need for `shutdown-agents`.\"\n  [map-fn & sequences]\n  (impl/pmap (ParallelOptions. 0 64000 true) map-fn sequences))\n\n\n(defn upmap\n  \"Unordered pmap using the commonPool.  This is useful for interacting with other\n  primitives, namely [[pgroups]] which are also based on this pool.\n\n  Before using this primitive please see if [[ham-fisted.reduce/preduce]] will work.\n\n  Like pmap this uses the commonPool so it composes with this api's pmap, pgroups, and\n  dtype-next's parallelism primitives *but* it does not impose an ordering constraint on the\n  results and thus may be significantly faster in some cases.\"\n  [map-fn & sequences]\n  (impl/pmap (ParallelOptions. 0 64000 false) map-fn sequences))\n\n\n(defn pmap-opts\n  \"[[pmap]] but takes an extra option map as the *first* argument.  This is useful if you,\n   for instance, want to control exactly the parallel options arguments such as\n  `:n-lookahead`.  See docs for [[ham-fisted.reduce/options->parallel-options]].\"\n  [opts map-fn & sequences]\n  (impl/pmap (hamf-rf/options->parallel-options opts) map-fn sequences))\n\n\n(defn pmap-io\n  \"pmap for io bound tasks where you want to specify how far ahead\n  to run - uses the clojure.lang.Agent/soloExecutor for execution of presumably\n  io-bound operations.\"\n  [n-lookahead map-fn & sequences]\n  (impl/pmap (hamf-rf/options->parallel-options {:pool clojure.lang.Agent/soloExecutor\n                                                 :n-lookahead n-lookahead}) map-fn sequences))\n\n\n(defn persistent!\n  \"If object is an ITransientCollection, call clojure.core/persistent!.  Else return\n  collection.\"\n  [v]\n  (if (instance? ITransientCollection v)\n    (clojure.core/persistent! v)\n    v))\n\n\n(defn transient\n  [v]\n  (if (instance? IEditableCollection v)\n    (clojure.core/transient v)\n    v))\n\n\n(defn mut-map-union!\n  \"Very fast union that may simply update lhs and return it.  Both lhs and rhs *must* be\n  mutable maps.  See docs for [[map-union]].\"\n  [merge-bifn ^Map l ^Map r]\n  (cond\n    (identical? l r) l\n    (map-set? l) (.union ^MapSetOps l r (->bi-function merge-bifn))\n    :else\n    (let [merge-bifn (->bi-function merge-bifn)]\n      (reduce (fn [acc kv]\n                (.merge ^Map acc (key kv) (val kv) merge-bifn)\n                acc)\n              l r))))\n\n(defn freq-reducer\n  \"Return a hamf parallel reducer that performs a frequencies operation.\"\n  ([options]\n   (let [map-fn (get options :map-fn mut-map)\n         cfn (function _v (Consumers$IncConsumer.))\n         sk? (get options :skip-finalize?)\n         fin-bfn (when-not sk? (bi-function k v (deref v)))]\n     (reify\n       protocols/Reducer\n       (->init-val-fn [this] map-fn)\n       (->rfn [this] (fn [acc v]\n                       (.inc ^Consumers$IncConsumer (.computeIfAbsent ^Map acc v cfn))\n                       acc))\n       protocols/ParallelReducer\n       (->merge-fn [this] #(map-union hamf-rf/reducible-merge %1 %2))\n       protocols/Finalize\n       (finalize [this v]\n         (if sk?\n           v\n           (update-values v fin-bfn))))))\n  ([] (freq-reducer nil)))\n\n(def ^:private nil-freq-reducer (freq-reducer nil))\n(def ^:private freq-parallel-opts (options->parallel-options {:min-n 1000\n                                                              :ordered? true}))\n\n(defn frequencies\n  \"Faster implementation of clojure.core/frequencies.\"\n  ([coll] (frequencies nil coll))\n  ([options coll]\n   (preduce-reducer (if options (freq-reducer options) nil-freq-reducer)\n                    (if options options freq-parallel-opts)\n                    coll)))\n\n\n(defn ^:no-doc inc-consumer\n  \"Return a consumer which increments a long counter.  Consumer ignores\n  its input.  Deref the consumer to get the value of the counter.\"\n  ^Consumer [] #(Consumers$IncConsumer.))\n\n\n(def ^{:doc \"A hamf reducer that works with inc-consumers\"} inc-consumer-reducer\n  (reify\n    protocols/Finalize\n    (finalize [this v] (deref v))\n    protocols/Reducer\n    (->init-val-fn [this] #(Consumers$IncConsumer.))\n    (->rfn [this] hamf-rf/consumer-accumulator)\n    protocols/ParallelReducer\n    (->merge-fn [this] hamf-rf/reducible-merge)))\n\n\n(defn merge\n  \"Merge 2 maps with the rhs values winning any intersecting keys.  Uses map-union\n  with `BitmapTrieCommon/rhsWins`.\n\n  Returns a new persistent map.\"\n  ([] nil)\n  ([m1] m1)\n  ([m1 m2] (union m1 m2))\n  ([m1 m2 & args]\n   ;;union on mutable maps can just be putAll.\n   (reduce #(union %1 %2)\n           (union m1 m2)\n           args)))\n\n\n(defn merge-with\n  \"Merge (union) any number of maps using `f` as the merge operator.  `f` gets passed two\n  arguments, lhs-val and rhs-val and must return a new value.\n\n  Returns a new persistent map.\"\n  ([f] nil)\n  ([f m1] m1)\n  ([f m1 m2] (map-union f m1 m2))\n  ([f m1 m2 & args]\n   (union-reduce-maps f (apply-concat [[(map-union f m1 m2)] args]))))\n\n\n(defn memoize\n  \"Efficient thread-safe version of clojure.core/memoize.\n\n  Also see [[clear-memoized-fn!]] [[evict-memoized-call]] and [[memoize-cache-as-map]] to\n  mutably clear the backing store, manually evict a value, and get a java.util.Map view of\n  the cache backing store.\n\n\n```clojure\nham-fisted.api> (def m (memoize (fn [& args] (println \\\"fn called - \\\" args) args)\n                                {:write-ttl-ms 1000 :eviction-fn (fn [args rv cause]\n                                                                   (println \\\"evicted - \\\" args rv cause))}))\n#'ham-fisted.api/m\nham-fisted.api> (m 3)\nfn called -  (3)\n(3)\nham-fisted.api> (m 4)\nfn called -  (4)\n(4)evicted -  [3] (3) :expired\nham-fisted.api> (dotimes [idx 4] (do (m 3) (evict-memoized-call m [3])))\nfn called -  (3)\nfn called -  (3)\nfn called -  (3)\nfn called -  (3)\nnil\nham-fisted.api> (dotimes [idx 4] (do (m 3) #_(evict-memoized-call m [3])))\nfn called -  (3)\nnil\n```\n\n  Options:\n\n  * `:write-ttl-ms` - Time that values should remain in the cache after write in milliseconds.\n  * `:access-ttl-ms` - Time that values should remain in the cache after access in milliseconds.\n  * `:soft-values?` - When true, the cache will store [SoftReferences](https://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html) to the data.\n  * `:weak-values?` - When true, the cache will store [WeakReferences](https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html) to the data.\n  * `:max-size` - When set, the cache will behave like an LRU cache.\n  * `:record-stats?` - When true, the LoadingCache will record access statistics.  You can\n     get those via the undocumented function memo-stats.\n  * `:eviction-fn - Function that receives 3 arguments, [args v cause], when a value is\n     evicted.  Causes the keywords `:collected :expired :explicit :replaced and :size`.  See\n     [caffeine documentation](https://www.javadoc.io/static/com.github.ben-manes.caffeine/caffeine/2.9.3/com/github/benmanes/caffeine/cache/RemovalCause.html) for cause definitions.\"\n  ([memo-fn] (memoize memo-fn nil))\n  ([memo-fn {:keys [write-ttl-ms\n                    access-ttl-ms\n                    soft-values?\n                    weak-values?\n                    max-size\n                    record-stats?\n                    eviction-fn] :as options}]\n   (let [^LoadingCache cache (hamf-caffeine/cache\n                              (assoc options :load-fn\n                                     (fn [args]\n                                       (Box.\n                                        (case (count args)\n                                          0 (memo-fn)\n                                          1 (memo-fn (args 0))\n                                          2 (memo-fn (args 0) (args 1))\n                                          3 (memo-fn (args 0) (args 1) (args 2))\n                                          (.applyTo ^IFn memo-fn (seq args)))))))]\n     (-> (fn\n           ([] (.val ^Box (.get cache [])))\n           ([a] (.val ^Box (.get cache [a])))\n           ([a b] (.val ^Box (.get cache [a b])))\n           ([a b c] (.val ^Box (.get cache [a b c])))\n           ([a b c & args] (let [^IMutList obj-ary (mut-list)]\n                             (.add obj-ary a)\n                             (.add obj-ary b)\n                             (.add obj-ary c)\n                             (.addAllReducible obj-ary args)\n                             (.val ^Box (.get cache (persistent! obj-ary))))))\n         (with-meta {:cache cache})))))\n\n\n(defn clear-memoized-fn!\n  \"Clear a memoized function backing store.\"\n  [memoized-fn]\n  (if-let [map (get (meta memoized-fn) :cache)]\n    (hamf-caffeine/invalidate-all! map)\n    (throw (Exception. (str \"Arg is not a memoized fn - \" memoized-fn))))\n  memoized-fn)\n\n\n(defn memoize-cache-as-map\n  \"Return the memoize backing store as an implementation of java.util.Map.\"\n  ^Map [memoized-fn]\n  (when-let [^Cache cache (get (meta memoized-fn) :cache)]\n    (.asMap cache)))\n\n\n(defn evict-memoized-call\n  [memo-fn fn-args]\n  (when-let [cache (memoize-cache-as-map memo-fn)]\n    (hamf-caffeine/invalidate! cache (vec fn-args))))\n\n\n(defn ^:no-doc memo-stats\n  \"Return the statistics from a google guava cache.  In order for a memoized function\n  to produce these the :record-stats? option must be true.\"\n  [memoize-fn]\n  (when-let [cache (:cache (meta memoize-fn))]\n    (when (instance? Cache cache)\n      (hamf-caffeine/keyword-stats cache))))\n\n\n\n(defn subvec\n  \"More general version of subvec.  Works for any java list implementation\n  including persistent vectors and any array.\"\n  ([m sidx eidx]\n   (let [^List m (if (instance? List m)\n                   m\n                   (->random-access m))]\n     (.subList m sidx eidx)))\n  ([m sidx] (subvec m sidx (count m))))\n\n\n(defn group-by-reduce\n  \"Group by key. Apply the reduce-fn with the new value an the return of init-val-fn.\n  Merged maps due to multithreading will be merged with merge-fn in a similar way\n  of [[preduce]].\n\n  This type of reduction can be both faster and more importantly use\n  less memory than a reduction of the forms:\n\n```clojure\n  (->> group-by map into)\n  ;; or\n  (->> group-by mapmap)\n```\n\n  Options (which are passed to [[preduce]]):\n\n  * `:map-fn` Function which takes no arguments and must return an instance of\n    java.util.Map that supports `computeIfAbsent`.  Some examples:\n    - `(constantly (java.util.concurrent.ConcurrentHashMap. ...))`  Very fast update\n       especially in the case where the keyspace is large.\n    - `mut-map` - Fast merge, fast update, in-place immutable conversion via `persistent!`.\n    - `java-hashmap` - fast merge, fast update, just a simple java.util.HashMap-based reduction.\n    - `#(LinkedHashMap.)` - When used with options {:ordered? true} the result keys will be\n       in order *and* the result values will be reduced in order.\"\n  ([key-fn init-val-fn rfn merge-fn options coll]\n   (let [has-map-fn? (get :map-fn options)\n         map-fn (get options :map-fn mut-map)\n         merge-bifn (->bi-function merge-fn)\n         rfn (cond\n               (or (= identity key-fn) (nil? key-fn))\n               (let [bifn (bi-function k acc (rfn (or acc (init-val-fn)) k))]\n                 (fn [^Map l v]\n                   (.compute l v bifn)\n                   l))\n               ;;These formulations can trigger more efficient primitive reductions when,\n               ;;for instance, you are reducing over a stream of integer indexes.\n               (and (instance? IFn$LO key-fn) (instance? IFn$OLO rfn))\n               (long-accumulator\n                l v\n                (.compute ^Map l (.invokePrim ^IFn$LO key-fn v)\n                          (bi-function\n                           k acc (.invokePrim ^IFn$OLO rfn (or acc (init-val-fn)) v)))\n                l)\n               (and (instance? IFn$DO key-fn) (instance? IFn$ODO rfn))\n               (double-accumulator\n                l v\n                (.compute ^Map l (.invokePrim ^IFn$DO key-fn v)\n                          (bi-function\n                           k acc (.invokePrim ^IFn$ODO rfn (or acc (init-val-fn)) v)))\n                l)\n               :else\n               (fn [^Map l v]\n                 ;;It annoys the hell out of me that I have to create a new\n                 ;;bifunction here but there is no threadsafe way to pass in the\n                 ;;new value to the reducer otherwise.\n                 (.compute l (key-fn v) (bi-function k acc (rfn (or acc (init-val-fn)) v)))\n                 l))]\n     (cond-> (preduce map-fn rfn #(mut-map-union! merge-bifn %1 %2)\n                      (merge {:min-n 1000} options)\n                      coll)\n       ;;In the case where no map-fn was passed in we return a persistent hash map.\n       (not has-map-fn?)\n       (persistent!))))\n  ([key-fn init-val-fn rfn merge-fn coll]\n   (group-by-reduce key-fn init-val-fn rfn merge-fn nil coll)))\n\n\n(defn group-by-reducer\n  \"Perform a group-by-reduce passing in a reducer.  Same options as group-by-reduce.\n\n  Options:\n\n  * `:skip-finalize?` - skip finalization step.\"\n  ([key-fn reducer coll]\n   (group-by-reducer key-fn reducer nil coll))\n  ([key-fn reducer options coll]\n   (let [finalizer (if (:skip-finalize? options)\n                     identity\n                     #(update-values % (bi-function k v (protocols/finalize reducer v))))]\n     (-> (group-by-reduce key-fn\n                          (protocols/->init-val-fn reducer)\n                          (protocols/->rfn reducer)\n                          (protocols/->merge-fn reducer)\n                          options coll)\n         (finalizer)))))\n\n\n(defn group-by-consumer\n  \"Perform a group-by-reduce passing in a reducer.  Same options as group-by-reduce -\n  This uses a slightly different pathway - computeIfAbsent - in order to preserve order.\n  In this case the return value of the reduce fn is ignored.  This allows things like\n  the linked hash map to preserve initial order of keys.  It map also be slightly\n  more efficient because the map itself does not need to check the return value\n  of rfn - something that the `.compute` primitive *does* need to do.\n\n  Options:\n\n  * `:skip-finalize?` - skip finalization step.\"\n  ([key-fn reducer coll]\n   (group-by-reducer key-fn reducer nil coll))\n  ([key-fn reducer options coll]\n   (let [finalizer (when-not (:skip-finalize? options)\n                     #(update-values % (bi-function k v (protocols/finalize reducer v))))\n         has-map-fn? (get :map-fn options)\n         map-fn (get options :map-fn mut-map)\n         merge-fn (protocols/->merge-fn reducer)\n         merge-bifn (->bi-function merge-fn)\n         init-fn (protocols/->init-val-fn reducer)\n         afn (function k (init-fn))\n         rfn (protocols/->rfn reducer)\n         rfn (cond\n               (or (= identity key-fn) (nil? key-fn))\n               (fn [^Map l v]\n                 (-> (.computeIfAbsent l v afn)\n                     (rfn v))\n                 l)\n               ;;These formulations can trigger more efficient primitive reductions when,\n               ;;for instance, you are reducing over a stream of integer indexes.\n               (and (instance? IFn$LO key-fn) (instance? IFn$OLO rfn))\n               (long-accumulator\n                l v\n                (let [acc (.computeIfAbsent ^Map l (.invokePrim ^IFn$LO key-fn v) afn)]\n                  (.invokePrim ^IFn$OLO rfn acc v))\n                l)\n               (and (instance? IFn$DO key-fn) (instance? IFn$ODO rfn))\n               (double-accumulator\n                l v\n                (let [acc (.computeIfAbsent ^Map l (.invokePrim ^IFn$DO key-fn v) afn)]\n                  (.invokePrim ^IFn$ODO rfn acc v))\n                l)\n               :else\n               (fn [^Map l v]\n                 (-> (.computeIfAbsent l (key-fn v) afn)\n                     (rfn v))\n                 l))]\n     (let [fin-map (preduce map-fn rfn #(mut-map-union! merge-bifn %1 %2)\n                            (merge {:min-n 1000} options)\n                            coll)]\n       (cond\n         finalizer\n         (finalizer fin-map)\n         (not has-map-fn?)\n         (persistent! fin-map)\n         :else\n         fin-map)))))\n\n\n\n(defn group-by\n  \"Group items in collection by the grouping function f.  Returns persistent map of\n  keys to persistent vectors.\n\n  Options are same as [[group-by-reduce]] but this reductions defaults to an\n  ordered reduction.\"\n  ([f options coll]\n   (group-by-reduce f object-array-list conj! add-all!\n                    (merge {:ordered? true :min-n 1000} options) coll))\n  ([f coll]\n   (group-by f nil coll)))\n\n\n(defn vec\n  \"Produce a persistent vector.  Optimized pathways exist for object arrays and\n  java List implementations.\"\n  ([data]\n   (if (vector? data)\n     (if (instance? IObj data)\n       (with-meta data nil)\n       data)\n     (immut-list data)))\n  ([] (immut-list)))\n\n\n(defn vector\n  ([] empty-vec)\n  ([a] (ArrayImmutList/create true nil (ObjArray/create a)))\n  ([a b] (ArrayImmutList/create true nil (ObjArray/create a b)))\n  ([a b c] (ArrayImmutList/create true nil (ObjArray/create a b c)))\n  ([a b c d] (ArrayImmutList/create true nil (ObjArray/create a b c d)))\n  ([a b c d e] (ArrayImmutList/create true nil (ObjArray/create a b c d e)))\n  ([a b c d e f] (ArrayImmutList/create true nil (ObjArray/create a b c d e f)))\n  ([a b c d e f g] (ArrayImmutList/create true nil (ObjArray/create a b c d e f g)))\n  ([a b c d e f g h] (ArrayImmutList/create true nil (ObjArray/create a b c d e f g h)))\n  ([a b c d e f g h i] (ArrayImmutList/create true nil (ObjArray/create a b c d e f g h i)))\n  ([a b c d e f g h i j] (ArrayImmutList/create true nil (ObjArray/create a b c d e f g h i j)))\n  ([a b c d e f g h i j k] (ArrayImmutList/create true nil (ObjArray/create a b c d e f g h i j k)))\n  ([a b c d e f g h i j k & args] (ArrayImmutList/create true nil (apply obj-ary a b c d e f g h i j k args))))\n\n\n(defn splice\n  \"Splice v2 into v1 at idx.  Returns a persistent vector.\"\n  [v1 idx v2]\n  (let [retval (mut-list)\n        v1 (->collection v1)]\n    (.addAll retval (subvec v1 0 idx))\n    (.addAll retval (->collection v2))\n    (.addAll retval (subvec v1 idx))\n    (persistent! retval)))\n\n\n(defn empty?\n  [coll]\n  (if coll\n    (.isEmpty (->collection coll))\n    true))\n\n\n(defn- concat-reducible\n  (^IMutList [^IMutList retval v1 v2]\n   (let [retval (mut-list)]\n     (.addAllReducible retval (->reducible v1))\n     (.addAllReducible retval (->reducible v2))\n     retval))\n  (^IMutList [^IMutList retval v1 v2 args]\n   (when-not (nil? v1) (.addAllReducible retval (->reducible v1)))\n   (when-not (nil? v2) (.addAllReducible retval (->reducible v2)))\n   (reduce (fn [data c]\n             (when-not (nil? c) (.addAllReducible retval (->reducible c)))\n             retval)\n           retval\n           args)))\n\n(defn apply-concatv\n  [data]\n  (reduce (fn [^IMutList v data]\n            (when data\n              (.addAllReducible v data))\n            v)\n          (mut-list)\n          data))\n\n(defn concatv\n  \"non-lazily concat a set of items returning a persistent vector.  \"\n  ([] empty-vec)\n  ([v1] (vec v1))\n  ([v1 v2]\n   (cond\n     (nil? v1) (vec v2)\n     (nil? v2) (vec v1)\n     :else\n     (-> (concat-reducible (mut-list) v1 v2)\n         (persistent!))))\n  ([v1 v2 & args]\n   (-> (concat-reducible (mut-list) v1 v2 args)\n       (persistent!))))\n\n\n(defn concata\n  \"non-lazily concat a set of items returning an object array.  This always returns an\n  object array an may return an empty array whereas concat may return nil.\"\n  (^objects [] (object-array nil))\n  (^objects [v1] (object-array v1))\n  (^objects [v1 v2]\n   (cond\n     (nil? v1) (object-array v2)\n     (nil? v2) (object-array v1)\n     :else\n     (-> (concat-reducible (ArrayLists$ObjectArrayList.) v1 v2)\n         (.toArray))))\n  (^objects [v1 v2 & args]\n   (-> (concat-reducible (ArrayLists$ObjectArrayList.) v1 v2 args)\n       (.toArray))))\n\n\n(defn apply-concat\n  \"Faster lazy noncaching version of (apply concat)\"\n  [args]\n  (if args\n    (lznc/apply-concat args)\n    '()))\n\n\n(defn object-array\n  \"Faster version of object-array for java collections and strings.\"\n  ^objects [item] (lznc/object-array item))\n\n\n(defn into-array\n  \"Faster version of clojure.core/into-array.\"\n  ([aseq] (lznc/into-array aseq))\n  ([ary-type aseq] (lznc/into-array ary-type aseq))\n  ([ary-type mapfn aseq] (lznc/into-array ary-type mapfn aseq)))\n\n\n(defn- ->comparator\n  ^java.util.Comparator [comp]\n  (or comp compare))\n\n\n(defn sorta\n  \"Sort returning an object array.\"\n  (^objects [coll] (sorta hamf-fn/comp-nan-last coll))\n  (^objects [comp coll]\n   (let [coll (->reducible coll)]\n     (if (instance? IMutList coll)\n       (-> (.immutSort ^IMutList coll comp)\n           (.toArray))\n       (let [a (object-array coll)]\n         (if (< (alength a) 1000)\n           (if comp\n             (Arrays/sort a (->comparator comp))\n             (Arrays/sort a))\n           (Arrays/parallelSort a 0 (alength a) (if comp (->comparator comp) compare)))\n         a)))))\n\n\n(defn sort\n  \"Exact replica of clojure.core/sort but instead of wrapping the final object array in a seq\n  which loses the fact the result is countable and random access.  Faster implementations\n  are provided when the input is an integer, long, or double array.\n\n  The default comparison is nan-last meaning null-last if the input is an undefined\n  container and nan-last if the input is a double or float specific container.\"\n  ([coll] (sort hamf-fn/comp-nan-last coll))\n  ([comp coll]\n   (let [coll (->collection coll)]\n     (if (instance? ImmutSort coll)\n       (if (nil? comp)\n         (.immutSort ^ImmutSort coll)\n         (.immutSort ^ImmutSort coll (->comparator comp)))\n       (let [a (sorta comp coll)]\n         (ArrayLists/toList a 0 (alength a) ^IPersistentMap (meta coll)))))))\n\n\n(defn sort-by\n  \"Sort a collection by keyfn.  Typehinting the return value of keyfn will somewhat increase\n  the speed of the sort :-).\"\n  ([keyfn coll]\n   (sort-by keyfn nil coll))\n  ([keyfn comp coll]\n   (let [coll (->random-access coll)\n         data (map keyfn coll)\n         ;;Arraylists are faster to create because they do not have to be sized exactly\n         ;;to the collection.  They have very fast addAllReducible pathways that specialize\n         ;;for constant sized containers.\n         data (case (lznc/type-single-arg-ifn keyfn)\n                :float64\n                (double-array-list data)\n                :int64\n                (long-array-list data)\n                (object-array-list data))\n         indexes (argsort comp data)]\n     (reindex coll indexes))))\n\n\n(defn shuffle\n  \"shuffle values returning random access container.  If you are calling this repeatedly\n   on the same collection you should call [[->random-access]] on the collection *before*\n   you start as shuffle internally only works on random access collections.\n\n  Options:\n\n  * `:seed` - If instance of java.util.Random, use this.  If integer, use as seed.\n  If not provided a new instance of java.util.Random is created.\"\n  (^List [coll] (lznc/shuffle coll nil))\n  (^List [coll opts] (lznc/shuffle coll opts)))\n\n\n(defn binary-search\n  \"Binary search.  Coll must be a sorted random access container.\n  comp must be an implementation of java.lang.Comparator.  If you know your container's\n  type, such as a double array, then comp should be a fastutil DoubleComparator.\n\n\n  The most efficient method will be to convert coll to random access using\n  ->random-access, so for a pure double array it is slightly better to call\n  ->random-access outside this function before the function call.\n\n  This search defaults to the slower java.util.Collections search using\n  clojure's built in `compare` - reason being that that allows you to search\n  for a double number in a vector of only longs.  If you want an accelerated search\n  you can explicitly pass in a nil comparator *but* you need to make sure that\n  you are searching for the rough datatype in the data - e.g. long in a byte array\n  or a double in a double for float array.  Searching for doubles in integer arrays\n  with an accelerated search will probably result in confusing results.\n\n```clojure\nham-fisted.api> (def data (->random-access (double-array (range 10))))\n#'ham-fisted.api/data\nham-fisted.api> (binary-search data 0)\n0\nham-fisted.api> (binary-search data -1)\n0\nham-fisted.api> (binary-search data 1)\n1\nham-fisted.api> (binary-search data 1.1)\n2\nham-fisted.api> (binary-search data 10)\n10\nham-fisted.api> (binary-search data 11)\n10\nham-fisted.api> ;;be wary of datatype conversions in typed containers\nham-fisted.api> (def data (->random-access (int-array (range 10))))\n#'ham-fisted.api/data\nham-fisted.api> (binary-search data 1)\n1\nham-fisted.api> (binary-search data 1.1)\n  2\nham-fisted.api> ;;accelerated search - flattens input to container datatype\nham-fisted.api> (binary-search data 1.1 nil)\n1\n```\"\n  (^long [coll v] (binary-search coll v compare))\n  (^long [coll v comp]\n   (let [comp (when comp (->comparator comp))\n         coll (->random-access coll)]\n     (if (instance? IMutList coll)\n       (if comp\n         (.binarySearch ^IMutList coll v comp)\n         (.binarySearch ^IMutList coll v))\n       (let [rv (if comp\n                  (Collections/binarySearch coll v comp)\n                  ;;This corrects for things like searching 50.1 in a list that has longs\n                  (Collections/binarySearch coll v compare))]\n         (if (< rv 0)\n           (- -1 rv)\n           rv))))))\n\n\n(defn iarange\n  \"Return an integer array holding the values of the range.  Use `->collection` to get a\n  list implementation wrapping for generic access.\"\n  (^ints [end]\n   (iarange 0 end 1))\n  (^ints [start end]\n   (iarange start end 1))\n  (^ints [start end step]\n   (ArrayLists/iarange start end step)))\n\n(defn larange\n  \"Return a long array holding values of the range.  Use `->collection` get a list\n  implementation for generic access.\"\n  (^longs [end]\n   (larange 0 end 1))\n  (^longs [start end]\n   (larange start end 1))\n  (^longs [start end step]\n   (ArrayLists/larange start end step)))\n\n(defn darange\n  \"Return a double array holding the values of the range.  Use `wrap-array` to get\n  an implementation of java.util.List that supports the normal Clojure interfaces.\"\n  (^doubles [end]\n   (darange 0 end 1))\n  (^doubles [start end]\n   (darange start end 1))\n  (^doubles [start end step]\n   (ArrayLists/darange start end step)))\n\n\n(defn- floating?\n  [item]\n  (or (double? item) (float? item)))\n\n\n(defn range\n  \"When given arguments returns a range that implements random access java list\n  interfaces so nth, reverse and friends are efficient.\"\n  ([] (clojure.core/range))\n  ([end] (range 0 end 1))\n  ([start end] (range start end 1))\n  ([start end step]\n   (if (and (integer? start) (integer? end) (integer? step))\n     (Ranges$LongRange. start end step nil)\n     (Ranges$DoubleRange. start end step nil))))\n\n\n(defn argsort\n  \"Sort a collection of data returning an array of indexes.  The collection must be\n  random access and the return value is an integer array of indexes which will read the\n  input data in sorted order.  Faster implementations are provided when the collection\n  is an integer, long, or double array.  See also [[reindex]].\"\n  ([comp coll]\n   (let [^List coll (if (instance? RandomAccess coll)\n                      coll\n                      (let [coll (->collection coll)]\n                        (if (instance? RandomAccess coll)\n                          coll\n                          (object-array-list coll))))]\n     (->\n      (if (instance? IMutList coll)\n        (.sortIndirect ^IMutList coll (when comp (->comparator comp)))\n        (let [idata (iarange (.size coll))\n              idx-comp (ArrayLists/intIndexComparator coll comp)]\n          (IntArrays/parallelQuickSort idata ^IntComparator idx-comp)\n          idata))\n      (->collection))))\n  ([coll]\n   (argsort hamf-fn/comp-nan-last coll)))\n\n\n(defn ^:no-doc do-make-array\n  [clj-ary-fn ary-ra-fn ary-list-fn data]\n  (cond\n    (number? data)\n    (clj-ary-fn data)\n    :else\n    (let [data (->reducible data)]\n      (if-let [c (constant-count data)]\n        (let [retval (clj-ary-fn c)]\n          (.fillRangeReducible ^IMutList (ary-ra-fn retval) 0 data)\n          retval)\n        (.toNativeArray ^IMutList (ary-list-fn data))))))\n\n\n(defn byte-array-list\n  (^IMutList [] (ByteArrayList. (clojure.core/byte-array 4) 0 nil))\n  (^IMutList [data]\n   (if (number? data)\n     (ByteArrayList. (clojure.core/byte-array data) 0 nil)\n     (let [^IMutList retval (if (instance? RandomAccess data)\n                              (byte-array-list (.size ^List data))\n                              (byte-array-list))]\n       (.addAllReducible retval data)\n       retval))))\n\n\n(defn byte-array\n  (^bytes [] (byte-array 0))\n  (^bytes [data]\n   (if (instance? IMutList data)\n     (let [^IMutList data data\n           sz (.size data)\n           rv (clojure.core/byte-array sz)]\n       (dotimes [idx sz]\n         (ArrayHelpers/aset rv idx (unchecked-byte (.getLong data idx))))\n       rv)\n     (do-make-array clojure.core/byte-array\n                    #(ArrayLists/toList ^bytes %)\n                    byte-array-list data))))\n\n\n(defn short-array-list\n  (^IMutList [] (ShortArrayList. (clojure.core/short-array 4) 0 nil))\n  (^IMutList [data]\n   (if (number? data)\n     (ShortArrayList. (clojure.core/short-array data) 0 nil)\n     (let [^IMutList retval (if (instance? RandomAccess data)\n                              (short-array-list (.size ^List data))\n                              (short-array-list))]\n       (.addAllReducible retval data)\n       retval))))\n\n\n(defn short-array\n  (^shorts [] (short-array 0))\n  (^shorts [data]\n   (if (instance? IMutList data)\n     (let [^IMutList data data\n           sz (.size data)\n           rv (clojure.core/short-array sz)]\n       (dotimes [idx sz]\n         (ArrayHelpers/aset rv idx (unchecked-short (.getLong data idx))))\n       rv)\n     (do-make-array clojure.core/short-array\n                    #(ArrayLists/toList ^shorts %)\n                    short-array-list data))))\n\n\n(defn char-array-list\n  (^IMutList [] (CharArrayList. (clojure.core/char-array 4) 0 nil))\n  (^IMutList [data]\n   (if (number? data)\n     (CharArrayList. (clojure.core/char-array data) 0 nil)\n     (let [^IMutList retval (if (instance? RandomAccess data)\n                              (char-array-list (.size ^List data))\n                              (char-array-list))]\n       (.addAllReducible retval data)\n       retval))))\n\n\n(defn char-array\n  (^chars [] (char-array 0))\n  (^chars [data] (do-make-array clojure.core/char-array\n                                #(ArrayLists/toList ^chars %)\n                                char-array-list data)))\n\n\n(defn boolean-array-list\n  (^IMutList [] (BooleanArrayList. (clojure.core/boolean-array 4) 0 nil))\n  (^IMutList [data]\n   (if (number? data)\n     (BooleanArrayList. (clojure.core/boolean-array data) 0 nil)\n     (let [^IMutList retval (if (instance? RandomAccess data)\n                              (boolean-array-list (.size ^List data))\n                              (boolean-array-list))]\n       (.addAllReducible retval data)\n       retval))))\n\n\n(defn boolean-array\n  (^booleans [] (boolean-array 0))\n  (^booleans [data] (do-make-array clojure.core/boolean-array\n                                   #(ArrayLists/toList ^booleans %)\n                                   boolean-array-list data)))\n\n\n(defmacro ^:no-doc impl-array-macro\n  [data ctor elem-cast vecfn]\n  (cond\n    (number? data)\n    `(~ctor ~data)\n    ;;16 chosen arbitrarily\n    (and (vector? data) (< (count data) 16))\n    `(let [~'ary (~ctor (unchecked-int ~(count data)))]\n       (do\n         ~@(->> (range (count data))\n                (map (fn [^long idx]\n                       `(ArrayHelpers/aset ~'ary (unchecked-int ~idx) (~elem-cast ~(data idx))))))\n         ~'ary))\n    :else\n    `(~vecfn ~data)))\n\n\n(defn int-array-list\n  \"An array list that is as fast as java.util.ArrayList for add,get, etc but includes\n  many accelerated operations such as fill and an accelerated addAll when the src data\n  is an array list.\"\n  (^IMutList [] (ArrayLists$IntArrayList.))\n  (^IMutList [cap-or-data]\n   (if (number? cap-or-data)\n     (ArrayLists$IntArrayList. (int cap-or-data))\n     (doto (ArrayLists$IntArrayList.)\n       (.addAllReducible (->reducible cap-or-data))))))\n\n\n(def ^:private int-ary-cls (Class/forName \"[I\"))\n\n\n(defn ^:no-doc int-array-v\n  ^ints [data]\n  (cond\n    (instance? int-ary-cls data)\n    data\n    (instance? IMutList data)\n    (.toIntArray ^IMutList data)\n    :else\n    (do-make-array #(ArrayLists/intArray %) #(ArrayLists/toList ^ints %)\n                   int-array-list data)))\n\n\n\n(defmacro int-array\n  ([] `(ArrayLists/intArray 0))\n  ([data]\n   `(impl-array-macro ~data ArrayLists/intArray Casts/longCast int-array-v)))\n\n\n(defn reindex\n  \"Permut coll by the given indexes.  Result is random-access and the same length as\n  the index collection.  Indexes are expected to be in the range of [0->count(coll)).\"\n  [coll indexes]\n  (lznc/reindex (->random-access coll) (int-array indexes)))\n\n\n(defmacro ivec\n  \"Create a persistent-vector-compatible list backed by an int array.\"\n  ([] `(ArrayLists/toList (int-array)))\n  ([data] `(ArrayLists/toList (int-array ~data))))\n\n\n(defn long-array-list\n  \"An array list that is as fast as java.util.ArrayList for add,get, etc but includes\n  many accelerated operations such as fill and an accelerated addAll when the src data\n  is an array list.\"\n  (^IMutList [] (ArrayLists$LongArrayList.))\n  (^IMutList [cap-or-data]\n   (if (number? cap-or-data)\n     (ArrayLists$LongArrayList. (int cap-or-data))\n     (doto (ArrayLists$LongArrayList.)\n       (.addAllReducible (->reducible cap-or-data))))))\n\n(def ^:no-doc long-array-cls (Class/forName \"[J\"))\n\n(defn ^:no-doc long-array-v\n  ^longs [data]\n  (cond\n    (instance? long-array-cls data)\n    data\n    (instance? IMutList data)\n    (.toLongArray ^IMutList data)\n    :else\n    (do-make-array #(ArrayLists/longArray %) #(ArrayLists/toList ^longs %)\n                   long-array-list data)))\n\n\n(defmacro long-array\n  ([] `(ArrayLists/longArray 0))\n  ([data]\n   `(impl-array-macro ~data ArrayLists/longArray Casts/longCast long-array-v)))\n\n\n(defmacro lvec\n  \"Create a persistent-vector-compatible list backed by a long array.\"\n  ([] `(ArrayLists/toList (long-array)))\n  ([data] `(ArrayLists/toList (long-array ~data))))\n\n\n(defn float-array-list\n  (^IMutList [] (FloatArrayList. (clojure.core/float-array 4) 0 nil))\n  (^IMutList [data]\n   (if (number? data)\n     (FloatArrayList. (clojure.core/float-array data) 0 nil)\n     (let [^IMutList retval (if (instance? RandomAccess data)\n                              (float-array-list (.size ^List data))\n                              (float-array-list))]\n       (.addAllReducible retval data)\n       retval))))\n\n(defn ^:no-doc float-array-v\n  ^floats [data]\n  (if (instance? IMutList data)\n    (.toFloatArray ^IMutList data)\n    (do-make-array #(ArrayLists/floatArray %) #(ArrayLists/toList ^floats %)\n                   float-array-list data)))\n\n\n(defmacro float-array\n  ([] `(ArrayLists/floatArray 0))\n  ([data]\n   `(impl-array-macro ~data ArrayLists/floatArray Casts/doubleCast float-array-v)))\n\n\n(defmacro fvec\n  \"Create a persistent-vector-compatible list backed by a float array.\"\n  ([] `(ArrayLists/toList (float-array)))\n  ([data] `(ArrayLists/toList (float-array ~data))))\n\n\n(defn double-array-list\n  \"An array list that is as fast as java.util.ArrayList for add,get, etc but includes\n  many accelerated operations such as fill and an accelerated addAll when the src data\n  is an array list.\"\n  (^IMutList [] (ArrayLists$DoubleArrayList.))\n  (^IMutList [cap-or-data]\n   (if (number? cap-or-data)\n     (ArrayLists$DoubleArrayList. (int cap-or-data))\n     (doto (ArrayLists$DoubleArrayList.)\n       (.addAllReducible (->reducible cap-or-data))))))\n\n\n(def dbl-ary-cls (Class/forName \"[D\"))\n\n\n(defn ^:no-doc double-array-v\n  ^doubles [data]\n  (cond\n    (instance? dbl-ary-cls data)\n    data\n    (instance? IMutList data)\n    (.toDoubleArray ^IMutList data)\n    :else\n    (do-make-array #(ArrayLists/doubleArray %) #(ArrayLists/toList ^doubles %)\n                   double-array-list data)))\n\n\n\n(defmacro double-array\n  ([] `(ArrayLists/doubleArray 0))\n  ([data]\n   `(impl-array-macro ~data ArrayLists/doubleArray Casts/doubleCast double-array-v)))\n\n\n\n(defmacro dvec\n  \"Create a persistent-vector-compatible list backed by a double array.\"\n  ([] `(ArrayLists/toList (double-array)))\n  ([data] `(ArrayLists/toList (double-array ~data))))\n\n\n\n(defn object-array-list\n  \"An array list that is as fast as java.util.ArrayList for add,get, etc but includes\n  many accelerated operations such as fill and an accelerated addAll when the src data\n  is an object array based list.\"\n  (^IMutList [] (ArrayLists$ObjectArrayList.))\n  (^IMutList [cap-or-data]\n   (if (number? cap-or-data)\n     (ArrayLists$ObjectArrayList. (int cap-or-data))\n     (doto (ArrayLists$ObjectArrayList.)\n       (.addAllReducible (->reducible cap-or-data))))))\n\n\n\n(defn ^:no-doc ovec-v\n  ^ArrayImmutList [data]\n  (if (instance? obj-ary-cls data)\n    (ArrayImmutList. ^objects data 0 (alength ^objects data) nil)\n    (into (vec) data)))\n\n\n(defmacro ovec\n  \"Return an immutable persistent vector like object backed by a single object array.\"\n  ([] `ArrayImmutList/EMPTY)\n  ([data]\n   (cond\n     (number? data)\n     `(ArrayImmutList. (ArrayLists/objectArray ~data) 0 ~data nil)\n     (vector? data)\n     `(ArrayImmutList. (obj-ary ~@data) 0 ~(count data) ~(meta data))\n     :else\n     `(ovec-v ~data))))\n\n\n(defn add-constant!\n  (^List [^List l ^long idx v]\n   (.add l (unchecked-int idx) v)\n   l)\n  (^IMutList [^IMutList l ^long idx ^long count v]\n   (.add l (unchecked-int idx) (unchecked-int count) v)\n   l))\n\n\n(defmacro dnth\n  \"nth operation returning a primitive double.  Efficient when obj is a double array.\"\n  [obj idx]\n  `(TypedNth/dnth ~obj ~idx))\n\n\n(defmacro lnth\n  \"nth operation returning a primitive long.  Efficient when obj is a long array.\"\n  [obj idx]\n  `(TypedNth/lnth ~obj ~idx))\n\n\n(defmacro fnth\n  \"nth operation returning a primitive float.  Efficient when obj is a float array.\"\n  [obj idx]\n  `(TypedNth/fnth ~obj ~idx))\n\n\n(defmacro inth\n  \"nth operation returning a primitive int.  Efficient when obj is an int array.\"\n  [obj idx]\n  `(TypedNth/inth ~obj ~idx))\n\n\n(defn mapv\n  \"Produce a persistent vector from a collection.\"\n  ([map-fn coll]\n   (if-let [c (constant-count coll)]\n     (let [c (int c)\n           rv (ArrayLists/objectArray c)]\n       (reduce (hamf-rf/indexed-accum\n                acc idx v\n                (ArrayHelpers/aset rv idx (map-fn v)))\n               nil\n               coll)\n       (ArrayImmutList. rv 0 c nil))\n     (let [rv (ArrayLists$ObjectArrayList. (ArrayLists/objectArray 8) 0 nil)\n           _ (reduce (fn [acc v] (.conj rv (map-fn v))) rv coll)]\n       (persistent! rv))))\n  ([map-fn c1 c2]\n   (ovec (map map-fn c1 c2)))\n  ([map-fn c1 c2 c3]\n   (ovec (map map-fn c1 c2 c3)))\n  ([map-fn c1 c2 c3 & args]\n   (ovec (apply map map-fn c1 c2 c3 args))))\n\n\n(defn filterv\n  \"Filter a collection into a vector.\"\n  [pred coll]\n  (ovec (filter pred coll)))\n\n\n(defn sum-fast\n  \"Fast simple double summation.  Does not do any nan checking or summation\n  compensation.\"\n  ^double [coll]\n  ;;Using raw reduce call as opposed to reduce-reducer to avoid protocol dispatch for small N\n  @(reduce double-consumer-accumulator (Sum$SimpleSum.) coll))\n\n(defn ^:no-doc apply-nan-strategy\n  [options coll]\n  (case (get options :nan-strategy :remove)\n    :remove (filter (hamf-fn/double-predicate v (not (Double/isNaN v))) coll)\n    :keep coll\n    :exception (map (hamf-fn/double-unary-operator v\n                                                   (when (Double/isNaN v)\n                                                     (throw (Exception. \"Nan detected\")))\n                                                   v)\n                    coll)))\n\n\n(defn sum-stable-nelems\n  \"Stable sum returning map of {:sum :n-elems}. See options for [[sum]].\"\n  ([coll] (sum-stable-nelems nil coll))\n  ([options coll]\n   (->> (->reducible coll)\n        (apply-nan-strategy options)\n        (preduce-reducer (Sum.) options))))\n\n\n(defn sum\n  \"Very stable high performance summation.  Uses both threading and kahans compensated\n  summation.\n\n  Options:\n\n  * `nan-strategy` - defaults to `:remove`.  Options are `:keep`, `:remove` and\n  `:exception`.\"\n  (^double [coll] (sum nil coll))\n  (^double [options coll]\n   (get (sum-stable-nelems options coll) :sum)))\n\n(defn- long-summary-sum\n  ^long [^LongSummaryStatistics lstats]\n  (.getSum lstats))\n\n(defn lsum\n  \"Simple summation that returns a long integer.\"\n  ^long [data]\n  (let [lv (long-array 1)]\n    (reduce (fn [_ ^long v] (let [_ (aset lv 0 (+ (aget lv 0) v))]) nil)\n            nil\n            data)\n    (aget lv 0)))\n\n(defn lsummary\n  \"Summary statistics {:mean :max :min :n-elems :sum} in long space\"\n  [data]\n  (let [^LongSummaryStatistics lstats (reduce long-consumer-accumulator (LongSummaryStatistics.) data)]\n    {:max (.getMax lstats)\n     :min (.getMin lstats)\n     :n-elems (.getCount lstats)\n     :mean (.getAverage lstats)\n     :sum (.getSum lstats)}))\n\n(defn mean\n  \"Return the mean of the collection.  Returns double/NaN for empty collections.\n  See options for [[sum]].\"\n  (^double [coll] (mean nil coll))\n  (^double [options coll]\n   (let [vals (sum-stable-nelems options coll)]\n     (/ (double (vals :sum))\n        (long (vals :n-elems))))))\n\n\n(defn dsummary\n  \"Summary statistics {:mean :max :min :n-elems :sum} in double space\"\n  [data]\n  (let [^DoubleSummaryStatistics lstats (reduce double-consumer-accumulator (DoubleSummaryStatistics.) data)]\n    {:max (.getMax lstats)\n     :min (.getMin lstats)\n     :n-elems (.getCount lstats)\n     :mean (.getAverage lstats)\n     :sum (.getSum lstats)}))\n\n\n(defn first\n  \"Get the first item of a collection.\"\n  [coll]\n  (if (nil? coll)\n    nil\n    (let [coll (->reducible coll)]\n      (if (instance? RandomAccess coll)\n        (when-not (.isEmpty ^List coll)\n          (.get ^List coll 0))\n        (clojure.core/first coll)))))\n\n\n(defn last\n  \"Get the last item in the collection.  Constant time for\n  random access lists.\"\n  [coll]\n  (if (nil? coll)\n    nil\n    (let [coll (->reducible coll)]\n      (cond\n        (instance? RandomAccess coll)\n        (let [^List coll coll\n              sz (.size coll)]\n          (when-not (== 0 sz)\n            (.get coll (unchecked-dec sz))))\n        (instance? Reversible coll)\n        (RT/first (.rseq ^Reversible coll))\n        :else\n        (clojure.core/last coll)))))\n\n\n(defn- key? [e] (when e (key e)))\n\n\n(deftype ^:private MaxKeyReducer [^{:unsynchronized-mutable true\n                                    :tag long} data\n                                  ^:unsynchronized-mutable value\n                                  ^IFn$OL mapper]\n  Consumer\n  (accept [this v]\n    (let [mval (.invokePrim mapper v)]\n      (when (>= mval data)\n        (set! data mval)\n        (set! value v))))\n  clojure.lang.IDeref\n  (deref [this] value)\n  Reducible\n  (reduce [this o]\n    (cond\n      (== data Long/MIN_VALUE)\n      o\n      (== (.-data ^MaxKeyReducer o) Long/MIN_VALUE)\n      this\n      :else\n      (do\n        (.accept this (deref o))\n        this))))\n\n(defn- ensure-obj->long ^IFn$OL [f] (if (instance? IFn$OL f) f (obj->long v (f v))))\n\n(defn mmax-key\n  \"Faster and nil-safe version of #(apply max-key %1 %2)\"\n  [f data]\n  (let [f (ensure-obj->long f)]\n    @(reduce hamf-rf/consumer-accumulator (MaxKeyReducer. Long/MIN_VALUE nil f) data)))\n\n(deftype ^:private MinKeyReducer [^{:unsynchronized-mutable true\n                                    :tag long} data\n                                  ^:unsynchronized-mutable value\n                                  ^IFn$OL mapper]\n  Consumer\n  (accept [this v]\n    (let [mval (.invokePrim mapper v)]\n      (when (<= mval data)\n        (set! data mval)\n        (set! value v))))\n  clojure.lang.IDeref\n  (deref [this] value)\n  Reducible\n  (reduce [this o]\n    (cond\n      (== data Long/MAX_VALUE)\n      o\n      (== (.-data ^MinKeyReducer o) Long/MAX_VALUE)\n      this\n      :else\n      (do\n        (.accept this (deref o))\n        this))))\n\n\n(defn mmin-key\n  \"Faster and nil-safe version of #(apply min-key %1 %2)\"\n  [f data]\n  (let [f (ensure-obj->long f)]\n    @(reduce hamf-rf/consumer-accumulator (MinKeyReducer. Long/MAX_VALUE nil f) data)))\n\n\n(deftype ^:private MaxIdx [^{:unsynchronized-mutable true\n                             :tag long} data\n                           ^{:unsynchronized-mutable true\n                             :tag long} idx\n                           ^{:unsynchronized-mutable true\n                             :tag long} value\n                           ^IFn$OL mapper]\n  Consumer\n  (accept [this v]\n    (let [mval (.invokePrim mapper v)]\n      (when (>= mval data)\n        (set! data mval)\n        (set! value idx))\n      (set! idx (unchecked-inc idx))))\n  clojure.lang.IDeref\n  (deref [this] value))\n\n\n(defn mmax-idx\n  \"Like [[mmin-key]] but returns the max index.  F should be a function from obj->long.\"\n  ^long [f data]\n  @(reduce hamf-rf/consumer-accumulator (MaxIdx. Long/MIN_VALUE 0 -1 (ensure-obj->long f))\n           data))\n\n\n(deftype ^:private MinIdx [^{:unsynchronized-mutable true\n                             :tag long} data\n                           ^{:unsynchronized-mutable true\n                             :tag long} idx\n                           ^{:unsynchronized-mutable true\n                             :tag long} value\n                           ^IFn$OL mapper]\n  Consumer\n  (accept [this v]\n    (let [mval (.invokePrim mapper v)]\n      (when (<= mval data)\n        (set! data mval)\n        (set! value idx))\n      (set! idx (unchecked-inc idx))))\n  clojure.lang.IDeref\n  (deref [this] value))\n\n\n(defn mmin-idx\n  \"Like [[mmin-key]] but returns the min index.  F should be a function from obj->long.\"\n  ^long [f data]\n  @(reduce hamf-rf/consumer-accumulator (MinIdx. Long/MAX_VALUE 0 -1 (ensure-obj->long f))\n           data))\n\n\n(defn intersect-sets\n  \"Given a sequence of sets, efficiently perform the intersection of them.  This algorithm is usually faster and has a more stable\n   runtime than (reduce clojure.set/intersection sets) which degrades depending on the order of the sets and the pairwise\n   intersection of the initial sets.\"\n  [sets]\n  (let [sets (vec sets)\n        ns (count sets)]\n    (case ns\n      0 #{}\n      1 (sets 0)\n      (let [min-idx (mmin-idx (fn ^long [arg] (.size ^Set arg)) sets)]\n        (-> (reduce (fn [^Set rv ^long idx]\n                      (cond\n                        (.isEmpty rv) (reduced rv)\n                        (== idx min-idx) rv\n                        :else (intersection rv (sets idx))))\n                    (transient (sets min-idx))\n                    (range ns))\n            (persistent!))))))\n\n\n\n(defn mode\n  \"Return the most common occurance in the data.\"\n  [data]\n  (->> (frequencies {:map-fn java-hashmap} data)\n       (mmax-key val)\n       (key?)))\n\n\n(defn rest\n  \"Version of rest that does uses subvec if collection is random access.  This preserves the\n  ability to reduce in parallel over the collection.\"\n  [coll]\n  (cond\n    (nil? coll) nil\n    (instance? RandomAccess coll)\n    (if (pos? (count coll))\n      (subvec coll 1)\n      [])\n    :else (clojure.core/rest coll)))\n\n\n(defn reverse\n  \"Reverse a collection or sequence.  Constant time reverse is provided\n  for any random access list.\"\n  [coll]\n  (if (instance? Comparator coll)\n    (.reversed ^Comparator coll)\n    (let [coll (->reducible coll)]\n      (cond\n        (instance? IMutList coll)\n        (.reverse ^IMutList coll)\n        (instance? RandomAccess coll)\n        (ReverseList/create coll (meta coll))\n        :else\n        (clojure.core/reverse coll)))))\n\n\n(defn take\n  \"Take the first N values from a collection.  If the input is\n  random access, the result will be random access.\"\n  ([n] (clojure.core/take n))\n  ([n coll]\n   (when coll\n     (let [coll (->reducible coll)]\n       (if (instance? RandomAccess coll)\n         (.subList ^List coll 0 (min (long n) (.size ^List coll)))\n         (clojure.core/take n coll))))))\n\n\n(defn take-last\n  \"Take the last N values of the collection.  If the input is random-access,\n  the result will be random-access.\"\n  ([n coll]\n   (when coll\n     (let [coll (->reducible coll)]\n       (if (instance? RandomAccess coll)\n         (let [ne (.size ^List coll)\n               n (long n)]\n           (.subList ^List coll (- ne n 1) ne))\n         (clojure.core/take-last n coll))))))\n\n\n(defn- priority-queue-rf\n  [^long n comp]\n  (let [comp (when comp (.reversed (->comparator comp)))]\n    (fn\n      ([] (if comp\n            (PriorityQueue. n comp)\n            (PriorityQueue. n)))\n      ([acc] (->random-access (.toArray ^Collection acc)))\n      ([acc v]\n       (let [^PriorityQueue acc acc]\n         (.offer acc v)\n         (when (> (.size acc) n) (.poll acc)))\n       acc))))\n\n\n(defn take-min\n  \"Take the min n values of a collection.  This is not an order-preserving operation.\"\n  ([n comp values]\n   (reduce-reducer (priority-queue-rf n comp) values))\n  ([n values]\n   (take-min n < values)))\n\n\n(defn drop\n  \"Drop the first N items of the collection.  If item is random access, the return\n  value is random-access.\"\n  [n coll]\n  (when coll\n    (let [coll (->reducible coll)]\n      (if (instance? RandomAccess coll)\n        (subvec coll (min (long n) (.size ^List coll)))\n        (clojure.core/drop n coll)))))\n\n\n(defn drop-min\n  \"Drop the min n values of a collection.  This is not an order-preserving operation.\"\n  ([n comp values]\n   (let [values (->random-access values)\n         tn (- (count values) (long n))]\n     (if (<= tn 0)\n       empty-vec\n       (take-min tn (.reversed (->comparator comp)) values))))\n  ([n values]\n   (drop-min n nil values)))\n\n\n(defn drop-last\n  \"Drop the last N values from a collection.  IF the input is random access,\n  the result will be random access.\"\n  ([n] (clojure.core/drop-last n))\n  ([n coll]\n   (when coll\n     (let [coll (->reducible coll)]\n       (if (instance? RandomAccess coll)\n         (let [ne (.size ^List coll)\n               n (min (long n) ne)]\n           (.subList ^List coll 0 (- ne n)))\n         (clojure.core/take-last n coll))))))\n\n\n(defn repeat\n  \"When called with no arguments, produce an infinite sequence of v.\n  When called with 2 arguments, produce a random access list that produces v at each\n  index.\"\n  ([v] (clojure.core/repeat v))\n  (^List [n v] (ConstList/create n v nil)))\n\n\n(defn ^:no-doc double-eq\n  [lhs rhs]\n  (if (number? lhs)\n    (let [lhs (double lhs)\n          rhs (double rhs)]\n      (cond\n        (and (Double/isNaN lhs)\n             (Double/isNaN rhs))\n        true\n        (or (Double/isNaN lhs)\n            (Double/isNaN rhs))\n        false\n        :else\n        (== lhs rhs)))\n    (and (== (count lhs) (count rhs))\n         (every? identity (map double-eq lhs rhs)))))\n\n\n(defmacro reduced->\n  \"Helper macro to implement reduce chains checking for if the accumulator\n  is reduced before calling the next expression in data.\n\n```clojure\n(defrecord YMC [year-month ^long count]\n  clojure.lang.IReduceInit\n  (reduce [this rfn init]\n    (let [init (reduced-> rfn init\n                   (clojure.lang.MapEntry/create :year-month year-month)\n                   (clojure.lang.MapEntry/create :count count))]\n      (if (and __extmap (not (reduced? init)))\n        (reduce rfn init __extmap)\n        init))))\n```\"\n  [rfn acc & data]\n  (reduce (fn [expr next-val]\n            `(let [val# ~expr]\n               (if (reduced? val#)\n                 val#\n                 (~rfn val# ~next-val))))\n          acc\n          data))\n\n\n(defmacro custom-ireduce\n  \"Custom implementation of IReduceInit and nothing else.  This can be the most efficient\n  way to pass data to other interfaces.  Also see [[custom-counted-ireduce]] if the object\n  should also implement ICounted.  See [[reduced->]] for implementation helper.\"\n  [rfn acc & code]\n  `(reify ITypedReduce\n     (reduce [this# ~rfn ~acc]\n       ~@code)))\n\n\n(defmacro custom-counted-ireduce\n  \"Custom implementation of IReduceInit and nothing else.  This can be the most efficient\n  way to pass data to other interfaces.  Also see custom-ireduce if the object\n  does not need to be counted and see [[reduced->]] for implementation helper.\"\n  [n-elems rfn acc & code]\n  `(reify\n     Counted\n     (count [this] (unchecked-int ~n-elems))\n     ITypedReduce\n     (reduce [this# ~rfn ~acc]\n       ~@code)))\n\n\n(defn wrap-array\n  \"Wrap an array with an implementation of IMutList\"\n  ^IMutList [ary] (alists/wrap-array ary))\n\n\n(defn wrap-array-growable\n  \"Wrap an array with an implementation of IMutList that supports add and addAllReducible.\n  'ptr is the numeric put ptr, defaults to the array length.  Pass in zero for a preallocated\n  but empty growable wrapper.\"\n  (^IMutList [ary ptr]\n   (alists/wrap-array-growable ary ptr))\n  (^IMutList [ary]\n   (alists/wrap-array-growable ary)))\n\n\n(defn inc-consumer\n  \"Return a consumer that simply increments a long.  See java/ham_fisted/Consumers.java for definition.\"\n  (^Consumers$IncConsumer [] (Consumers$IncConsumer.))\n  (^Consumers$IncConsumer [^long init-value] (Consumers$IncConsumer. init-value)))\n\n\n(defn re-matches\n  \"Much faster version of clojure.core/re-matches.\"\n  [^java.util.regex.Pattern re s]\n  (let [m (re-matcher re s)]\n    (when (. m (matches))\n      (let [gc  (. m (groupCount))]\n        (if (zero? gc)\n          (.group m)\n          (do\n            (let [gc (inc gc)\n                  rv (object-array gc)]\n              (dotimes [idx gc]\n                (aset rv idx (.group m idx)))\n              (ArrayLists/toList rv))))))))\n\n\n(defn lines\n  \"Return a closeable iterable that produces an iterator that simply produces lines of the reader.\n  Iterator does not cache more than 1 line so there is no possibility of holding onto head normal nor\n  chunked seq-ing.\n\n\n  Example:\n```clojure\n(with-open [ld (hamf/lines fname)]\n  (->> ld\n       (hamf/pmap (fn [line] ...))\n       (reduce ...)))\n```\"\n  ^java.lang.AutoCloseable [fname]\n  (let [^java.io.BufferedReader rdr (cond\n                                      (instance? java.io.BufferedReader fname) fname\n                                      (instance? String fname) (-> (java.io.FileReader. (str fname))\n                                                                   (java.io.BufferedReader.))\n                                      :else\n                                      (clojure.java.io/reader fname))]\n    (reify Iterable\n      java.lang.AutoCloseable\n      (close [this] (.close rdr))\n      (iterator [this]\n        (let [line* (volatile! (.readLine rdr))]\n          (reify java.util.Iterator\n            (hasNext [this] (boolean @line*))\n            (next [this]\n              (let [rv @line*]\n                (vreset! line* (.readLine rdr))\n                rv))))))))\n\n\n(defn linear-merge-iterable\n  \"Create an N-way merge iterable using cmp to order the merge of provided iterables.\n  If a predicate pred is provided the iterable itself will filter out values for which\n  the pred returns false.  In this mode it is possible for the iterator to return null\n  if the last value is filtered out -- the hasNext method doesn't check if the next value\n  passes the predicate.\"\n  ([cmp pred iterables]\n   (reify Iterable\n     (iterator [this]\n       (iterator/linear-merge-iterator cmp pred (lznc/map iterator/->iterator iterables)))))\n  ([cmp iterables] (linear-merge-iterable cmp MergeIterator/alwaysTrue iterables))\n  ([iterables]  (linear-merge-iterable compare MergeIterator/alwaysTrue iterables)))\n\n\n(defn merge-iterator\n  \"Create an N-way priority queue iterable using cmp to order the merge of provided iterables.\n  If a predicate pred is provided the iterable itself will filter out values for which\n  the pred returns false.  In this mode it is possible for the iterator to return null\n  if the last value is filtered out -- the hasNext method doesn't check if the next value\n  passes the predicate.\"\n  [cmp iterables] (iterator/merge-iterable cmp iterables))\n"
  },
  {
    "path": "src/ham_fisted/bloom_filter.clj",
    "content": "(ns ham-fisted.bloom-filter\n  \"Simple fast bloom filter based on apache parquet BlockSplitBloomFilter.\"\n  (:require [ham-fisted.protocols :as hamf-proto]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.defprotocol :refer [extend extend-type extend-protocol]])\n  (:import [ham_fisted BlockSplitBloomFilter]\n           [java.util UUID]\n           [java.time Instant]\n           [clojure.lang IFn$OL])\n  (:refer-clojure :exclude [contains? extend extend-type extend-protocol]))\n\n(set! *warn-on-reflection* true)\n\n(def byte-array-cls (type (byte-array 0)))\n\n(extend-protocol hamf-proto/SerializeObjBytes\n  nil\n  (serialize->bytes [v] (byte-array 0))\n  Double\n  (serialize->bytes [v] (-> (java.nio.ByteBuffer/allocate 8)\n                            (.putDouble v)\n                            (.array)))\n  UUID\n  (serialize->bytes [v]\n    (let [^UUID v v\n          bdata (byte-array 16)\n          ^java.nio.ByteBuffer bbuf (-> (java.nio.ByteBuffer/wrap bdata)\n                                        (.order java.nio.ByteOrder/LITTLE_ENDIAN))]\n      (.putLong bbuf (.getMostSignificantBits v))\n      (.putLong bbuf (.getLeastSignificantBits v))\n      bdata))\n  String\n  (serialize->bytes [v]\n    (.getBytes ^String v))\n  Instant\n  (serialize->bytes [inst]\n    (let [buf (java.nio.ByteBuffer/wrap (byte-array 12))]\n      (.putLong buf (.getEpochSecond inst))\n      (.putInt buf (.getNano inst))\n      (.array buf))))\n\n(defn serialize->bytes\n  \"Serialize an object to a byte array\"\n  ^bytes [o]\n  (if (instance? byte-array-cls o)\n    o\n    (hamf-proto/serialize->bytes o)))\n\n(defn hash-obj\n  \"Hash an object. If integer - return integer else serialize->bytes and hash those\"\n  ^long [obj]\n  (if (or (instance? Long obj) (instance? Integer obj) (instance? Short obj) (instance? Byte obj))\n    (long obj)\n    (BlockSplitBloomFilter/hash (serialize->bytes obj))))\n\n(defn bloom-filter\n  \"Create a bloom filter.\n  * 'n' - Number of distinct values.\n  * 'f' - Value from 1.0-0.0, defaults to 0.01.  False positive rate.\"\n  [n f]\n  (BlockSplitBloomFilter. (quot (BlockSplitBloomFilter/optimalNumOfBits n f) 8)))\n\n(defn insert-hash!\n  ^BlockSplitBloomFilter [^BlockSplitBloomFilter bf ^long hc]\n  (.insertHash bf hc)\n  bf)\n\n(defn make-long-hash-predicate\n  [^BlockSplitBloomFilter bf]\n  (hamf-fn/long-predicate hs (.findHash bf hs)))\n\n(defn make-obj-predicate\n  [^BlockSplitBloomFilter bf]\n  (hamf-fn/predicate hs (.findHash bf (hash-obj hs))))\n\n(defn contains?\n  [^BlockSplitBloomFilter bf obj]\n  (.findHash bf (hash-obj obj)))\n\n(defn insert-obj\n  ^BlockSplitBloomFilter [bf o]\n  (if (instance? Long o)\n    (insert-hash! bf (long o))\n    (insert-hash! bf (BlockSplitBloomFilter/hash (serialize->bytes o)))))\n\n(defn bitset-size\n  \"Return the length of the byte array underlying this bitset\"\n  ^long [^BlockSplitBloomFilter fb]\n  (.getBitsetSize fb))\n\n(defn bloom-filter->byte-array\n  ^bytes [^BlockSplitBloomFilter bf]\n  (.bitset bf))\n\n(defn byte-array->bloom-filter\n  ^BlockSplitBloomFilter [^bytes data]\n  (BlockSplitBloomFilter. data))\n\n(defn make-uuid-hasher\n  ^IFn$OL []\n  (let [bbuf (-> (java.nio.ByteBuffer/allocate 16)\n                 (.order java.nio.ByteOrder/LITTLE_ENDIAN))\n        bdata (.array bbuf)]\n    (hamf-fn/obj->long\n     v\n     (do\n       (.putLong bbuf (.getMostSignificantBits ^UUID v))\n       (.putLong bbuf (.getLeastSignificantBits ^UUID v))\n       (.position bbuf 0)\n       (BlockSplitBloomFilter/hash bdata)))))\n\n(defn add-uuids!\n  ^BlockSplitBloomFilter [bf val-seq]\n  (let [^IFn$OL hasher (make-uuid-hasher)]\n    (reduce (fn [bf v]\n              (if (instance? UUID v)\n                (insert-hash! bf (.invokePrim hasher v))\n                (throw (Exception. (str \"Unsupported datatype: \" (type v))))))\n            bf\n            val-seq)))\n\n(defn make-uuid-pred\n  [^BlockSplitBloomFilter bf]\n  (let [hasher (make-uuid-hasher)]\n    (fn [uuid]\n      (.findHash bf (.invokePrim ^IFn$OL hasher uuid)))))\n\n(comment\n\n  (def M (long 1e6))\n  (def uuids (vec (repeatedly M #(UUID/randomUUID))))\n  (def bf (bloom-filter M 0.01))\n\n  (reduce insert-hash! bf (map hash-obj uuids))\n\n  (def pred (make-pred bf))\n\n  (pred (uuids 0))\n\n  (pred (UUID/randomUUID))\n\n  (reduce (fn [eax _]\n            (if (pred (UUID/randomUUID))\n              (inc eax)\n              eax))\n          0\n          (range M))\n\n  (reduce (fn [eax u]\n            (if (pred u)\n              (inc eax)\n              eax))\n          0\n          uuids)\n  )\n"
  },
  {
    "path": "src/ham_fisted/caffeine.clj",
    "content": "(ns ham-fisted.caffeine\n  (:require [ham-fisted.function :as hamf-fn])\n  (:import [com.github.benmanes.caffeine.cache Caffeine LoadingCache CacheLoader Cache\n            RemovalCause Weigher]\n           [com.github.benmanes.caffeine.cache.stats CacheStats]\n           [java.time Duration]\n           [java.util Map]))\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n\n(defn cache\n  \"Create a caffeine cache.\n\n  Options:\n\n  * `:write-ttl-ms` - Time that values should remain in the cache after write in milliseconds.\n  * `:access-ttl-ms` - Time that values should remain in the cache after access in milliseconds.\n  * `:soft-values?` - When true, the cache will store [SoftReferences](https://docs.oracle.com/javase/7/docs/api/java/lang/ref/SoftReference.html) to the data.\n  * `:weak-values?` - When true, the cache will store [WeakReferences](https://docs.oracle.com/javase/7/docs/api/java/lang/ref/WeakReference.html) to the data.\n  * `:max-size` - When set, the cache will behave like an LRU cache.\n  * `:record-stats?` - When true, the LoadingCache will record access statistics.  You can\n     get those via the undocumented function memo-stats.\n  * `:eviction-fn` - Function that receives 3 arguments, [args v cause], when a value is\n     evicted.  Causes the keywords `:collected :expired :explicit :replaced and :size`.  See\n     [caffeine documentation](https://www.javadoc.io/static/com.github.ben-manes.caffeine/caffeine/2.9.3/com/github/benmanes/caffeine/cache/RemovalCause.html) for cause definitions.\n  * `:weight-limited` - tuple of `[weight-fn max-weight]`.  weight-fn takes 2 args - k, v.\n  * `:load-fn` - Pass in a function that will automatically compute the answer.\"\n  ^Cache [{:keys [write-ttl-ms\n                  access-ttl-ms\n                  soft-values?\n                  weak-values?\n                  max-size\n                  record-stats?\n                  eviction-fn\n                  weight-limited\n                  load-fn]}]\n  (let [^Caffeine builder\n        (cond-> (Caffeine/newBuilder)\n          access-ttl-ms\n          (.expireAfterAccess (Duration/ofMillis access-ttl-ms))\n          write-ttl-ms\n          (.expireAfterWrite (Duration/ofMillis write-ttl-ms))\n          soft-values?\n          (.softValues)\n          weak-values?\n          (.weakValues)\n          max-size\n          (.maximumSize (long max-size))\n          record-stats?\n          (.recordStats)\n          eviction-fn\n          (.evictionListener (reify com.github.benmanes.caffeine.cache.RemovalListener\n                               (onRemoval [this args v cause]\n                                 (eviction-fn args v\n                                              (condp identical? cause\n                                                RemovalCause/COLLECTED :collected\n                                                RemovalCause/EXPIRED :expired\n                                                RemovalCause/EXPLICIT :explicit\n                                                RemovalCause/REPLACED :replaced\n                                                RemovalCause/SIZE :size\n                                                (keyword (.toLowerCase (str cause)))))))))\n        ^Caffeine builder (if weight-limited\n                            (let [[wfn weight] weight-limited]\n                              (-> (.maximumWeight builder (long weight))\n                                  (.weigher (reify Weigher\n                                              (weigh [_ k v] (wfn k v))))))\n                            builder)]\n    (if load-fn\n      (.build builder (proxy [CacheLoader] []\n                        (load [k] (load-fn k))))\n      (.build builder))))\n\n\n(defn get-if-present\n  \"\"\n  [^Cache c k]\n  (.getIfPresent c k))\n\n\n(defn get-or-load!\n  [^Cache c k load-fn]\n  (.get c k (hamf-fn/->function load-fn)))\n\n\n(defn invalidate!\n  \"Invalidate an entry.  Returns the cache.\"\n  [^Cache c k] (.invalidate c k) c)\n\n(defn invalidate-all!\n  \"Invalidate all entries or all entries with given keys.  Returns cache.\"\n  ([^Cache c] (.invalidateAll c) c)\n  ([^Cache c ks] (.invalidateAll c (or ks '())) c))\n\n(defn as-map\n  \"Return a caffeine cache as a map.  Some Useful methods are .putIfAbsent and computeIfAbsent.\"\n  ^Map [^Cache cache]\n  (.asMap cache))\n\n(defn stats\n  \"Return the caffeine cache stats.\"\n  ^CacheStats [^Cache cache]\n  (.stats cache))\n\n(defn keyword-stats\n  \"Return a persistent map with keyword keys and caffeine stat values.\n\n  Returns:\n  `{:hit-count (.hitCount stats)\n     :hit-rate (.hitRate stats)\n     :miss-count (.missCount stats)\n     :miss-rate (.missRate stats)\n     :load-success-count (.loadSuccessCount stats)\n     :average-load-penalty-nanos (.averageLoadPenalty stats)\n     :total-load-time-nanos (.totalLoadTime stats)\n     :eviction-count (.evictionCount stats)}`\"\n\n  [^Cache cache]\n  (let [stats (stats cache)]\n    {:hit-count (.hitCount stats)\n     :hit-rate (.hitRate stats)\n     :miss-count (.missCount stats)\n     :miss-rate (.missRate stats)\n     :load-success-count (.loadSuccessCount stats)\n     :average-load-penalty-nanos (.averageLoadPenalty stats)\n     :total-load-time-nanos (.totalLoadTime stats)\n     :eviction-count (.evictionCount stats)}))\n"
  },
  {
    "path": "src/ham_fisted/datatypes.clj",
    "content": "(ns ham-fisted.datatypes\n  (:require [ham-fisted.protocols :as protocols]\n            [ham-fisted.defprotocol :as hamf-defproto]\n            [ham-fisted.language :as hamf-language])\n  (:import [java.util Set HashSet]))\n\n;; apply datatypes to all primitive types, array types\n\n(defn unsigned-type?\n  [dt]\n  (or (identical? :uint8 dt)\n      (identical? :uint16 dt)\n      (identical? :uint32 dt)\n      (identical? :uint64 dt)))\n\n(defn integer-type?\n  [dt]\n  (or (identical? :int8 dt)\n      (identical? :byte dt)\n      (identical? :int16 dt)\n      (identical? :short dt)\n      (identical? :int32 dt)\n      (identical? :int dt)\n      (identical? :int64 dt)\n      (identical? :long dt)\n      (unsigned-type? dt)))\n\n(defn float-type?\n  [dt]\n  (or (identical? :float32 dt)\n      (identical? :float64 dt)))\n\n(defn datatype->simplified-datatype\n  [dt]\n  (if (integer-type? dt)\n    :int64\n    (if (float-type? dt) :float64\n        :object)))\n\n(defn extend-datatypes\n  \"dtype map is a map of class to datatype\"\n  [dtype-map]\n  (->> dtype-map\n       (run!\n        (fn [kv]\n          (hamf-defproto/extend (key kv) protocols/Datatype\n                                {:datatype (val kv)\n                                 :simplified-datatype (datatype->simplified-datatype (val kv))})))))\n\n(extend-datatypes\n {Byte/TYPE :int8\n  Byte :int8\n  Short/TYPE :int16\n  Short :int16\n  Integer/TYPE :int32\n  Integer :int32\n  Long/TYPE :int64\n  Long :int64\n  Float/TYPE :float32\n  Float :float32\n  Double/TYPE :float64\n  Double :float64\n  String :string\n  clojure.lang.Keyword :keyword})\n\n(extend-datatypes\n (into {} (map (fn [kv] [(val kv) :array])) hamf-language/array-classes))\n\n(def java-keyword-type->datatype {:byte :int8\n                                  :short :int16\n                                  :int :int32\n                                  :integer :int32\n                                  :long :int64\n                                  :float :float32\n                                  :double :float64\n                                  :object :object})\n\n(defn datatype->simplified-contained-datatype\n  [dt]\n  (when dt\n    (datatype->simplified-datatype dt)))\n\n(defn extend-contained-datatypes\n  [dtype-map]\n  (->> dtype-map\n       (run!\n        (fn [kv]\n          (hamf-defproto/extend\n              (key kv) protocols/ContainedDatatype\n              {:contained-datatype (val kv)\n               :simplified-contained-datatype (datatype->simplified-contained-datatype (val kv))})))))\n\n(extend-contained-datatypes\n {CharSequence :char\n  Iterable :object\n  java.util.Map :object\n  java.util.stream.Stream :object\n  java.util.stream.LongStream :int64\n  java.util.stream.IntStream :int32\n  java.util.stream.DoubleStream :float64})\n\n(extend-contained-datatypes\n (into {} (map (fn [kv]\n                 [(val kv) (java-keyword-type->datatype (key kv))])\n               hamf-language/array-classes)))\n\n(defn generated-classes\n  [argcount]\n  (let [argcount (inc argcount)\n        n-fns (long (Math/pow 3 argcount))]\n    (->> (for [^long fn-idx (range n-fns)]\n           (let [fn-vars\n                 (loop [arg-idx 0\n                        fn-idx fn-idx\n                        data '()]\n                   (if (< arg-idx argcount)\n                     (let [local-idx (rem fn-idx 3)\n                           next-idx (quot fn-idx 3)\n                           data (conj data (case local-idx\n                                             0 \"O\"\n                                             1 \"L\"\n                                             2 \"D\"))]\n                       (recur (inc arg-idx) next-idx data))\n                     data))\n                 rval (last fn-vars)]\n             (if (every? #(= % \"O\") fn-vars)\n               [clojure.lang.IFn :object]\n               [(Class/forName\n                 (apply str \"clojure.lang.IFn$\" fn-vars))\n                (cond\n                  (= \"O\" rval) :object\n                  (= \"L\" rval) :int64\n                  (= \"D\" rval) :float64)]))))))\n\n(def fn-classes\n  (into {clojure.lang.IFn :object}\n        (mapcat generated-classes)\n        (range 5)))\n\n(run!\n (fn [kv]\n   (hamf-defproto/extend (key kv)\n     protocols/ReturnedDatatype\n     {:returned-datatype (val kv)\n      :simplified-returned-datatype (datatype->simplified-datatype (val kv))}))\n fn-classes)\n"
  },
  {
    "path": "src/ham_fisted/defprotocol.clj",
    "content": "(ns ham-fisted.defprotocol\n  \"Alternative protocol implementation.\n\n  Major features:\n\n  * Allows subclasses to override only a subset of the methods and if the superclass\n  has overridden the method then the superclasses implementation will be used.\n\n  * Supports primitive typehints on function arguments and return values.\n\n  * Much higher and more predictable multithreaded performance for protocol method invocation due to\n  the fewer number of global variables that are read and written to for a single protocol method\n  invocation.  Does not write to global variables on a per-call basis meaning far less cpu/cache traffic\n  in high contention scenarios.\n\n  * Attempting to extend a protocol method that doesn't exist is an error at extension time.\n\n  * Overriding the protocol for the base object array class overrides it for all things convertible\n  to object array while still allowing the concrete array type to match a specific override.\n\n  Another design decision is to avoid the interface check - this simplifes the hot path a slight bit\n  at the cost of slightly slower calltimes in the case the interface is used.  For those cases often\n  it is possible to simply typehint the interface and call it directly avoiding any protocol dispatch\n  overhead.\n\n  Additional call overhead above and beyond a normal fn invocation in an arm mac is `-6ns` - the time\n  for `.getClass` call into single concurrent hash map lookup.\"\n  (:refer-clojure :exclude [defprotocol extend extend-type extend-protocol extends? satisfies?\n                            find-protocol-method find-protocol-impl extenders])\n  (:import [ham_fisted MethodImplCache Casts]\n           [java.util Map]))\n\n(set! *warn-on-reflection* true)\n\n(defn find-protocol-cache-method\n  [protocol ^MethodImplCache cache x]\n  (when cache\n    (let [cc (if (class? x) x (class x))]\n      (if (.isAssignableFrom (.-iface cache) cc)\n        (.-ifaceFn cache)\n        (if-let [mfn (when (get protocol :extend-via-metadata)\n                       (get (meta x) (.-ns_methodk cache)))]\n          mfn\n          (.findFnFor cache cc))))))\n\n(defn find-protocol-method\n  \"It may be more efficient in a tight loop to bypass the protocol dispatch on a per-call basis.\"\n  ([protocol methodk x]\n   (find-protocol-cache-method protocol @(get (get protocol :method-caches) methodk) x)))\n\n(defn- protocol?\n  [maybe-p]\n  (boolean (and (get maybe-p :on-interface)\n                (get maybe-p :method-caches))))\n\n(defn- implements? [protocol atype]\n  (and atype (.isAssignableFrom ^Class (:on-interface protocol) atype)))\n\n(defn extends?\n  \"Returns true if atype extends protocol\"\n  [protocol atype]\n  (boolean (or (implements? protocol atype)\n               (get (:impls protocol) atype))))\n\n(defn extenders\n  \"Returns a collection of the types explicitly extending protocol\"\n  [protocol]\n  (keys (:impls protocol)))\n\n(defn satisfies?\n  \"Returns true if x satisfies the protocol\"\n  [protocol x]\n  (or (instance? (get protocol :on-interface) x)\n      (every? #(boolean (find-protocol-cache-method protocol % @x))\n              (vals (get protocol :method-caches)))))\n\n(defn- assert-same-protocol [protocol-var method-syms]\n  (doseq [m method-syms]\n    (let [v (resolve m)\n          p (:protocol (meta v))]\n      (when (and v (bound? v) (not= protocol-var p))\n        (binding [*out* *err*]\n          (println \"Warning: protocol\" protocol-var \"is overwriting\"\n                   (if p\n                     (str \"method \" (.sym ^clojure.lang.Var v) \" of protocol \" (.sym ^clojure.lang.Var p))\n                     (str \"function \" (.sym ^clojure.lang.Var v)))))))))\n\n(defn ^:no-doc find-fn\n  [target ^MethodImplCache cache ns protocol]\n  (let [rv (.findFnFor cache (class target))]\n    (if-not (nil? rv)\n      rv\n      (throw (IllegalArgumentException. (format\n                                         \"No implementation of method: %s of protocol: #'%s/%s found for class: %s\"\n                                         (.-methodk cache)\n                                         ns\n                                         protocol\n                                         (if-let [c (class target)]\n                                           (.getName ^Class c)\n                                           \"nil\")))))))\n\n;;Instance check is already taken care of\n(defn ^:no-doc find-fn-via-metadata\n  [target ns-method cache ns protocol]\n  (if-let [f (get (meta target) ns-method)]\n    f\n    (find-fn target cache ns protocol)))\n\n(defn ^:no-doc fn-tag-for-tags\n  [arg-tags]\n  (-> (apply str \"clojure.lang.IFn$\" (map (fn [arg-tag]\n                                            (cond\n                                              (= 'long arg-tag) \"L\"\n                                              (= 'double arg-tag) \"D\"\n                                              :else \"O\"))\n                                          arg-tags))\n      symbol))\n\n(defn- emit-protocol [name opts+sigs]\n  (let [iname (symbol (str (munge (namespace-munge *ns*)) \".\" (munge name)))\n        [opts sigs]\n        (loop [opts {:on (list 'quote iname) :on-interface iname} sigs opts+sigs]\n          (condp #(%1 %2) (first sigs)\n            string? (recur (assoc opts :doc (first sigs)) (next sigs))\n            keyword? (recur (assoc opts (first sigs) (second sigs)) (nnext sigs))\n            [opts sigs]))\n        sigs (when sigs\n               (reduce (fn [m s]\n                         (let [tag-to-class (fn [tag]\n                                              (if-let [c (and (instance? clojure.lang.Symbol tag)\n                                                              (= (.indexOf (.getName ^clojure.lang.Symbol tag) \".\") -1)\n                                                              (not (contains? '#{int long float double char short byte boolean void\n                                                                                 ints longs floats doubles chars shorts bytes booleans objects} tag))\n                                                              (resolve tag))]\n                                                (symbol (.getName ^Class c))\n                                                tag))\n                               name-meta (update-in (meta (first s)) [:tag] tag-to-class)\n                               mname (with-meta (first s) nil)\n                               [arglists doc]\n                               (loop [as [] rs (rest s)]\n                                 (if (vector? (first rs))\n                                   (recur (conj as (first rs)) (next rs))\n                                   [(seq as) (first rs)]))\n                               name-kwd (keyword mname)\n                               mname (vary-meta mname assoc\n                                                :doc doc\n                                                :arglists arglists\n                                                :tag (:tag name-meta))]\n                           (when (some #{0} (map count arglists))\n                             (throw (IllegalArgumentException. (str \"Definition of function \" mname \" in protocol \" name \" must take at least one arg.\"))))\n                           (when (m (keyword mname))\n                             (throw (IllegalArgumentException. (str \"Function \" mname \" in protocol \" name \" was redefined. Specify all arities in single definition.\"))))\n                           (assoc m (keyword mname)\n                                  (merge name-meta\n                                         {:name mname\n                                          :methodk name-kwd\n                                          :ns-methodk (keyword (clojure.core/name (.-name *ns*))\n                                                               (clojure.core/name mname))\n                                          :arglists arglists\n                                          :doc doc\n                                          :cache-sym (symbol (str \"-\" mname \"-cache\"))\n                                          :iface-sym (symbol (str \"-\" mname \"-iface\"))}))))\n                       {} sigs))\n        meths (mapcat (fn [sig]\n                        (let [m (munge (:name sig))\n                              m-tag (or (:tag (meta (:name sig))) 'Object)]\n                          (map #(vector m (vec (repeat (dec (count %)) 'Object)) m-tag)\n                               (:arglists sig))))\n                      (vals sigs))\n        opts (assoc opts :sigs sigs)\n        name (if-let [proto-doc (:doc opts)]\n               (with-meta name {:doc proto-doc})\n               name)]\n    `(do\n       (gen-interface :name ~iname :methods ~meths)\n       ~@(mapcat (fn [{:keys [methodk ns-methodk cache-sym iface-sym arglists tag]\n                       mname :name}]\n                   [`(defn ~(with-meta iface-sym\n                              {:private true\n                               :tag (list 'quote tag)})\n                       ~@(map (fn [args]\n                                (let [args (vec args) #_(mapv #(gensym (str %)) args)\n                                      args (vary-meta (vec args) assoc :tag\n                                                      (if (class? tag)\n                                                        (list 'quote )\n                                                        tag))\n                                      target (first args)]\n                                  `(~args\n                                    (. ~(with-meta target\n                                          {:tag iname})\n                                       (~mname\n                                        ~@(rest args))))))\n                              arglists))\n                    `(let [~'cache (ham_fisted.MethodImplCache. ~methodk ~ns-methodk ~iname ~iface-sym)]\n                       (def ~(with-meta cache-sym\n                               {:private true\n                                :tag 'ham_fisted.MethodImplCache})\n                         ~'cache)\n                       (defn ~(vary-meta mname assoc :tag (list 'quote tag))\n                         {:hamf-protocol ~(list 'quote name)}\n                         ~@(map (fn [args]\n                                  (let [args (vary-meta (vec args) assoc :tag\n                                                        (if (class? tag)\n                                                          (list 'quote )\n                                                          tag))\n                                        arg-tags (when (< (count args) 5)\n                                                   (conj (mapv (comp :tag meta) args) tag))\n                                        rval-tag (last arg-tags)\n                                        invoker (when (first (filter #{'long 'double} arg-tags))\n                                                  '.invokePrim)\n                                        target (first args)\n                                        find-data (if (:extend-via-metadata opts)\n                                                    `(find-fn-via-metadata ~target\n                                                                           ~ns-methodk\n                                                                           ~'cache\n                                                                           ~(list 'quote (.-name *ns*))\n                                                                           ~(list 'quote name))\n                                                    `(find-fn ~target ~'cache ~(list 'quote (.-name *ns*))\n                                                              ~(list 'quote name)))]\n                                    `(~args\n                                      ~(if invoker\n                                         `(let [~(with-meta 'ff {:tag (fn-tag-for-tags arg-tags)}) ~find-data]\n                                            (~invoker ~'ff ~@args))\n                                         `(let [~'ff ~find-data]\n                                            (~'ff ~@args))))))\n                                arglists)))])\n                 (vals sigs))\n       (def ~name ~(assoc (update opts\n                                  :sigs (fn [sigmap]\n                                          (->> sigmap\n                                               (map (fn [e]\n                                                      [(key e) (-> (select-keys (val e) [:name :doc :arglists :tag])\n                                                                   (update :arglists\n                                                                           (fn [arglists]\n                                                                             (mapv (fn [arglist]\n                                                                                     (mapv (fn [sym]\n                                                                                             (list 'quote sym))\n                                                                                           arglist))\n                                                                                   arglists)))\n                                                                   (update :tag (fn [t] (when t (list 'quote t))))\n                                                                   (update :name #(list 'quote %)))]))\n                                               (into {}))))\n                          :method-caches (->> (map (fn [{:keys [methodk cache-sym]}]\n                                                     ;;Subtle issue here if you dereference the var --\n                                                     ;;if the file is reloaded you can get protocol referenes that\n                                                     ;;point to the wrong cache var.\n                                                     [methodk (list 'var cache-sym)])\n                                                   (vals sigs))\n                                              (into {}))\n                          ;;No more alter-var-root -- unnecessary\n                          :impls `(atom {}))))))\n\n(defmacro defprotocol\n  \"A protocol is a named set of named methods and their signatures:\n```clojure\n  (defprotocol AProtocolName\n\n    ;optional doc string\n    \\\"A doc string for AProtocol abstraction\\\"\n\n   ;options\n   :extend-via-metadata true\n\n  ;method signatures\n    (bar [this a b] \\\"bar docs\\\")\n    (baz [this a] [this a b] [this a b c] \\\"baz docs\\\"))\n```\n\n  No implementations are provided. Docs can be specified for the\n  protocol overall and for each method. The above yields a set of\n  polymorphic functions and a protocol object. All are\n  namespace-qualified by the ns enclosing the definition The resulting\n  functions dispatch on the type of their first argument, which is\n  required and corresponds to the implicit target object ('this' in\n  Java parlance). defprotocol is dynamic, has no special compile-time\n  effect, and defines no new types or classes. Implementations of\n  the protocol methods can be provided using extend.\n\n  When :extend-via-metadata is true, values can extend protocols by\n  adding metadata where keys are fully-qualified protocol function\n  symbols and values are function implementations. Protocol\n  implementations are checked first for direct definitions (defrecord,\n  deftype, reify), then metadata definitions, then external\n  extensions (extend, extend-type, extend-protocol)\n\n  defprotocol will automatically generate a corresponding interface,\n  with the same name as the protocol, i.e. given a protocol:\n  my.ns/Protocol, an interface: my.ns.Protocol. The interface will\n  have methods corresponding to the protocol functions, and the\n  protocol will automatically work with instances of the interface.\n\n  Note that you should not use this interface with deftype or\n  reify, as they support the protocol directly:\n```clojure\n\n  (defprotocol P\n    (foo [this])\n    (bar-me [this] [this y]))\n\n  (deftype Foo [a b c]\n   P\n    (foo [this] a)\n    (bar-me [this] b)\n    (bar-me [this y] (+ c y)))\n\n  (bar-me (Foo. 1 2 3) 42)\n  => 45\n\n  (foo\n    (let [x 42]\n      (reify P\n        (foo [this] 17)\n        (bar-me [this] x)\n        (bar-me [this y] x))))\n  => 17\n```\"\n  {:added \"1.2\"}\n  [name & opts+sigs]\n  (emit-protocol name opts+sigs))\n\n(defn- correct-primitive-fn-type\n  [arg-tags-v method]\n  (doseq [arg-tags arg-tags-v]\n    (when (first (filter #{'long 'double} arg-tags))\n      (let [prim-cls (Class/forName (apply str \"clojure.lang.IFn$\"\n                                           (map (fn [tag]\n                                                  (cond\n                                                    (= tag 'long) \"L\"\n                                                    (= tag 'double) \"D\"\n                                                    :else 'O))\n                                                arg-tags)))]\n        (when-not (.isAssignableFrom prim-cls (.getClass ^Object method))\n          (throw (RuntimeException. \"Primitive hinted protocol methods must have primitive hinted implementations!\"))))))\n  method)\n\n(defn- clear-object-tag\n  [tag]\n  (cond\n    (= tag 'long) 'long\n    (= tag 'double) 'double))\n\n(defn- check-constant-return\n  [tag arglists]\n  (when-not (and (== 1 (count arglists))\n                 (= [nil (clear-object-tag tag)]\n                    (mapv clear-object-tag (first arglists))))\n    (throw (IllegalArgumentException. (str \"Primitive constants only work with object->constant translations: \"\n                                           arglists)))))\n\n(defn extend\n  \"Implementations of protocol methods can be provided using the extend construct:\n\n```clojure\n  (extend AType\n    AProtocol\n     {:foo an-existing-fn\n      :bar (fn [a b] ...)\n      :baz (fn ([a]...) ([a b] ...)...)}\n    BProtocol\n      {...}\n    ...)\n```\n  extend takes a type/class (or interface, see below), and one or more\n  protocol + method map pairs. It will extend the polymorphism of the\n  protocol's methods to call the supplied methods when an AType is\n  provided as the first argument.\n\n  Method maps are maps of the keyword-ized method names to ordinary\n  fns. This facilitates easy reuse of existing fns and fn maps, for\n  code reuse/mixins without derivation or composition. You can extend\n  an interface to a protocol. This is primarily to facilitate interop\n  with the host (e.g. Java) but opens the door to incidental multiple\n  inheritance of implementation since a class can inherit from more\n  than one interface, both of which extend the protocol. It is TBD how\n  to specify which impl to use. You can extend a protocol on nil.\n\n  If you are supplying the definitions explicitly (i.e. not reusing\n  exsting functions or mixin maps), you may find it more convenient to\n  use the extend-type or extend-protocol macros.\n\n  Note that multiple independent extend clauses can exist for the same\n  type, not all protocols need be defined in a single extend call.\n\n  See also:\n  extends?, satisfies?, extenders\"\n  {:added \"1.2\"}\n  [atype & proto+mmaps]\n  (doseq [[proto mmap] (partition 2 proto+mmaps)]\n    (when-not (protocol? proto)\n      (throw (IllegalArgumentException.\n              (str proto \" is not a protocol\"))))\n    (when (implements? proto atype)\n      (throw (IllegalArgumentException.\n              (str atype \" already directly implements \" (:on-interface proto)))))\n    (let [impls (:impls proto)\n          method-caches (:method-caches proto)]\n      (swap! impls assoc atype mmap)\n      (->> mmap\n           (run! (fn [kv]\n                   (let [methodk (key kv)\n                         method (val kv)\n                         {:keys [tag arglists]} (get-in proto [:sigs methodk])\n\n                         _ (when-not arglists\n                             (throw (IllegalArgumentException.\n                                     (str \"method not found: \" methodk \" in protocol \" (:on proto)\n                                          \" - protocol methods: \"\n                                          (pr-str (.keySet ^Map (get proto :sigs)))))))\n                         arg-tags (mapv #(conj (mapv (comp :tag meta) %) tag) arglists)\n                         method (cond\n                                  (and (= 'long tag) (number? method))\n                                  (let [ll (Casts/longCast method)]\n                                    (check-constant-return tag arg-tags)\n                                    (fn ^long [o] ll))\n                                  (and (= 'double tag) (number? method))\n                                  (let [ll (Casts/doubleCast method)]\n                                    (check-constant-return tag arg-tags)\n                                    (fn ^double [o] ll))\n                                  (fn? method)\n                                  method\n                                  :else\n                                  (do\n                                    (check-constant-return tag arg-tags)\n                                    (fn [o] method)))\n                         method (correct-primitive-fn-type arg-tags method)]\n                     (.extend ^MethodImplCache @(get method-caches methodk) atype method))))))))\n\n(defn- normalize-specs\n  [specs]\n  (if (vector? (first specs))\n    (list specs)\n    specs))\n\n(defn- emit-fn-map\n  [p hint fs]\n  (let [proto (resolve p)\n        pcol (when proto (deref proto))\n        _ (when-not (protocol? pcol)\n            (throw (IllegalArgumentException.\n                    (str p \" is not a hamf protocol\"))))\n        sigs (get pcol :sigs)\n        define-fn (fn [fn-entry]\n                    (let [fn-name (-> fn-entry first name keyword)\n                          specs (hint (normalize-specs (drop 1 fn-entry)))\n                          {:keys [tag arglists] :as sig} (get sigs fn-name)\n                          arglist-map (into {} (map (fn [arglist]\n                                                      [(count arglist)\n                                                       (mapv (comp :tag meta) arglist)]))\n                                            arglists)\n                          apply-primitive-typehints\n                          (fn [[[target & args :as arglist] & body]]\n                            (let [args (->> (map (fn [tag arg-sym]\n                                                   (vary-meta arg-sym update :tag #(or % tag)))\n                                                 (drop 1 (arglist-map (inc (count args)))) args)\n                                            (into [target]))]\n                              (cons (vary-meta args update :tag #(or % tag)) body)))]\n                      [fn-name (cons 'fn (map apply-primitive-typehints specs))]))]\n    (into {} (map define-fn) fs)))\n\n(defn- emit-impl [[p fs]]\n  [p (emit-fn-map p identity fs)])\n\n(defn- emit-hinted-impl [c [p fs]]\n  (let [typehint-first-arg\n        #(->> % (map (fn [[[target & args :as arglist] & body]]\n                       (cons (into [(vary-meta target assoc :tag c)] args)\n                             body))))]\n    [p (emit-fn-map p typehint-first-arg fs)]))\n\n(defn- parse-impls [specs]\n  (loop [ret {} s specs]\n    (if (seq s)\n      (recur (assoc ret (first s) (take-while seq? (next s)))\n             (drop-while seq? (next s)))\n      ret)))\n\n(defn- emit-extend-type [c specs]\n  (let [impls (parse-impls specs)]\n    `(extend ~c\n       ~@(mapcat (partial emit-hinted-impl c) impls))))\n\n(defmacro extend-type\n  \"A macro that expands into an extend call. Useful when you are\n  supplying the definitions explicitly inline, extend-type\n  automatically creates the maps required by extend.  Propagates the\n  class as a type hint on the first argument of all fns.\n\n```clojure\n  (extend-type MyType\n    Countable\n      (cnt [c] ...)\n    Foo\n      (bar [x y] ...)\n      (baz ([x] ...) ([x y & zs] ...)))\n```\n\n  expands into:\n\n```clojure\n\n  (extend MyType\n   Countable\n     {:cnt (fn [c] ...)}\n   Foo\n     {:baz (fn ([x] ...) ([x y & zs] ...))\n      :bar (fn [x y] ...)})\n```\"\n  {:added \"1.2\"}\n  [t & specs]\n  (emit-extend-type t specs))\n\n(defn- emit-extend-protocol [p specs]\n  (let [impls (parse-impls specs)]\n    `(do\n       ~@(map (fn [[t fs]]\n                `(extend-type ~t ~p ~@fs))\n              impls))))\n\n(defmacro extend-protocol\n  \"Useful when you want to provide several implementations of the same\n  protocol all at once. Takes a single protocol and the implementation\n  of that protocol for one or more types. Expands into calls to\n  extend-type:\n\n```clojure\n  (extend-protocol Protocol\n    AType\n      (foo [x] ...)\n      (bar [x y] ...)\n    BType\n      (foo [x] ...)\n      (bar [x y] ...)\n    AClass\n      (foo [x] ...)\n      (bar [x y] ...)\n    nil\n      (foo [x] ...)\n      (bar [x y] ...))\n```\n\n  expands into:\n\n```clojure\n  (do\n   (clojure.core/extend-type AType Protocol\n     (foo [x] ...)\n     (bar [x y] ...))\n   (clojure.core/extend-type BType Protocol\n     (foo [x] ...)\n     (bar [x y] ...))\n   (clojure.core/extend-type AClass Protocol\n     (foo [x] ...)\n     (bar [x y] ...))\n   (clojure.core/extend-type nil Protocol\n     (foo [x] ...)\n     (bar [x y] ...)))\n```\"\n  {:added \"1.2\"}\n\n  [p & specs]\n  (emit-extend-protocol p specs))\n"
  },
  {
    "path": "src/ham_fisted/fjp.clj",
    "content": "(ns ham-fisted.fjp\n  \"Support for java.util.concurrent.ForkJoinPool-specific operations such as managed block and task fork/join.\n  Additionally supports concept of 'exception-safe' via wrapping executing code and unwrapper result post\n  execution in order avoid wrapping exceptions and breaking calling code that may be expecting specific\n  exception types.\n\n  Some of the api's fall back to regular executor service code when called.\n\n  Example:\n\n```clojure\n(defn split-parallel-reduce\n  \\\"Perform a parallel reduction of a spliterator using the provided ExecutorService\\\"\n  [executor-service split ideal-split init-fn rfn merge-fn]\n  (let [n-elems (proto/estimate-count split)\n        pool (or executor-service (ForkJoinPool/commonPool))]\n    (if (or (<= n-elems (long ideal-split)) (= n-elems Long/MAX_VALUE))\n      (split-reduce rfn (init-fn) split)\n      (if-let [[lhs rhs] (proto/split split)]\n        (let [lt (fjp/safe-fork-task pool (split-parallel-reduce pool lhs ideal-split init-fn rfn merge-fn))\n              rt (fjp/safe-fork-task pool (split-parallel-reduce pool rhs ideal-split init-fn rfn merge-fn))]\n          (merge-fn (fjp/managed-block-unwrap lt) (fjp/managed-block-unwrap rt)))))))\n```\"\n  (:require [ham-fisted.language :refer [cond not]]\n            [ham-fisted.protocols :as proto]\n            [ham-fisted.defprotocol :refer [extend-type extend-protocol]])\n  (:import [java.util.concurrent ForkJoinPool ForkJoinTask ForkJoinPool$ManagedBlocker RecursiveTask Future\n            ExecutorService]\n           [clojure.lang IDeref]\n           [ham_fisted FJTask])\n  (:refer-clojure :exclude [cond not extend-type extend-protocol]))\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n(defn common-pool \"Returns  (ForkJoinPool/commonPool)\"\n  ^ForkJoinPool [] (ForkJoinPool/commonPool))\n(defn common-pool-parallelism \"Integer parallelism assigned to the common pool \"\n  ^long [] (ForkJoinPool/getCommonPoolParallelism))\n(defn in-fork-join-pool? \"Returns true if this task is executing in a fork join pool thread\"\n  [] (ForkJoinTask/inForkJoinPool))\n\n(extend-protocol proto/ManagedBlocker\n  ForkJoinTask\n  (managed-blocker [m] (reify ForkJoinPool$ManagedBlocker\n                         (block [_] (.quietlyComplete m) true)\n                         (isReleasable [_] (.isDone m))\n                         clojure.lang.IDeref\n                         (deref [_] (.get m))))\n  Future\n  (managed-blocker [m] (reify ForkJoinPool$ManagedBlocker\n                         (block [_] (.get m) true)\n                         (isReleasable [_] (.isDone m))\n                         clojure.lang.IDeref\n                         (deref [_] (.get m))))\n  clojure.lang.IPending\n  (managed-blocker [m] (reify ForkJoinPool$ManagedBlocker\n                         (block [_] (deref m) true)\n                         (isReleasable [_] (realized? m))\n                         clojure.lang.IDeref\n                         (deref [_] (deref m))))\n  ForkJoinPool$ManagedBlocker\n  (managed-blocker [m] m))\n\n(defn managed-block\n  \"Block on a delay or future using the fjp system's managed blocking facility.  Safe to call all the time\n  whether the current system is in a forkjoinpool task or not.\"\n  ([dly]\n   (if (instance? ForkJoinTask dly)\n     (.join ^ForkJoinTask dly)\n     (let [dly (proto/managed-blocker dly)]\n       (ForkJoinPool/managedBlock dly)\n       @dly)))\n  ([finished? wait-till-finished get-value]\n   (managed-block (reify\n                    ForkJoinPool$ManagedBlocker\n                    (block [this] (wait-till-finished))\n                    (isReleasable [this] (finished?))\n                    clojure.lang.IDeref\n                    (deref [this] (get-value))))))\n\n(defn task \"Create a task from a clojure IFn or something that implements IDeref\"\n  ^FJTask [f] (FJTask. f))\n\n(defn fork-task\n  \"Begin a separate execution for f.  If already in a fork join pool fork the task else\n  submit f to passed in pool.\"\n  [pool f] (if (in-fork-join-pool?)\n             (let [t (task f)] (.fork t) t)\n             (.submit ^ExecutorService pool ^Callable f)))\n\n(defmacro exception-safe\n  \"Wrap code in an exception-safe wrapper - returns a map with either\n  `:ham-fisted.fjp/result` or `:ham-fisted.fjp.error`.\"\n  [& code]\n  `(let [~(with-meta 'ffn {:tag 'Callable})\n         (^:once fn* []\n          (try {:ham-fisted.fjp/result (do ~@code)}\n               (catch Throwable e# {:ham-fisted.fjp/error e#})))]\n     ~'ffn))\n\n(defmacro safe-fork-task\n  \"Called from within an executing task, fork a executing some code and wrapping it in [[exception-safe]]\n  then calling [[fork-task]]\"\n  [pool & code]\n  `(->> (do ~@code)\n        (exception-safe)\n        (fork-task ~pool)))\n\n(defn join\n  \"join a previously forked task returning the result\"\n  [^ForkJoinTask t] (.join t))\n\n(defn compute\n  \"compute a task in current thread - returns result\"\n  [t]\n  (if (instance? FJTask t)\n    (.deref (.-c ^FJTask t))\n    (throw (RuntimeException. \"Only recursive tasks (or tasks create via \\\"task\\\" can be computed\"))))\n\n(defn unsafe-common-pool\n  \"Run a callable on the common pool.  If the callable throws you will get a wrapped exception thrown\n  which may confuse calling code - specifically code that relies on exact exception types or ex-info.\"\n  [code]\n  (-> (.submit (ForkJoinPool/commonPool) ^Callable code)\n      (deref)))\n\n(defn unwrap-safe\n  \"Unwrap result created via executing code wrapped in [[exception-safe]].  Throws original exception if found.\"\n  [m]\n  (let [rv (get m ::result ::failure)]\n    (if (identical? rv ::failure)\n      (throw (get m ::error))\n      rv)))\n\n(defn safe-common-pool\n  \"Run safe code - see [[exception-safe]] unwrapping the result and re-throwing the wrapped exception.  This allows\n  systems based on typed exceptions to pass error info.\"\n  [safe-code]\n  (unwrap-safe (unsafe-common-pool safe-code)))\n\n(defmacro on-cp\n  \"Run arbitrary code on the common-pool.  Make sure any blocking operations are wrapped in [[managed-block]].\"\n  [& code]\n  `(safe-common-pool (exception-safe ~@code)))\n\n(defn managed-block-unwrap \"managed block then safe unwrap the exception-safe result\"\n  [dly] (managed-block dly) (unwrap-safe @dly))\n"
  },
  {
    "path": "src/ham_fisted/function.clj",
    "content": "(ns ham-fisted.function\n  \"Helpers for working with [java.util.function](https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html)\n  package objects.\"\n  (:import [ham_fisted IFnDef$ODO IFnDef$OOO IFnDef$OO IFnDef$OL IFnDef$LongPredicate\n            IFnDef$DoublePredicate IFnDef$DD IFnDef$LL IFnDef IFnDef$LD IFnDef$DL IFnDef$OD\n            IFnDef$LO Casts IFnDef$Predicate IFnDef$LLL IFnDef$DDD]\n           [java.util.function BiFunction BiConsumer Function DoublePredicate LongPredicate Predicate\n            Consumer LongConsumer DoubleConsumer LongBinaryOperator DoubleBinaryOperator\n            BiPredicate]\n           [java.util Comparator]\n           [clojure.lang Util]\n           [it.unimi.dsi.fastutil.longs LongComparator]\n           [it.unimi.dsi.fastutil.doubles DoubleComparator]))\n\n\n(defmacro bi-function\n  \"Create an implementation of java.util.function.BiFunction.\"\n  [arg1 arg2 & code]\n  `(reify IFnDef$OOO (invoke [this# ~arg1 ~arg2] ~@code)))\n\n\n(defmacro bi-consumer\n  [arg1 arg2 & code]\n  `(reify BiConsumer\n     (accept [this# ~arg1 ~arg2]\n       ~@code)))\n\n\n(defn ->bi-function\n  \"Convert an object to a java.util.BiFunction. Object can either already be a\n  bi-function or an IFn to be invoked with 2 arguments.\"\n  ^BiFunction [cljfn]\n  (if (instance? BiFunction cljfn)\n    cljfn\n    (bi-function a b (cljfn a b))))\n\n\n\n(defmacro function\n  \"Create a java.util.function.Function\"\n  [arg & code]\n  `(reify IFnDef$OO (invoke [this# ~arg] ~@code)))\n\n\n(defmacro obj->long\n  \"Create a function that converts objects to longs\"\n  ([]\n   `(reify IFnDef$OL\n      (invokePrim [this# v#]\n        (Casts/longCast v#))))\n  ([varname & code]\n   `(reify IFnDef$OL\n      (invokePrim [this ~varname]\n        (Casts/longCast ~@code)))))\n\n\n(defmacro obj->double\n  \"Create a function that converts objects to doubles\"\n  ([]\n   `(reify IFnDef$OD\n      (invokePrim [this# v#]\n        (Casts/doubleCast v#))))\n  ([varname & code]\n   `(reify IFnDef$OD\n      (invokePrim [this# ~varname]\n        (Casts/doubleCast ~@code)))))\n\n\n(defmacro long->double\n  \"Create a function that receives a long and returns a double\"\n  [varname & code]\n  `(reify IFnDef$LD\n     (invokePrim [this# ~varname] ~@code)))\n\n\n(defmacro double->long\n  \"Create a function that receives a double and returns a long\"\n  [varname & code]\n  `(reify IFnDef$DL\n     (invokePrim [this# ~varname] ~@code)))\n\n\n(defmacro long->obj\n  \"Create a function that receives a primitive long and returns an object.\"\n  [varname & code]\n  `(reify IFnDef$LO\n     (invokePrim [this# ~varname] ~@code)))\n\n\n(defmacro double->obj\n  [varname & code]\n  `(reify IFnDef$DO\n     (invokePrim [this# ~varname] ~@code)))\n\n\n(defn ->function\n  \"Convert an object to a java Function. Object can either already be a\n  Function or an IFn to be invoked.\"\n  ^Function [cljfn]\n  (if (instance? Function cljfn)\n    cljfn\n    (reify IFnDef$OO (invoke [this a] (cljfn a)))))\n\n\n(defmacro double-predicate\n  \"Create an implementation of java.util.Function.DoublePredicate\"\n  [varname & code]\n  `(reify\n     IFnDef$DoublePredicate\n     (test [this# ~varname]\n       ~@code)))\n\n\n(defmacro double-unary-operator\n  \"Create an implementation of java.util.function.DoubleUnaryOperator\"\n  [varname & code]\n  `(reify\n     IFnDef$DD\n     (invokePrim [this# ~varname]\n       ~@code)))\n\n\n(defmacro long-predicate\n  \"Create an implementation of java.util.Function.LongPredicate\"\n  [varname & code]\n  `(reify\n     IFnDef$LongPredicate\n     (test [this# ~varname]\n       ~@code)))\n\n\n(defn ->long-predicate\n  ^LongPredicate [f]\n  (if (instance? LongPredicate f)\n    f\n    (long-predicate ll (boolean (f ll)))))\n\n\n(defmacro long-unary-operator\n  \"Create an implementation of java.util.function.LongUnaryOperator\"\n  [varname & code]\n  `(reify\n     IFnDef$LL\n     (invokePrim [this# ~varname]\n       ~@code)))\n\n\n(defmacro predicate\n  \"Create an implementation of java.util.Function.Predicate\"\n  [varname & code]\n  `(reify\n     IFnDef$Predicate\n     (test [this# ~varname]\n       ~@code)))\n\n\n(defmacro unary-operator\n  \"Create an implementation of java.util.function.UnaryOperator\"\n  [varname & code]\n  `(function ~varname ~@code))\n\n\n(defmacro binary-operator\n  \"Create an implementation of java.util.function.BinaryOperator\"\n  [arg1 arg2 & code]\n  `(bi-function ~arg1 ~arg2 ~@code))\n\n\n(defmacro double-consumer\n  \"Create an instance of a java.util.function.DoubleConsumer\"\n  [varname & code]\n  `(reify\n     DoubleConsumer\n     (accept [this# ~varname]\n       ~@code)\n     IFnDef$DO\n     (invokePrim [this# v#] (.accept this# v#))))\n\n\n(defmacro long-consumer\n  \"Create an instance of a java.util.function.LongConsumer\"\n  [varname & code]\n  `(reify\n     LongConsumer\n     (accept [this# ~varname]\n       ~@code)\n     IFnDef$LO\n     (invokePrim [this# v#] (.accept this# v#))))\n\n\n(defmacro consumer\n  \"Create an instance of a java.util.function.Consumer\"\n  [varname & code]\n  `(reify Consumer\n     (accept [this# ~varname]\n       ~@code)\n     IFnDef$OO\n     (invoke [this# arg#] (.accept this# arg#))))\n\n\n(defmacro make-long-comparator\n  \"Make a comparator that gets passed two long arguments.\"\n  [lhsvar rhsvar & code]\n  (let [lhsvar (with-meta lhsvar {:tag 'long})\n        rhsvar (with-meta rhsvar {:tag 'long})\n        compsym (with-meta 'compare {:tag 'int})]\n    `(reify\n       LongComparator\n       (~compsym [this# ~lhsvar ~rhsvar]\n        ~@code)\n       IFnDef\n       (invoke [this# l# r#]\n         (.compare this# l# r#)))))\n\n\n(defmacro make-double-comparator\n  \"Make a comparator that gets passed two double arguments.\"\n  [lhsvar rhsvar & code]\n  (let [lhsvar (with-meta lhsvar {:tag 'double})\n        rhsvar (with-meta rhsvar {:tag 'double})\n        compsym (with-meta 'compare {:tag 'int})]\n    `(reify\n       DoubleComparator\n       (~compsym [this# ~lhsvar ~rhsvar]\n        ~@code)\n       IFnDef\n       (invoke [this# l# r#]\n         (.compare this# l# r#)))))\n\n\n(defmacro make-comparator\n  \"Make a java comparator.\"\n  [lhsvar rhsvar & code]\n  `(reify\n     Comparator\n     (compare [this# ~lhsvar ~rhsvar]\n       ~@code)\n     IFnDef\n     (invoke [this# l# r#]\n       (.compare this# l# r#))))\n\n\n\n\n(def ^{:doc \"A reverse comparator that sorts in descending order\" }\n  rcomp\n  (reify\n    Comparator\n    (^int compare [this ^Object l ^Object r]\n     (Util/compare r l))\n    DoubleComparator\n    (^int compare [this ^double l ^double r]\n     (Double/compare r l))\n    LongComparator\n    (^int compare [this ^long l ^long r]\n     (Long/compare r l))\n    IFnDef\n    (invoke [this l r]\n      (.compare this l r))))\n\n\n(def ^{:doc \"A comparator that sorts null, NAN first, natural order\"}\n  comp-nan-first\n  (reify\n    Comparator\n    (^int compare [this ^Object l ^Object r]\n     (cond\n       (nil? l) -1\n       (nil? r) 1\n       :else (Util/compare l r)))\n    DoubleComparator\n    (^int compare [this ^double l ^double r]\n     (cond\n       (Double/isNaN l) -1\n       (Double/isNaN r) 1\n       :else\n       (Double/compare l r)))\n    LongComparator\n    (^int compare [this ^long l ^long r]\n     (Long/compare l r))\n    IFnDef\n    (invoke [this l r]\n      (.compare this l r))))\n\n\n(def ^{:doc \"A comparator that sorts null, NAN last, natural order\"}\n  comp-nan-last\n  (reify\n    Comparator\n    (^int compare [this ^Object l ^Object r]\n     (cond\n       (nil? l) 1\n       (nil? r) -1\n       :else (clojure.lang.Util/compare l r)))\n    DoubleComparator\n    (^int compare [this ^double l ^double r]\n     (cond\n       (Double/isNaN l) 1\n       (Double/isNaN r) -1\n       :else\n       (Double/compare l r)))\n    LongComparator\n    (^int compare [this ^long l ^long r]\n     (Long/compare l r))\n    IFnDef\n    (invoke [this l r]\n      (.compare this l r))))\n\n\n(defmacro double-binary-operator\n  \"Create a binary operator that is specialized for double values.  Useful to speed up\n  operations such as sorting or summation.\"\n  [lvar rvar & code]\n  `(reify\n     DoubleBinaryOperator\n     (applyAsDouble [this# ~lvar ~rvar]\n       ~@code)\n     IFnDef$DDD\n     (invokePrim [this# l# r#]\n       (.applyAsDouble this# l# r#))))\n\n\n(defmacro long-binary-operator\n  \"Create a binary operator that is specialized for long values.  Useful to speed up\n  operations such as sorting or summation.\"\n  [lvar rvar & code]\n  `(reify\n     LongBinaryOperator\n     (applyAsLong [this# ~lvar ~rvar]\n       ~@code)\n     IFnDef$LLL\n     (invokePrim [this# l# r#]\n       (.applyAsLong this# l# r#))))\n\n\n(defmacro binary-predicate\n  \"Create a java.util.function.BiPredicate\"\n  [xvar yvar code]\n  `(reify\n     BiPredicate\n     (test [this# ~xvar ~yvar] (boolean ~code))\n     IFnDef\n     (invoke [this# ~xvar ~yvar] (boolean ~code))))\n\n\n(defn binary-predicate-or-null\n  \"If f is null, return null.  Else return f as a java.util.function.BiPredicate.\"\n  ^BiPredicate [f]\n  (when f\n    (if (instance? BiPredicate f)\n      f\n      (binary-predicate x y (f x y)))))\n"
  },
  {
    "path": "src/ham_fisted/hlet.clj",
    "content": "(ns ham-fisted.hlet\n  \"Extensible let to allow efficient typed destructuring.\n\n  Registered Extensions:\n\n  `dbls` and `lngs` will most efficiently destructure java primitive arrays and fall back to casting the result\n  of clojure.lang.RT/nth if input is not a double or long array.\n\n  `dlb-fns` and `lng-fns` call the object's IFn interface with no interface checking.  This will *not* work\n   with a raw array but is the fastest way - faster than RT/nth - to get data out of a persistent-vector or map\n   like object.\n\n  `obj-fns` - fast IFn-based destructuring to objects - does not work with object arrays.  Often much faster\n   than RT/nth.\n\n  This can significantly reduce boxing in tight loops without needing to result in really verbose pathways.\n\n```clojure\nuser> (h/let [[a b] (dbls [1 2])] (+ a b))\n  3.0\nuser> (hamf/sum-fast (lznc/cartesian-map\n                      #(h/let [[a b c d](lng-fns %)]\n                         (-> (+ a b) (+ c) (+ d)))\n                      [1 2 3]\n                      [4 5 6]\n                      [7 8 9]\n                      [10 11 12 13 14]))\n3645.0\n```\n  See also [[ham-fisted.primitive-invoke]], [[ham-fisted.api/dnth]] [[ham-fisted.api/lnth]].\"\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [ham-fisted.reduce :as hamf-rf])\n  (:import [java.util List]\n           [ham_fisted Casts])\n  (:refer-clojure :exclude [let]))\n\n\n(def ^{:private true\n       :tag java.util.Map} extension-table (hamf/java-concurrent-hashmap))\n\n\n(defn extend-let\n  \"Code gets a tuple of [lhs rhs] must return\n  a flattened sequence of left and right hand sides.\n  This uses a special symbol that will look like a function call on the\n  right hand side as the dispatch mechanism.\n\n  See source code of this file for example extensions.\"\n  [sym-name code]\n  (.put extension-table sym-name code))\n\n\n(defn- rhs-code\n  [r]\n  (when (list? r)\n    (clojure.core/let [s (first r)]\n      (when (symbol? s)\n        (.get extension-table s)))))\n\n\n(defn- add-all!\n  [a bs]\n  (.addAll ^List a bs)\n  a)\n\n(defn- add!\n  ([a b]\n   (.add ^List a b)\n   a)\n  ([a b c]\n   (.add ^List a b)\n   (.add ^List a c)\n   a))\n\n\n(defn- process-bindings\n  [bindings]\n  (->\n   (reduce (fn [acc pair]\n             (if-let [code (rhs-code (pair 1))]\n               (clojure.core/let [new-pairs (code pair)]\n                 (when-not (== 0 (rem (count new-pairs) 2))\n                   (throw (RuntimeException. (str \"Code for symbol \" (first (pair 1)) \" returned uneven number of results\"))))\n                 (add-all! acc new-pairs))\n               (add-all! acc pair)))\n           (hamf/mut-list)\n           (lznc/partition-all 2 (vec bindings)))\n   (persistent!)))\n\n\n(defmacro let\n  \"Extensible let intended to allow typed destructuring of arbitrary datatypes such as primitive arrays\n  or point types.  Falls back to normal let after extension process.  Several extensions are registered by default -\n  * `dbls` and `lngs` which destructure into primitive doubles and primitive longs, respectively.\n  * `dlb-fns` and `lng-fns` which destructure into primitive doubls and longs but use the often faster IFn overloads\n     to get the data - avoiding RT.nth calls.\n  * `obj-fns` which destructure into objects using the IFn interface.\n\n```clojure\nuser> (h/let [[x y] (dbls (hamf/double-array [1 2]))]\n        (+ x y))\n3.0\n```\n  \"\n  [bindings & body]\n  (when-not (== 0 (rem (count bindings) 2))\n    (throw (RuntimeException. \"Bindings must be divisible by 2\")))\n  `(clojure.core/let ~(process-bindings bindings)\n     ~@body))\n\n(defn ^:no-doc typed-destructure\n  [code scalar-fn nth-fn]\n  (clojure.core/let [lvec (code 0)\n                     rdata (second (code 1))]\n    (if (vector? lvec)\n      (let [rtemp (if (symbol? rdata)\n                    rdata\n                    (gensym \"__tmp\"))]\n        (-> (reduce (hamf-rf/indexed-accum\n                     acc idx lv-entry\n                     (nth-fn rtemp acc idx lv-entry))\n                    (hamf/mut-list (if (identical? rtemp rdata)\n                                     nil\n                                     [rtemp rdata]))\n                    lvec)\n            (persistent!)))\n      (scalar-fn lvec rdata))))\n\n\n(defn ^:no-doc typed-nth-destructure\n  [nth-symbol scalar-cast code]\n  (typed-destructure code\n                     (fn [lvec rdata]\n                       [lvec `(~scalar-cast ~rdata)])\n                     (fn [rtemp acc ^long idx lv-entry]\n                       (add! acc lv-entry `(~nth-symbol ~rtemp ~idx)))))\n\n(extend-let 'dbls #(typed-nth-destructure 'ham-fisted.api/dnth 'ham_fisted.Casts/doubleCast %))\n(extend-let 'lngs #(typed-nth-destructure 'ham-fisted.api/lnth 'ham_fisted.Casts/longCast %))\n\n\n(defn ^:no-doc typed-fn-destructure\n  [scalar-cast code]\n  (typed-destructure code\n                     (fn [lvec rdata]\n                       [lvec `(~scalar-cast ~rdata)])\n                     (fn [rtemp acc ^long idx lv-entry]\n                       (add! acc lv-entry `(~scalar-cast (~rtemp ~idx))))))\n\n\n(extend-let 'lng-fns #(typed-fn-destructure 'ham_fisted.Casts/longCast %))\n(extend-let 'dbl-fns #(typed-fn-destructure 'ham_fisted.Casts/doubleCast %))\n(extend-let 'obj-fns #(typed-destructure %\n                                         (fn [lvec rdata]\n                                           [lvec `~rdata])\n                                         (fn [rtemp acc ^long idx lv-entry]\n                                           (add! acc lv-entry `(~rtemp ~idx)))))\n\n\n(defn let-extension-names\n  \"Return the current extension names.\"\n  []\n  (keys extension-table))\n"
  },
  {
    "path": "src/ham_fisted/impl.clj",
    "content": "(ns ham-fisted.impl\n  (:require [ham-fisted.lazy-noncaching :refer [map concat] :as lznc]\n            [ham-fisted.protocols :as protocols]\n            [clojure.core.protocols :as cl-proto]\n            [ham-fisted.language :refer [constantly]]\n            [ham-fisted.iterator :as hamf-iter]\n            [ham-fisted.defprotocol :refer [extend extend-type extend-protocol]]\n            [ham-fisted.print :refer [implement-tostring-print]])\n  (:import [java.util.concurrent ForkJoinPool ForkJoinTask ArrayBlockingQueue Future\n            TimeUnit ConcurrentHashMap]\n           [clojure.lang MapEntry Box]\n           [java.util Iterator Set Map RandomAccess Spliterator BitSet Collection\n            Iterator ArrayDeque]\n           [java.util.function Supplier]\n           [ham_fisted ParallelOptions ITypedReduce IFnDef\n            ICollectionDef ArrayLists$ObjectArrayList Reductions$ReduceConsumer\n            Reductions Transformables IFnDef$OLO ArrayLists StringCollection]\n           [clojure.lang IteratorSeq IReduceInit PersistentHashMap IFn$OLO IFn$ODO Seqable\n            IReduce PersistentList]\n           [java.util.logging Logger Level])\n  (:refer-clojure :exclude [map pmap concat extend extend-type extend-protocol constantly]))\n\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n\n(defn in-fork-join-task?\n  \"True if you are currently running in a fork-join task\"\n  []\n  (ForkJoinTask/inForkJoinPool))\n\n(defrecord ^:private GroupData [^long gsize ^long ngroups ^long leftover])\n\n\n(defn- n-elems->groups\n  \"This algorithm goes somewhat over batch size but attempts to all the indexes evenly\n  between tasks.\"\n  ^GroupData [^long parallelism ^long n-elems ^long max-batch-size]\n  (let [gsize (max 1 (min max-batch-size (quot n-elems parallelism)))\n        ngroups (quot n-elems gsize)\n        leftover (rem n-elems gsize)\n        left-blocks (quot leftover ngroups)\n        gsize (+ gsize left-blocks)\n        leftover (rem leftover ngroups)]\n    (GroupData. gsize ngroups leftover)))\n\n\n(defn- seq->lookahead\n  [^long n-ahead data]\n  ;;Ensure lazy-caching\n  (let [data (seq data)\n        n-ahead (count (take n-ahead data))]\n    [data (concat (drop n-ahead data) (repeat n-ahead nil))]))\n\n\n(defn n-lookahead\n  ^long [^ParallelOptions options]\n  (max 1\n       (long (let [n-ahead (.nLookahead options)]\n               (if (== n-ahead -1)\n                 (* (.-parallelism options) 2)\n                 n-ahead)))))\n\n\n(defn- pgroup-submission\n  [^long n-elems body-fn ^ParallelOptions options]\n  (let [pool (.-pool options)\n        n-elems (long n-elems)\n        parallelism (.-parallelism options)\n        ^GroupData gdata (n-elems->groups parallelism n-elems (.-maxBatchSize options))\n        ;;_ (println parallelism gdata)\n        gsize (.gsize gdata)\n        ngroups (.ngroups gdata)\n        leftover (.leftover gdata)]\n    (->> (range ngroups)\n         (map (fn [^long gidx]\n                (let [start-idx (long (+ (* gidx gsize)\n                                         (min gidx leftover)))\n                      end-idx (min n-elems\n                                   (long (+ (+ start-idx gsize)\n                                            (long (if (< gidx leftover)\n                                                    1 0)))))]\n                  (.submit pool ^Callable #(body-fn start-idx end-idx)))))\n         (seq->lookahead (n-lookahead options)))))\n\n\n(defrecord ^:private ErrorRecord [e])\n\n\n(defn- queue-take\n  [^ArrayBlockingQueue queue]\n  (let [^Box b (.take queue)\n        v (.-val b)]\n    (if (instance? ErrorRecord v)\n      (throw (.-e ^ErrorRecord v))\n      v)))\n\n\n(defmacro queue-put!\n  [queue v put-timeout-ms]\n  ;;You cannot put nil into a queue\n  `(let [data# (-> (try ~v (catch Exception e# (ErrorRecord. e#)))\n                   (Box.))]\n     (when-not (.offer ~queue data# ~put-timeout-ms TimeUnit/MILLISECONDS)\n       (let [msg# (str \":put-timeout-ms \" ~put-timeout-ms\n                       \"ms exceeded\")]\n         (.warning (Logger/getLogger \"ham_fisted\") msg#)\n         (throw (RuntimeException. msg#))))\n     data#))\n\n\n(defn- iter-queue->seq\n  [^Iterator iter ^ArrayBlockingQueue queue]\n  ;;We are taking advantage of the fact that iteratorSeq locks the iterator so all of the\n  ;;code below is threadsafe once it leaves this function.\n  (IteratorSeq/create (reify Iterator\n                        (hasNext [this] (.hasNext iter))\n                        (next [this]\n                          (.next iter)\n                          (queue-take queue)))))\n\n\n(defn- options->queue\n  ^ArrayBlockingQueue [^ParallelOptions options]\n  (when-not (.-ordered options)\n    (ArrayBlockingQueue. (n-lookahead options))))\n\n(defn pgroups\n  \"Run y groups across n-elems.   Y is common pool parallelism.\n\n  body-fn gets passed two longs, startidx and endidx.\n\n  Returns a sequence of the results of body-fn applied to each group of indexes.\n\n  Options:\n\n  * - See the ParallelOptions java object.\"\n  ([n-elems body-fn ^ParallelOptions options]\n   (let [parallelism (.-parallelism options)\n         n-elems (long n-elems)]\n     (if (or (in-fork-join-task?)\n             (< n-elems (.-minN options))\n             (< parallelism 2))\n       [(body-fn 0 n-elems)]\n       (let [queue (options->queue options)\n             wrapped-body-fn (if (.-ordered options)\n                               body-fn\n                               (fn [^long sidx ^long eidx]\n                                 (queue-put! queue (body-fn sidx eidx) (.-putTimeoutMs options))))\n             [submissions lookahead] (pgroup-submission n-elems wrapped-body-fn options)]\n         (if (.-ordered options)\n           ;;This will correctly propagate errors\n           (map (fn [l r] (.get ^Future l)) submissions lookahead)\n           (iter-queue->seq (.iterator ^Iterable lookahead) queue))))))\n  ([n-elems body-fn]\n   (pgroups n-elems body-fn nil)))\n\n(defn- lookahead-iterable\n  ^Iterable [^Iterator submissions ^long n-ahead deref?]\n  (let [queue (ArrayDeque. n-ahead)\n        ;;in the pmap context this immediately launches all lookahead threads\n        ;;and does no further work.\n        _ (loop [idx 0]\n            (when (and (.hasNext submissions)\n                       (< idx n-ahead))\n              (.push queue (.next submissions))\n              (recur (inc idx))))\n        update! (fn []\n                  (let [nn (if-not (.isEmpty queue)\n                             (.removeLast queue)\n                             ::finish)]\n                    (if (.hasNext submissions)\n                      (.push queue (.next submissions))\n                      (.push queue ::finish))\n                    (if (identical? nn ::finish)\n                      nn\n                      (if deref?\n                        (.get ^Future nn)\n                        nn))))]\n    (-> (hamf-iter/once-iterable #(not (identical? % ::finish)) update!)\n        (hamf-iter/seq-iterable))))\n\n(defn pmap\n  [^ParallelOptions options map-fn sequences]\n  (if (in-fork-join-task?)\n    (apply map map-fn sequences)\n    (let [pool (.-pool options)\n          ;;In this case we want a caching sequence - so we call 'seq' on a lazy noncaching\n          ;;map\n          queue (options->queue options)\n          submit-fn\n          (if (.-ordered options)\n            (case (count sequences)\n              1 (fn [arg] (.submit pool ^Callable (fn [] (map-fn arg))))\n              2 (fn [a1 a2] (.submit pool ^Callable (fn [] (map-fn a1 a2))))\n              3 (fn [a1 a2 a3] (.submit pool ^Callable (fn [] (map-fn a1 a2 a3))))\n              (fn [& args]\n                (.submit pool ^Callable (fn [] (apply map-fn args)))))\n            (case (count sequences)\n              1 (fn [arg] (.submit pool ^Callable (fn [] (queue-put! queue (map-fn arg) (.-putTimeoutMs options)))))\n              2 (fn [a1 a2] (.submit pool ^Callable (fn [] (queue-put! queue (map-fn a1 a2) (.-putTimeoutMs options)))))\n              3 (fn [a1 a2 a3] (.submit pool ^Callable (fn [] (queue-put! queue (map-fn a1 a2 a3) (.-putTimeoutMs options)))))\n              (fn [& args]\n                (.submit pool ^Callable (fn [] (queue-put! queue (apply map-fn args) (.-putTimeoutMs options)))))))\n\n          submissions (.iterator ^Iterable (apply map submit-fn sequences))\n          n-ahead (n-lookahead options)]\n      (if (.-ordered options)\n        ;;lazy noncaching map - the future itself does the caching for us.\n        (lookahead-iterable submissions n-ahead true)\n        (iter-queue->seq\n         (.iterator ^Iterable (lookahead-iterable submissions n-ahead false))\n         queue)))))\n\n\n(defn- split-spliterator\n  [^long n-splits ^Spliterator spliterator]\n  (let [lhs spliterator\n        ;;Mutates lhs...\n        rhs (.trySplit spliterator)]\n    (cond\n      ;;Sometimes the splits fail as we have too few elements\n      (nil? rhs) [lhs]\n      ;;Here we have split enough\n      (<= n-splits 1) [lhs rhs]\n      :else\n      (let [n-splits (dec n-splits)]\n        (concat (split-spliterator n-splits lhs)\n                (split-spliterator n-splits rhs))))))\n\n\n(defn- consume-spliterator!\n  [rfn acc ^Spliterator s]\n  (if (instance? IReduceInit s)\n    (.reduce ^IReduceInit s rfn acc)\n    (let [c (Reductions$ReduceConsumer/create acc rfn)]\n      (.forEachRemaining s c)\n      @c)))\n\n\n(defn parallel-spliterator-reduce\n  [initValFn rfn mergeFn ^Spliterator s ^ParallelOptions options]\n  (let [pool (.-pool options)\n        ;;I just want enough splits so that there is decent granularity as compared\n        ;;to the parallelism of the pool.  Another more common technique is to split\n        ;;until each spliterator has less than or equal to some threshold - this is used\n        ;;in various places but it requires the spliterator to estimate size correctly.\n        ;;This technique does not have that requirement.\n        n-splits (Math/round (/ (Math/log (* 4 (.-parallelism options)))\n                                (Math/log 2)))\n        spliterators (split-spliterator n-splits s)\n        ^ArrayBlockingQueue queue (options->queue options)\n        [submissions lookahead]\n        (->> spliterators\n             (map (fn [spliterator]\n                    (.submit pool\n                             ^Callable\n                             (fn []\n                               (let [acc (initValFn)\n                                     ^Spliterator s spliterator]\n                                 (if (.-ordered options)\n                                   (consume-spliterator! rfn acc s)\n                                   (queue-put! queue (consume-spliterator! rfn acc s)\n                                               (.-putTimeoutMs options))))))))\n             (seq->lookahead (n-lookahead options)))]\n    (->> (if (.-ordered options)\n           (map (fn [l r] (.get ^Future l)) submissions lookahead)\n           (map (fn [l] (queue-take queue)) lookahead))\n         (Reductions/iterableMerge options mergeFn))))\n\n\n(defn- bitset-reduce\n  ([^BitSet coll rfn acc]\n   (let [^IFn$OLO rfn (Transformables/toLongReductionFn rfn)]\n     (loop [bit (.nextSetBit coll 0)\n            acc acc]\n       (if (and (>= bit 0) (not (reduced? acc)))\n         (recur (.nextSetBit coll (unchecked-inc bit))\n                (.invokePrim rfn acc (Integer/toUnsignedLong bit)))\n         acc))))\n  ([^BitSet coll rfn]\n   (if (.isEmpty coll)\n     (rfn)\n     (loop [bit (.nextSetBit coll 0)\n            first true\n            acc nil]\n       (if (and (>= bit 0) (not (reduced? acc)))\n         (recur (.nextSetBit coll (unchecked-inc bit))\n                false\n                (if first\n                  bit\n                  (rfn acc (Integer/toUnsignedLong bit))))\n         acc)))))\n\n\n(deftype ^:private BitSetIterator [^{:unsynchronized-mutable true\n                                     :tag long} setbit\n                                   ^BitSet data]\n  Iterator\n  (hasNext [this] (not (== setbit -1)))\n  (next [this] (let [retval setbit\n                     nextbit (.nextSetBit data (unchecked-inc setbit))]\n                 (set! setbit (long (if (== nextbit -1) -1 nextbit)))\n                 retval)))\n\n(deftype SupplierIterator [^Supplier sup\n                           ^:unsynchronized-mutable val]\n  Iterator\n  (hasNext [this] (boolean val))\n  (next [this]\n    (let [rv val]\n      (set! val (.get sup))\n      rv)))\n\n\n(extend-protocol protocols/ToIterable\n  nil\n  (convertible-to-iterable? [item] true)\n  (->iterable [item] PersistentList/EMPTY)\n  java.util.function.Supplier\n  (convertible-to-iterable? [item] true)\n  (->iterable [item] (reify Iterable\n                       (iterator [this]\n                         (SupplierIterator. item (.get ^java.util.function.Supplier item)))))\n  Object\n  (convertible-to-iterable? [item] (or (instance? Iterable item)\n                                       (protocols/convertible-to-collection? item)))\n  (->iterable [item]\n    (cond\n      (instance? Iterable item)\n      item\n      (protocols/convertible-to-collection? item)\n      (protocols/->collection item)\n      :else\n      (throw (RuntimeException. (str \"Item is not iterable: \" (type item)))))))\n\n\n(extend-protocol protocols/ToCollection\n  nil\n  (convertible-to-collection? [item] true)\n  (->collection [item] PersistentList/EMPTY)\n\n  Object\n  (convertible-to-collection? [item] (or (instance? Collection item)\n                                         (instance? Map item)\n                                         (instance? Seqable item)\n                                         (.isArray (.getClass item))))\n  (->collection [item]\n    (cond\n      (instance? Collection item)\n      item\n      (.isArray (.getClass item))\n      (ArrayLists/toList item)\n      (instance? Map item)\n      (.entrySet ^Map item)\n      (instance? Seqable item)\n      (seq item)\n      :else\n      (throw (RuntimeException. (str \"Item is not convertible to collection: \" (type item))))))\n  String\n  (->collection [item] (StringCollection. item))\n  BitSet\n  (convertible-to-collection? [item] true)\n  (->collection [item]\n    (reify\n      ICollectionDef\n      (add [c obj]\n        (let [obj (int obj)\n              retval (.get item obj)]\n          (.set item (int obj))\n          retval))\n      (remove [c obj]\n        (let [obj (int obj)\n              retval (.get item obj)]\n          (.clear item obj)\n          retval))\n      (clear [c] (.clear item))\n      (size [c] (.cardinality item))\n      (iterator [c] (BitSetIterator. (.nextSetBit item 0) item))\n      (toArray [c] (let [alist (ArrayLists$ObjectArrayList. (.cardinality item))]\n                     (.addAllReducible alist c)\n                     (.toArray alist)))\n      IReduce\n      (reduce [c rfn] (bitset-reduce item rfn))\n      IReduceInit\n      (reduce [c rfn init] (bitset-reduce item rfn init)))))\n\n\n(extend-protocol protocols/PAdd\n  Collection\n  (add-fn [c] #(do (.add ^Collection %1 %2) %1)))\n\n\n(extend BitSet\n  protocols/Reduction\n  {:reducible? (constantly true)})\n\n\n(clojure.core/extend BitSet\n  cl-proto/CollReduce {:coll-reduce bitset-reduce})\n\n\n(defn- fjfork [task] (.fork ^ForkJoinTask task))\n(defn- fjjoin [task] (.join ^ForkJoinTask task))\n(defn- fjtask [^Callable f] (ForkJoinTask/adapt f))\n\n(defn- ensure-fj-pool\n  ^ForkJoinPool [p]\n  (when-not (instance? ForkJoinPool p)\n    (throw (RuntimeException. \"Pool passed in must be a forkjoin pool\")))\n  p)\n\n(extend-protocol protocols/ParallelReduction\n  Object\n  (preduce [coll init-val-fn rfn merge-fn options]\n    (cond\n      (instance? ITypedReduce coll)\n      (.parallelReduction ^ITypedReduce coll init-val-fn rfn merge-fn options)\n      (instance? RandomAccess coll)\n      (Reductions/parallelRandAccessReduction init-val-fn rfn merge-fn coll options)\n      (instance? IReduceInit coll)\n      (Reductions/serialParallelReduction init-val-fn rfn options coll)\n      (instance? Set coll)\n      (Reductions/parallelCollectionReduction init-val-fn rfn merge-fn coll options)\n      (instance? Map coll)\n      (Reductions/parallelCollectionReduction init-val-fn rfn merge-fn\n                                              (.entrySet ^Map coll) options)\n      :else\n      (Reductions/serialParallelReduction init-val-fn rfn options coll)))\n  PersistentHashMap\n  (preduce [coll init-val-fn rfn merge-fn options]\n    (let [options ^ParallelOptions options\n          pool (ensure-fj-pool (.-pool options))\n          n (.-minN options)\n          _ (when (.-unmergedResult options)\n              (throw (RuntimeException. \"Persistent hash maps do not support unmerged results\")))\n          combinef (fn\n                     ([] (init-val-fn))\n                     ([lhs rhs] (merge-fn lhs rhs)))\n          fjinvoke (fn [f]\n                     (if (in-fork-join-task?)\n                       (f)\n                       (.invoke pool ^ForkJoinTask (fjtask f))))\n          rf (fn [acc k v] (rfn acc (MapEntry/create k v)))]\n      (.fold coll n combinef rf fjinvoke fjtask fjfork fjjoin))))\n\n\n(defmacro array-fast-reduce\n  [ary-cls]\n  `(do\n     (clojure.core/extend ~ary-cls\n       cl-proto/CollReduce\n       {:coll-reduce (fn\n                       ([~(with-meta 'coll {:tag ary-cls}) f#]\n                        (.reduce (ArrayLists/toList ~'coll) f#))\n                       ([~(with-meta 'coll {:tag ary-cls}\n                            ) f# acc#]\n                        (.reduce (ArrayLists/toList ~'coll) f# acc#)))})\n     (extend ~ary-cls\n       protocols/Reduction\n       {:reducible? (constantly true)})))\n\n\n(array-fast-reduce (Class/forName \"[B\"))\n(array-fast-reduce (Class/forName \"[S\"))\n(array-fast-reduce (Class/forName \"[C\"))\n(array-fast-reduce (Class/forName \"[I\"))\n(array-fast-reduce (Class/forName \"[J\"))\n(array-fast-reduce (Class/forName \"[F\"))\n(array-fast-reduce (Class/forName \"[D\"))\n(array-fast-reduce (Class/forName \"[Z\"))\n(array-fast-reduce (Class/forName \"[Ljava.lang.Object;\"))\n\n\n(defn map-fast-reduce\n  [map-cls]\n  (clojure.core/extend\n      cl-proto/CollReduce\n    {:coll-reduce (fn map-reducer\n                    ([coll f]\n                     (Reductions/iterReduce (.entrySet ^Map coll) f))\n                    ([coll f init]\n                     (Reductions/iterReduce (.entrySet ^Map coll) init f)))})\n  (extend map-cls\n    protocols/ToCollection\n    {:convertible-to-collection? (constantly true)\n     :->collection (fn [^Map m]\n                     (reify\n                       ICollectionDef\n                       (size [this] (.size m))\n                       (iterator [this] (.iterator (.entrySet m)))\n                       IReduce\n                       (reduce [this rfn]\n                         (if (instance? IReduce m)\n                           (.reduce ^IReduce m rfn)\n                           (Reductions/iterReduce (.entrySet m) rfn)))\n                       IReduceInit\n                       (reduce [this rfn init]\n                         (if (instance? IReduceInit m)\n                           (.reduce ^IReduceInit m rfn init)\n                           (Reductions/iterReduce (.entrySet m) init rfn)))))}\n    protocols/ToIterable\n    {:convertible-to-iterable? (constantly true)\n     :->iterable (fn [m] (protocols/->collection m))}))\n\n(map-fast-reduce java.util.HashMap)\n(map-fast-reduce java.util.LinkedHashMap)\n(map-fast-reduce java.util.SortedMap)\n(map-fast-reduce java.util.concurrent.ConcurrentHashMap)\n\n\n(defn iterable-fast-reduce\n  [coll-cls]\n  (clojure.core/extend coll-cls\n    cl-proto/CollReduce\n    {:coll-reduce (fn map-reducer\n                    ([coll f]\n                     (Reductions/iterReduce coll f))\n                    ([coll f init]\n                     (Reductions/iterReduce coll init f)))}))\n\n\n(iterable-fast-reduce java.util.HashSet)\n(iterable-fast-reduce java.util.LinkedHashSet)\n(iterable-fast-reduce java.util.SortedSet)\n"
  },
  {
    "path": "src/ham_fisted/iterator.clj",
    "content": "(ns ham-fisted.iterator\n  \"Generialized efficient pathways involving iterators.\"\n  (:require [ham-fisted.language :refer [cond not]]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.print :refer [implement-tostring-print]])\n  (:import [java.util Iterator PriorityQueue Comparator]\n           [java.util.stream Stream]\n           [java.util.function Supplier Function BiFunction Consumer Predicate BiConsumer]\n           [java.util.concurrent BlockingQueue]\n           [clojure.lang ArraySeq Seqable IteratorSeq]\n           [ham_fisted StringCollection ArrayLists MergeIterator MergeIterator$CurrentIterator\n            Transformables$MapIterable ITypedReduce Reductions Transformables])\n  (:refer-clojure :exclude [cond not next]))\n\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n(defn has-next? \"Given an iterator or nil return true if the iterator has next.\"\n  [^Iterator iter] (boolean (and iter (.hasNext iter))))\n\n(defn next \"Given an iterator call next.\"\n  [^Iterator iter] (.next iter))\n\n(defn maybe-next \"Given an iterator or nil return the next element if the iterator hasNext.\"\n  [^Iterator iter] (when (has-next? iter) (.next iter)))\n\n(def ^{:arglists '[[a]]} non-nil? (hamf-fn/predicate a (if (nil? a) false true)))\n\n(defn- failed-coercion-message\n  ^String [item target-type]\n  (format \"Item type %s has no coercion to %s\"\n          (type item) target-type))\n\n\n(defn ary-iter\n  \"Create an iterator for any primitive or object java array.\"\n  ^Iterator [ary-data]\n  (.iterator (ArrayLists/toList ary-data)))\n\n(definterface CtxAdvance\n  (advance []))\n\n(deftype ^:private CtxIter [valid? init-fn update-fn val-fn\n                            ^:unsynchronized-mutable step\n                            ^:unsynchronized-mutable ctx]\n  CtxAdvance\n  (advance [m]\n    (let [s step]\n      (cond\n        (identical? s ::empty-init)\n        (set! ctx (init-fn))\n        (identical? s ::empty-update)\n        (set! ctx (update-fn ctx)))\n      (set! step ::value)))\n  Iterator\n  (hasNext [this]\n    (.advance this)\n    (boolean (valid? ctx)))\n  (next [this]\n    (.advance this)\n    (set! step ::empty-update)\n    (val-fn ctx)))\n\n(defn ctx-iter\n  ^CtxIter [valid? init-fn update-fn val-fn]\n  (CtxIter. valid? init-fn update-fn val-fn ::empty-init nil))\n\n(defn ->iterator\n  \"Convert a stream, supplier, or an iterable into an iterator.\"\n  ^Iterator [item]\n  (cond\n    (nil? item)\n    nil\n    (instance? Iterator item)\n    item\n    (instance? ArraySeq item)\n    (->iterator (.array ^ArraySeq item))\n    (instance? Iterable item)\n    (.iterator ^Iterable item)\n\n    (.isArray (.getClass ^Object item))\n    (ary-iter item)\n    (instance? CharSequence item)\n    (.iterator (StringCollection. ^CharSequence item))\n    (instance? Stream item)\n    (.iterator ^Stream item)\n    (instance? Supplier item)\n    (let [^Supplier item item\n          init-update (fn ([] (.get item)) ([_] (.get item)))]\n      (ctx-iter non-nil? init-update init-update identity))\n    :else\n    (throw (Exception. (failed-coercion-message item \"iterator\")))))\n\n\n(defmacro doiter\n  \"Execute body for every item in the iterable.  Expecting side effects, returns nil.\"\n  [varname iterable & body]\n  `(let [iter# (->iterator ~iterable)]\n     (loop [continue?# (.hasNext iter#)]\n       (when continue?#\n         (let [~varname (.next iter#)]\n           ~@body\n           (recur (.hasNext iter#)))))))\n\n\n(defn linear-merge-iterator\n  \"Create a merging iterator - fast for N < 8.\"\n  (^Iterator [cmp p iterators] (MergeIterator/createMergeIterator iterators cmp p))\n  (^Iterator [cmp iterators] (MergeIterator/createMergeIterator iterators cmp))\n  (^Iterator [iterators] (MergeIterator/createMergeIterator iterators compare)))\n\n(deftype ^:private CurrentIterator [^Iterator iter ^:unsynchronized-mutable current]\n  Iterator\n  (hasNext [this] (.hasNext iter))\n  (next [this] (let [c (.next iter)]\n                 (set! current c)\n                 c))\n  clojure.lang.IDeref\n  (deref [this] current))\n\n(defn current-iterator\n  \"Return a current iterator - and iterator that retains the current object.\n  This iterator is positioned just before the first object so it's current item\n  is nil.\"\n  ^CurrentIterator [item]\n  (let [iter (->iterator item)]\n    (cond\n      (nil? iter)\n      nil\n      (.hasNext iter)\n      (CurrentIterator. iter nil)\n      :else\n      nil)))\n\n(defn iterable\n  \"Create an iterable.  init-fn is not called until the first has-next call.\n\n  * valid? - ctx->boolean - defaults to non-nil?\n  * init-fn - creates new ctx\n  * update-fn - function from ctx->ctx\n  * val-fn - function from ctx->val - defaults to deref\"\n  (^Iterable [valid? init-fn update-fn val-fn]\n   (reify Iterable\n     (iterator [this]\n       (ctx-iter valid? init-fn update-fn val-fn))))\n  (^Iterable [init-fn update-fn]\n   (iterable non-nil? init-fn update-fn deref)))\n\n(defn once-iterable\n  \"Create an iterable that can only be iterated once - it always returns the same (non threadsafe) iterator\n  every `iterator` call.  init-fn is not called until the first has-next call - also see [[iterable]].\n\n  The arguments have different defaults as once-iterables can close over global context on construction\n  as they can only be iterated once.\n\n  * valid? - ctx->boolean - defaults to non-nil?\n  * init-fn - creates new ctx\n  * update-fn - function from ctx->ctx - defaults to init-fn ignoring argument.\n  * val-fn - function from ctx->val - defaults to identity\"\n  (^Iterable [valid? init-fn update-fn val-fn]\n   ;;iterator defined outside of iterable so we can correctly survive patterns like (when (seq v) ...)\n   (let [iter (.iterator (iterable valid? init-fn update-fn val-fn))]\n     (reify Iterable (iterator [this] iter))))\n  (^Iterable [valid? init-fn]\n   (once-iterable valid? init-fn (fn [_] (init-fn)) identity))\n  (^Iterable [init-fn]\n   (once-iterable non-nil? init-fn)))\n\n(deftype ^:private SeqIterable [^Iterable iable seq-data* m]\n  clojure.lang.IPersistentCollection\n  (cons [_ o]\n    (if-let [sq @seq-data*]\n      (.cons ^clojure.lang.IPersistentCollection sq o)\n      (list o)))\n  (empty [_] '())\n  (equiv [this o] (clojure.lang.Util/equiv (seq this) o))\n  clojure.lang.Sequential\n  clojure.lang.IHashEq\n  (hasheq [this] (hash (or (seq this) '())))\n  Seqable\n  (seq [this]\n    (vswap! seq-data*\n            (fn [val]\n              (if val\n                val\n                (IteratorSeq/create (.iterator this))))))\n  ITypedReduce\n  (reduce [this rfn acc]\n    (if-let [seq-impl @seq-data*]\n      (reduce rfn acc seq-impl)\n      (Reductions/iterReduce this acc rfn)))\n  Iterable\n  (iterator [this]\n    (if-let [ss @seq-data*]\n      (.iterator ^Iterable @seq-data*)\n      (.iterator iable)))\n  clojure.lang.IObj\n  (withMeta [this new-m] (SeqIterable. iable seq-data* new-m))\n  (meta [this] m)\n  Object\n  (toString [this] (Transformables/sequenceToString (or (seq this) '()))))\n\n(implement-tostring-print SeqIterable)\n\n(defn seq-iterable\n  \"Iterable with efficient reduce but also contains a cached seq conversion so patterns like:\n  (when (seq v) ...) still work without needing to dereference the iterable twice.\"\n  ^Iterable [iterable]\n  (SeqIterable. iterable (volatile! nil) nil))\n\n(defn seq-once-iterable\n  (^Iterable [valid? init update val-fn]\n   (-> (once-iterable valid? init update val-fn)\n       (seq-iterable)))\n  (^Iterable [valid? init]\n   (-> (once-iterable valid? init)\n       (seq-iterable)))\n  (^Iterable [init]\n   (-> (once-iterable init)\n       (seq-iterable))))\n\n(defn- is-not-empty?\n  [^java.util.Collection c]\n  (not (.isEmpty c)))\n\n(defn- obj-aget [^objects a ^long idx] (aget a idx))\n\n(deftype ^:private ConsIter [^:unsynchronized-mutable v ^Iterator iter]\n  Iterator\n  (hasNext [this] (boolean (or (not (identical? v ::empty)) (.hasNext iter))))\n  (next [this]\n    (if (identical? v ::empty)\n      (.next iter)\n      (do (let [rv v] (set! v ::empty) rv))))\n  clojure.lang.IDeref\n  (deref [this] v))\n\n(defn iter-cons\n  \"Produce a new iterator that points to vv then defers to passed in iterator.\"\n  ^Iterator [vv ^Iterator iter]\n  ;;attempt to keep stack of cons-iters as small as possible\n  (if (and (instance? ConsIter iter) (identical? @iter ::empty))\n    (iter-cons vv (.-iter ^ConsIter iter))\n    (ConsIter. vv iter)))\n\n(defn dedup-first-by\n  \"Given a sorted sequence remove duplicates keeping first.\"\n  ([key-fn ^Comparator cmp data]\n   (let [update (fn [{:keys [iter]}]\n                  (when (has-next? iter)\n                    (let [vv (next iter)\n                          k (key-fn vv)]\n                      (loop []\n                        (if (has-next? iter)\n                          (let [nv (next iter)]\n                            (if (== 0 (.compare cmp k (key-fn nv)))\n                              (recur)\n                              {:iter (iter-cons nv iter)\n                               :val vv}))\n                          {:val vv})))))]\n     (seq-once-iterable :val #(update {:iter (->iterator data)}) update :val)))\n  ([^Comparator cmp data]\n   (dedup-first-by identity cmp data)))\n\n(defn merge-iterable\n  \"Create an efficient stable n-way merge between a sequence of iterables using comparator.  If iterables themselves\n  are sorted result will be sorted.  If two items tie then the one from the leftmost iterable wins.\"\n  [^Comparator cmp iterables]\n  (seq-iterable\n   (iterable\n    is-not-empty?\n    #(let [pq (PriorityQueue. (hamf-fn/make-comparator a b\n                                                       (let [cc (.compare cmp (obj-aget a 1) (obj-aget b 1))]\n                                                         (if (== cc 0)\n                                                           (.compareTo ^Comparable (obj-aget a 2) (obj-aget b 2))\n                                                           cc))))]\n       (loop [outer-iter (->iterator iterables)\n              idx 0]\n         (when (has-next? outer-iter)\n           (when-let [iter (->iterator (.next outer-iter))]\n             (when (has-next? iter)\n               (.offer pq (object-array [iter (.next iter) idx]))))\n           (recur outer-iter (inc idx))))\n       pq)\n    (fn [^PriorityQueue pq]\n      (let [^objects entry (.poll pq)\n            ^Iterator iter (aget entry 0)]\n        (when (.hasNext iter)\n          (aset entry 1 (.next iter))\n          (.offer pq entry)))\n      pq)\n    #(obj-aget (.peek ^PriorityQueue %) 1))))\n\n(defn unstable-merge-iterable\n  \"Create an efficient n-way merge between a sequence of iterables using comparator.  If iterables themselves\n  are sorted result will be sorted.\"\n  [^Comparator cmp iterables]\n  (seq-iterable\n   (iterable\n    is-not-empty?\n    #(let [pq (PriorityQueue. (hamf-fn/make-comparator a b (.compare cmp (obj-aget a 1) (obj-aget b 1))))]\n       (run! (fn [iable]\n               (when-let [iter (->iterator iable)]\n                 (when (.hasNext iter)\n                   (.offer pq (object-array [iter (.next iter)])))))\n             iterables)\n       pq)\n    (fn [^PriorityQueue pq]\n      (let [^objects entry (.poll pq)\n            ^Iterator iter (aget entry 0)]\n        (when (.hasNext iter)\n          (aset entry 1 (.next iter))\n          (.offer pq entry)))\n      pq)\n    #(obj-aget (.peek ^PriorityQueue %) 1))))\n\n(defn blocking-queue->iterable\n  \"Given a blocking queue return an iterable that iterates until queue returns term-symbol.  Uses\n  take to block indefinitely  --  will throw any throwable that comes out of the queue.\"\n  ([^BlockingQueue queue term-symbol]\n   (seq-iterable (once-iterable\n                  #(not (identical? % term-symbol))\n                  #(let [v (.take queue)]\n                     (when (instance? Throwable v)\n                       (throw (RuntimeException. \"Error retrieving queue value\" v)))\n                     v))))\n  ([^BlockingQueue queue timeout-us timeout-symbol term-symbol]\n   (seq-iterable (once-iterable\n                  #(not (identical? % term-symbol))\n                  #(let [v (.poll queue timeout-us java.util.concurrent.TimeUnit/MICROSECONDS)]\n                     (cond\n                       (instance? Throwable v) (throw (RuntimeException. \"Error retrieving queue value\" v))\n                       (nil? v) timeout-symbol\n                       v))))))\n\n(defn const-iterable\n  \"Return an iterable that always returns a arg.\"\n  ^Iterable [arg]\n  (reify Iterable\n    (iterator [this]\n      (reify Iterator\n        (hasNext [this] true)\n        (next [this] arg)))))\n\n(deftype IterTake [^Iterator iter ^long n ^{:unsynchronized-mutable true\n                                            :tag long} idx]\n  Iterator\n  (hasNext [this] (and (.hasNext iter) (< idx n)))\n  (next [this]\n    (set! idx (inc idx))\n    (.next iter)))\n\n(defn iter-take \"take n from an iterator returning a new iterator\"\n  ^Iterator [^long n coll] (IterTake. (->iterator coll) n 0))\n\n(defn wrap-iter\n  \"Wrap an iterator returning an iterable.\"\n  ^Iterable [iter]\n  (-> (reify Iterable (iterator [this] (->iterator iter)))\n      seq-iterable))\n\n(defn iter-take-while\n  \"Returns {:data :rest*} where rest* resolves to an iterator once data has been\n  completely consumed.\"\n  [pred iter]\n  (let [iter (->iterator iter)]\n    (when (has-next? iter)\n      (let [res (promise)\n            updater (fn []\n                      (try\n                        (if (has-next? iter)\n                          (let [v (next iter)]\n                            (if (pred v)\n                              v\n                              (do\n                                (deliver res\n                                         (seq-iterable\n                                          (reify Iterable\n                                            (iterator [this]\n                                              (if v (iter-cons v iter) iter)))))\n                                nil)))\n                          (do\n                            (deliver res nil)\n                            nil))\n                        (catch Throwable e\n                          (println \"During take while!!\" e)\n                          (deliver res e)\n                          e)))]\n        {:data (seq-once-iterable non-nil? updater)\n         :rest* res}))))\n"
  },
  {
    "path": "src/ham_fisted/language.clj",
    "content": "(ns ham-fisted.language\n  (:import [ham_fisted Transformables]\n           [ham_fisted ObjArray])\n  (:refer-clojure :exclude [cond constantly not]))\n\n(defmacro cond\n  \"See documentation for [[ham-fisted.api/cond]]\"\n  [& clauses]\n  (let [clauses (vec clauses)\n        nc (count clauses)\n        constant-clause? #(or (identical? % true)\n                              (keyword? %))\n        odd-clauses? (odd? nc)\n        else? (or odd-clauses? (and (> nc 2)\n                                    (constant-clause? (nth clauses (- nc 2)))))]\n    (if-not else?\n      `(clojure.core/cond ~@clauses)\n      (let [[clauses else-branch] (if odd-clauses?\n                                    [(subvec clauses 0 (dec nc)) (last clauses)]\n                                    [(subvec clauses 0 (- nc 2)) (last clauses)])\n            pred-true-branch (reverse (partition 2 clauses))]\n        (reduce (fn [stmts [pred true-branch]]\n                  `(if ~pred ~true-branch ~stmts))\n                else-branch\n                pred-true-branch)))))\n\n(def array-classes {:byte (.getClass ^Object (clojure.core/byte-array 0))\n                    :short (.getClass ^Object (clojure.core/short-array 0))\n                    :char (.getClass ^Object (clojure.core/char-array 0))\n                    :int (.getClass ^Object (clojure.core/int-array 0))\n                    :long (.getClass ^Object (clojure.core/long-array 0))\n                    :float (.getClass ^Object (clojure.core/float-array 0))\n                    :double (.getClass ^Object (clojure.core/double-array 0))\n                    :boolean (.getClass ^Object (clojure.core/boolean-array 0))\n                    :object (.getClass ^Object (clojure.core/object-array 0))})\n\n(defn constantly\n  [x]\n  (fn constantly-fn\n    ([] x)\n    ([a] x)\n    ([a b] x)\n    ([a b c] x)\n    ([a b c d] x)\n    ([a b c d e] x)\n    ([a b c d e & args] x)))\n\n(defn not\n  \"Returns boolean opposite of passed in value\"\n  {:inline (fn [x] `(Transformables/not ~x))\n   :inline-arities #{1}}\n  [a]\n  (Transformables/not a))\n\n(def ^:private empty-objs (clojure.core/object-array 0))\n\n\n(defn obj-ary\n  \"As quickly as possible, produce an object array from these inputs.  Very fast for arities\n  <= 16.\"\n  (^objects [] empty-objs)\n  (^objects [v0] (ObjArray/create v0))\n  (^objects [v0 v1] (ObjArray/create v0 v1))\n  (^objects [v0 v1 v2] (ObjArray/create v0 v1 v2))\n  (^objects [v0 v1 v2 v3] (ObjArray/create v0 v1 v2 v3))\n  (^objects [v0 v1 v2 v3 v4] (ObjArray/create v0 v1 v2 v3 v4))\n  (^objects [v0 v1 v2 v3 v4 v5] (ObjArray/create v0 v1 v2 v3 v4 v5))\n  (^objects [v0 v1 v2 v3 v4 v5 v6] (ObjArray/create v0 v1 v2 v3 v4 v5 v6))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9) v10)\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v0 v11))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v0 v11 v12))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v0 v11 v12 v13))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v0 v11 v12 v13 v14))\n  (^objects [v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15] (ObjArray/create v0 v1 v2 v3 v4 v5 v6 v7 v8 v9 v0 v11 v12 v13 v14 v15)))\n"
  },
  {
    "path": "src/ham_fisted/lazy_caching.clj",
    "content": "(ns ham-fisted.lazy-caching\n  (:require [ham-fisted.lazy-noncaching :as lznc])\n  (:import [java.util RandomAccess List Iterator]\n           [ham_fisted Transformables$CachingIterable Transformables$CachingList\n            ArrayLists ArrayHelpers ArrayLists$ObjectArrayList LazyChunkedSeq]\n           [clojure.lang ISeq ArraySeq IFn ChunkedCons ArrayChunk])\n  (:refer-clojure :exclude [map filter concat repeatedly]))\n\n\n(defmacro lazy-chunked-seq\n  [chunked-cons-code]\n  `(LazyChunkedSeq. (fn [] ~chunked-cons-code)))\n\n\n(defn- seq-map-recur\n  ([f ^ISeq c1 ^ISeq c2]\n   (let [chunk-data (ArrayLists/objectArray 32)]\n     (loop [c1 c1\n            c2 c2\n            idx 0]\n       (if (and c1 c2 (< idx 32))\n         (do\n           (ArrayHelpers/aset chunk-data idx (f (.first c1) (.first c2)))\n           (recur (.next c1) (.next c2) (unchecked-inc idx)))\n         (ChunkedCons. (ArrayChunk. chunk-data 0 idx)\n                       (when (and c1 c2)\n                         (lazy-chunked-seq (seq-map-recur f c1 c2))))))))\n  ([f ^ISeq c1 ^ISeq c2 ^ISeq c3]\n   (let [chunk-data (ArrayLists/objectArray 32)]\n     (loop [c1 c1\n            c2 c2\n            c3 c3\n            idx 0]\n       (if (and c1 c2 c3 (< idx 32))\n         (do\n           (ArrayHelpers/aset chunk-data idx (f (.first c1) (.first c2) (.first c3)))\n           (recur (.next c1) (.next c2) (.next c3 )(unchecked-inc idx)))\n         (ChunkedCons. (ArrayChunk. chunk-data 0 idx)\n                       (when (and c1 c2 c3)\n                         (lazy-chunked-seq (seq-map-recur f c1 c2 c3))))))))\n  ([f ^ISeq c1 ^ISeq c2 ^ISeq c3 ^ISeq c4]\n   (let [chunk-data (ArrayLists/objectArray 32)]\n     (loop [c1 c1\n            c2 c2\n            c3 c3\n            c4 c4\n            idx 0]\n       (if (and c1 c2 c3 c4 (< idx 32))\n         (do\n           (ArrayHelpers/aset chunk-data idx (f (.first c1) (.first c2) (.first c3) (.first c4)))\n           (recur (.next c1) (.next c2) (.next c3) (.next c4) (unchecked-inc idx)))\n         (ChunkedCons. (ArrayChunk. chunk-data 0 idx)\n                       (when (and c1 c2 c3 c4)\n                         (lazy-chunked-seq (seq-map-recur f c1 c2 c3 c4))))))))\n  ([f ^List cs]\n   (let [chunk-data (ArrayLists/objectArray 32)\n         ncs (.size cs)\n         args (ArrayLists/objectArray ncs)\n         [cidx next?]\n         (loop [cidx 0\n                next? true]\n           (if (and next? (< cidx 32))\n             (let [next? (loop [idx 0 next? true]\n                           (if (< idx ncs)\n                             (let [^ISeq c (.get cs (unchecked-int idx))\n                                   _ (ArrayHelpers/aset args (unchecked-int idx) (.first c))\n                                   c (.next c)]\n                               (.set cs (unchecked-int idx) c)\n                               (recur (unchecked-inc idx) (and next? c)))\n                             next?))]\n               (ArrayHelpers/aset chunk-data cidx (.applyTo ^IFn f (ArraySeq/create args)))\n               (recur (unchecked-inc cidx) next?))\n             [cidx next?]))]\n     (ChunkedCons. (ArrayChunk. chunk-data 0 cidx)\n                   (when next?\n                     (lazy-chunked-seq (seq-map-recur f cs)))))))\n\n(defn ^:no-doc seq-map\n  ([f arg] (clojure.core/map f arg))\n  ([f c1 c2]\n   (let [^ISeq c1 (seq c1)\n         ^ISeq c2 (seq c2)]\n     (if (and c1 c2)\n       (seq-map-recur f c1 c2)\n       '())))\n  ([f c1 c2 c3]\n   (let [^ISeq c1 (seq c1)\n         ^ISeq c2 (seq c2)\n         ^ISeq c3 (seq c3)]\n     (if (and c1 c2 c3)\n       (seq-map-recur f c1 c2 c3)\n       '())))\n  ([f c1 c2 c3 c4]\n   (let [^ISeq c1 (seq c1)\n         ^ISeq c2 (seq c2)\n         ^ISeq c3 (seq c3)\n         ^ISeq c4 (seq c4)]\n     (if (and c1 c2 c3 c4)\n       (seq-map-recur f c1 c2 c3 c4)\n       '())))\n  ([f c1 c2 c3 c4 args]\n   (let [cs (ArrayLists$ObjectArrayList.)\n         c1 (seq c1)\n         c2 (seq c2)\n         c3 (seq c3)\n         c4 (seq c4)]\n     (if (and c1 c2 c3 c4)\n       (do\n         (.add cs c1)\n         (.add cs c2)\n         (.add cs c3)\n         (.add cs c4)\n         (let [all-valid?\n               (reduce (fn [acc v]\n                         (if-let [s (seq v)]\n                           (do (.add cs s)\n                               acc)\n                           (reduced false)))\n                       true\n                       args)]\n           (if all-valid?\n             (seq-map-recur f cs)\n             '())))\n       '()))))\n\n\n(defn map\n  ([f arg] (clojure.core/map f arg))\n  ([f c1 c2] (seq-map f c1 c2))\n  ([f c1 c2 c3] (seq-map f c1 c2 c3))\n  ([f c1 c2 c3 c4] (seq-map f c1 c2 c3 c4))\n  ([f c1 c2 c3 c4 & args] (seq-map f c1 c2 c3 c4 args)))\n\n\n(defn- seq-tuple-map\n  ([f ^ISeq c1 ^ISeq c2]\n   (let [args (ArrayLists/objectArray 2)\n         _ (ArrayHelpers/aset args (unchecked-int 0) (.first c1))\n         _ (ArrayHelpers/aset args (unchecked-int 1) (.first c2))\n         c1 (.next c1)\n         c2 (.next c2)]\n     (cons (f (ArrayLists/toList args))\n           (when (and c1 c2)\n             (lazy-seq (seq-tuple-map f c1 c2))))))\n  ([f ^List cs]\n   (let [n-args (.size cs)\n         args (ArrayLists/objectArray n-args)\n         next? (loop [idx 0\n                      next? true]\n                 (if (< idx n-args)\n                   (let [^ISeq c (.get cs (unchecked-int idx))\n                         _ (ArrayHelpers/aset args (unchecked-int idx) (.first c))\n                         c (.next c)]\n                     (.set cs (unchecked-int idx) c)\n                     (recur (unchecked-inc idx) (and next? c)))\n                   next?))]\n     (cons (f (ArrayLists/toList args))\n           (when next?\n             (lazy-seq (seq-tuple-map f cs)))))))\n\n\n(defn tuple-map\n  \"f always receives a single tuple argument.  This is *far* faster for larger argument lists.\"\n  ([f arg] (clojure.core/map #(f [%]) arg))\n  ([f c1 c2]\n   (let [c1 (seq c1)\n         c2 (seq c2)]\n     (if (and c1 c2)\n       (seq-tuple-map f c1 c2)\n       '())))\n  ([f c1 c2 & args]\n   (let [args (doto  (ArrayLists$ObjectArrayList.)\n                (.add (seq c1))\n                (.add (seq c2))\n                (.addAll (lznc/map seq args)))]\n     (if (lznc/every? identity args)\n       (seq-tuple-map f args)\n       '()))))\n\n\n\n(defn filter\n  [pred coll]\n  (-> (lznc/filter pred coll)\n      (seq)))\n\n\n(defn concat\n  ([] nil)\n  ([a] a)\n  ([a b] (->> (lznc/concat a b)\n              (seq)))\n  ([a b & args]\n   (-> (apply lznc/concat a b args)\n       (seq))))\n\n\n(defn repeatedly\n  ([f] (clojure.core/repeatedly f))\n  ([n f] (-> (lznc/repeatedly n f)\n             (seq))))\n"
  },
  {
    "path": "src/ham_fisted/lazy_noncaching.clj",
    "content": "(ns ham-fisted.lazy-noncaching\n  \"Lazy, noncaching implementation of many clojure.core functions.  There are several benefits of carefully\n   constructed lazy noncaching versions:\n\n   1. No locking - better multithreading/green thread performance.\n   2. Higher performance generally.\n   3. More datatype flexibility - if map is passed a single randomly addressible or generically\n   parallelizable container the result is still randomly addressible or generically perallelizable.\n   For instance (map key {:a 1 :b 2}) returns in the generic case something that can still be parallelizable\n   as the entry set of a map implements spliterator.\"\n  (:require [ham-fisted.iterator :as iterator]\n            [ham-fisted.alists :as alists]\n            [ham-fisted.protocols :as protocols]\n            [ham-fisted.defprotocol :as hamf-defproto]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.print :as pp]\n            [ham-fisted.language :as hamf-language]\n            [ham-fisted.iterator :as hamf-iter]\n            [ham-fisted.datatypes])\n  (:import [ham_fisted Transformables$MapIterable Transformables$FilterIterable\n            Transformables$CatIterable Transformables$MapList Transformables$IMapable\n            Transformables$SingleMapList Transformables StringCollection ArrayLists\n            ArrayImmutList ArrayLists$ObjectArrayList IMutList TypedList LongMutList\n            DoubleMutList ReindexList Transformables$IndexedMapper\n            IFnDef$OLO IFnDef$ODO Reductions Reductions$IndexedAccum\n            IFnDef$OLOO ArrayHelpers ITypedReduce PartitionByInner Casts\n            IMutList LazyChunkedSeq ParallelOptions$CatParallelism MutTreeList IFnDef\n            LongAccum]\n           [java.lang.reflect Array]\n           [it.unimi.dsi.fastutil.ints IntArrays]\n           [java.util.concurrent.atomic AtomicLong]\n           [java.util RandomAccess Collection Map List Random Set Iterator Map$Entry ArrayList Comparator]\n           [clojure.lang RT IPersistentMap IReduceInit IReduce PersistentList\n            IFn$OLO IFn$ODO IFn$DD IFn$LD IFn$OD IFn ArraySeq\n            IFn$DL IFn$LL IFn$OL IFn$D IFn$L IFn$LO IFn$DO Counted IDeref Seqable IObj\n            ])\n  (:refer-clojure :exclude [map concat filter repeatedly into-array shuffle object-array\n                            remove map-indexed partition-by partition-all every?\n                            complement cond drop take count]))\n\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n\n(def ^{:tag ArrayImmutList} empty-vec ArrayImmutList/EMPTY)\n\n(declare concat map-reducible every?)\n\n(defmacro cond\n  \"See documentation for [[ham-fisted.api/cond]]\"\n  [& clauses]\n  `(hamf-language/cond ~@clauses))\n\n(defn count\n  ^long [m]\n  (protocols/count m))\n\n(hamf-defproto/extend Map$Entry protocols/Counted {:count 2})\n(hamf-defproto/extend nil protocols/Counted {:count 0})\n\n(defmacro countable-arrays\n  []\n  `(do\n     ~@(->> hamf-language/array-classes\n            (mapcat (fn [kv]\n                      (let [alen-name (symbol (str (name (key kv)) \"-alength\"))]\n                        `[(defn ~alen-name\n                            ~(with-meta [(with-meta 'm {:tag (.getName ^Class (val kv))})]\n                               {:tag 'long})\n                            (alength ~'m))\n                          (hamf-defproto/extend ~(val kv) protocols/Counted {:count ~alen-name})]))))))\n\n(countable-arrays)\n\n(hamf-defproto/extend-protocol protocols/Counted\n  clojure.lang.Counted (count [s] (.count s))\n  java.util.RandomAccess (count [s] (.size ^java.util.Collection s))\n  CharSequence (count [s] (.length s))\n  Map (count [s] (.size s))\n  Transformables$CatIterable (count [s]\n                               (let [lc (LongAccum. 0)]\n                                 (reduce (fn [^LongAccum lc _v]\n                                           (.accept lc (count _v))\n                                           lc)\n                                         lc\n                                         (reify Iterable (iterator [this]\n                                                           (.containerIter ^Transformables$CatIterable s))))\n                                 (long (.deref lc))))\n  Object (count [s] (let [lc (LongAccum. 0)]\n                      (reduce (fn [^LongAccum lc _v]\n                                (.accept lc 1)\n                                lc)\n                              lc\n                              s)\n                      (long (.deref lc)))))\n\n\n(defn ->collection\n  \"Ensure an item implements java.util.Collection.  This is inherently true for seqs and any\n  implementation of java.util.List but not true for object arrays.  For maps this returns\n  the entry set.\"\n  ^Collection [item]\n  (cond\n    (nil? item) empty-vec\n    (instance? Collection item)\n    item\n    :else\n    (protocols/->collection item)))\n\n\n(defn ->reducible\n  [item]\n  (if (or (instance? IReduceInit item)\n          (instance? IReduce item)\n          (instance? Iterable item)\n          (protocols/reducible? item))\n    item\n    (->collection item)))\n\n\n(defn ->iterable\n  ^Iterable [a]\n  (if (instance? Iterable a) a\n      (protocols/->iterable a)))\n\n\n(def ^:private obj-ary-cls (Class/forName \"[Ljava.lang.Object;\"))\n\n\n(defn object-array\n  \"Faster version of object-array for eductions, java collections and strings.\"\n  ^objects [item]\n  (let [item (if (instance? Map item) (.entrySet ^Map item) item)]\n    (cond\n      (or (nil? item) (number? item))\n      (clojure.core/object-array item)\n      (instance? obj-ary-cls item)\n      item\n      ;;Results of eduction aren't collections but do implement IReduceInit\n      (instance? IReduceInit item)\n      (if (or (instance? RandomAccess item) (instance? Counted item))\n        (let [item-size (if (instance? RandomAccess item) (.size ^List item) (count item))\n              retval (clojure.core/object-array item-size)]\n          (reduce (Reductions$IndexedAccum.\n                   (reify IFnDef$OLOO\n                     (invokePrim [this acc idx v]\n                       (ArrayHelpers/aset ^objects acc (unchecked-int idx) v)\n                       acc)))\n                  retval\n                  item))\n        (let [retval (ArrayLists$ObjectArrayList.)]\n          (.addAllReducible retval item)\n          (.toArray retval)))\n      (instance? Collection item)\n      (.toArray ^Collection item)\n      (instance? String item)\n      (.toArray (StringCollection. item))\n      (.isArray (.getClass ^Object item))\n      (.toArray (ArrayLists/toList item))\n      (instance? Iterable item)\n      (let [alist (ArrayLists$ObjectArrayList.)]\n        (.addAllReducible alist item)\n        (.toArray alist))\n      :else\n      (throw (Exception. (str \"Unable to coerce item of type: \" (type item)\n                              \" to an object array\"))))))\n\n(def ^:no-doc long-array-cls (Class/forName \"[J\"))\n(def ^:no-doc double-array-cls (Class/forName \"[D\"))\n(def ^:no-doc obj-array-cls (Class/forName \"[Ljava.lang.Object;\"))\n\n\n(defn as-random-access\n  \"If item implements RandomAccess, return List interface.\"\n  ^List [item]\n  (cond (instance? RandomAccess item) item\n        (instance? long-array-cls item) (ArrayLists/toList ^longs item)\n        (instance? double-array-cls item) (ArrayLists/toList ^doubles item)\n        (instance? obj-array-cls item) (ArrayLists/toList ^objects item)))\n\n\n(defn ->random-access\n  ^List [item]\n  (if (instance? RandomAccess item)\n    item\n    (let [c (->collection item)]\n      (if (instance? RandomAccess c)\n        c\n        (-> (doto (MutTreeList.)\n              (.addAllReducible c))\n            (persistent!))))))\n\n(defn constant-countable?\n  [data]\n  (or (nil? data)\n      (instance? RandomAccess data)\n      (instance? Counted data)\n      (instance? Set data)\n      (instance? Map data)\n      (.isArray (.getClass ^Object data))))\n\n\n(defn constant-count\n  \"Constant time count.  Returns nil if input doesn't have a constant time count.\"\n  [data]\n  (cond\n    (nil? data) 0\n    (instance? RandomAccess data) (.size ^List data)\n    (instance? Counted data) (.count ^Counted data)\n    (instance? Map data) (.size ^Map data)\n    (instance? Set data) (.size ^Set data)\n    (.isArray (.getClass ^Object data)) (Array/getLength data)))\n\n\n(defn into-array\n  ([aseq] (into-array (if-let [item (first aseq)] (.getClass ^Object item) Object) aseq))\n  ([ary-type aseq]\n   (let [^Class ary-type (or ary-type Object)\n         aseq (->reducible aseq)]\n     (if-let [c (constant-count aseq)]\n       (let [rv (Array/newInstance ary-type (int c))]\n         (.fillRangeReducible ^IMutList (alists/wrap-array rv) 0 aseq)\n         rv)\n       (let [^IMutList al (alists/wrap-array-growable (Array/newInstance ary-type 4) 0)]\n         (.addAllReducible al aseq)\n         (.toNativeArray al)))))\n  ([ary-type mapfn aseq]\n   (if mapfn\n     (into-array ary-type (map-reducible mapfn aseq))\n     (into-array ary-type aseq))))\n\n\n(defn map\n  ([f]\n   (fn [rf]\n     (let [rf (Transformables/typedMapReducer rf f)]\n       (cond\n         (instance? IFn$OLO rf)\n         (reify IFnDef$OLO\n           (invoke [this] (rf))\n           (invoke [this result] (rf result))\n           (invokePrim [this acc v] (.invokePrim ^IFn$OLO rf acc v))\n           (applyTo [this args]\n             (rf (first args) (apply f (rest args)))))\n         (instance? IFn$ODO rf)\n         (reify IFnDef$ODO\n           (invoke [this] (rf))\n           (invoke [this result] (rf result))\n           (invokePrim [this acc v] (.invokePrim ^IFn$ODO rf acc v))\n           (applyTo [this args]\n             (rf (first args) (apply f (rest args)))))\n         :else\n         (fn\n           ([] (rf))\n           ([result] (rf result))\n           ([result input]\n            (rf result input))\n           ([result input & inputs]\n            (apply rf result input inputs)))))))\n  ([f arg]\n   (cond\n     (nil? arg) PersistentList/EMPTY\n     (instance? Transformables$IMapable arg)\n     (.map ^Transformables$IMapable arg f)\n     (instance? RandomAccess arg)\n     (Transformables$SingleMapList. f nil arg)\n     :else\n     (Transformables$MapIterable/createSingle f nil arg)))\n  ([f arg & args]\n   (let [args (concat [arg] args)]\n     (if (every? #(instance? RandomAccess %) args)\n       (Transformables$MapList/create f nil (into-array List args))\n       (Transformables$MapIterable. f nil (.toArray ^Collection args))))))\n\n\n(pp/implement-tostring-print Transformables$SingleMapList)\n(pp/implement-tostring-print Transformables$MapIterable)\n(pp/implement-tostring-print Transformables$MapList)\n\n\n(defn map-indexed\n  [map-fn coll]\n  (cond\n    (nil? coll)\n    coll\n    (instance? RandomAccess coll)\n    (let [^List coll coll]\n      (reify\n        IMutList\n        (size [this] (.size coll))\n        (get [this idx] (map-fn idx (.get coll idx)))\n        (subList [this sidx eidx]\n          (map-indexed map-fn (.subList coll sidx eidx)))\n        (reduce [this rfn acc]\n          (reduce (Reductions$IndexedAccum.\n                   (reify IFnDef$OLOO\n                     (invokePrim [this acc idx v]\n                       (rfn acc (map-fn idx v)))))\n                  acc coll))\n        Transformables$IMapable\n        (map [this mfn] (map-indexed (fn [idx v]\n                                       (-> (map-fn idx v)\n                                           (mfn)))\n                                     coll))))\n    :else\n    (Transformables$IndexedMapper. map-fn (->iterable coll) nil)))\n\n\n(pp/implement-tostring-print Transformables$IndexedMapper)\n\n\n(defn map-reducible\n  \"Map a function over r - r need only be reducible.  Returned value does not implement\n  seq but is countable when r is countable.\"\n  [f r]\n  (if-let [c (constant-count r)]\n    (reify\n      Counted\n      (count [this] c)\n      IReduceInit\n      (reduce [this rfn acc]\n        (Reductions/serialReduction (Transformables/typedMapReducer rfn f) acc r)))\n    (reify\n      IReduceInit\n      (reduce [this rfn acc]\n        (Reductions/serialReduction (Transformables/typedMapReducer rfn f) acc r)))))\n\n\n(defn tuple-map\n  \"Lazy nonaching map but f simply gets a single random-access list of arguments.\n  The argument list may be mutably updated between calls.\"\n  ([f c1]\n   (let [rdc (fn [rfn acc] (reduce (fn [acc v] (rfn acc (f [v]))) acc c1))]\n     (if-let [c1 (as-random-access c1)]\n       (reify IMutList\n         (size [this] (.size c1))\n         (get [this idx] (f [(.get c1 idx)]))\n         (subList [this sidx eidx]\n           (tuple-map f (.subList c1 sidx eidx)))\n         (reduce [this rfn acc]\n           (rdc rfn acc)))\n       (reify\n         Iterable\n         (iterator [this]\n           (let [citer (.iterator (->iterable c1))]\n             (reify Iterator\n               (hasNext [this] (.hasNext citer))\n               (next [this] (f [(.next citer)])))))\n         Seqable\n         (seq [this] (LazyChunkedSeq/chunkIteratorSeq (.iterator this)))\n         ITypedReduce\n         (reduce [this rfn acc]\n           (rdc rfn acc))))))\n  ([f c1 c2]\n   (let [c1 (->iterable c1)\n         c2 (->iterable c2)]\n     (reify\n       Iterable\n       (iterator [this]\n         (let [c1-iter (.iterator c1)\n               c2-iter (.iterator c2)]\n           (reify Iterator\n             (hasNext [this] (and (.hasNext c1-iter)\n                                  (.hasNext c2-iter)))\n             (next [this]\n               (f [(.next c1-iter) (.next c2-iter)])))))\n       Seqable\n       (seq [this] (LazyChunkedSeq/chunkIteratorSeq (.iterator this)))\n       ITypedReduce\n       (reduce [this rfn acc]\n         (Reductions/iterReduce this acc rfn)))))\n  ([f c1 c2 & cs]\n   (let [cs (doto (ArrayLists$ObjectArrayList.)\n              (.add c1)\n              (.add c2)\n              (.addAll cs))\n         nargs (.size cs)\n         next-fn (fn next-fn [iters ^objects args]\n                   (loop [idx 0]\n                     (if (< idx nargs)\n                       (let [^Iterator iter (iters idx)]\n                         (if (.hasNext iter)\n                           (do\n                             (ArrayHelpers/aset args (unchecked-int idx) (.next iter))\n                             (recur (unchecked-inc idx)))\n                           false))\n                       true)))\n         rdc (fn [rfn acc]\n               (let [iters (mapv #(.iterator (->iterable %)) cs)]\n                 (loop [acc acc\n                        args (ArrayLists/objectArray nargs)\n                        next? (next-fn iters args)]\n                   (if next?\n                     (let [acc (rfn acc (f (ArrayLists/toList ^objects args)))]\n                       (if (reduced? acc)\n                         (deref acc)\n                         (let [args (ArrayLists/objectArray nargs)]\n                           (recur acc args (next-fn iters args)))))\n                     acc))))]\n     (reify\n       Iterable\n       (iterator [this]\n         (let [args (ArrayLists/objectArray nargs)\n               argvec (ArrayLists/toList args)\n               iters (mapv #(.iterator (->iterable %)) cs)]\n           (reify\n             Iterator\n             (hasNext [this] (next-fn iters args))\n             (next [this] (f argvec)))))\n       Seqable\n       (seq [this] (LazyChunkedSeq/chunkIteratorSeq (.iterator this)))\n       ITypedReduce\n       (reduce [this rfn acc]\n         (rdc rfn acc))))))\n\n(pp/implement-tostring-print Transformables$CatIterable)\n\n(defn apply-concat\n  \"A more efficient form of (apply concat ...) that doesn't force data to be a clojure seq.\n  See [[concat-opts]] for opts definition.\"\n  ([] PersistentList/EMPTY)\n  ([data]\n   (Transformables$CatIterable. data))\n  ([opts data]\n   (Transformables$CatIterable. nil\n                                (condp identical? (get opts :cat-parallelism)\n                                  :seq-wise ParallelOptions$CatParallelism/SEQWISE\n                                  :elem-wise ParallelOptions$CatParallelism/ELEMWISE\n                                  nil nil)\n                                data)))\n\n(defn concat\n  ([] PersistentList/EMPTY)\n  ([a] (if a a PersistentList/EMPTY))\n  ([a & args]\n   (if (instance? Transformables$IMapable a)\n     (.cat ^Transformables$IMapable a args)\n     (apply-concat (cons a args)))))\n\n\n(defn concat-opts\n  \"Concat where the first argument is an options map.  This variation allows you to set the `:cat-parallelism`\n  as you may have an idea the best way to parallelism this concatenation at time of the concatenation creation.\n\n  Options:\n\n  `:cat-parallelism` - Set the type of parallelism - either `:elem-wise` or `:seq-wise`  - this overrides\n   settings later passed into calls such as [[reduce.preduce]] - see [[reduce/options->parallel-options]]\n   for definition.\"\n  ([opts a] (if a a PersistentList/EMPTY))\n  ([opts a & args]\n   (if (instance? Transformables$IMapable a)\n     (.cat ^Transformables$IMapable a args)\n     (apply-concat opts (cons a args)))))\n\n\n(defn filter\n  ([pred]\n   (fn [rf]\n     (Transformables$FilterIterable/typedReducer rf pred)))\n  ([pred coll]\n   (cond\n     (nil? coll) PersistentList/EMPTY\n     (instance? Transformables$IMapable coll)\n     (.filter ^Transformables$IMapable coll pred)\n     :else\n     (Transformables$FilterIterable. pred nil coll))))\n\n\n(pp/implement-tostring-print Transformables$FilterIterable)\n\n\n(defn complement\n  \"Like clojure core complement but avoids var lookup on 'not'\"\n  [f]\n  (fn\n    ([] (Transformables/not (f)))\n    ([x] (Transformables/not (f x)))\n    ([x y] (Transformables/not (f x y)))\n    ([x y & zs] (Transformables/not (apply f x y zs)))))\n\n\n(defn remove\n  \"Returns a lazy sequence of the items in coll for which\n  (pred item) returns logical false. pred must be free of side-effects.\n  Returns a transducer when no collection is provided.\"\n  {:added \"1.0\"\n   :static true}\n  ([pred coll]\n   (filter (complement pred) coll))\n  ([pred] (filter (complement pred))))\n\n(declare drop take)\n\n(deftype ^:private DropIterable [^long n data]\n  clojure.lang.Sequential\n  Iterable\n  (iterator [this]\n    (let [src-iter (.iterator (->iterable data))]\n      (dotimes [idx n]\n        (when (.hasNext src-iter)\n          (.next src-iter)))\n      src-iter))\n  ITypedReduce\n  (reduce [this rfn acc]\n    (let [rfn ((drop n) rfn)]\n      (reduce rfn acc data)))\n  Object\n  (toString [this] (Transformables/sequenceToString this)))\n\n(pp/implement-tostring-print DropIterable)\n\n(defmacro define-drop-tducer\n  [nm iface rf-tag]\n  (let [invoke-nm (if (= iface 'IFnDef)\n                    'invoke\n                    'invokePrim)]\n    `(deftype ~(with-meta nm {:private true})\n         [~(with-meta 'n {:unsynchronized-mutable true\n                          :tag 'long})\n          ~'rf]\n       ~iface (~invoke-nm [this# ~'result ~'input]\n               (let [~'nn (max -1 (dec ~'n))]\n                 (set! ~'n ~'nn)\n                 (if (neg? ~'nn)\n                   (~(symbol (str \".\" (name invoke-nm))) ~(with-meta 'rf {:tag rf-tag}) ~'result ~'input)\n                   ~'result)))\n       (invoke [this#] (~'rf))\n       (invoke [this# result#] (~'rf result#))\n       clojure.lang.Fn)))\n\n(define-drop-tducer DropLongTducer IFnDef$OLO clojure.lang.IFn$OLO)\n(define-drop-tducer DropDoubleTducer IFnDef$ODO clojure.lang.IFn$ODO)\n(define-drop-tducer DropTducer IFnDef clojure.lang.IFn)\n\n(defn drop\n  ([n]\n   (fn [rf]\n     (cond\n       (instance? clojure.lang.IFn$OLO rf)\n       (DropLongTducer. n rf)\n       (instance? clojure.lang.IFn$ODO rf)\n       (DropDoubleTducer. n rf)\n       :else\n       (DropTducer. n rf))))\n  ([^long n data]\n   (if(nil? data)\n     '()\n     (if-let [l (as-random-access data)]\n       (let [sl (.size l)]\n         (if (< sl n)\n           '[]\n           (.subList l n sl)))\n       (DropIterable. n data)))))\n\n(defmacro define-take-tducer\n  [nm invoke-nm iface rf-tag]\n  `(deftype ~(with-meta nm {:private true})\n       [~(with-meta 'n {:unsynchronized-mutable true\n                        :tag 'long})\n        ~'rf]\n     ~iface\n     (~invoke-nm [this# ~'acc ~'v]\n      (set! ~'n (max -1 (dec ~'n)))\n      (if (neg? ~'n)\n        ~'acc\n        (let [~'acc (~(symbol (str \".\" (name invoke-nm))) ~(with-meta 'rf {:tag rf-tag})\n                     ~'acc ~'v)]\n          (if (zero? ~'n)\n            (ensure-reduced ~'acc)\n            ~'acc))))\n     (invoke [this#] (~'rf))\n     (invoke [this# acc#] (~'rf acc#))\n     clojure.lang.Fn))\n\n(define-take-tducer TakeTducer invoke IFnDef clojure.lang.IFn)\n(define-take-tducer TakeLongTducer invokePrim IFnDef$OLO clojure.lang.IFn$OLO)\n(define-take-tducer TakeDoubleTducer invokePrim IFnDef$ODO clojure.lang.IFn$ODO)\n\n(deftype TakeIterator [^{:unsynchronized-mutable true\n                         :tag long} n\n                       ^Iterator data]\n  Iterator\n  (hasNext [this] (and (pos? n) (.hasNext data)))\n  (next [this]\n    (set! n (dec n))\n    (if (.hasNext data)\n      (.next data)\n      (throw (java.util.NoSuchElementException. \"Iter out of range\")))))\n\n(deftype TakeIterable [n data]\n  clojure.lang.Sequential\n  Iterable\n  (iterator [this]\n    (TakeIterator. n (.iterator (->iterable data))))\n  ITypedReduce\n  (reduce [this rfn acc]\n    (reduce ((take n) rfn) acc data))\n  Object\n  (toString [this] (Transformables/sequenceToString this)))\n\n(pp/implement-tostring-print TakeIterable)\n\n(defn take\n  ([n]\n   (fn [rf]\n     (cond\n       (instance? clojure.lang.IFn$OLO rf)\n       (TakeLongTducer. n rf)\n       (instance? clojure.lang.IFn$ODO rf)\n       (TakeDoubleTducer. n rf)\n       :else\n       (TakeTducer. n rf))))\n  ([^long n data]\n   (if (nil? data)\n     '()\n     (if-let [l (as-random-access data)]\n       (.subList l 0 (min n (.size l)))\n       (TakeIterable. n data)))))\n\n(defmacro make-readonly-list\n  \"Implement a readonly list.  If cls-type-kwd is provided it must be, at compile time,\n  either :int64, :float64 or :object and the getLong, getDouble or get interface methods\n  will be filled in, respectively.  In those cases read-code must return the appropriate\n  type.\"\n  ([n idxvar read-code]\n   `(make-readonly-list :object ~n ~idxvar ~read-code))\n  ([cls-type-kwd n idxvar read-code]\n   `(let [~'nElems (int ~n)]\n      ~(case cls-type-kwd\n         :int64\n         `(reify\n            TypedList\n            (containedType [this#] Long/TYPE)\n            LongMutList\n            (size [this#] ~'nElems)\n            (getLong [this# ~idxvar] ~read-code))\n         :float64\n         `(reify\n            TypedList\n            (containedType [this#] Double/TYPE)\n            DoubleMutList\n            (size [this#] ~'nElems)\n            (getDouble [this# ~idxvar] ~read-code))\n         :object\n         `(reify IMutList\n            (size [this#] ~'nElems)\n            (get [this# ~idxvar] ~read-code))))))\n\n\n(defn type-single-arg-ifn\n  \"Categorize the return type of a single argument ifn.  May be :float64, :int64, or :object.\"\n  [ifn]\n  (protocols/simplified-returned-datatype ifn))\n\n\n(defn type-zero-arg-ifn\n  \"Categorize the return type of a single argument ifn.  May be :float64, :int64, or :object.\"\n  [ifn]\n  (protocols/simplified-returned-datatype ifn))\n\n(defn repeatedly\n  \"When called with one argument, produce infinite list of calls to v.\n  When called with two arguments, produce a non-caching random access list of length n of calls to v.\"\n  ([f]\n   (reify Iterable\n     (iterator [this]\n       (reify java.util.Iterator\n         (hasNext [this] true)\n         (next [this] (f))))))\n  (^IMutList [n f]\n   (let [n (int n)]\n     (case (protocols/simplified-returned-datatype f)\n       :int64\n       (reify TypedList\n         (containedType [this] Long/TYPE)\n         LongMutList\n         (size [this] (unchecked-int n))\n         (getLong [this idx] (.invokePrim ^IFn$L f)))\n       :float64\n       (reify TypedList\n         (containedType [this] Double/TYPE)\n         DoubleMutList\n         (size [this] (unchecked-int n))\n         (getDouble [this idx] (.invokePrim ^IFn$D f)))\n       (reify IMutList\n         (size [this] (int n))\n         (get [this idx] (f)))))))\n\n\n(defn ^:no-doc contained-type\n  [coll]\n  (when (instance? TypedList coll)\n    (.containedType ^TypedList coll)))\n\n\n(defn- int-primitive?\n  [cls]\n  (or (identical? Byte/TYPE cls)\n      (identical? Short/TYPE cls)\n      (identical? Integer/TYPE cls)\n      (identical? Long/TYPE cls)))\n\n\n(defn- double-primitive?\n  [cls]\n  (or (identical? Float/TYPE cls)\n      (identical? Double/TYPE cls)))\n\n\n\n(defn shift\n  \"Shift a collection forward or backward repeating either the first or the last entries.\n  Returns a random access list with the same elements as coll.\n\n  Example:\n\n```clojure\nham-fisted.api> (shift 2 (range 10))\n[0 0 0 1 2 3 4 5 6 7]\nham-fisted.api> (shift -2 (range 10))\n[2 3 4 5 6 7 8 9 9 9]\n```\"\n  [n coll]\n  (let [n (long n)\n        coll (->random-access coll)\n        n-elems (.size coll)\n        ne (dec n-elems)\n        ctype (contained-type coll)\n        ^IMutList ml coll]\n    (cond\n      (int-primitive? ctype)\n      (make-readonly-list :int64 n-elems idx (.getLong ml (min ne (max 0 (- idx n)))))\n      (double-primitive? ctype)\n      (make-readonly-list :float64 n-elems idx (.getDouble ml (min ne (max 0 (- idx n)))))\n      :else\n      (make-readonly-list n-elems idx (.get coll (min ne (max 0 (- idx n))))))))\n\n\n(defn seed->random\n  ^Random [seed]\n  (cond\n    (instance? Random seed) seed\n    (number? seed) (Random. (int seed))\n    (nil? seed) (Random.)\n    :else\n    (throw (Exception. (str \"Invalid seed type: \" seed)))))\n\n\n(def ^:private int-ary-cls (Class/forName \"[I\"))\n\n\n(defn reindex\n  \"Permut coll by the given indexes.  Result is random-access and the same length as\n  the index collection.  Indexes are expected to be in the range of [0->count(coll)).\"\n  [coll indexes]\n  (let [^ints indexes (if (instance? int-ary-cls indexes)\n                        indexes\n                        (int-array indexes))\n        ^List coll (if (instance? RandomAccess coll)\n                     coll\n                     (->random-access coll))]\n    (if (instance? IMutList coll)\n      (.reindex ^IMutList coll indexes)\n      (ReindexList/create indexes coll (meta coll)))))\n\n\n(defn shuffle\n  \"shuffle values returning random access container.\n\n  Options:\n\n  * `:seed` - If instance of java.util.Random, use this.  If integer, use as seed.\n  If not provided a new instance of java.util.Random is created.\"\n  (^List [coll] (shuffle coll nil))\n  (^List [coll opts]\n   (let [coll (->random-access coll)\n         random (seed->random (get opts :seed))]\n     (if (instance? IMutList coll)\n       (.immutShuffle ^IMutList coll random)\n       (reindex coll (IntArrays/shuffle (ArrayLists/iarange 0 (.size coll) 1) random))))))\n\n\n(deftype ^:private PartitionOuterIter [^Iterator iter\n                                       ignore-leftover?\n                                       f\n                                       binary-predicate\n                                       ^:unsynchronized-mutable last-iter]\n  Iterator\n  (hasNext [this] (if last-iter\n                    (do (when (and (not ignore-leftover?)\n                                   (.hasNext ^Iterator last-iter))\n                          (throw (RuntimeException. \"Sub-collection was not completely iterated through\")))\n                        (boolean @last-iter))\n                    (.hasNext iter)))\n  (next [this]\n    (if last-iter\n      (let [piter-data @last-iter\n            v (piter-data 0)\n            fv (piter-data 1)\n            rv (PartitionByInner. iter f v binary-predicate)]\n        (set! last-iter rv)\n        rv)\n      (let [v (.next iter)\n            fv (f v)\n            rv (PartitionByInner. iter f v binary-predicate)]\n        (set! last-iter rv)\n        rv))))\n\n\n(deftype ^:private PartitionBy [f coll ignore-leftover? m\n                                binary-predicate\n                                ^{:unsynchronized-mutable true\n                                  :tag long} _hasheq]\n  ITypedReduce\n  (reduce [this rfn acc]\n    (let [citer (.iterator ^Iterable (protocols/->iterable coll))]\n      (if (.hasNext citer)\n        (loop [acc acc\n               v (.next citer)\n               fv (f v)]\n          (let [\n                piter (PartitionByInner. citer f v binary-predicate)\n                ;;piter (PartitionInnerIter. citer f fv true v fv)\n                acc (rfn acc piter)\n                _ (when (and (not ignore-leftover?)\n                             (.hasNext piter))\n                    (throw (RuntimeException. \"Sub-collection was not entirely consumed.\")))\n                piter-data @piter]\n            (if (reduced? acc)\n              @acc\n              (if piter-data\n                (recur acc (piter-data 0) (piter-data 1))\n                acc))))\n        acc)))\n  Iterable\n  (iterator [this] (PartitionOuterIter. (.iterator ^Iterable (protocols/->iterable coll))\n                                        ignore-leftover?\n                                        f\n                                        binary-predicate\n                                        nil))\n  Seqable\n  (seq [this]\n    (let [ii (clojure.lang.IteratorSeq/create (.iterator this))]\n      (when ii\n        (clojure.core/map vec (clojure.lang.IteratorSeq/create (.iterator this))))))\n  clojure.lang.Sequential\n  clojure.lang.IHashEq\n  (hasheq [this]\n    (when (== _hasheq 0)\n      (set! _hasheq (long (hash (seq this)))))\n    _hasheq)\n  clojure.lang.IPersistentCollection\n  (count [this] (count (seq this)))\n  (cons [this o] (cons (seq this) o))\n  (empty [this] PersistentList/EMPTY)\n  (equiv [this o]\n    (if (identical? this o)\n      true\n      (if (instance? clojure.lang.IPersistentCollection o)\n        (clojure.lang.Util/pcequiv (seq this) o)\n        false)))\n  IObj\n  (meta [this] m)\n  (withMeta [this mm] (PartitionBy. f coll ignore-leftover? mm binary-predicate 0))\n  Object\n  (toString [this] (.toString ^Object (map vec this)))\n  (hashCode [this] (.hasheq this))\n  (equals [this o] (.equiv this o)))\n\n\n(pp/implement-tostring-print PartitionBy)\n\n\n(defn partition-by\n  \"Lazy noncaching version of partition-by.  For reducing partitions into a singular value please see\n  [[apply-concat]].  Return value most efficiently implements reduce with a slightly less efficient\n  implementation of Iterable.\n\n  Unlike clojure.core/partition-by this does not store intermediate elements nor does it build\n  up intermediate containers.  This makes it somewhat faster in most contexts.\n\n  Each sub-collection must be iterated through entirely before the next method of the parent iterator\n  else the result will not be correct.\n\n  Options:\n\n  * `:ignore-leftover?` - When true leftover items in the previous iteration do not cause an exception.\n  Defaults to false.\n  * `:binary-predicate` - When provided, use this for equality semantics.  Defaults to equiv semantics\n     but in a numeric context it may be useful to have `(== ##NaN ##Nan)`.\n\n\n```clojure\nuser> ;;incorrect - inner items not iterated and non-caching!\nuser> (into [] (lznc/partition-by identity [1 1 1 2 2 2 3 3 3]))\nExecution error at ham_fisted.lazy_noncaching.PartitionBy/reduce (lazy_noncaching.clj:514).\nSub-collection was not entirely consumed.\n\nuser> ;;correct - transducing form of into calls vec on each sub-collection\nuser> ;;thus iterating through it entirely.\nuser> (into [] (map vec) (lznc/partition-by identity [1 1 1 2 2 2 3 3 3]))\n[[1 1 1] [2 2 2] [3 3 3]]\nuser> ;;filter,collect NaN out of sequence\nuser> (lznc/map hamf/vec (lznc/partition-by identity {:binary-predicate (hamf-fn/binary-predicate\n                                                                         x y (let [x (double x)\n                                                                                   y (double y)]\n                                                                               (cond\n                                                                                 (Double/isNaN x)\n                                                                                 (if (Double/isNaN y)\n                                                                                   true\n                                                                                   false)\n                                                                                 (Double/isNaN y) false\n                                                                                 :else true))) }\n                                            [1 2 3 ##NaN ##NaN 3 4 5]))\n([1 2 3] [NaN NaN] [3 4 5])\n\nuser> (def init-data (vec (lznc/apply-concat (lznc/map #(repeat 100 %) (range 1000)))))\n#'user/init-data\nuser> (crit/quick-bench (mapv hamf/sum-fast (lznc/partition-by identity init-data)))\n             Execution time mean : 366.915796 µs\n  ...\nnil\nuser> (crit/quick-bench (mapv hamf/sum-fast (clojure.core/partition-by identity init-data)))\n             Execution time mean : 6.699424 ms\n  ...\nnil\nuser> (crit/quick-bench (into [] (comp (clojure.core/partition-by identity)\n                                       (map hamf/sum-fast)) init-data))\n             Execution time mean : 1.705864 ms\n  ...\n```\"\n  ([f] (clojure.core/partition-by f))\n  ([f coll] (partition-by f nil coll))\n  ([f options coll]\n   (PartitionBy. f coll (boolean (get options :ignore-leftover?)) nil\n                 (hamf-fn/binary-predicate-or-null (get options :binary-predicate))\n                 0)))\n\n(defn partition-by-comparator\n  \"Partition by a comparator.  Sub partitions must be fully consumed before parent is called.  An optional\n  timeout can be used if sub partitions are being consumed in a future - the parent iteration will block\n  until the sub partition is fully consumed.\n\n  Options:\n  * `:timeout-ms` - Timeout in milliseconds - if the sub partition isn't consumed by this time an exception\n  is thrown.\"\n  ([cmp coll] (partition-by-comparator cmp nil coll))\n  ([^Comparator cmp options coll]\n   (let [tms (long (get options :timeout-ms 1))\n         update (fn [{:keys [rest*] :as ctx}]\n                  (let [iter (hamf-iter/->iterator (let [ii (deref rest* tms ::timeout)]\n                                                     (when (identical? ii ::timeout)\n                                                       (throw (ex-info \"Sub partition not fully consumed\"\n                                                                       {:timeout-ms tms})))\n                                                     ii))]\n                    (when (hamf-iter/has-next? iter)\n                      (let [next-v (hamf-iter/next iter)\n                            pred #(== 0 (.compare cmp next-v %))]\n                        (hamf-iter/iter-take-while pred (hamf-iter/iter-cons next-v iter))))))]\n     (hamf-iter/seq-once-iterable\n      :data\n      #(update {:rest* (deliver (promise) (hamf-iter/->iterator coll))})\n      update\n      :data))))\n\n(defn partition-by-cost\n  \"Partition a sequence by integer cost.  Will produce partitions of average cost '(quot max-cost 2)\n  with some partitions being larger or smaller if the input sequence ends.  This function not very lazy\n  with each new partition greedily calculated.\"\n  [cost-fn ^long max-cost coll]\n  (let [^clojure.lang.IFn$OL cost-fn (if (instance? clojure.lang.IFn$OL cost-fn)\n                                       cost-fn\n                                       (fn ^long [o] (long (cost-fn o))))\n        next-partition (ArrayList.)\n        half-max (quot max-cost 2)\n        update (fn [{:keys [iter half-info cur-cost] :as ctx}]\n                 (loop [cur-cost (long (or cur-cost 0))\n                        half-info half-info]\n                   (if (hamf-iter/has-next? iter)\n                     (let [next-e (.next ^Iterator iter)\n                           cur-cost (+ cur-cost (.invokePrim cost-fn next-e))\n                           over-half? (>= cur-cost half-max)]\n                       (.add next-partition next-e)\n                       (if (< cur-cost max-cost)\n                         (recur cur-cost (if (and (nil? half-info) over-half?)\n                                           [cur-cost (.size next-partition)]\n                                           half-info))\n                         (let [[half-cost half-idx] half-info\n                               next-cost (- cur-cost (long (or half-cost 0)))\n                               split-idx (long (or half-idx (.size next-partition)))\n                               subl (.subList next-partition 0 split-idx)\n                               ctx (assoc ctx\n                                          :rows (vec subl)\n                                          :half-cost next-cost\n                                          :cur-cost next-cost\n                                          :half-idx (- (.size next-partition) split-idx))]\n                           (.clear subl)\n                           ctx)))\n                     (when-not (.isEmpty next-partition)\n                       (let [rv {:rows (vec next-partition)}]\n                         (.clear next-partition)\n                         rv)))))]\n    (hamf-iter/seq-once-iterable :rows #(update {:iter (hamf-iter/->iterator coll)}) update :rows)))\n\n(defn partition-all\n  \"Lazy noncaching version of partition-all.  When input is random access returns random access result.\n\n  If input is not random access then similar to [[partition-by]] each sub-collection must be entirely\n  iterated through before requesting the next sub-collection.\n\n```clojure\nuser> (crit/quick-bench (mapv hamf/sum-fast (lznc/partition-all 100 (range 100000))))\n             Execution time mean : 335.821098 µs\nnil\nuser> (crit/quick-bench (mapv hamf/sum-fast (partition-all 100 (range 100000))))\n             Execution time mean : 6.831242 ms\nnil\nuser> (crit/quick-bench (into [] (comp (partition-all 100)\n                                       (map hamf/sum-fast))\n                              (range 100000)))\n             Execution time mean : 1.645954 ms\nnil\n```\"\n  ([n] (clojure.core/partition-all n))\n  ([n coll] (partition-all n n coll))\n  ([^long n ^long step coll]\n   (if (empty? coll)\n     '()\n     (let [ns step]\n       (if-let [coll (as-random-access coll)]\n         (let [n-elems (.size coll)\n               n-batches (quot (+ n-elems (dec ns)) ns)]\n           (if (== n step)\n             (reify IMutList\n               (size [this] (unchecked-int n-batches))\n               (get [this outer]\n                 (when-not (and (>= outer 0) (< outer n-batches))\n                   (throw (IndexOutOfBoundsException.)))\n                 (let [sidx (* outer ns)\n                       eidx (min n-elems (+ sidx n))]\n                   (.subList coll sidx eidx))))\n             (reify IMutList\n               (size [this] (unchecked-int n-batches))\n               (get [this outer]\n                 (when-not (and (>= outer 0) (< outer n-batches))\n                   (throw (IndexOutOfBoundsException.)))\n                 (let [batch-start (* outer ns)\n                       batch-n (long (min n (quot (- n-elems batch-start) step)))]\n                   (reify IMutList\n                     (size [this] (unchecked-int batch-n))\n                     (get [this inner]\n                       (.get coll (+ batch-start (* inner step))))))))))\n         (if (== n step)\n           (let [iter (hamf-iter/->iterator coll)\n                 update (fn [sub-iter]\n                          (when (hamf-iter/has-next? sub-iter)\n                            (throw (RuntimeException. \"Sub iterator has more elements left\")))\n                          (when (hamf-iter/has-next? iter)\n                            (hamf-iter/iter-take n iter)))]\n             (-> (hamf-iter/once-iterable\n                  identity\n                  #(update nil)\n                  update\n                  hamf-iter/wrap-iter)\n                 (hamf-iter/seq-iterable)))\n           ;;No fastpath here because if step isn't n then that implies caching in the sequence\n           (clojure.core/partition-all n step coll)))))))\n\n\n(defn every?\n  \"Faster (in most circumstances) implementation of clojure.core/every?.  This can be much faster in the case\n  of primitive arrays of values.  Type-hinted functions are best if coll is primitive array - see example.\n\n```clojure\nuser> (type data)\n[J\nuser> (count data)\n100\nuser> (def vdata (vec data))\n#'user/vdata\nuser> (crit/quick-bench (every? (fn [^long v] (> v 80)) data))\n             Execution time mean : 40.248868 ns\nnil\nuser> (crit/quick-bench (lznc/every? (fn [^long v] (> v 80)) data))\n             Execution time mean : 7.601190 ns\nnil\nuser> (crit/quick-bench (every? (fn [^long v] (< v 80)) vdata))\n             Execution time mean : 1.269582 µs\nnil\nuser> (crit/quick-bench (lznc/every? (fn [^long v] (< v 80)) vdata))\n             Execution time mean : 211.645613 ns\nnil\nuser>\n```\"\n  [pred coll]\n  (if-let [coll (as-random-access coll)]\n    (let [ne (.size coll)\n          pred-type (if (instance? IMutList coll)\n                      (cond (instance? IFn$LO pred) :int64\n                            (instance? IFn$DO pred) :float64\n                            :else :object)\n                      :object)]\n      (case pred-type\n        :int64\n        (loop [idx 0]\n          (if (< idx ne)\n            (if (.invokePrim ^IFn$LO pred (.getLong ^IMutList coll (unchecked-int idx)))\n              (recur (unchecked-inc idx))\n              false)\n            true))\n        :float64\n        (loop [idx 0]\n          (if (< idx ne)\n            (if (.invokePrim ^IFn$DO pred (.getDouble ^IMutList coll (unchecked-int idx)))\n              (recur (unchecked-inc idx))\n              false)\n            true))\n        (loop [idx 0]\n          (if (< idx ne)\n            (if (pred (.get coll (unchecked-int idx)))\n              (recur (unchecked-inc idx))\n              false)\n            true))))\n    (cond\n      (instance? IFn$LO pred)\n      (reduce (fn [acc ^long v]\n                (if-not (.invokePrim ^IFn$LO pred v)\n                  (reduced false)\n                  true))\n              true\n              coll)\n      (instance? IFn$DO pred)\n      (reduce (fn [acc ^double v]\n                (if-not (.invokePrim ^IFn$DO pred v)\n                  (reduced false)\n                  true))\n              true\n              coll)\n      :else\n      (reduce (fn [acc v]\n                (if-not (pred v)\n                  (reduced false)\n                  true))\n              true\n              coll))))\n\n\n\n(defn cartesian-map\n  \"Create a new sequence that is the cartesian join of the input sequence passed through f.\n  Unlike map, f is passed the arguments as a single persistent vector.  This is to enable much\n  higher efficiency in the higher-arity applications.  For tight numeric loops, see [[ham-fisted.hlet/let]].\n\n  The argument vector is mutably updated between function calls so you can't cache it.  Use `(into [] args)`\n  or some variation thereof to cache the arguments as is.\n\n```clojure\nuser> (hamf/sum-fast (lznc/cartesian-map\n                      #(h/let [[a b c d](lng-fns %)]\n                         (-> (+ a b) (+ c) (+ d)))\n                      [1 2 3]\n                      [4 5 6]\n                      [7 8 9]\n                      [10 11 12 13 14]))\n3645.0\n```\"\n  ([f] '())\n  ([f a] (map #(f [%]) a))\n  ([f a b]\n   (let [reducer (fn [rfn acc]\n                   (let [values (ArrayLists/objectArray (unchecked-int 2))\n                         val-seq (ArrayLists/toList values)\n                         inner-reducer (fn [acc bb]\n                                         (ArrayHelpers/aset values 1 bb)\n                                         (rfn acc (f val-seq)))\n                         outer-reducer (if (instance? IReduceInit b)\n                                         (fn [acc aa]\n                                           (ArrayHelpers/aset values 0 aa)\n                                           ;;In very tight loops the reduce dispatch can take some time.\n                                           (.reduce ^IReduceInit b inner-reducer acc))\n                                         (fn [acc aa]\n                                           (ArrayHelpers/aset values 0 aa)\n                                           (reduce inner-reducer acc b)))]\n                     (reduce outer-reducer acc a)))]\n     (reify\n       Iterable\n       (iterator [this]\n         (let [a (->iterable a)\n               b (->iterable b)\n               ia (.iterator a)\n               ib (clojure.lang.Box. (.iterator b))\n               a-v? (clojure.lang.Box. (.hasNext ia))\n               values (ArrayLists/objectArray (unchecked-int 2))\n               val-seq (ArrayLists/toList values)]\n           (when (.-val a-v?)\n             (aset values (unchecked-int 0) (.next ia)))\n           (reify Iterator\n             (hasNext [this] (and (.-val a-v?)\n                                  (.hasNext ^Iterator (.-val ib))))\n             (next [this]\n               (let [^Iterator iib (.-val ib)\n                     _ (aset values (unchecked-int 1) (.next iib))\n                     rv (f val-seq)]\n                 (when-not (.hasNext iib)\n                   (set! (.-val a-v?) (.hasNext ia))\n                   (when (.-val a-v?)\n                     (aset values (unchecked-int 0) (.next ia))\n                     (set! (.-val ib) (.iterator b))))\n                 rv)))))\n       Seqable\n       (seq [this] (LazyChunkedSeq/chunkIteratorSeq (.iterator this)))\n       ITypedReduce\n       (reduce [this rfn acc]\n         (reducer rfn acc)))))\n  ([f a b & args]\n   (let [args (vec (concat [a b] args))\n         nargs (count args)\n         dnargs (dec nargs)]\n     (reify\n       Iterable\n       (iterator [this]\n         (let [iterables (mapv ->iterable args)\n               iterators (ArrayLists/toList (.toArray ^Collection (map #(.iterator ^Iterable %) iterables)))\n               values-valid? (clojure.lang.Box. false)\n               values (ArrayLists/objectArray (unchecked-int nargs))\n               val-seq (ArrayLists/toList values)\n               lidx\n               (long (loop [idx 0]\n                       (if (and (< idx dnargs) (.hasNext ^Iterator (iterators idx)))\n                         (do\n                           (aset values idx (.next ^Iterator (iterators idx)))\n                           (recur (unchecked-inc idx)))\n                         idx)))]\n           (set! (.-val values-valid?) (== lidx dnargs))\n           (reify\n             Iterator\n             (hasNext [this] (and (.-val values-valid?)\n                                  (.hasNext ^Iterator (iterators dnargs))))\n             (next [this]\n               (let [last-iter ^Iterator (iterators dnargs)\n                     _ (aset values dnargs (.next last-iter))\n                     rv (f val-seq)]\n                 (when-not (.hasNext last-iter)\n                   ;;Find the first iterator seaching backward that does have a valid next item\n                   (let [nidx (long (loop [idx 1]\n                                      (if (< idx nargs)\n                                        (let [ridx (- dnargs idx)\n                                              ^Iterator iter (iterators ridx)]\n                                          (if (.hasNext iter)\n                                            ridx\n                                            (recur (unchecked-inc idx))))\n                                        -1)))]\n                     (if (not (== nidx -1))\n                       (do\n                         (aset values nidx (.next ^Iterator (iterators nidx)))\n                         (loop [idx (unchecked-inc nidx)]\n                           (when (< idx nargs)\n                             (let [iter (.iterator ^Iterable (iterables idx))]\n                               (.set iterators idx iter)\n                               (when (< idx dnargs)\n                                 (aset values idx (.next iter)))\n                               (recur (unchecked-inc idx))))))\n                       ;;If there are no more valid iterators\n                       (set! (.-val values-valid?) false))))\n                 rv)))))\n       Seqable\n       (seq [this] (LazyChunkedSeq/chunkIteratorSeq (.iterator this)))\n       ITypedReduce\n       (reduce [this rfn acc]\n         (let [values (ArrayLists/objectArray (unchecked-int nargs))\n               val-seq (ArrayLists/toList values)\n               ;;We could cache the reducer but it wouldn't help in most cases as people aren't going to cache the\n               ;;cartesian map object.\n               reducer (reduce (fn [rrfn ^long idx]\n                                 (let [ridx (- dnargs idx)\n                                       reduce-target (args ridx)\n                                       inner-reducer (if (== idx 0)\n                                                       (fn final-reducer [acc v]\n                                                         (ArrayHelpers/aset values (unchecked-int ridx) v)\n                                                         (rfn acc (f val-seq)))\n                                                       (fn intermediate-reducer [acc v]\n                                                         (ArrayHelpers/aset values (unchecked-int ridx) v)\n                                                         (rrfn acc)))]\n                                   (if (instance? IReduceInit reduce-target)\n                                     #(.reduce ^IReduceInit reduce-target inner-reducer %)\n                                     #(reduce inner-reducer % reduce-target))))\n                               nil\n                               (range nargs))]\n           (reducer acc)))))))\n"
  },
  {
    "path": "src/ham_fisted/mut_map.clj",
    "content": "(ns ham-fisted.mut-map\n  \"Functions for working with java's mutable map interface\"\n  (:require [ham-fisted.function :as hamf-fn])\n  (:import [java.util Map Set Collection]))\n\n\n(defn compute!\n  \"Compute a new value in a map derived from an existing value.  bfn gets passed k, v where k\n  may be nil.  If the function returns nil the corresponding key is removed from the map.\n\n  See [Map.compute](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#compute-K-java.util.function.BiFunction-)\n\n  An example `bfn` for counting occurrences would be `#(if % (inc (long %)) 1)`.\"\n  [m k bfn]\n  (.compute ^Map m k (hamf-fn/->bi-function bfn)))\n\n\n(defn compute-if-present!\n  \"Compute a new value if the value already exists and is non-nil in the hashmap.  Must use\n  mutable maps.  bfn gets passed k, v where v is non-nil.\n\n  See [Map.computeIfPresent](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfPresent-K-java.util.function.BiFunction-)\"\n  [m k bfn]\n  (.computeIfPresent ^Map m k (hamf-fn/->bi-function bfn)))\n\n\n(defn compute-if-absent!\n  \"Compute a value if absent from the map.  Useful for memoize-type operations.  Must use\n  mutable maps.  bfn gets passed k.\n\n  See [map.computeIfAbsent](https://docs.oracle.com/javase/8/docs/api/java/util/Map.html#computeIfAbsent-K-java.util.function.Function-)\"\n  [m k bfn]\n  (.computeIfAbsent ^Map m k (hamf-fn/->function bfn)))\n\n\n(defn keyset\n  \"Return the keyset of the map.  This may not be in the same order as (keys m) or (vals\n  m).  For hamf maps, this has the same ordering as (keys m).  For both hamf and java\n  hashmaps, the returned implementation of java.util.Set has both more utility and better\n  performance than (keys m).\"\n  ^Set [^Map m] (.keySet m))\n\n\n(defn values\n  \"Return the values collection of the map.  This may not be in the same order as (keys m)\n  or (vals m).  For hamf hashmaps, this does have the same order as (vals m).\"\n  ^Collection [^Map m] (.values m))\n"
  },
  {
    "path": "src/ham_fisted/primitive_invoke.clj",
    "content": "(ns ham-fisted.primitive-invoke\n  \"For statically traced calls the Clojure compiler calls the primitive version of type-hinted functions\n  and this makes quite a difference in tight loops.  Often times, however, functions are passed by values\n  or returned from if-statements and then you need to explicitly call the primitive overload - this makes\n  that pathway less verbose.  Functions must first be check-casted to their primitive types and then\n  calling them will use their primitive overloads avoiding all casting.\n\n```clojure\n(defn doit [f x y]\n   (let [f (pi/->ddd f)]\n     (loop [x x y y]\n      (if (< x y)\n        (recur (pi/ddd f x y) y)\n        x))))\n```\")\n\n(defn ->l ^clojure.lang.IFn$L [f]\n  (if (instance? clojure.lang.IFn$L f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$L\")))))\n(defmacro l [f]\n  `(.invokePrim ~f))\n(defn ->d ^clojure.lang.IFn$D [f]\n  (if (instance? clojure.lang.IFn$D f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$D\")))))\n(defmacro d [f]\n  `(.invokePrim ~f))\n(defn ->lo ^clojure.lang.IFn$LO [f]\n  (if (instance? clojure.lang.IFn$LO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LO\")))))\n(defmacro lo [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->do ^clojure.lang.IFn$DO [f]\n  (if (instance? clojure.lang.IFn$DO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DO\")))))\n(defmacro do [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->ol ^clojure.lang.IFn$OL [f]\n  (if (instance? clojure.lang.IFn$OL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OL\")))))\n(defmacro ol [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->ll ^clojure.lang.IFn$LL [f]\n  (if (instance? clojure.lang.IFn$LL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LL\")))))\n(defmacro ll [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->dl ^clojure.lang.IFn$DL [f]\n  (if (instance? clojure.lang.IFn$DL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DL\")))))\n(defmacro dl [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->od ^clojure.lang.IFn$OD [f]\n  (if (instance? clojure.lang.IFn$OD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OD\")))))\n(defmacro od [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->ld ^clojure.lang.IFn$LD [f]\n  (if (instance? clojure.lang.IFn$LD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LD\")))))\n(defmacro ld [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->dd ^clojure.lang.IFn$DD [f]\n  (if (instance? clojure.lang.IFn$DD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DD\")))))\n(defmacro dd [f arg0]\n  `(.invokePrim ~f ~arg0))\n(defn ->olo ^clojure.lang.IFn$OLO [f]\n  (if (instance? clojure.lang.IFn$OLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLO\")))))\n(defmacro olo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->odo ^clojure.lang.IFn$ODO [f]\n  (if (instance? clojure.lang.IFn$ODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODO\")))))\n(defmacro odo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->loo ^clojure.lang.IFn$LOO [f]\n  (if (instance? clojure.lang.IFn$LOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOO\")))))\n(defmacro loo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->llo ^clojure.lang.IFn$LLO [f]\n  (if (instance? clojure.lang.IFn$LLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLO\")))))\n(defmacro llo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ldo ^clojure.lang.IFn$LDO [f]\n  (if (instance? clojure.lang.IFn$LDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDO\")))))\n(defmacro ldo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->doo ^clojure.lang.IFn$DOO [f]\n  (if (instance? clojure.lang.IFn$DOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOO\")))))\n(defmacro doo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->dlo ^clojure.lang.IFn$DLO [f]\n  (if (instance? clojure.lang.IFn$DLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLO\")))))\n(defmacro dlo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ddo ^clojure.lang.IFn$DDO [f]\n  (if (instance? clojure.lang.IFn$DDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDO\")))))\n(defmacro ddo [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ool ^clojure.lang.IFn$OOL [f]\n  (if (instance? clojure.lang.IFn$OOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOL\")))))\n(defmacro ool [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->oll ^clojure.lang.IFn$OLL [f]\n  (if (instance? clojure.lang.IFn$OLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLL\")))))\n(defmacro oll [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->odl ^clojure.lang.IFn$ODL [f]\n  (if (instance? clojure.lang.IFn$ODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODL\")))))\n(defmacro odl [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->lol ^clojure.lang.IFn$LOL [f]\n  (if (instance? clojure.lang.IFn$LOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOL\")))))\n(defmacro lol [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->lll ^clojure.lang.IFn$LLL [f]\n  (if (instance? clojure.lang.IFn$LLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLL\")))))\n(defmacro lll [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ldl ^clojure.lang.IFn$LDL [f]\n  (if (instance? clojure.lang.IFn$LDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDL\")))))\n(defmacro ldl [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->dol ^clojure.lang.IFn$DOL [f]\n  (if (instance? clojure.lang.IFn$DOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOL\")))))\n(defmacro dol [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->dll ^clojure.lang.IFn$DLL [f]\n  (if (instance? clojure.lang.IFn$DLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLL\")))))\n(defmacro dll [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ddl ^clojure.lang.IFn$DDL [f]\n  (if (instance? clojure.lang.IFn$DDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDL\")))))\n(defmacro ddl [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ood ^clojure.lang.IFn$OOD [f]\n  (if (instance? clojure.lang.IFn$OOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOD\")))))\n(defmacro ood [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->old ^clojure.lang.IFn$OLD [f]\n  (if (instance? clojure.lang.IFn$OLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLD\")))))\n(defmacro old [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->odd ^clojure.lang.IFn$ODD [f]\n  (if (instance? clojure.lang.IFn$ODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODD\")))))\n(defmacro odd [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->lod ^clojure.lang.IFn$LOD [f]\n  (if (instance? clojure.lang.IFn$LOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOD\")))))\n(defmacro lod [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->lld ^clojure.lang.IFn$LLD [f]\n  (if (instance? clojure.lang.IFn$LLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLD\")))))\n(defmacro lld [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ldd ^clojure.lang.IFn$LDD [f]\n  (if (instance? clojure.lang.IFn$LDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDD\")))))\n(defmacro ldd [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->dod ^clojure.lang.IFn$DOD [f]\n  (if (instance? clojure.lang.IFn$DOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOD\")))))\n(defmacro dod [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->dld ^clojure.lang.IFn$DLD [f]\n  (if (instance? clojure.lang.IFn$DLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLD\")))))\n(defmacro dld [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->ddd ^clojure.lang.IFn$DDD [f]\n  (if (instance? clojure.lang.IFn$DDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDD\")))))\n(defmacro ddd [f arg0 arg1]\n  `(.invokePrim ~f ~arg0 ~arg1))\n(defn ->oolo ^clojure.lang.IFn$OOLO [f]\n  (if (instance? clojure.lang.IFn$OOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLO\")))))\n(defmacro oolo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oodo ^clojure.lang.IFn$OODO [f]\n  (if (instance? clojure.lang.IFn$OODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODO\")))))\n(defmacro oodo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oloo ^clojure.lang.IFn$OLOO [f]\n  (if (instance? clojure.lang.IFn$OLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOO\")))))\n(defmacro oloo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ollo ^clojure.lang.IFn$OLLO [f]\n  (if (instance? clojure.lang.IFn$OLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLO\")))))\n(defmacro ollo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oldo ^clojure.lang.IFn$OLDO [f]\n  (if (instance? clojure.lang.IFn$OLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDO\")))))\n(defmacro oldo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->odoo ^clojure.lang.IFn$ODOO [f]\n  (if (instance? clojure.lang.IFn$ODOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOO\")))))\n(defmacro odoo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->odlo ^clojure.lang.IFn$ODLO [f]\n  (if (instance? clojure.lang.IFn$ODLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLO\")))))\n(defmacro odlo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oddo ^clojure.lang.IFn$ODDO [f]\n  (if (instance? clojure.lang.IFn$ODDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDO\")))))\n(defmacro oddo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->looo ^clojure.lang.IFn$LOOO [f]\n  (if (instance? clojure.lang.IFn$LOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOO\")))))\n(defmacro looo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lolo ^clojure.lang.IFn$LOLO [f]\n  (if (instance? clojure.lang.IFn$LOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLO\")))))\n(defmacro lolo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lodo ^clojure.lang.IFn$LODO [f]\n  (if (instance? clojure.lang.IFn$LODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODO\")))))\n(defmacro lodo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lloo ^clojure.lang.IFn$LLOO [f]\n  (if (instance? clojure.lang.IFn$LLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOO\")))))\n(defmacro lloo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lllo ^clojure.lang.IFn$LLLO [f]\n  (if (instance? clojure.lang.IFn$LLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLO\")))))\n(defmacro lllo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lldo ^clojure.lang.IFn$LLDO [f]\n  (if (instance? clojure.lang.IFn$LLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDO\")))))\n(defmacro lldo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ldoo ^clojure.lang.IFn$LDOO [f]\n  (if (instance? clojure.lang.IFn$LDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOO\")))))\n(defmacro ldoo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ldlo ^clojure.lang.IFn$LDLO [f]\n  (if (instance? clojure.lang.IFn$LDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLO\")))))\n(defmacro ldlo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lddo ^clojure.lang.IFn$LDDO [f]\n  (if (instance? clojure.lang.IFn$LDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDO\")))))\n(defmacro lddo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dooo ^clojure.lang.IFn$DOOO [f]\n  (if (instance? clojure.lang.IFn$DOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOO\")))))\n(defmacro dooo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dolo ^clojure.lang.IFn$DOLO [f]\n  (if (instance? clojure.lang.IFn$DOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLO\")))))\n(defmacro dolo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dodo ^clojure.lang.IFn$DODO [f]\n  (if (instance? clojure.lang.IFn$DODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODO\")))))\n(defmacro dodo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dloo ^clojure.lang.IFn$DLOO [f]\n  (if (instance? clojure.lang.IFn$DLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOO\")))))\n(defmacro dloo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dllo ^clojure.lang.IFn$DLLO [f]\n  (if (instance? clojure.lang.IFn$DLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLO\")))))\n(defmacro dllo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dldo ^clojure.lang.IFn$DLDO [f]\n  (if (instance? clojure.lang.IFn$DLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDO\")))))\n(defmacro dldo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ddoo ^clojure.lang.IFn$DDOO [f]\n  (if (instance? clojure.lang.IFn$DDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOO\")))))\n(defmacro ddoo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ddlo ^clojure.lang.IFn$DDLO [f]\n  (if (instance? clojure.lang.IFn$DDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLO\")))))\n(defmacro ddlo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dddo ^clojure.lang.IFn$DDDO [f]\n  (if (instance? clojure.lang.IFn$DDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDO\")))))\n(defmacro dddo [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oool ^clojure.lang.IFn$OOOL [f]\n  (if (instance? clojure.lang.IFn$OOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOL\")))))\n(defmacro oool [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ooll ^clojure.lang.IFn$OOLL [f]\n  (if (instance? clojure.lang.IFn$OOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLL\")))))\n(defmacro ooll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oodl ^clojure.lang.IFn$OODL [f]\n  (if (instance? clojure.lang.IFn$OODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODL\")))))\n(defmacro oodl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->olol ^clojure.lang.IFn$OLOL [f]\n  (if (instance? clojure.lang.IFn$OLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOL\")))))\n(defmacro olol [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->olll ^clojure.lang.IFn$OLLL [f]\n  (if (instance? clojure.lang.IFn$OLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLL\")))))\n(defmacro olll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oldl ^clojure.lang.IFn$OLDL [f]\n  (if (instance? clojure.lang.IFn$OLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDL\")))))\n(defmacro oldl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->odol ^clojure.lang.IFn$ODOL [f]\n  (if (instance? clojure.lang.IFn$ODOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOL\")))))\n(defmacro odol [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->odll ^clojure.lang.IFn$ODLL [f]\n  (if (instance? clojure.lang.IFn$ODLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLL\")))))\n(defmacro odll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oddl ^clojure.lang.IFn$ODDL [f]\n  (if (instance? clojure.lang.IFn$ODDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDL\")))))\n(defmacro oddl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lool ^clojure.lang.IFn$LOOL [f]\n  (if (instance? clojure.lang.IFn$LOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOL\")))))\n(defmacro lool [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->loll ^clojure.lang.IFn$LOLL [f]\n  (if (instance? clojure.lang.IFn$LOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLL\")))))\n(defmacro loll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lodl ^clojure.lang.IFn$LODL [f]\n  (if (instance? clojure.lang.IFn$LODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODL\")))))\n(defmacro lodl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->llol ^clojure.lang.IFn$LLOL [f]\n  (if (instance? clojure.lang.IFn$LLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOL\")))))\n(defmacro llol [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->llll ^clojure.lang.IFn$LLLL [f]\n  (if (instance? clojure.lang.IFn$LLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLL\")))))\n(defmacro llll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lldl ^clojure.lang.IFn$LLDL [f]\n  (if (instance? clojure.lang.IFn$LLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDL\")))))\n(defmacro lldl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ldol ^clojure.lang.IFn$LDOL [f]\n  (if (instance? clojure.lang.IFn$LDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOL\")))))\n(defmacro ldol [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ldll ^clojure.lang.IFn$LDLL [f]\n  (if (instance? clojure.lang.IFn$LDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLL\")))))\n(defmacro ldll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lddl ^clojure.lang.IFn$LDDL [f]\n  (if (instance? clojure.lang.IFn$LDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDL\")))))\n(defmacro lddl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dool ^clojure.lang.IFn$DOOL [f]\n  (if (instance? clojure.lang.IFn$DOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOL\")))))\n(defmacro dool [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->doll ^clojure.lang.IFn$DOLL [f]\n  (if (instance? clojure.lang.IFn$DOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLL\")))))\n(defmacro doll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dodl ^clojure.lang.IFn$DODL [f]\n  (if (instance? clojure.lang.IFn$DODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODL\")))))\n(defmacro dodl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dlol ^clojure.lang.IFn$DLOL [f]\n  (if (instance? clojure.lang.IFn$DLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOL\")))))\n(defmacro dlol [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dlll ^clojure.lang.IFn$DLLL [f]\n  (if (instance? clojure.lang.IFn$DLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLL\")))))\n(defmacro dlll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dldl ^clojure.lang.IFn$DLDL [f]\n  (if (instance? clojure.lang.IFn$DLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDL\")))))\n(defmacro dldl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ddol ^clojure.lang.IFn$DDOL [f]\n  (if (instance? clojure.lang.IFn$DDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOL\")))))\n(defmacro ddol [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ddll ^clojure.lang.IFn$DDLL [f]\n  (if (instance? clojure.lang.IFn$DDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLL\")))))\n(defmacro ddll [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dddl ^clojure.lang.IFn$DDDL [f]\n  (if (instance? clojure.lang.IFn$DDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDL\")))))\n(defmacro dddl [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oood ^clojure.lang.IFn$OOOD [f]\n  (if (instance? clojure.lang.IFn$OOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOD\")))))\n(defmacro oood [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oold ^clojure.lang.IFn$OOLD [f]\n  (if (instance? clojure.lang.IFn$OOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLD\")))))\n(defmacro oold [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oodd ^clojure.lang.IFn$OODD [f]\n  (if (instance? clojure.lang.IFn$OODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODD\")))))\n(defmacro oodd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->olod ^clojure.lang.IFn$OLOD [f]\n  (if (instance? clojure.lang.IFn$OLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOD\")))))\n(defmacro olod [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->olld ^clojure.lang.IFn$OLLD [f]\n  (if (instance? clojure.lang.IFn$OLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLD\")))))\n(defmacro olld [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oldd ^clojure.lang.IFn$OLDD [f]\n  (if (instance? clojure.lang.IFn$OLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDD\")))))\n(defmacro oldd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->odod ^clojure.lang.IFn$ODOD [f]\n  (if (instance? clojure.lang.IFn$ODOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOD\")))))\n(defmacro odod [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->odld ^clojure.lang.IFn$ODLD [f]\n  (if (instance? clojure.lang.IFn$ODLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLD\")))))\n(defmacro odld [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->oddd ^clojure.lang.IFn$ODDD [f]\n  (if (instance? clojure.lang.IFn$ODDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDD\")))))\n(defmacro oddd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lood ^clojure.lang.IFn$LOOD [f]\n  (if (instance? clojure.lang.IFn$LOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOD\")))))\n(defmacro lood [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lold ^clojure.lang.IFn$LOLD [f]\n  (if (instance? clojure.lang.IFn$LOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLD\")))))\n(defmacro lold [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lodd ^clojure.lang.IFn$LODD [f]\n  (if (instance? clojure.lang.IFn$LODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODD\")))))\n(defmacro lodd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->llod ^clojure.lang.IFn$LLOD [f]\n  (if (instance? clojure.lang.IFn$LLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOD\")))))\n(defmacro llod [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->llld ^clojure.lang.IFn$LLLD [f]\n  (if (instance? clojure.lang.IFn$LLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLD\")))))\n(defmacro llld [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lldd ^clojure.lang.IFn$LLDD [f]\n  (if (instance? clojure.lang.IFn$LLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDD\")))))\n(defmacro lldd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ldod ^clojure.lang.IFn$LDOD [f]\n  (if (instance? clojure.lang.IFn$LDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOD\")))))\n(defmacro ldod [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ldld ^clojure.lang.IFn$LDLD [f]\n  (if (instance? clojure.lang.IFn$LDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLD\")))))\n(defmacro ldld [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->lddd ^clojure.lang.IFn$LDDD [f]\n  (if (instance? clojure.lang.IFn$LDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDD\")))))\n(defmacro lddd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dood ^clojure.lang.IFn$DOOD [f]\n  (if (instance? clojure.lang.IFn$DOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOD\")))))\n(defmacro dood [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dold ^clojure.lang.IFn$DOLD [f]\n  (if (instance? clojure.lang.IFn$DOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLD\")))))\n(defmacro dold [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dodd ^clojure.lang.IFn$DODD [f]\n  (if (instance? clojure.lang.IFn$DODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODD\")))))\n(defmacro dodd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dlod ^clojure.lang.IFn$DLOD [f]\n  (if (instance? clojure.lang.IFn$DLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOD\")))))\n(defmacro dlod [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dlld ^clojure.lang.IFn$DLLD [f]\n  (if (instance? clojure.lang.IFn$DLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLD\")))))\n(defmacro dlld [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dldd ^clojure.lang.IFn$DLDD [f]\n  (if (instance? clojure.lang.IFn$DLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDD\")))))\n(defmacro dldd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ddod ^clojure.lang.IFn$DDOD [f]\n  (if (instance? clojure.lang.IFn$DDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOD\")))))\n(defmacro ddod [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ddld ^clojure.lang.IFn$DDLD [f]\n  (if (instance? clojure.lang.IFn$DDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLD\")))))\n(defmacro ddld [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->dddd ^clojure.lang.IFn$DDDD [f]\n  (if (instance? clojure.lang.IFn$DDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDD\")))))\n(defmacro dddd [f arg0 arg1 arg2]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2))\n(defn ->ooolo ^clojure.lang.IFn$OOOLO [f]\n  (if (instance? clojure.lang.IFn$OOOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOLO\")))))\n(defmacro ooolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooodo ^clojure.lang.IFn$OOODO [f]\n  (if (instance? clojure.lang.IFn$OOODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOODO\")))))\n(defmacro ooodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooloo ^clojure.lang.IFn$OOLOO [f]\n  (if (instance? clojure.lang.IFn$OOLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLOO\")))))\n(defmacro ooloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oollo ^clojure.lang.IFn$OOLLO [f]\n  (if (instance? clojure.lang.IFn$OOLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLLO\")))))\n(defmacro oollo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooldo ^clojure.lang.IFn$OOLDO [f]\n  (if (instance? clojure.lang.IFn$OOLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLDO\")))))\n(defmacro ooldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oodoo ^clojure.lang.IFn$OODOO [f]\n  (if (instance? clojure.lang.IFn$OODOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODOO\")))))\n(defmacro oodoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oodlo ^clojure.lang.IFn$OODLO [f]\n  (if (instance? clojure.lang.IFn$OODLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODLO\")))))\n(defmacro oodlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooddo ^clojure.lang.IFn$OODDO [f]\n  (if (instance? clojure.lang.IFn$OODDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODDO\")))))\n(defmacro ooddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olooo ^clojure.lang.IFn$OLOOO [f]\n  (if (instance? clojure.lang.IFn$OLOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOOO\")))))\n(defmacro olooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ololo ^clojure.lang.IFn$OLOLO [f]\n  (if (instance? clojure.lang.IFn$OLOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOLO\")))))\n(defmacro ololo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olodo ^clojure.lang.IFn$OLODO [f]\n  (if (instance? clojure.lang.IFn$OLODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLODO\")))))\n(defmacro olodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olloo ^clojure.lang.IFn$OLLOO [f]\n  (if (instance? clojure.lang.IFn$OLLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLOO\")))))\n(defmacro olloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olllo ^clojure.lang.IFn$OLLLO [f]\n  (if (instance? clojure.lang.IFn$OLLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLLO\")))))\n(defmacro olllo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olldo ^clojure.lang.IFn$OLLDO [f]\n  (if (instance? clojure.lang.IFn$OLLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLDO\")))))\n(defmacro olldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oldoo ^clojure.lang.IFn$OLDOO [f]\n  (if (instance? clojure.lang.IFn$OLDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDOO\")))))\n(defmacro oldoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oldlo ^clojure.lang.IFn$OLDLO [f]\n  (if (instance? clojure.lang.IFn$OLDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDLO\")))))\n(defmacro oldlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olddo ^clojure.lang.IFn$OLDDO [f]\n  (if (instance? clojure.lang.IFn$OLDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDDO\")))))\n(defmacro olddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odooo ^clojure.lang.IFn$ODOOO [f]\n  (if (instance? clojure.lang.IFn$ODOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOOO\")))))\n(defmacro odooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odolo ^clojure.lang.IFn$ODOLO [f]\n  (if (instance? clojure.lang.IFn$ODOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOLO\")))))\n(defmacro odolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ododo ^clojure.lang.IFn$ODODO [f]\n  (if (instance? clojure.lang.IFn$ODODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODODO\")))))\n(defmacro ododo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odloo ^clojure.lang.IFn$ODLOO [f]\n  (if (instance? clojure.lang.IFn$ODLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLOO\")))))\n(defmacro odloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odllo ^clojure.lang.IFn$ODLLO [f]\n  (if (instance? clojure.lang.IFn$ODLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLLO\")))))\n(defmacro odllo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odldo ^clojure.lang.IFn$ODLDO [f]\n  (if (instance? clojure.lang.IFn$ODLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLDO\")))))\n(defmacro odldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oddoo ^clojure.lang.IFn$ODDOO [f]\n  (if (instance? clojure.lang.IFn$ODDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDOO\")))))\n(defmacro oddoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oddlo ^clojure.lang.IFn$ODDLO [f]\n  (if (instance? clojure.lang.IFn$ODDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDLO\")))))\n(defmacro oddlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odddo ^clojure.lang.IFn$ODDDO [f]\n  (if (instance? clojure.lang.IFn$ODDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDDO\")))))\n(defmacro odddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loooo ^clojure.lang.IFn$LOOOO [f]\n  (if (instance? clojure.lang.IFn$LOOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOOO\")))))\n(defmacro loooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loolo ^clojure.lang.IFn$LOOLO [f]\n  (if (instance? clojure.lang.IFn$LOOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOLO\")))))\n(defmacro loolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loodo ^clojure.lang.IFn$LOODO [f]\n  (if (instance? clojure.lang.IFn$LOODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOODO\")))))\n(defmacro loodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loloo ^clojure.lang.IFn$LOLOO [f]\n  (if (instance? clojure.lang.IFn$LOLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLOO\")))))\n(defmacro loloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lollo ^clojure.lang.IFn$LOLLO [f]\n  (if (instance? clojure.lang.IFn$LOLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLLO\")))))\n(defmacro lollo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loldo ^clojure.lang.IFn$LOLDO [f]\n  (if (instance? clojure.lang.IFn$LOLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLDO\")))))\n(defmacro loldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lodoo ^clojure.lang.IFn$LODOO [f]\n  (if (instance? clojure.lang.IFn$LODOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODOO\")))))\n(defmacro lodoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lodlo ^clojure.lang.IFn$LODLO [f]\n  (if (instance? clojure.lang.IFn$LODLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODLO\")))))\n(defmacro lodlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loddo ^clojure.lang.IFn$LODDO [f]\n  (if (instance? clojure.lang.IFn$LODDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODDO\")))))\n(defmacro loddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llooo ^clojure.lang.IFn$LLOOO [f]\n  (if (instance? clojure.lang.IFn$LLOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOOO\")))))\n(defmacro llooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llolo ^clojure.lang.IFn$LLOLO [f]\n  (if (instance? clojure.lang.IFn$LLOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOLO\")))))\n(defmacro llolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llodo ^clojure.lang.IFn$LLODO [f]\n  (if (instance? clojure.lang.IFn$LLODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLODO\")))))\n(defmacro llodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llloo ^clojure.lang.IFn$LLLOO [f]\n  (if (instance? clojure.lang.IFn$LLLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLOO\")))))\n(defmacro llloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llllo ^clojure.lang.IFn$LLLLO [f]\n  (if (instance? clojure.lang.IFn$LLLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLLO\")))))\n(defmacro llllo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llldo ^clojure.lang.IFn$LLLDO [f]\n  (if (instance? clojure.lang.IFn$LLLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLDO\")))))\n(defmacro llldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lldoo ^clojure.lang.IFn$LLDOO [f]\n  (if (instance? clojure.lang.IFn$LLDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDOO\")))))\n(defmacro lldoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lldlo ^clojure.lang.IFn$LLDLO [f]\n  (if (instance? clojure.lang.IFn$LLDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDLO\")))))\n(defmacro lldlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llddo ^clojure.lang.IFn$LLDDO [f]\n  (if (instance? clojure.lang.IFn$LLDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDDO\")))))\n(defmacro llddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldooo ^clojure.lang.IFn$LDOOO [f]\n  (if (instance? clojure.lang.IFn$LDOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOOO\")))))\n(defmacro ldooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldolo ^clojure.lang.IFn$LDOLO [f]\n  (if (instance? clojure.lang.IFn$LDOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOLO\")))))\n(defmacro ldolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldodo ^clojure.lang.IFn$LDODO [f]\n  (if (instance? clojure.lang.IFn$LDODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDODO\")))))\n(defmacro ldodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldloo ^clojure.lang.IFn$LDLOO [f]\n  (if (instance? clojure.lang.IFn$LDLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLOO\")))))\n(defmacro ldloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldllo ^clojure.lang.IFn$LDLLO [f]\n  (if (instance? clojure.lang.IFn$LDLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLLO\")))))\n(defmacro ldllo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldldo ^clojure.lang.IFn$LDLDO [f]\n  (if (instance? clojure.lang.IFn$LDLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLDO\")))))\n(defmacro ldldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lddoo ^clojure.lang.IFn$LDDOO [f]\n  (if (instance? clojure.lang.IFn$LDDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDOO\")))))\n(defmacro lddoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lddlo ^clojure.lang.IFn$LDDLO [f]\n  (if (instance? clojure.lang.IFn$LDDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDLO\")))))\n(defmacro lddlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldddo ^clojure.lang.IFn$LDDDO [f]\n  (if (instance? clojure.lang.IFn$LDDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDDO\")))))\n(defmacro ldddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doooo ^clojure.lang.IFn$DOOOO [f]\n  (if (instance? clojure.lang.IFn$DOOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOOO\")))))\n(defmacro doooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doolo ^clojure.lang.IFn$DOOLO [f]\n  (if (instance? clojure.lang.IFn$DOOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOLO\")))))\n(defmacro doolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doodo ^clojure.lang.IFn$DOODO [f]\n  (if (instance? clojure.lang.IFn$DOODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOODO\")))))\n(defmacro doodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doloo ^clojure.lang.IFn$DOLOO [f]\n  (if (instance? clojure.lang.IFn$DOLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLOO\")))))\n(defmacro doloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dollo ^clojure.lang.IFn$DOLLO [f]\n  (if (instance? clojure.lang.IFn$DOLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLLO\")))))\n(defmacro dollo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doldo ^clojure.lang.IFn$DOLDO [f]\n  (if (instance? clojure.lang.IFn$DOLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLDO\")))))\n(defmacro doldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dodoo ^clojure.lang.IFn$DODOO [f]\n  (if (instance? clojure.lang.IFn$DODOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODOO\")))))\n(defmacro dodoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dodlo ^clojure.lang.IFn$DODLO [f]\n  (if (instance? clojure.lang.IFn$DODLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODLO\")))))\n(defmacro dodlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doddo ^clojure.lang.IFn$DODDO [f]\n  (if (instance? clojure.lang.IFn$DODDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODDO\")))))\n(defmacro doddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlooo ^clojure.lang.IFn$DLOOO [f]\n  (if (instance? clojure.lang.IFn$DLOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOOO\")))))\n(defmacro dlooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlolo ^clojure.lang.IFn$DLOLO [f]\n  (if (instance? clojure.lang.IFn$DLOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOLO\")))))\n(defmacro dlolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlodo ^clojure.lang.IFn$DLODO [f]\n  (if (instance? clojure.lang.IFn$DLODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLODO\")))))\n(defmacro dlodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlloo ^clojure.lang.IFn$DLLOO [f]\n  (if (instance? clojure.lang.IFn$DLLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLOO\")))))\n(defmacro dlloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlllo ^clojure.lang.IFn$DLLLO [f]\n  (if (instance? clojure.lang.IFn$DLLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLLO\")))))\n(defmacro dlllo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlldo ^clojure.lang.IFn$DLLDO [f]\n  (if (instance? clojure.lang.IFn$DLLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLDO\")))))\n(defmacro dlldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dldoo ^clojure.lang.IFn$DLDOO [f]\n  (if (instance? clojure.lang.IFn$DLDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDOO\")))))\n(defmacro dldoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dldlo ^clojure.lang.IFn$DLDLO [f]\n  (if (instance? clojure.lang.IFn$DLDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDLO\")))))\n(defmacro dldlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlddo ^clojure.lang.IFn$DLDDO [f]\n  (if (instance? clojure.lang.IFn$DLDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDDO\")))))\n(defmacro dlddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddooo ^clojure.lang.IFn$DDOOO [f]\n  (if (instance? clojure.lang.IFn$DDOOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOOO\")))))\n(defmacro ddooo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddolo ^clojure.lang.IFn$DDOLO [f]\n  (if (instance? clojure.lang.IFn$DDOLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOLO\")))))\n(defmacro ddolo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddodo ^clojure.lang.IFn$DDODO [f]\n  (if (instance? clojure.lang.IFn$DDODO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDODO\")))))\n(defmacro ddodo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddloo ^clojure.lang.IFn$DDLOO [f]\n  (if (instance? clojure.lang.IFn$DDLOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLOO\")))))\n(defmacro ddloo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddllo ^clojure.lang.IFn$DDLLO [f]\n  (if (instance? clojure.lang.IFn$DDLLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLLO\")))))\n(defmacro ddllo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddldo ^clojure.lang.IFn$DDLDO [f]\n  (if (instance? clojure.lang.IFn$DDLDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLDO\")))))\n(defmacro ddldo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dddoo ^clojure.lang.IFn$DDDOO [f]\n  (if (instance? clojure.lang.IFn$DDDOO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDOO\")))))\n(defmacro dddoo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dddlo ^clojure.lang.IFn$DDDLO [f]\n  (if (instance? clojure.lang.IFn$DDDLO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDLO\")))))\n(defmacro dddlo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddddo ^clojure.lang.IFn$DDDDO [f]\n  (if (instance? clojure.lang.IFn$DDDDO f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDDO\")))))\n(defmacro ddddo [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooool ^clojure.lang.IFn$OOOOL [f]\n  (if (instance? clojure.lang.IFn$OOOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOOL\")))))\n(defmacro ooool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oooll ^clojure.lang.IFn$OOOLL [f]\n  (if (instance? clojure.lang.IFn$OOOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOLL\")))))\n(defmacro oooll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooodl ^clojure.lang.IFn$OOODL [f]\n  (if (instance? clojure.lang.IFn$OOODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOODL\")))))\n(defmacro ooodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oolol ^clojure.lang.IFn$OOLOL [f]\n  (if (instance? clojure.lang.IFn$OOLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLOL\")))))\n(defmacro oolol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oolll ^clojure.lang.IFn$OOLLL [f]\n  (if (instance? clojure.lang.IFn$OOLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLLL\")))))\n(defmacro oolll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooldl ^clojure.lang.IFn$OOLDL [f]\n  (if (instance? clojure.lang.IFn$OOLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLDL\")))))\n(defmacro ooldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oodol ^clojure.lang.IFn$OODOL [f]\n  (if (instance? clojure.lang.IFn$OODOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODOL\")))))\n(defmacro oodol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oodll ^clojure.lang.IFn$OODLL [f]\n  (if (instance? clojure.lang.IFn$OODLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODLL\")))))\n(defmacro oodll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooddl ^clojure.lang.IFn$OODDL [f]\n  (if (instance? clojure.lang.IFn$OODDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODDL\")))))\n(defmacro ooddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olool ^clojure.lang.IFn$OLOOL [f]\n  (if (instance? clojure.lang.IFn$OLOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOOL\")))))\n(defmacro olool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ololl ^clojure.lang.IFn$OLOLL [f]\n  (if (instance? clojure.lang.IFn$OLOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOLL\")))))\n(defmacro ololl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olodl ^clojure.lang.IFn$OLODL [f]\n  (if (instance? clojure.lang.IFn$OLODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLODL\")))))\n(defmacro olodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ollol ^clojure.lang.IFn$OLLOL [f]\n  (if (instance? clojure.lang.IFn$OLLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLOL\")))))\n(defmacro ollol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ollll ^clojure.lang.IFn$OLLLL [f]\n  (if (instance? clojure.lang.IFn$OLLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLLL\")))))\n(defmacro ollll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olldl ^clojure.lang.IFn$OLLDL [f]\n  (if (instance? clojure.lang.IFn$OLLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLDL\")))))\n(defmacro olldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oldol ^clojure.lang.IFn$OLDOL [f]\n  (if (instance? clojure.lang.IFn$OLDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDOL\")))))\n(defmacro oldol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oldll ^clojure.lang.IFn$OLDLL [f]\n  (if (instance? clojure.lang.IFn$OLDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDLL\")))))\n(defmacro oldll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olddl ^clojure.lang.IFn$OLDDL [f]\n  (if (instance? clojure.lang.IFn$OLDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDDL\")))))\n(defmacro olddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odool ^clojure.lang.IFn$ODOOL [f]\n  (if (instance? clojure.lang.IFn$ODOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOOL\")))))\n(defmacro odool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odoll ^clojure.lang.IFn$ODOLL [f]\n  (if (instance? clojure.lang.IFn$ODOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOLL\")))))\n(defmacro odoll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ododl ^clojure.lang.IFn$ODODL [f]\n  (if (instance? clojure.lang.IFn$ODODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODODL\")))))\n(defmacro ododl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odlol ^clojure.lang.IFn$ODLOL [f]\n  (if (instance? clojure.lang.IFn$ODLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLOL\")))))\n(defmacro odlol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odlll ^clojure.lang.IFn$ODLLL [f]\n  (if (instance? clojure.lang.IFn$ODLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLLL\")))))\n(defmacro odlll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odldl ^clojure.lang.IFn$ODLDL [f]\n  (if (instance? clojure.lang.IFn$ODLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLDL\")))))\n(defmacro odldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oddol ^clojure.lang.IFn$ODDOL [f]\n  (if (instance? clojure.lang.IFn$ODDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDOL\")))))\n(defmacro oddol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oddll ^clojure.lang.IFn$ODDLL [f]\n  (if (instance? clojure.lang.IFn$ODDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDLL\")))))\n(defmacro oddll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odddl ^clojure.lang.IFn$ODDDL [f]\n  (if (instance? clojure.lang.IFn$ODDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDDL\")))))\n(defmacro odddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loool ^clojure.lang.IFn$LOOOL [f]\n  (if (instance? clojure.lang.IFn$LOOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOOL\")))))\n(defmacro loool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->looll ^clojure.lang.IFn$LOOLL [f]\n  (if (instance? clojure.lang.IFn$LOOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOLL\")))))\n(defmacro looll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loodl ^clojure.lang.IFn$LOODL [f]\n  (if (instance? clojure.lang.IFn$LOODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOODL\")))))\n(defmacro loodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lolol ^clojure.lang.IFn$LOLOL [f]\n  (if (instance? clojure.lang.IFn$LOLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLOL\")))))\n(defmacro lolol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lolll ^clojure.lang.IFn$LOLLL [f]\n  (if (instance? clojure.lang.IFn$LOLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLLL\")))))\n(defmacro lolll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loldl ^clojure.lang.IFn$LOLDL [f]\n  (if (instance? clojure.lang.IFn$LOLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLDL\")))))\n(defmacro loldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lodol ^clojure.lang.IFn$LODOL [f]\n  (if (instance? clojure.lang.IFn$LODOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODOL\")))))\n(defmacro lodol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lodll ^clojure.lang.IFn$LODLL [f]\n  (if (instance? clojure.lang.IFn$LODLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODLL\")))))\n(defmacro lodll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loddl ^clojure.lang.IFn$LODDL [f]\n  (if (instance? clojure.lang.IFn$LODDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODDL\")))))\n(defmacro loddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llool ^clojure.lang.IFn$LLOOL [f]\n  (if (instance? clojure.lang.IFn$LLOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOOL\")))))\n(defmacro llool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lloll ^clojure.lang.IFn$LLOLL [f]\n  (if (instance? clojure.lang.IFn$LLOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOLL\")))))\n(defmacro lloll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llodl ^clojure.lang.IFn$LLODL [f]\n  (if (instance? clojure.lang.IFn$LLODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLODL\")))))\n(defmacro llodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lllol ^clojure.lang.IFn$LLLOL [f]\n  (if (instance? clojure.lang.IFn$LLLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLOL\")))))\n(defmacro lllol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lllll ^clojure.lang.IFn$LLLLL [f]\n  (if (instance? clojure.lang.IFn$LLLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLLL\")))))\n(defmacro lllll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llldl ^clojure.lang.IFn$LLLDL [f]\n  (if (instance? clojure.lang.IFn$LLLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLDL\")))))\n(defmacro llldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lldol ^clojure.lang.IFn$LLDOL [f]\n  (if (instance? clojure.lang.IFn$LLDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDOL\")))))\n(defmacro lldol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lldll ^clojure.lang.IFn$LLDLL [f]\n  (if (instance? clojure.lang.IFn$LLDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDLL\")))))\n(defmacro lldll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llddl ^clojure.lang.IFn$LLDDL [f]\n  (if (instance? clojure.lang.IFn$LLDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDDL\")))))\n(defmacro llddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldool ^clojure.lang.IFn$LDOOL [f]\n  (if (instance? clojure.lang.IFn$LDOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOOL\")))))\n(defmacro ldool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldoll ^clojure.lang.IFn$LDOLL [f]\n  (if (instance? clojure.lang.IFn$LDOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOLL\")))))\n(defmacro ldoll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldodl ^clojure.lang.IFn$LDODL [f]\n  (if (instance? clojure.lang.IFn$LDODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDODL\")))))\n(defmacro ldodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldlol ^clojure.lang.IFn$LDLOL [f]\n  (if (instance? clojure.lang.IFn$LDLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLOL\")))))\n(defmacro ldlol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldlll ^clojure.lang.IFn$LDLLL [f]\n  (if (instance? clojure.lang.IFn$LDLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLLL\")))))\n(defmacro ldlll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldldl ^clojure.lang.IFn$LDLDL [f]\n  (if (instance? clojure.lang.IFn$LDLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLDL\")))))\n(defmacro ldldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lddol ^clojure.lang.IFn$LDDOL [f]\n  (if (instance? clojure.lang.IFn$LDDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDOL\")))))\n(defmacro lddol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lddll ^clojure.lang.IFn$LDDLL [f]\n  (if (instance? clojure.lang.IFn$LDDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDLL\")))))\n(defmacro lddll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldddl ^clojure.lang.IFn$LDDDL [f]\n  (if (instance? clojure.lang.IFn$LDDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDDL\")))))\n(defmacro ldddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doool ^clojure.lang.IFn$DOOOL [f]\n  (if (instance? clojure.lang.IFn$DOOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOOL\")))))\n(defmacro doool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dooll ^clojure.lang.IFn$DOOLL [f]\n  (if (instance? clojure.lang.IFn$DOOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOLL\")))))\n(defmacro dooll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doodl ^clojure.lang.IFn$DOODL [f]\n  (if (instance? clojure.lang.IFn$DOODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOODL\")))))\n(defmacro doodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dolol ^clojure.lang.IFn$DOLOL [f]\n  (if (instance? clojure.lang.IFn$DOLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLOL\")))))\n(defmacro dolol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dolll ^clojure.lang.IFn$DOLLL [f]\n  (if (instance? clojure.lang.IFn$DOLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLLL\")))))\n(defmacro dolll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doldl ^clojure.lang.IFn$DOLDL [f]\n  (if (instance? clojure.lang.IFn$DOLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLDL\")))))\n(defmacro doldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dodol ^clojure.lang.IFn$DODOL [f]\n  (if (instance? clojure.lang.IFn$DODOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODOL\")))))\n(defmacro dodol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dodll ^clojure.lang.IFn$DODLL [f]\n  (if (instance? clojure.lang.IFn$DODLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODLL\")))))\n(defmacro dodll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doddl ^clojure.lang.IFn$DODDL [f]\n  (if (instance? clojure.lang.IFn$DODDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODDL\")))))\n(defmacro doddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlool ^clojure.lang.IFn$DLOOL [f]\n  (if (instance? clojure.lang.IFn$DLOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOOL\")))))\n(defmacro dlool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dloll ^clojure.lang.IFn$DLOLL [f]\n  (if (instance? clojure.lang.IFn$DLOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOLL\")))))\n(defmacro dloll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlodl ^clojure.lang.IFn$DLODL [f]\n  (if (instance? clojure.lang.IFn$DLODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLODL\")))))\n(defmacro dlodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dllol ^clojure.lang.IFn$DLLOL [f]\n  (if (instance? clojure.lang.IFn$DLLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLOL\")))))\n(defmacro dllol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dllll ^clojure.lang.IFn$DLLLL [f]\n  (if (instance? clojure.lang.IFn$DLLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLLL\")))))\n(defmacro dllll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlldl ^clojure.lang.IFn$DLLDL [f]\n  (if (instance? clojure.lang.IFn$DLLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLDL\")))))\n(defmacro dlldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dldol ^clojure.lang.IFn$DLDOL [f]\n  (if (instance? clojure.lang.IFn$DLDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDOL\")))))\n(defmacro dldol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dldll ^clojure.lang.IFn$DLDLL [f]\n  (if (instance? clojure.lang.IFn$DLDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDLL\")))))\n(defmacro dldll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlddl ^clojure.lang.IFn$DLDDL [f]\n  (if (instance? clojure.lang.IFn$DLDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDDL\")))))\n(defmacro dlddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddool ^clojure.lang.IFn$DDOOL [f]\n  (if (instance? clojure.lang.IFn$DDOOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOOL\")))))\n(defmacro ddool [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddoll ^clojure.lang.IFn$DDOLL [f]\n  (if (instance? clojure.lang.IFn$DDOLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOLL\")))))\n(defmacro ddoll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddodl ^clojure.lang.IFn$DDODL [f]\n  (if (instance? clojure.lang.IFn$DDODL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDODL\")))))\n(defmacro ddodl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddlol ^clojure.lang.IFn$DDLOL [f]\n  (if (instance? clojure.lang.IFn$DDLOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLOL\")))))\n(defmacro ddlol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddlll ^clojure.lang.IFn$DDLLL [f]\n  (if (instance? clojure.lang.IFn$DDLLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLLL\")))))\n(defmacro ddlll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddldl ^clojure.lang.IFn$DDLDL [f]\n  (if (instance? clojure.lang.IFn$DDLDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLDL\")))))\n(defmacro ddldl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dddol ^clojure.lang.IFn$DDDOL [f]\n  (if (instance? clojure.lang.IFn$DDDOL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDOL\")))))\n(defmacro dddol [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dddll ^clojure.lang.IFn$DDDLL [f]\n  (if (instance? clojure.lang.IFn$DDDLL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDLL\")))))\n(defmacro dddll [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddddl ^clojure.lang.IFn$DDDDL [f]\n  (if (instance? clojure.lang.IFn$DDDDL f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDDL\")))))\n(defmacro ddddl [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooood ^clojure.lang.IFn$OOOOD [f]\n  (if (instance? clojure.lang.IFn$OOOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOOD\")))))\n(defmacro ooood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooold ^clojure.lang.IFn$OOOLD [f]\n  (if (instance? clojure.lang.IFn$OOOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOOLD\")))))\n(defmacro ooold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooodd ^clojure.lang.IFn$OOODD [f]\n  (if (instance? clojure.lang.IFn$OOODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOODD\")))))\n(defmacro ooodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oolod ^clojure.lang.IFn$OOLOD [f]\n  (if (instance? clojure.lang.IFn$OOLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLOD\")))))\n(defmacro oolod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oolld ^clojure.lang.IFn$OOLLD [f]\n  (if (instance? clojure.lang.IFn$OOLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLLD\")))))\n(defmacro oolld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooldd ^clojure.lang.IFn$OOLDD [f]\n  (if (instance? clojure.lang.IFn$OOLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OOLDD\")))))\n(defmacro ooldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oodod ^clojure.lang.IFn$OODOD [f]\n  (if (instance? clojure.lang.IFn$OODOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODOD\")))))\n(defmacro oodod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oodld ^clojure.lang.IFn$OODLD [f]\n  (if (instance? clojure.lang.IFn$OODLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODLD\")))))\n(defmacro oodld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ooddd ^clojure.lang.IFn$OODDD [f]\n  (if (instance? clojure.lang.IFn$OODDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OODDD\")))))\n(defmacro ooddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olood ^clojure.lang.IFn$OLOOD [f]\n  (if (instance? clojure.lang.IFn$OLOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOOD\")))))\n(defmacro olood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olold ^clojure.lang.IFn$OLOLD [f]\n  (if (instance? clojure.lang.IFn$OLOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLOLD\")))))\n(defmacro olold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olodd ^clojure.lang.IFn$OLODD [f]\n  (if (instance? clojure.lang.IFn$OLODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLODD\")))))\n(defmacro olodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ollod ^clojure.lang.IFn$OLLOD [f]\n  (if (instance? clojure.lang.IFn$OLLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLOD\")))))\n(defmacro ollod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ollld ^clojure.lang.IFn$OLLLD [f]\n  (if (instance? clojure.lang.IFn$OLLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLLD\")))))\n(defmacro ollld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olldd ^clojure.lang.IFn$OLLDD [f]\n  (if (instance? clojure.lang.IFn$OLLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLLDD\")))))\n(defmacro olldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oldod ^clojure.lang.IFn$OLDOD [f]\n  (if (instance? clojure.lang.IFn$OLDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDOD\")))))\n(defmacro oldod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oldld ^clojure.lang.IFn$OLDLD [f]\n  (if (instance? clojure.lang.IFn$OLDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDLD\")))))\n(defmacro oldld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->olddd ^clojure.lang.IFn$OLDDD [f]\n  (if (instance? clojure.lang.IFn$OLDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$OLDDD\")))))\n(defmacro olddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odood ^clojure.lang.IFn$ODOOD [f]\n  (if (instance? clojure.lang.IFn$ODOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOOD\")))))\n(defmacro odood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odold ^clojure.lang.IFn$ODOLD [f]\n  (if (instance? clojure.lang.IFn$ODOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODOLD\")))))\n(defmacro odold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ododd ^clojure.lang.IFn$ODODD [f]\n  (if (instance? clojure.lang.IFn$ODODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODODD\")))))\n(defmacro ododd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odlod ^clojure.lang.IFn$ODLOD [f]\n  (if (instance? clojure.lang.IFn$ODLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLOD\")))))\n(defmacro odlod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odlld ^clojure.lang.IFn$ODLLD [f]\n  (if (instance? clojure.lang.IFn$ODLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLLD\")))))\n(defmacro odlld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odldd ^clojure.lang.IFn$ODLDD [f]\n  (if (instance? clojure.lang.IFn$ODLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODLDD\")))))\n(defmacro odldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oddod ^clojure.lang.IFn$ODDOD [f]\n  (if (instance? clojure.lang.IFn$ODDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDOD\")))))\n(defmacro oddod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->oddld ^clojure.lang.IFn$ODDLD [f]\n  (if (instance? clojure.lang.IFn$ODDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDLD\")))))\n(defmacro oddld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->odddd ^clojure.lang.IFn$ODDDD [f]\n  (if (instance? clojure.lang.IFn$ODDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$ODDDD\")))))\n(defmacro odddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loood ^clojure.lang.IFn$LOOOD [f]\n  (if (instance? clojure.lang.IFn$LOOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOOD\")))))\n(defmacro loood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loold ^clojure.lang.IFn$LOOLD [f]\n  (if (instance? clojure.lang.IFn$LOOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOOLD\")))))\n(defmacro loold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loodd ^clojure.lang.IFn$LOODD [f]\n  (if (instance? clojure.lang.IFn$LOODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOODD\")))))\n(defmacro loodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lolod ^clojure.lang.IFn$LOLOD [f]\n  (if (instance? clojure.lang.IFn$LOLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLOD\")))))\n(defmacro lolod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lolld ^clojure.lang.IFn$LOLLD [f]\n  (if (instance? clojure.lang.IFn$LOLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLLD\")))))\n(defmacro lolld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loldd ^clojure.lang.IFn$LOLDD [f]\n  (if (instance? clojure.lang.IFn$LOLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LOLDD\")))))\n(defmacro loldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lodod ^clojure.lang.IFn$LODOD [f]\n  (if (instance? clojure.lang.IFn$LODOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODOD\")))))\n(defmacro lodod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lodld ^clojure.lang.IFn$LODLD [f]\n  (if (instance? clojure.lang.IFn$LODLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODLD\")))))\n(defmacro lodld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->loddd ^clojure.lang.IFn$LODDD [f]\n  (if (instance? clojure.lang.IFn$LODDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LODDD\")))))\n(defmacro loddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llood ^clojure.lang.IFn$LLOOD [f]\n  (if (instance? clojure.lang.IFn$LLOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOOD\")))))\n(defmacro llood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llold ^clojure.lang.IFn$LLOLD [f]\n  (if (instance? clojure.lang.IFn$LLOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLOLD\")))))\n(defmacro llold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llodd ^clojure.lang.IFn$LLODD [f]\n  (if (instance? clojure.lang.IFn$LLODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLODD\")))))\n(defmacro llodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lllod ^clojure.lang.IFn$LLLOD [f]\n  (if (instance? clojure.lang.IFn$LLLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLOD\")))))\n(defmacro lllod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lllld ^clojure.lang.IFn$LLLLD [f]\n  (if (instance? clojure.lang.IFn$LLLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLLD\")))))\n(defmacro lllld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llldd ^clojure.lang.IFn$LLLDD [f]\n  (if (instance? clojure.lang.IFn$LLLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLLDD\")))))\n(defmacro llldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lldod ^clojure.lang.IFn$LLDOD [f]\n  (if (instance? clojure.lang.IFn$LLDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDOD\")))))\n(defmacro lldod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lldld ^clojure.lang.IFn$LLDLD [f]\n  (if (instance? clojure.lang.IFn$LLDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDLD\")))))\n(defmacro lldld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->llddd ^clojure.lang.IFn$LLDDD [f]\n  (if (instance? clojure.lang.IFn$LLDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LLDDD\")))))\n(defmacro llddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldood ^clojure.lang.IFn$LDOOD [f]\n  (if (instance? clojure.lang.IFn$LDOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOOD\")))))\n(defmacro ldood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldold ^clojure.lang.IFn$LDOLD [f]\n  (if (instance? clojure.lang.IFn$LDOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDOLD\")))))\n(defmacro ldold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldodd ^clojure.lang.IFn$LDODD [f]\n  (if (instance? clojure.lang.IFn$LDODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDODD\")))))\n(defmacro ldodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldlod ^clojure.lang.IFn$LDLOD [f]\n  (if (instance? clojure.lang.IFn$LDLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLOD\")))))\n(defmacro ldlod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldlld ^clojure.lang.IFn$LDLLD [f]\n  (if (instance? clojure.lang.IFn$LDLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLLD\")))))\n(defmacro ldlld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldldd ^clojure.lang.IFn$LDLDD [f]\n  (if (instance? clojure.lang.IFn$LDLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDLDD\")))))\n(defmacro ldldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lddod ^clojure.lang.IFn$LDDOD [f]\n  (if (instance? clojure.lang.IFn$LDDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDOD\")))))\n(defmacro lddod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->lddld ^clojure.lang.IFn$LDDLD [f]\n  (if (instance? clojure.lang.IFn$LDDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDLD\")))))\n(defmacro lddld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ldddd ^clojure.lang.IFn$LDDDD [f]\n  (if (instance? clojure.lang.IFn$LDDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$LDDDD\")))))\n(defmacro ldddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doood ^clojure.lang.IFn$DOOOD [f]\n  (if (instance? clojure.lang.IFn$DOOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOOD\")))))\n(defmacro doood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doold ^clojure.lang.IFn$DOOLD [f]\n  (if (instance? clojure.lang.IFn$DOOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOOLD\")))))\n(defmacro doold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doodd ^clojure.lang.IFn$DOODD [f]\n  (if (instance? clojure.lang.IFn$DOODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOODD\")))))\n(defmacro doodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dolod ^clojure.lang.IFn$DOLOD [f]\n  (if (instance? clojure.lang.IFn$DOLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLOD\")))))\n(defmacro dolod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dolld ^clojure.lang.IFn$DOLLD [f]\n  (if (instance? clojure.lang.IFn$DOLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLLD\")))))\n(defmacro dolld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doldd ^clojure.lang.IFn$DOLDD [f]\n  (if (instance? clojure.lang.IFn$DOLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DOLDD\")))))\n(defmacro doldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dodod ^clojure.lang.IFn$DODOD [f]\n  (if (instance? clojure.lang.IFn$DODOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODOD\")))))\n(defmacro dodod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dodld ^clojure.lang.IFn$DODLD [f]\n  (if (instance? clojure.lang.IFn$DODLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODLD\")))))\n(defmacro dodld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->doddd ^clojure.lang.IFn$DODDD [f]\n  (if (instance? clojure.lang.IFn$DODDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DODDD\")))))\n(defmacro doddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlood ^clojure.lang.IFn$DLOOD [f]\n  (if (instance? clojure.lang.IFn$DLOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOOD\")))))\n(defmacro dlood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlold ^clojure.lang.IFn$DLOLD [f]\n  (if (instance? clojure.lang.IFn$DLOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLOLD\")))))\n(defmacro dlold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlodd ^clojure.lang.IFn$DLODD [f]\n  (if (instance? clojure.lang.IFn$DLODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLODD\")))))\n(defmacro dlodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dllod ^clojure.lang.IFn$DLLOD [f]\n  (if (instance? clojure.lang.IFn$DLLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLOD\")))))\n(defmacro dllod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dllld ^clojure.lang.IFn$DLLLD [f]\n  (if (instance? clojure.lang.IFn$DLLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLLD\")))))\n(defmacro dllld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlldd ^clojure.lang.IFn$DLLDD [f]\n  (if (instance? clojure.lang.IFn$DLLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLLDD\")))))\n(defmacro dlldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dldod ^clojure.lang.IFn$DLDOD [f]\n  (if (instance? clojure.lang.IFn$DLDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDOD\")))))\n(defmacro dldod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dldld ^clojure.lang.IFn$DLDLD [f]\n  (if (instance? clojure.lang.IFn$DLDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDLD\")))))\n(defmacro dldld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dlddd ^clojure.lang.IFn$DLDDD [f]\n  (if (instance? clojure.lang.IFn$DLDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DLDDD\")))))\n(defmacro dlddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddood ^clojure.lang.IFn$DDOOD [f]\n  (if (instance? clojure.lang.IFn$DDOOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOOD\")))))\n(defmacro ddood [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddold ^clojure.lang.IFn$DDOLD [f]\n  (if (instance? clojure.lang.IFn$DDOLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDOLD\")))))\n(defmacro ddold [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddodd ^clojure.lang.IFn$DDODD [f]\n  (if (instance? clojure.lang.IFn$DDODD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDODD\")))))\n(defmacro ddodd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddlod ^clojure.lang.IFn$DDLOD [f]\n  (if (instance? clojure.lang.IFn$DDLOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLOD\")))))\n(defmacro ddlod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddlld ^clojure.lang.IFn$DDLLD [f]\n  (if (instance? clojure.lang.IFn$DDLLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLLD\")))))\n(defmacro ddlld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddldd ^clojure.lang.IFn$DDLDD [f]\n  (if (instance? clojure.lang.IFn$DDLDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDLDD\")))))\n(defmacro ddldd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dddod ^clojure.lang.IFn$DDDOD [f]\n  (if (instance? clojure.lang.IFn$DDDOD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDOD\")))))\n(defmacro dddod [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->dddld ^clojure.lang.IFn$DDDLD [f]\n  (if (instance? clojure.lang.IFn$DDDLD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDLD\")))))\n(defmacro dddld [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n(defn ->ddddd ^clojure.lang.IFn$DDDDD [f]\n  (if (instance? clojure.lang.IFn$DDDDD f)\n    f\n    (throw (RuntimeException. (str f \" is not an instance ofclojure.lang.IFn$DDDDD\")))))\n(defmacro ddddd [f arg0 arg1 arg2 arg3]\n  `(.invokePrim ~f ~arg0 ~arg1 ~arg2 ~arg3))\n"
  },
  {
    "path": "src/ham_fisted/print.clj",
    "content": "(ns ham-fisted.print)\n\n\n(defmacro implement-tostring-print\n  \"Implement tostring printing for a particular type name.\"\n  [typename]\n  `(.addMethod ~(with-meta 'print-method {:tag 'clojure.lang.MultiFn}) ~typename\n               ham_fisted.Reductions/ToStringPrint))\n"
  },
  {
    "path": "src/ham_fisted/process.clj",
    "content": "(ns ham-fisted.process\n  (:require [ham-fisted.iterator :as hamf-iter]\n            [ham-fisted.reduce :as hamf-rf]))\n\n(defn stream->strings\n  ([input] (stream->strings input 256 (java.nio.charset.Charset/defaultCharset)))\n  ([^java.io.InputStream input bufsize ^java.nio.charset.Charset charset]\n   (let [buffer (byte-array bufsize)]\n     (hamf-iter/once-iterable\n      #(let [size (long (try (.read input buffer)\n                             (catch Exception e 0)))]\n         (when (pos? size)\n           (String. buffer 0 size charset)))))))\n\n(defn- strip-trailing\n  ^String [data]\n  (.stripTrailing (str data)))\n\n(defn- naive-split-lines\n  [^String data]\n  (let [nl (int \\newline)]\n    (loop [data data\n           nn (.indexOf data nl)\n           rv []]\n      (if (neg? nn)\n        [rv data]\n        (let [rv (conj rv (.substring data 0 nn))\n              data (.substring data (inc nn))]\n          (recur data (.indexOf data nl) rv))))))\n\n(defn out-rf\n  [print?]\n  (fn do-out-rf\n    ([] {:temp-buf (StringBuilder.) :total-buf (StringBuilder.)})\n    ([{:keys [^StringBuilder temp-buf ^StringBuilder total-buf] :as acc} ^String data]\n     (.append temp-buf data)\n     (.append total-buf data)\n     (let [temp-str (.toString temp-buf)\n           [strs leftover] (naive-split-lines (.toString temp-buf))]\n       (when print? (run! println (map strip-trailing strs)))\n       (.delete temp-buf (int 0) (int (.length temp-buf)))\n       (.append temp-buf leftover))\n     acc)\n    ([{:keys [^StringBuilder temp-buf ^StringBuilder total-buf] :as acc}]\n     (when print? (println (.toString temp-buf)))\n     (.toString total-buf))))\n\n(def ^{:doc \"Print process output using println.  Example process output handler.\n  Returns total output as a string to when finalized.\"}\n  println-rf (out-rf true))\n\n(def ^{:doc \"Returns total output as a string to when finalized.\"} quiet-rf (out-rf false))\n\n(def ^{:doc \"Record all the strings and save them to a vector\"}\n  record-rf\n  (fn record-rf\n    ([] (transient []))\n    ([acc v] (conj! acc v))\n    ([acc] (persistent! acc))))\n\n(defn destroy-forcibly!\n  \"Destroy the process handle's process forcibly.\"\n  [^java.lang.ProcessHandle proc-hdl]\n  (.destroyForcibly proc-hdl))\n\n(defn process-descendants\n  \"Get the first descendants of a process handle.\"\n  [^java.lang.ProcessHandle proc-hdl]\n  (-> (reify Iterable\n        (iterator [this]\n          (.iterator (.descendants proc-hdl))))\n      (vec)))\n\n(defn launch\n  \"Launch a proccess.\n\n  * cmd-line string command line.\n  * stdout-hdrl, stderr-hdlr - transduce-style rf functions that receive each string read from stdout\n    and stderr respectively.\n\n  Returns `{:keys [^java.lang.ProcessHandle proc-hdl wait-or-kill]}`:\n\n  * `proc-hdl` -  java.lang.ProcessHandle\n  * `wait-or-kill` - function that has two arities:\n    1. (proc) - kill the process returning any output as {:out :err}.\n    2. (proc time-ms timeout-symbol) - wait specified time for process to terminate returning either\n       the timeout symbol or {:out :err}.\n\n  Example:\n\n```clojure\nham-fisted.process> (launch \\\"ls -al\\\" {:print-cmd-line? false})\n  {:proc-hdl #object[java.lang.ProcessHandleImpl 0x7f8e8742 \\\"31019\\\"],\n  :wait-or-kill #function[ham-fisted.process/launch/wait-or-kill--65545]}\n  ...\n\nham-fisted.process> (def result ((:wait-or-kill *1)))\n#'ham-fisted.process/result\nham-fisted.process> (keys result)\n(:out :err)\n```\"\n  ([cmd-line] (launch cmd-line {}))\n  ([^String cmd-line {:keys [stdout-hdlr stderr-hdlr print-cmd-line?]\n                      :or {print-cmd-line? true}}]\n   (when print-cmd-line? (println \"launch-process:\" cmd-line))\n   (let [proc (.exec (Runtime/getRuntime) cmd-line)\n         phandle (.toHandle proc)\n         exit-future (.onExit phandle)\n         stdout-hdlr (or stdout-hdlr println-rf)\n         stderr-hdlr (or stderr-hdlr println-rf)\n         _ (.close (.getOutputStream proc))\n         stdout (.getInputStream proc)\n         stderr (.getErrorStream proc)\n         out (future (hamf-rf/reduce-reducer stdout-hdlr (stream->strings stdout)))\n         err (future (hamf-rf/reduce-reducer stderr-hdlr (stream->strings stderr)))\n         cleanup (fn [close?]\n                   (when close?\n                     ;;close the streams to force termination as the process hasn't exited\n                     (.close stdout)\n                     (.close stderr))\n                   {:out @out\n                    :err @err})]\n     {:proc-hdl phandle\n      :wait-or-kill\n      (fn wait-or-kill\n        ([]\n         (let [desc (process-descendants phandle)]\n           (run! destroy-forcibly! desc)\n           (destroy-forcibly! phandle)\n           (cleanup true)))\n        ([^long time-ms timeout-symbol]\n         (if-let [rv (try (.get exit-future time-ms java.util.concurrent.TimeUnit/MILLISECONDS)\n                          (catch java.util.concurrent.TimeoutException e nil))]\n           (cleanup false)\n           timeout-symbol)))})))\n\n(defn sh\n  ([cmd-line] (sh cmd-line {:print-cmd-line? false :stdout-hdlr quiet-rf :stderr-hdlr quiet-rf}))\n  ([^String cmd-line {:keys [timeout-ms]\n                      :or {timeout-ms Integer/MAX_VALUE} :as opts}]\n   (let [rv ((:wait-or-kill (launch cmd-line opts)) timeout-ms ::timeout)]\n     (if (identical? rv ::timeout)\n       (throw (RuntimeException. \"Process timed out\"))\n       rv))))\n\n(defn ^:private map->cmd-line\n  [args]\n  (->> (flatten (seq args))\n       (map str)))\n\n(defn launch-jvm\n  \"Assumes a jvm process launched from a shell command.  Will hang looking for first process descendant.\n\n  If shell command then arguments other than :xmx :jvm-opts may need to have quoted strings if they are\n  being passed the clojure process.\n\n  Example:\n\n```clojure\nham-fisted.process> (launch-jvm \\\"clojure\\\" {:jvm-opts [\\\"-A:dev\\\" \\\"-X\\\" \\\"ham-fisted.protocol-perf/-main\\\"]})\nlaunch-process: clojure -A:dev -X ham-fisted.protocol-perf/-main\n{:proc-hdl #object[java.lang.ProcessHandleImpl 0x4f4a8dc7 \\\"31194\\\"],\n :wait-or-kill #function[ham-fisted.process/launch/wait-or-kill--10016],\n :jvm-pid 31199,\n  :jvm-proc #object[java.lang.ProcessHandleImpl 0x2e52e7c8 \\\"31199\\\"]}\n...\nham-fisted.process> (def result ((:wait-or-kill *1)))\n#'ham-fisted.process/result\n```\"\n  [cmd-name {:keys [xmx jvm-opts]\n             :as args}]\n  (let [jvm-opts (if xmx\n                   (conj (or jvm-opts []) (str \"-Xmx\" xmx))\n                   jvm-opts)\n        cmd-line\n        (clojure.string/join \" \" (concat [cmd-name]\n                                         (map->cmd-line jvm-opts)\n                                         (map->cmd-line (dissoc args :xmx :jvm-opts\n                                                                :stdout-hdlr :stderr-hdlr))))\n        {:keys [^java.lang.ProcessHandle proc-hdl] :as rv} (launch cmd-line args)\n        desc (loop [desc (process-descendants proc-hdl)]\n               (if (== 0 (count desc) )\n                 (do (Thread/sleep 5)\n                     (if (.isAlive proc-hdl)\n                       (recur (process-descendants proc-hdl))\n                       desc))\n                 desc))\n        ^java.lang.ProcessHandle jvm-proc (first desc)]\n    (if jvm-proc\n      (assoc rv :jvm-pid (.pid jvm-proc) :jvm-proc jvm-proc)\n      rv)))\n"
  },
  {
    "path": "src/ham_fisted/profile.clj",
    "content": "(ns ham-fisted.profile\n  (:import [java.util Map]\n           [java.util.concurrent ConcurrentHashMap]))\n\n(set! *warn-on-reflection* true)\n\n(def ^{:dynamic true :no-doc true :tag Map} time-map (ConcurrentHashMap.))\n\n(defmacro time-ms\n  \"Time an operation returning the results.  Puts time in double milliseconds\n  into the time map.\"\n  [kw & code]\n  `(let [start# (System/nanoTime)\n         rv# (do ~@code)\n         end# (System/nanoTime)]\n     (.put time-map ~kw (* (- end# start#) 1e-6))\n     rv#))\n\n(defn current-times \"Get the current time map\" [] (into {} time-map))\n(defn reset-times! \"Clear times out of current time map\" [] (.clear time-map))\n\n(defmacro with-times\n  \"Returns {:result :times}. Run a block of code with time map bound to a new map.\"\n  [& code]\n  `(with-bindings {#'time-map (ConcurrentHashMap.)}\n     (let [rv# (do ~@code)\n           times# (current-times)]\n       {:result rv#\n        :times times#})))\n"
  },
  {
    "path": "src/ham_fisted/protocols.clj",
    "content": "(ns ham-fisted.protocols\n  (:require [ham-fisted.defprotocol :refer [defprotocol extend-protocol extend-type extend]:as hamf-defproto])\n  (:import [clojure.lang IFn IReduceInit IDeref]\n           [java.util.function DoubleConsumer]\n           [java.util Map]\n           [ham_fisted Sum Sum$SimpleSum Reducible IFnDef$ODO ParallelOptions\n            Reductions IMutList])\n  (:refer-clojure :exclude [reduce set? count defprotocol extend-protocol extend-type extend]))\n\n(defprotocol Counted\n  (^long count [m]))\n\n(defprotocol ToIterable\n  (convertible-to-iterable? [item])\n  (->iterable [item]))\n\n\n(defprotocol ToCollection\n  (convertible-to-collection? [item])\n  (->collection [item]))\n\n\n(defprotocol Reduction\n  \"Faster check than satisfies? to see if something is reducible\"\n  (reducible? [coll]))\n\n\n(extend-protocol Reduction\n  nil\n  (reducible? [this] true)\n  Object\n  (reducible? [this]\n    (or (instance? IReduceInit this)\n        (instance? Iterable this)\n        (instance? Map this)\n        ;;This check is dog slow\n        (clojure.core/satisfies? clojure.core.protocols/CollReduce this))))\n\n\n(defprotocol ParallelReduction\n  \"Protocol to define a parallel reduction in a collection-specific pathway.  Specializations\n  are in impl as that is where the parallelization routines are found.\"\n  (preduce [coll init-val-fn rfn merge-fn ^ParallelOptions options]\n    \"Container-specific parallelized reduction.  Reductions must respect the pool passed in via\nthe options.\"))\n\n\n(defprotocol Finalize\n  \"Generic protocol for things that finalize results of reductions.  Defaults to deref of\n  instance of IDeref or identity.\"\n  (finalize [this val]))\n\n\n(extend-protocol Finalize\n  Object\n  (finalize [this val]\n    (if (instance? IDeref val)\n      (.deref ^IDeref val)\n      val))\n  ;;clojure rfn equivalence\n  IFn\n  (finalize [this val]\n    (this val)))\n\n\n(defprotocol Reducer\n  \"Reducer is the basic reduction abstraction as a single object.\"\n  (->init-val-fn [item]\n    \"Returns the initial values for a parallel reduction.  This function\ntakes no arguments and returns the initial accumulator.\")\n  (->rfn [item]\n    \"Returns the reduction function for a parallel reduction. This function takes\ntwo arguments, the accumulator and a value from the collection and returns a new\nor modified accumulator.\"))\n\n\n(extend-protocol Reducer\n  IFn\n  (->init-val-fn [this] this)\n  (->rfn [this] this))\n\n\n(defprotocol ParallelReducer\n  \"Parallel reducers are simple a single object that you can pass into preduce as\n  opposed to 3 separate functions.\"\n  (->merge-fn [item]\n    \"Returns the merge function for a parallel reduction.  This function takes\ntwo accumulators  and returns a or modified accumulator.\"))\n\n\n(extend-protocol ParallelReducer\n  IFn\n  (->merge-fn [this] this))\n\n\n(extend-protocol ParallelReducer\n  Object\n  (->merge-fn [this]\n    (fn [_l _r] (throw (RuntimeException. (str \"Object does not implement merge: \"\n                                               (type this)))))))\n\n\n(def ^:no-doc double-consumer-accumulator\n  (reify IFnDef$ODO\n    (invokePrim [f acc v]\n      (.accept ^DoubleConsumer acc v)\n      acc)))\n\n(defn- reducible-merge\n  [^Reducible lhs rhs]\n  (.reduce lhs rhs))\n\n(defprotocol PAdd\n  \"Define a function to mutably add items to a collection.  This function must return\n  the collection -- it must be useable in a reduce as the rf.\"\n  (add-fn [l]))\n\n(defprotocol SetOps\n  \"Simple protocol for set operations to make them uniformly extensible to new objects.\"\n  (set? [l])\n  (union [l r])\n  (difference [l r])\n  (intersection [l r])\n  (xor [l r])\n  (contains-fn [item]\n    \"Return an efficient function for deciding if this set contains a single item.\")\n  (^long cardinality [item]\n   \"Some sets don't work with clojure's count function.\"))\n\n\n(defprotocol BulkSetOps\n  (reduce-union [l data])\n  (reduce-intersection [l data]))\n\n\n(defprotocol BitSet\n  \"Protocol for efficiently dealing with bitsets\"\n  (bitset? [item])\n  (contains-range? [item sidx eidx])\n  (intersects-range? [item sidx eidx])\n  (min-set-value [item])\n  (max-set-value [item]))\n\n\n(defprotocol WrapArray\n  (^IMutList wrap-array [ary])\n  (^IMutList wrap-array-growable [ary ptr]))\n\n\n(defprotocol SerializeObjBytes\n  (serialize->bytes [o]))\n\n\n(defprotocol Datatype\n  (datatype [o]\n    \"Returns the datatype [:int8, :int16, etc] -- if known --\nelse the type can be assumed to be an object type.  The return value may not be a keyword\nbut it must be comparable with identical?\")\n  (simplified-datatype [o]\n    \"Returns exactly :int64, :float64, or :object\"))\n\n(hamf-defproto/extend nil Datatype {:datatype :object\n                                    :simplified-datatype :object})\n\n(hamf-defproto/extend Object Datatype {:datatype :object\n                                       :simplified-datatype :object})\n\n(defprotocol ContainedDatatype\n  (contained-datatype [o]\n    \"Datatype of contained datatype - may be nil if not a container\")\n  (simplified-contained-datatype [o]\n    \"Exactly :int64 :float64 :object or nil\"))\n\n(extend nil ContainedDatatype\n        {:contained-datatype nil\n         :simplified-contained-datatype nil})\n\n(extend Object ContainedDatatype\n        {:contained-datatype nil\n         :simplified-contained-datatype nil})\n\n\n(defprotocol ReturnedDatatype\n  (returned-datatype [o])\n  (simplified-returned-datatype [o]))\n\n(extend nil ReturnedDatatype\n        {:returned-datatype nil\n         :simplified-returned-datatype nil})\n\n(extend Object ReturnedDatatype\n        {:returned-datatype nil\n         :simplified-returned-datatype nil})\n\n(defprotocol EstimateCount\n  (^long estimate-count [m]))\n\n(defprotocol Split\n  (split [m]))\n\n(defprotocol ManagedBlocker\n  (^java.util.concurrent.ForkJoinPool$ManagedBlocker managed-blocker [m]))\n\n(defprotocol ToSpliterator\n  (^java.util.Spliterator ->spliterator [m]))\n"
  },
  {
    "path": "src/ham_fisted/reduce.clj",
    "content": "(ns ham-fisted.reduce\n  \"Protocol-based parallel reduction architecture and helper functions.\"\n  (:require [ham-fisted.protocols :as protocols]\n            [ham-fisted.defprotocol :refer [extend extend-type extend-protocol]]\n            [ham-fisted.lazy-noncaching :refer [map] :as lznc]\n            [ham-fisted.function :refer [bi-function]])\n  (:import [ham_fisted ParallelOptions ParallelOptions$CatParallelism Reductions\n            Transformables Reducible IFnDef$OOO IFnDef$OLOO\n            IFnDef$ODO IFnDef$OLO IFnDef$DDD IFnDef$LLL Sum Sum$SimpleSum Reductions$IndexedAccum\n            Reductions$IndexedLongAccum Reductions$IndexedDoubleAccum IFnDef$OLLO IFnDef$OLDO]\n           [clojure.lang IFn$DO IFn$LO IFn$OLO IFn$DDD IFn$LLL]\n           [java.util Map]\n           [java.util.function DoubleConsumer LongConsumer Consumer]\n           [java.util.concurrent Executor ForkJoinPool])\n  (:refer-clojure :exclude [map extend extend-type extend-protocol]))\n\n(set! *warn-on-reflection* true)\n\n\n(defn- unpack-reduced\n  [item]\n  (if (reduced? item)\n    (deref item)\n    item))\n\n\n(defn options->parallel-options\n  \"Convert an options map to a parallel options object.\n\n  Options:\n\n  * `:pool` - supply the forkjoinpool to use.\n  * `:max-batch-size` - Defaults to 64000, used for index-based  parallel pathways to control\n     the number size of each parallelized batch.\n  * `:ordered?` - When true process inputs and provide results in order.\n  * `:parallelism` - The amount of parallelism to expect.  Defaults to the number of threads\n     in the fork-join pool provided.\n  * `:cat-parallelism` - Either `:seq-wise` or `:elem-wise` - when parallelizing over a\n     concatenation of containers either parallelize each container meaning call preduce on each\n     container using many threads per container or use one thread per container - `seq-wise`.  Defaults\n     to `seq-wise` as this doesn't require each container itself to support parallelization but relies on\n     the sequence of containers to be long enough to saturate the processor.  Can also be set at time of\n     container construction - see [[lazy-noncaching/concat-opts]].\n  * `:put-timeout-ms` - The time to wait to put data into the queue.  This is a safety mechanism\n    so that if the processing system fails we don't just keep putting things into a queue.\n  * `:unmerged-result?` - Use with care.  For parallel reductions do not perform the merge step\n    but instead return the sequence of partially reduced results.\n  * `:n-lookahead` - How for to look ahead for pmap and upmap to add new jobs to the queue.  Defaults\n    to `(* 2 parallelism).\"\n  ^ParallelOptions [options]\n  (cond\n    (instance? ParallelOptions options)\n    options\n    (nil? options)\n    (ParallelOptions.)\n    :else\n    (let [^Map options (or options {})\n          ^Executor pool (.getOrDefault options :pool (ForkJoinPool/commonPool))]\n      (ParallelOptions. (.getOrDefault options :min-n 1000)\n                        (.getOrDefault options :max-batch-size 64000)\n                        (boolean (.getOrDefault options :ordered? true))\n                        pool\n                        (.getOrDefault options :parallelism\n                                       (if (instance? ForkJoinPool pool)\n                                         (.getParallelism ^ForkJoinPool pool)\n                                         1))\n                        (case (.getOrDefault options :cat-parallelism :seq-wise)\n                          :seq-wise ParallelOptions$CatParallelism/SEQWISE\n                          :elem-wise ParallelOptions$CatParallelism/ELEMWISE)\n                        (.getOrDefault options :put-timeout-ms 5000)\n                        (.getOrDefault options :unmerged-result? false)\n                        (.getOrDefault options :n-lookahead -1)))))\n\n\n(defn preduce\n  \"Parallelized reduction.  Currently coll must either be random access or a lznc map/filter\n  chain based on one or more random access entities, hashmaps and sets from this library or\n  any java.util set, hashmap or concurrent versions of these.  If input cannot be\n  parallelized this lowers to a normal serial reduction.\n\n  For potentially small-n invocations providing the parallel options explicitly will improve\n  performance surprisingly - converting the options map to the parallel options object\n  takes a bit of time.\n\n  * `init-val-fn` - Potentially called in reduction threads to produce each initial value.\n  * `rfn` - normal clojure reduction function.  Typehinting the second argument to double\n     or long will sometimes produce a faster reduction.\n  * `merge-fn` - Merge two reduction results into one.\n\n  Options:\n  * `:pool` - The fork-join pool to use.  Defaults to common pool which assumes reduction is\n     cpu-bound.\n  * `:parallelism` - What parallelism to use - defaults to pool's `getParallelism` method.\n  * `:max-batch-size` - Rough maximum batch size for indexed or grouped reductions.  This\n     can both even out batch times and ensure you don't get into safepoint trouble with\n     jdk-8.\n  * `:min-n` - minimum number of elements before initiating a parallelized reduction -\n     Defaults to 1000 but you should customize this particular to your specific reduction.\n  * `:ordered?` - True if results should be in order.  Unordered results sometimes are\n    slightly faster but again you should test for your specific situation..\n  * `:cat-parallelism` - Either `:seq-wise` or `:elem-wise`, defaults to `:seq-wise`.\n     Test for your specific situation, this really is data-dependent. This contols how a\n     concat primitive parallelizes the reduction across its contains.  Elemwise means each\n     container's reduction is individually parallelized while seqwise indicates to do a\n     pmap style initial reduction across containers then merge the results.\n  * `:put-timeout-ms` - Number of milliseconds to wait for queue space before throwing\n     an exception in unordered reductions.  Defaults to 50000.\n  * `:unmerged-result?` - Defaults to false.  When true, the sequence of results\n     be returned directly without any merge steps in a lazy-noncaching container.  Beware\n     the noncaching aspect -- repeatedly evaluating this result may kick off the parallelized\n     reduction multiple times.  To ensure caching if unsure call `seq` on the result.\"\n  ([init-val-fn rfn merge-fn coll] (preduce init-val-fn rfn merge-fn nil coll))\n  ([init-val-fn rfn merge-fn options coll]\n   (unpack-reduced\n    (Reductions/parallelReduction init-val-fn rfn merge-fn (lznc/->reducible coll)\n                                  (options->parallel-options options)))))\n\n\n(defn preduce-reducer\n  \"Given an instance of [[ham-fisted.protocols/ParallelReducer]], perform a parallel\n  reduction.\n\n  In the case where the result is requested unmerged then finalize will\n  be called on each result in a lazy noncaching way.  In this case you can use a\n  non-parallelized reducer and simply get a sequence of results as opposed to one.\n\n  * reducer - instance of ParallelReducer\n  * options - Same options as preduce.\n  * coll - something potentially with a parallelizable reduction.\n\n  See options for [[ham-fisted.reduce/preduce]].\n\n  Additional Options:\n\n  * `:skip-finalize?` - when true, the reducer's finalize method is not called on the result.\"\n  ([reducer options coll]\n   (let [retval (preduce (protocols/->init-val-fn reducer)\n                         (protocols/->rfn reducer)\n                         (protocols/->merge-fn reducer)\n                         options\n                         coll)]\n     (if (get options :skip-finalize?)\n       retval\n       (if (get options :unmerged-result?)\n         (lznc/map #(protocols/finalize reducer %) retval)\n         (protocols/finalize reducer retval)))))\n  ([reducer coll]\n   (preduce-reducer reducer nil coll)))\n\n\n(defmacro double-accumulator\n  \"Type-hinted double reduction accumulator.\n  consumer:\n\n```clojure\n  ham-fisted.api> (reduce (double-accumulator acc v (+ (double acc) v))\n                             0.0\n                             (range 1000))\n#<SimpleSum@2fbcf20: 499500.0>\nham-fisted.api> @*1\n499500.0\n```\"\n  [accvar varvar & code]\n  `(reify IFnDef$ODO\n     (invokePrim [this# ~accvar ~varvar]\n       ~@code)))\n\n\n(defmacro long-accumulator\n  \"Type-hinted double reduction accumulator.\n  consumer:\n\n```clojure\n  ham-fisted.api> (reduce (double-accumulator acc v (+ (double acc) v))\n                             0.0\n                             (range 1000))\n#<SimpleSum@2fbcf20: 499500.0>\nham-fisted.api> @*1\n499500.0\n```\"\n  [accvar varvar & code]\n  `(reify IFnDef$OLO\n     (invokePrim [this# ~accvar ~varvar]\n       ~@code)))\n\n(defn immut-map-kv\n  ([keyfn valfn data]\n   (-> (reduce (fn [^Map m v]\n                 (.put m (keyfn v) (valfn v))\n                 m)\n               (ham_fisted.UnsharedHashMap. nil)\n               data)\n       (persistent!)))\n  ([ks vs]\n   (let [rv (ham_fisted.UnsharedHashMap. nil)\n         ki (.iterator (Transformables/toIterable ks))\n         vi (.iterator (Transformables/toIterable vs))]\n     (while (and (.hasNext ki) (.hasNext vi))\n       (.put rv (.next ki) (.next vi)))\n     (persistent! rv))))\n\n\n(defn compose-reducers\n  \"Given a map or sequence of reducers return a new reducer that produces a map or\n  vector of results.\n\n  If data is a sequence then context is guaranteed to be an object array.\n\n  Options:\n\n  * `:rfn-datatype` - One of nil, :int64, or :float64.  This indicates that the rfn's\n  should all be uniform as accepting longs, doubles, or generically objects.  Defaults\n  to nil.\"\n  ([reducers] (compose-reducers nil reducers))\n  ([options reducers]\n   (if (instance? Map reducers)\n     (let [reducer (compose-reducers (vals reducers))]\n       (reify\n         protocols/Reducer\n         (->init-val-fn [_] (protocols/->init-val-fn reducer))\n         (->rfn [_] (protocols/->rfn reducer))\n         protocols/Finalize\n         (finalize [_ v] (immut-map-kv (keys reducers) (protocols/finalize reducer v)))\n         protocols/ParallelReducer\n         (->merge-fn [_] (protocols/->merge-fn reducer))))\n     (let [init-fns (.toArray ^java.util.Collection (lznc/map protocols/->init-val-fn reducers))\n           rfn-dt (get options :rfn-datatype)\n           ^objects rfns (object-array\n                          (case rfn-dt\n                            :int64\n                            (->> (map protocols/->rfn reducers)\n                                 (map #(Transformables/toLongReductionFn %)))\n                            :float64\n                            (->> (map protocols/->rfn reducers)\n                                 (map #(Transformables/toDoubleReductionFn %)))\n                            ;;else branch\n                            (map protocols/->rfn reducers)))\n           ^objects mergefns (object-array (map protocols/->merge-fn reducers))\n           n-vals (count rfns)\n           n-init (count init-fns)]\n       (reify\n         protocols/Reducer\n         (->init-val-fn [_] (fn compose-init []\n                              (let [rv (ham_fisted.ArrayLists/objectArray n-init)]\n                                (dotimes [idx n-init]\n                                  (aset rv idx ((aget init-fns idx))))\n                                rv)))\n         (->rfn [_]\n           (case rfn-dt\n             :int64 (Reductions/longCompose n-vals rfns)\n             :float64 (Reductions/doubleCompose n-vals rfns)\n             (Reductions/objCompose n-vals rfns)))\n         protocols/Finalize\n         (finalize [_ v] (mapv #(protocols/finalize %1 %2) reducers v))\n         protocols/ParallelReducer\n         (->merge-fn [_] (Reductions/mergeCompose n-vals, mergefns)))))))\n\n\n(defn preduce-reducers\n  \"Given a map or sequence of [[ham-fisted.protocols/ParallelReducer]], produce a map or\n  sequence of reduced values. Reduces over input coll once in parallel if coll is large\n  enough.  See options for [[ham-fisted.reduce/preduce]].\n\n```clojure\nham-fisted.api> (preduce-reducers {:sum (Sum.) :mult *} (range 20))\n{:mult 0, :sum #<Sum@5082c3b7: {:sum 190.0, :n-elems 20}>}\n```\"\n  ([reducers options coll]\n   (preduce-reducer (compose-reducers reducers) options coll))\n  ([reducers coll] (preduce-reducers reducers nil coll)))\n\n\n(defn reducer-xform->reducer\n  \"Given a reducer and a transducer xform produce a new reducer which will apply\n  the transducer pipeline before is reduction function.\n\n```clojure\nham-fisted.api> (reduce-reducer (reducer-xform->reducer (Sum.) (clojure.core/filter even?))\n                                (range 1000))\n#<Sum@479456: {:sum 249500.0, :n-elems 500}>\n```\n  !! - If you use a stateful transducer here then you must *not* use the reducer in a\n  parallelized reduction.\"\n  [reducer xform]\n  (let [rfn (protocols/->rfn reducer)\n        init-val-fn (protocols/->init-val-fn reducer)\n        xfn (xform (fn\n                     ([] (init-val-fn))\n                     ([v] (protocols/finalize reducer v))\n                     ([acc v] (rfn acc v))))]\n    (reify\n      protocols/Reducer\n      (->init-val-fn [this] init-val-fn)\n      (->rfn [this] xfn)\n      protocols/Finalize\n      (finalize [this v] (xfn v))\n      protocols/ParallelReducer\n      (->merge-fn [this] (protocols/->merge-fn reducer)))))\n\n\n(defn reducer->rf\n  \"Given a reducer, return a transduce-compatible rf -\n\n```clojure\nham-fisted.api> (transduce (clojure.core/map #(+ % 2)) (reducer->rf (Sum.)) (range 200))\n{:sum 20300.0, :n-elems 200}\n```\"\n  [reducer]\n  (let [rfn (protocols/->rfn reducer)\n        init-val-fn (protocols/->init-val-fn reducer)]\n    (fn\n      ([] (init-val-fn))\n      ([acc v] (rfn acc v))\n      ([v] (protocols/finalize reducer v)))))\n\n\n(defn reducer->completef\n  \"Return fold-compatible pair of [reducef, completef] given a parallel reducer.\n  Note that folded reducers are not finalized as of this time:\n\n```clojure\nham-fisted.api> (def data (vec (range 200000)))\n#'ham-fisted.api/data\nham-fisted.api> (r/fold (reducer->completef (Sum.)) (reducer->rfn (Sum.)) data)\n#<Sum@858c206: {:sum 1.99999E10, :n-elems 200000}>\n```\"\n  [reducer]\n  (let [rfn (protocols/->rfn reducer)\n        init-val-fn (protocols/->init-val-fn reducer)\n        merge-fn (protocols/->merge-fn reducer)]\n    (fn\n      ([] (init-val-fn))\n      ([l r] (merge-fn l r))\n      ([v] (protocols/finalize reducer v)))))\n\n\n(defn reducer-with-finalize\n  [reducer fin-fn]\n  (reify\n    protocols/Reducer\n    (->init-val-fn [r] (protocols/->init-val-fn reducer))\n    (->rfn [r] (protocols/->rfn reducer))\n    protocols/Finalize\n    (finalize [r v] (fin-fn v))\n    protocols/ParallelReducer\n    (->merge-fn [r] (protocols/->merge-fn reducer))))\n\n\n(defn reduce-reducer\n  \"Serially reduce a reducer.\n\n```clojure\nham-fisted.api> (reduce-reducer (Sum.) (range 1000))\n#<Sum@afbedb: {:sum 499500.0, :n-elems 1000}>\n```\"\n  [reducer coll]\n  (let [rfn (protocols/->rfn reducer)\n        init-val-fn (protocols/->init-val-fn reducer)]\n    (->> (reduce rfn (init-val-fn) coll)\n         (protocols/finalize reducer))))\n\n\n(defn reduce-reducers\n  \"Serially reduce a map or sequence of reducers into a map or sequence of results.\n\n```clojure\nham-fisted.api> (reduce-reducers {:a (Sum.) :b *} (range 1 21))\n{:b 2432902008176640000, :a #<Sum@6bcebeb1: {:sum 210.0, :n-elems 20}>}\n```\"\n  [reducers coll]\n  (reduce-reducer (compose-reducers reducers) coll))\n\n\n(defn ^:no-doc reduce-reducibles\n  [reducibles]\n  (let [^Reducible r (first reducibles)]\n    (when-not (instance? Reducible r)\n      (throw (Exception. (str \"Sequence does not contain reducibles: \" (type (first r))))))\n    (.reduce r (rest reducibles))))\n\n\n(def double-consumer-accumulator\n  \"Converts from a double consumer to a double reduction accumulator that returns the\n  consumer:\n\n```clojure\nham-fisted.api> (reduce double-consumer-accumulator\n                             (Sum$SimpleSum.)\n                             (range 1000))\n#<SimpleSum@2fbcf20: 499500.0>\nham-fisted.api> @*1\n499500.0\n```\" ham_fisted.ConsumerAccumulators$DoubleConsumerAccumulator/INST)\n\n\n(def long-consumer-accumulator\n  \"Converts from a long consumer to a long reduction accumulator that returns the\n  consumer:\n\n```clojure\nham-fisted.api> (reduce double-consumer-accumulator\n                             (Sum$SimpleSum.)\n                             (range 1000))\n#<SimpleSum@2fbcf20: 499500.0>\nham-fisted.api> @*1\n499500.0\n```\"\n  ham_fisted.ConsumerAccumulators$LongConsumerAccumulator/INST)\n\n\n(def consumer-accumulator\n  \"Generic reduction function using a consumer\"\n  ham_fisted.ConsumerAccumulators$ConsumerAccumulator/INST)\n\n\n(def ^{:doc \"Parallel reduction merge function that expects both sides to be an instances of\n  Reducible\"} reducible-merge\n  (bi-function lhs rhs (.reduce ^Reducible lhs rhs)))\n\n(defmacro indexed-accum\n  \"Create an indexed accumulator that recieves and additional long index\n  during a reduction:\n\n```clojure\nham-fisted.api> (reduce (indexed-accum\n                         acc idx v (conj acc [idx v]))\n                        []\n                        (range 5))\n[[0 0] [1 1] [2 2] [3 3] [4 4]]\n```\"\n  [accvar idxvar varvar & code]\n  `(Reductions$IndexedAccum.\n    (reify IFnDef$OLOO\n      (invokePrim [this# ~accvar ~idxvar ~varvar]\n        ~@code))))\n\n\n(defmacro indexed-double-accum\n  \"Create an indexed double accumulator that recieves and additional long index\n  during a reduction:\n\n```clojure\nham-fisted.api> (reduce (indexed-double-accum\n                         acc idx v (conj acc [idx v]))\n                        []\n                        (range 5))\n[[0 0.0] [1 1.0] [2 2.0] [3 3.0] [4 4.0]]\n```\"\n  [accvar idxvar varvar & code]\n  `(Reductions$IndexedDoubleAccum.\n    (reify IFnDef$OLDO\n      (invokePrim [this# ~accvar ~idxvar ~varvar]\n        ~@code))))\n\n\n(defmacro indexed-long-accum\n  \"Create an indexed long accumulator that recieves and additional long index\n  during a reduction:\n\n```clojure\nham-fisted.api> (reduce (indexed-long-accum\n                         acc idx v (conj acc [idx v]))\n                        []\n                        (range 5))\n[[0 0] [1 1] [2 2] [3 3] [4 4]]\n```\"\n  [accvar idxvar varvar & code]\n  `(Reductions$IndexedLongAccum.\n    (reify IFnDef$OLLO\n      (invokePrim [this# ~accvar ~idxvar ~varvar]\n        ~@code))))\n\n\n(defn ->consumer\n  \"Return an instance of a consumer, double consumer, or long consumer.\"\n  [cfn]\n  (cond\n    (or (instance? Consumer cfn)\n        (instance? DoubleConsumer cfn)\n        (instance? LongConsumer cfn))\n    cfn\n    (instance? IFn$DO cfn)\n    (reify DoubleConsumer (accept [this v] (.invokePrim ^IFn$DO cfn v)))\n    (instance? IFn$LO cfn)\n    (reify LongConsumer (accept [this v] (.invokePrim ^IFn$LO cfn v)))\n    :else\n    (reify Consumer (accept [this v] (cfn v)))))\n\n\n(defn consume!\n  \"Consumer a collection.  This is simply a reduction where the return value\n  is ignored.\n\n  Returns the consumer.\"\n  [consumer coll]\n  (let [c (->consumer consumer)]\n    (cond\n      (instance? DoubleConsumer c)\n      (reduce double-consumer-accumulator c coll)\n      (instance? LongConsumer c)\n      (reduce long-consumer-accumulator c coll)\n      :else\n      (reduce consumer-accumulator c coll))\n    consumer))\n\n\n(defn double-consumer-preducer\n  \"Return a preducer for a double consumer.\n\n  Consumer must implement java.util.function.DoubleConsumer,\n  ham_fisted.Reducible and clojure.lang.IDeref.\n\n```clojure\nuser> (require '[ham-fisted.api :as hamf])\nnil\nuser> (import '[java.util.function DoubleConsumer])\njava.util.function.DoubleConsumer\nuser> (import [ham_fisted Reducible])\nham_fisted.Reducible\nuser> (import '[clojure.lang IDeref])\nclojure.lang.IDeref\nuser> (deftype MeanR [^{:unsynchronized-mutable true :tag 'double} sum\n                      ^{:unsynchronized-mutable true :tag 'long} n-elems]\n        DoubleConsumer\n        (accept [this v] (set! sum (+ sum v)) (set! n-elems (unchecked-inc n-elems)))\n        Reducible\n        (reduce [this o]\n          (set! sum (+ sum (.-sum ^MeanR o)))\n          (set! n-elems (+ n-elems (.-n-elems ^MeanR o)))\n          this)\n        IDeref (deref [this] (/ sum n-elems)))\nuser.MeanR\nuser> (hamf/declare-double-consumer-preducer! MeanR (MeanR. 0 0))\nnil\n  user> (hamf/preduce-reducer (double-consumer-preducer #(MeanR. 0 0)) (hamf/range 200000))\n99999.5\n```\"\n  [constructor]\n  (reify\n    protocols/Reducer\n    (->init-val-fn [r] constructor)\n    (->rfn [r] double-consumer-accumulator)\n    protocols/Finalize\n    (finalize [r v] @v)\n    protocols/ParallelReducer\n    (->merge-fn [r] reducible-merge)))\n\n\n(deftype DDDReducer [^{:unsynchronized-mutable true\n                       :tag double} acc\n                     ^{:tag IFn$DDD} rfn\n                     merge-fn\n                     ^{:unsynchronized-mutable true\n                       :tag clojure.lang.Box} merged]\n\n  DoubleConsumer\n  (accept [this v] (set! acc (.invokePrim rfn acc v)))\n  Reducible\n  (reduce [this other]\n    (if merged\n      (set! (.-val merged) (merge-fn (.-val merged) @other))\n      (set! merged (clojure.lang.Box. (merge-fn acc @other))))\n    this)\n  clojure.lang.IDeref\n  (deref [this] (if merged (.-val merged) acc)))\n\n\n(deftype LLLReducer [^{:unsynchronized-mutable true\n                       :tag long} acc\n                     ^{:tag IFn$LLL} rfn\n                     merge-fn\n                     ^{:unsynchronized-mutable true\n                       :tag clojure.lang.Box} merged]\n\n  LongConsumer\n  (accept [this v] (set! acc (.invokePrim rfn acc v)))\n  Reducible\n  (reduce [this other]\n    (if merged\n      (set! (.-val merged) (merge-fn (.-val merged) @other))\n      (set! merged (clojure.lang.Box. (merge-fn acc @other))))\n    this)\n  clojure.lang.IDeref\n  (deref [this] (if merged (.-val merged) acc)))\n\n\n(defn parallel-reducer\n  \"Implement a parallel reducer by explicitly passing in the various required functions.\n\n  * 'init-fn' - Takes no argumenst and returns a new accumulation target.\n  * 'rfn' - clojure rf function - takes two arguments, the accumulation target and a new value\n     and produces a new accumulation target.\n  * 'merge-fn' - Given two accumulation targets returns a new combined accumulation target.\n  * 'fin-fn' - optional - Given an accumulation target returns the desired final type.\n\n```clojure\nuser> (hamf-rf/preduce-reducer\n       (hamf-rf/parallel-reducer\n        hamf/mut-set\n        #(do (.add ^java.util.Set %1 %2) %1)\n        hamf/union\n        hamf/sort)\n       (lznc/map (fn ^long [^long v] (rem v 13)) (hamf/range 1000000)))\n[0 1 2 3 4 5 6 7 8 9 10 11 12]\n```\n\"\n  ([init-fn rfn merge-fn fin-fn]\n   (cond\n     (instance? IFn$DDD rfn)\n     (reify protocols/Reducer\n       (->init-val-fn [this] #(DDDReducer. (double (init-fn)) rfn merge-fn nil))\n       (->rfn [r] double-consumer-accumulator)\n       protocols/ParallelReducer\n       (->merge-fn [r] reducible-merge)\n       protocols/Finalize\n       (finalize [r v] (fin-fn @v)))\n     (instance? IFn$LLL rfn)\n     (reify protocols/Reducer\n       (->init-val-fn [this] #(LLLReducer. (long (init-fn)) rfn merge-fn nil))\n       (->rfn [r] long-consumer-accumulator)\n       protocols/ParallelReducer\n       (->merge-fn [r] reducible-merge)\n       protocols/Finalize\n       (finalize [r v] (fin-fn @v)))\n     :else\n     (reify\n       protocols/Reducer\n       (->init-val-fn [this] init-fn)\n       (->rfn [r] rfn)\n       protocols/ParallelReducer\n       (->merge-fn [r] merge-fn)\n       protocols/Finalize\n       (finalize [r v] (fin-fn v)))))\n  ([init-fn rfn merge-fn]\n   (parallel-reducer init-fn rfn merge-fn identity)))\n\n\n(defn consumer-preducer\n  \"Bind a consumer as a parallel reducer.\n\n  Consumer must implement java.util.function.Consumer,\n  ham_fisted.Reducible and clojure.lang.IDeref.\n\n  Returns instance of type bound.\n\n  See documentation for [[declare-double-consumer-preducer!]].\n```\"\n  [constructor]\n  (reify\n    protocols/Reducer\n    (->init-val-fn [r] constructor)\n    (->rfn [r] consumer-accumulator)\n    protocols/Finalize\n    (finalize [r v] @v)\n    protocols/ParallelReducer\n    (->merge-fn [r] reducible-merge)))\n\n\n\n(defn bind-double-consumer-reducer!\n  \"Bind a classtype as a double consumer parallel reducer - the consumer must implement\n  DoubleConsumer, ham_fisted.Reducible, and IDeref.\"\n  ([cls-type ctor]\n   (extend cls-type\n     protocols/Reducer\n     {:->init-val-fn (fn [r] ctor)\n      :->rfn (fn [r] double-consumer-accumulator)}\n     protocols/ParallelReducer\n     {:->merge-fn (fn [r] reducible-merge)}))\n  ([ctor]\n   (bind-double-consumer-reducer! (type (ctor)) ctor)))\n\n\n(bind-double-consumer-reducer! #(Sum.))\n(bind-double-consumer-reducer! #(Sum$SimpleSum.))\n\n\n(defn double-consumer-reducer\n  \"Make a parallel double consumer reducer given a function that takes no arguments and is\n  guaranteed to produce a double consumer which also implements Reducible and IDeref\"\n  [ctor]\n  (reify\n    protocols/Reducer\n    (->init-val-fn [this] ctor)\n    (->rfn [this] double-consumer-accumulator)\n    protocols/Finalize\n    (finalize [this v] (deref v))\n    protocols/ParallelReducer\n    (->merge-fn [this] reducible-merge)))\n\n\n(defn long-consumer-reducer\n  \"Make a parallel double consumer reducer given a function that takes no arguments and is\n  guaranteed to produce a double consumer which also implements Reducible and IDeref\"\n  [ctor]\n  (reify\n    protocols/Reducer\n    (->init-val-fn [this] ctor)\n    (->rfn [this] long-consumer-accumulator)\n    protocols/Finalize\n    (finalize [this v] (deref v))\n    protocols/ParallelReducer\n    (->merge-fn [this] reducible-merge)))\n\n\n(defn consumer-reducer\n  \"Make a parallel double consumer reducer given a function that takes no arguments and is\n  guaranteed to produce a double consumer which also implements Reducible and IDeref\"\n  [ctor]\n  (reify\n    protocols/Reducer\n    (->init-val-fn [this] ctor)\n    (->rfn [this] consumer-accumulator)\n    protocols/Finalize\n    (finalize [this v] (deref v))\n    protocols/ParallelReducer\n    (->merge-fn [this] reducible-merge)))\n"
  },
  {
    "path": "src/ham_fisted/set.clj",
    "content": "(ns ham-fisted.set\n  (:require [ham-fisted.protocols :as hamf-proto]\n            [ham-fisted.api :as api]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.impl]\n            [ham-fisted.language :as hamf-language]\n            [ham-fisted.defprotocol :refer [extend extend-type extend-protocol]])\n  (:import [ham_fisted UnsharedHashSet PersistentHashSet Ranges$LongRange IMutList]\n           [java.util BitSet Set Map Collection]\n           [java.util.concurrent ConcurrentHashMap]\n           [clojure.lang APersistentSet])\n  (:refer-clojure :exclude [set set? extend extend-type extend-protocol]))\n\n\n(set! *warn-on-reflection* true)\n\n\n(declare unique bitset)\n\n\n(defn- set-add-all\n  [^Set s data]\n  (reduce (fn [^Set acc v]\n            (.add acc v)\n            acc)\n          s\n          data))\n\n(defn mut-set\n  \"Return a mutable set.\"\n  (^Set [] (UnsharedHashSet. nil))\n  (^Set [data]\n   (doto (UnsharedHashSet. nil)\n     (.addAll data))))\n\n\n(defn set\n  \"Return an immutable set\"\n  (^Set [] PersistentHashSet/EMPTY)\n  (^Set [data]\n   (if (instance? clojure.lang.IPersistentSet data)\n     data\n     (-> (mut-set data)\n         (persistent!)))))\n\n\n(defn set?\n  [data]\n  (when data (hamf-proto/set? data)))\n\n\n(defn java-hashset\n  \"Return a java hashset\"\n  (^Set [] (java.util.HashSet.))\n  (^Set [data] (if (instance? java.util.HashSet data)\n                 data\n                 (set-add-all (java.util.HashSet.) data))))\n\n\n(defn java-concurrent-hashset\n  \"Create a concurrent hashset.\"\n  (^Set [] (ConcurrentHashMap/newKeySet))\n  (^Set [data]\n   (if (instance? Set data)\n     data\n     (unique {:set-constructor (hamf-language/constantly (java-concurrent-hashset))} data))))\n\n\n(def ^{:private true\n       :tag 'long} unsigned-int-max (Integer/toUnsignedLong (int -1)))\n\n(defn- unsigned-int->host\n  ^long [^long v]\n  (when (or (< v 0)\n            (> v unsigned-int-max))\n    (throw (RuntimeException. (str \"Value out of range for unsigned integer: \" v))))\n  (unchecked-int v))\n\n(defn- reduce->range\n  [data]\n  (unique {:set-constructor bitset} data))\n\n(defn bitset\n  \"Create a java.util.Bitset.  The two argument version assumes you are passing in the\n  start, end of a monotonically incrementing range.\"\n  (^BitSet [] (BitSet.))\n  (^BitSet [data]\n   (cond\n     (instance? BitSet data)\n     data\n     (instance? Ranges$LongRange data)\n     (let [^Ranges$LongRange data data\n           rstart (.-start data)\n           rend (.-end data)\n           step (.-step data)]\n       (if (== 1 step)\n         (doto (BitSet.)\n           (.set (unchecked-int rstart) (unchecked-int rend)))\n         (reduce->range data)))\n     :else\n     (reduce->range data)))\n  (^BitSet [^long start ^long end]\n   (doto (BitSet.)\n     (.set (unchecked-int start) (unchecked-int end)))))\n\n\n\n(extend-protocol hamf-proto/SetOps\n  Object\n  (set? [l] (instance? Set l))\n  (union [l r] (api/union l r))\n  (difference [l r] (api/difference l r))\n  (intersection [l r] (api/intersection l r))\n  (xor [l r]\n    (api/difference (api/union l r)\n                    (api/intersection l r)))\n  (contains-fn [l]\n    #(.contains ^Set l %))\n  (cardinality [l] (.size ^Set l))\n  BitSet\n  (set? [l] true)\n  (union [l r]\n    (let [^BitSet l (.clone l)]\n      (.or ^BitSet (.clone l) (bitset r))\n      l))\n  (difference [l r]\n    (let [^BitSet l (.clone l)]\n      (.andNot l (bitset r))\n      l))\n  (intersection [l r]\n    (let [^BitSet l (.clone l)]\n      (.and l (bitset r))\n      l))\n  (xor [l r]\n    (let [^BitSet l (.clone l)]\n      (.xor l (bitset r))\n      l))\n  (contains-fn [l]\n    (hamf-fn/long-predicate v (.get l (unchecked-int v))))\n  (cardinality [l] (.cardinality l)))\n\n\n(extend-protocol hamf-proto/BulkSetOps\n  Object\n  (reduce-union [l data]\n    (reduce hamf-proto/union l data))\n  (reduce-intersection [l data]\n    (reduce hamf-proto/intersection l data)))\n\n\n(extend-protocol hamf-proto/PAdd\n  BitSet\n  (add-fn [c] (hamf-rf/long-accumulator b v (.set ^BitSet b (unchecked-int v)) b)))\n\n\n(extend-protocol hamf-proto/BitSet\n  Object\n  (bitset? [item] false)\n  BitSet\n  (bitset? [item] true)\n  (contains-range? [item sidx eidx]\n    (reduce (hamf-rf/long-accumulator\n             acc v\n             (if (and (>= v 0) (.get item (unchecked-int v)))\n               true\n               (reduced false)))\n            true\n            (api/range sidx eidx)))\n  (intersects-range? [item ^long sidx ^long eidx]\n    (reduce (hamf-rf/long-accumulator\n             acc v\n             (if (and (>= v 0) (.get item (unchecked-int v)))\n               (reduced true)\n               false))\n            false\n            (api/range sidx eidx)))\n  (min-set-value [item]\n    (.nextSetBit item 0))\n  (max-set-value [item]\n    (.previousSetBit item Integer/MAX_VALUE)))\n\n\n(defn union\n  \"set union\"\n  [l r]\n  (if l\n    (hamf-proto/union l r)\n    r))\n\n\n(defn reduce-union\n  \"Reduce a number of objects into one object via union\"\n  ([] (api/immut-set))\n  ([l] l)\n  ([l & data]\n   (hamf-proto/reduce-union l data)))\n\n\n(defn intersection\n  \"set intersection\"\n  ([] (api/immut-set))\n  ([l] l)\n  ([l r] (if l (hamf-proto/intersection l r) r)))\n\n\n(defn reduce-intersection\n  ([] (api/immut-set))\n  ([l] l)\n  ([l & data]\n   (hamf-proto/reduce-intersection l data)))\n\n\n(defn difference\n  \"set difference\"\n  [l r]\n  (when l\n    (hamf-proto/difference l r)))\n\n\n(defn xor\n  \"set xor - difference of intersection from union\"\n  [l r]\n  (if l\n    (hamf-proto/xor l r)\n    r))\n\n\n(defn map-invert\n  \"invert a map such that the keys are the vals and the vals are the keys\"\n  [m]\n  (when m\n    (-> (reduce (fn [^Map acc e]\n                  (.put acc (val e) (key e))\n                  acc)\n                (api/mut-map)\n                m)\n        (persistent!))))\n\n\n(defn contains-fn\n  \"Return an IFn that returns efficiently returns true if the set contains\n  a given element.\"\n  [s]\n  (hamf-proto/contains-fn s))\n\n\n(defn cardinality\n  \"Return the cardinality (size) of a given set.\"\n  ^long [s]\n  (hamf-proto/cardinality s))\n\n\n(defn bitset?\n  \"Return true if this is a bitset\"\n  [s]\n  (hamf-proto/bitset? s))\n\n\n(defn contains-range?\n  \"bitset-specific query that returns true if the set contains all the integers from\n  sidx to eidx non-inclusive.\"\n  [s ^long sidx ^long eidx]\n  (hamf-proto/contains-range? s sidx eidx))\n\n\n(defn intersects-range?\n  \"bitset-specific query that returns true if the set contains any the integers from\n  sidx to eidx non-inclusive.\"\n  [s ^long sidx ^long eidx]\n  (hamf-proto/intersects-range? s sidx eidx))\n\n\n(defn min-set-value\n  \"Given a bitset, return the minimum set value.  Errors if the bitset is empty.\"\n  [s] (hamf-proto/min-set-value s))\n\n\n(defn max-set-value\n  \"Given a bitset, return the maximum set value.  Errors if the bitset is empty.\"\n  [s] (hamf-proto/max-set-value s))\n\n\n(defn ->integer-random-access\n  \"Given a set (or bitset), return a efficient, sorted random access structure.  This assumes\n  the set contains integers.\"\n  [s]\n  (let [ne (cardinality s)\n        rv\n        (if (== 0 ne)\n          (api/range 0)\n          (if (bitset? s)\n            (let [mins (long (min-set-value s))\n                  maxs (long (max-set-value s))]\n              (if (== ne (- (unchecked-inc maxs) mins))\n                (api/range mins (unchecked-inc maxs))\n                (if (< maxs Integer/MAX_VALUE)\n                  (api/ivec s)\n                  (api/lvec s))))\n            (let [^IMutList l (api/lvec s)]\n              ;;Sorting means downstream access is in memory order.\n              (.sort l nil)\n              l)))]\n    (if (== 0 ne)\n      rv\n      ;;Keeping track of the min, max values allows downstream functions to choose\n      ;;perhaps different pathways.\n      (vary-meta rv assoc :min (rv 0) :max (rv -1)))))\n\n\n(defn unique-reducer\n  \"Create a parallel reducer that creates a set.\n\n  Options:\n\n  * `:set-constructor` construct something that implements [[ham-fisted.protocols/add-fn]]\n  and [[ham-fisted.protocols/union]]\n  * `:add-fn` Pass in user-defined add function as opposed to using protocol lookup to\n    find it.\"\n  [options]\n  (let [ctor (get options :set-constructor api/mut-set)\n        add-fn (or (get options :add-fn)\n                   (hamf-proto/add-fn (ctor)))]\n    (reify\n      hamf-proto/Reducer\n      (->init-val-fn [r] ctor)\n      (->rfn [r] add-fn)\n      hamf-proto/Finalize\n      (finalize [r v] (api/persistent! v))\n      hamf-proto/ParallelReducer\n      (->merge-fn [r] union))))\n\n\n(defn unique\n  \"Create a set of unique items.  Parallelized and non-lazy.\n\n  See options for [[unique-reducer]] and [[ham-fisted.api/preduce-reducer]].\"\n  ([options data]\n   (hamf-rf/preduce-reducer (unique-reducer options) (merge {:min-n 1000} options) data))\n  ([data] (unique nil data)))\n"
  },
  {
    "path": "src/ham_fisted/spliterator.clj",
    "content": "(ns ham-fisted.spliterator\n  \"Support for spliterator reduction and parallel reduction.\"\n  (:require [ham-fisted.protocols :as proto]\n            [ham-fisted.fjp :as fjp]\n            [ham-fisted.defprotocol :refer [extend-type extend]]\n            [ham-fisted.language :as hamf-language])\n  (:import [java.util Spliterator Spliterator$OfDouble Spliterator$OfLong List RandomAccess ArrayList]\n           [java.util.function Consumer]\n           [java.util.concurrent ForkJoinPool]\n           [clojure.lang IFn$DDD IFn$LLL IFn$OLO IFn$ODO]\n           [ham_fisted Consumers$IDerefLongConsumer Consumers$IDerefDoubleConsumer Consumers$IDerefConsumer\n            ParallelOptions Casts ArrayLists])\n  (:refer-clojure :exclude [extend-type extend]))\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n(extend-type nil\n  proto/EstimateCount\n  (estimate-count [m] 0)\n  proto/Split\n  (split [m] nil))\n\n(extend-type Object\n  proto/EstimateCount\n  (estimate-count [m] (proto/count m))\n  proto/Split\n  (split [m] nil))\n\n\n(run! (fn [[dt-name ary-cls]]\n        (extend ary-cls\n          proto/ToSpliterator\n          {:->spliterator\n           (case dt-name\n             :boolean (fn [a] (.spliterator (ArrayLists/toList ^booleans a)))\n             :byte (fn [a] (.spliterator (ArrayLists/toList ^bytes a)))\n             :short (fn [a] (.spliterator (ArrayLists/toList ^shorts a)))\n             :char (fn [a] (.spliterator (ArrayLists/toList ^chars a)))\n             :int (fn [a] (.spliterator (ArrayLists/toList ^ints a)))\n             :long (fn [a] (.spliterator (ArrayLists/toList ^longs a)))\n             :float (fn [a] (.spliterator (ArrayLists/toList ^floats a)))\n             :double (fn [a] (.spliterator (ArrayLists/toList ^doubles a)))\n             (fn [a] (.spliterator (ArrayLists/toList ^objects a))))}))\n      hamf-language/array-classes)\n\n(deftype ^:private DerefLongConsumer [^{:unsynchronized-mutable true\n                                        :tag long} v\n                                      ^IFn$LLL rfn]\n  Consumers$IDerefLongConsumer\n  (acceptLong [this d] (set! v (.invokePrim rfn v d)))\n  (deref [this] v))\n\n(defmacro deref-long-consumer\n  \"Create a LongConsumer with support for IDeref\"\n  [varname accept-code deref-code]\n  `(reify Consumers$IDerefLongConsumer\n     (acceptLong [_ ~varname] (let [l# ~accept-code]))\n     (deref [_] ~deref-code)))\n\n(deftype DerefDoubleConsumer [^{:unsynchronized-mutable true\n                                :tag double} v\n                              ^IFn$DDD rfn]\n  Consumers$IDerefDoubleConsumer\n  (acceptDouble [this d] (set! v (.invokePrim rfn v d)))\n  (deref [this] v))\n\n(defmacro deref-double-consumer\n  \"Create a DoubleConsumer with support for IDeref\"\n  [varname accept-code deref-code]\n  `(reify Consumers$IDerefDoubleConsumer\n     (acceptDouble [_ ~varname] (let [l# ~accept-code]))\n     (deref [_] ~deref-code)))\n\n(defmacro deref-consumer\n  \"Create a Consumer with support for IDeref\"\n  [varname accept-code deref-code]\n  `(reify Consumers$IDerefConsumer\n     (accept [_ ~varname] ~accept-code)\n     (deref [_] ~deref-code)))\n\n(defn ->spliterator ^Spliterator [ii] (if (instance? Spliterator ii) ii (proto/->spliterator ii)))\n\n(defn split-reduce \"Reduce over a spliterator.  Special support exists for IFn$LLL and IFn$DDD\"\n  ([rfn split]\n   (let [acc-ary (object-array 1)\n         cc (deref-consumer ll (aset acc-ary 0 ll) (aget acc-ary 0))\n         split (->spliterator split)]\n     (if (.tryAdvance split cc)\n       (split-reduce rfn (aget acc-ary 0) split)\n       (rfn))))\n  ([rfn acc split]\n   (cond\n     (instance? IFn$LLL rfn)\n     (let [cc (DerefLongConsumer. (Casts/longCast acc) rfn)]\n       (.forEachRemaining (->spliterator split) cc)\n       @cc)\n     (instance? IFn$OLO rfn)\n     (let [dd (hamf-language/obj-ary acc)\n           cc (deref-long-consumer ll (aset dd 0 (.invokePrim ^IFn$OLO rfn (aget dd 0) ll)) (aget dd 0))]\n       (.forEachRemaining (->spliterator split) cc)\n       @cc)\n     (instance? IFn$DDD rfn)\n     (let [cc (DerefDoubleConsumer. (Casts/doubleCast acc) rfn)]\n       (.forEachRemaining (->spliterator split) cc)\n       @cc)\n     (instance? IFn$ODO rfn)\n     (let [dd (hamf-language/obj-ary acc)\n           cc (deref-double-consumer ll (aset dd 0 (.invokePrim ^IFn$ODO rfn (aget dd 0) ll)) (aget dd 0))]\n       (.forEachRemaining (->spliterator split) cc)\n       @cc)\n     :else\n     (let [dd (hamf-language/obj-ary acc)\n           cc (deref-consumer ll (aset dd 0 (rfn (aget dd 0) ll)) (aget dd 0))\n           split (->spliterator split)]\n       (loop []\n         (let [c? (.tryAdvance split cc)]\n           (if c?\n             (let [vv @cc]\n               (if (reduced? vv)\n                 @vv\n                 (recur)))\n             (unreduced @cc))))))))\n\n(clojure.core/extend Spliterator\n  clojure.core.protocols/CollReduce\n  {:coll-reduce (fn reduce-spliterator\n                  ([coll rfn acc] (split-reduce rfn acc coll))\n                  ([coll rfn] (split-reduce rfn coll)))})\n\n(defn- println-ret [v] (println v) v)\n\n(extend-type Spliterator\n  proto/ToSpliterator\n  (->spliterator [s] s)\n  proto/EstimateCount\n  (estimate-count [s] (.estimateSize s))\n  proto/Split\n  (split [s] (when-let [ss (.trySplit s)] [s ss])))\n\n(extend-type java.util.RandomAccess\n  proto/Split\n  (split [s] (let [^List s s\n                   ne (.size s)]\n               (when (> ne 2)\n                 (let [n (quot ne 2)]\n                   [(.subList s 0 n)\n                    (.subList s n ne)])))))\n\n(defn split-parallel-reduce\n  \"Perform a parallel reduction of a spliterator using the provided ExecutorService\"\n  [executor-service split ideal-split init-fn rfn merge-fn]\n  (let [split (->spliterator split)\n        n-elems (.estimateSize split)\n        pool (or executor-service (ForkJoinPool/commonPool))]\n    (if (or (<= n-elems (long ideal-split)) (= n-elems Long/MAX_VALUE))\n      (split-reduce rfn (init-fn) split)\n      (if-let [rhs (.trySplit split)]\n        (let [lt (fjp/safe-fork-task pool (split-parallel-reduce pool split ideal-split init-fn rfn merge-fn))\n              rt (fjp/safe-fork-task pool (split-parallel-reduce pool rhs ideal-split init-fn rfn merge-fn))]\n          (merge-fn (fjp/managed-block-unwrap lt) (fjp/managed-block-unwrap rt)))\n        (split-reduce rfn (init-fn) split)))))\n\n(extend-type Spliterator\n  proto/ParallelReduction\n  (preduce [coll init-fn rfn merge-fn options]\n    (split-parallel-reduce (.-pool options) coll (.-minN options) init-fn rfn merge-fn)))\n\n(extend-type java.util.Collection\n  proto/ToSpliterator\n  (->spliterator [c] (.spliterator c)))\n\n(defn sum-fast\n  \"spliterator based serial summation\"\n  ^double [vv] (let [cc (ham_fisted.Sum$SimpleSum.)]\n                 (.forEachRemaining (->spliterator vv) cc)\n                 @cc))\n\n(defn- dp ^double [^double a ^double b] (+ a b))\n\n(defn psum \"spliterator based parallel summation - does not account for Double/NaN\"\n  ^double [vv] (split-parallel-reduce nil (->spliterator vv) 10000 (constantly 0) dp dp))\n\n(defn elements \"Return all the elements referenced by this spliterator as a persistent list\"\n  [data] (let [split (->spliterator data)\n               rv (ham_fisted.ArrayLists$ObjectArrayList.)\n               cc (reify Consumer\n                    (accept [this v] (.add rv v)))]\n           (.forEachRemaining split cc)\n           (persistent! rv)))\n\n(defn split-to-max-size [split ^long max-size op]\n  (let [split (->spliterator split)\n        n-elems (.estimateSize ^Spliterator split)]\n    (if (or (<= n-elems max-size) (== n-elems Long/MAX_VALUE))\n      [(op split)]\n      (let [rv (doto (ArrayList. ) (.add split))]\n        (loop [idx 0]\n          (if (== idx (.size rv))\n            rv\n            (let [ll (.get rv idx)]\n              (if (<= (.estimateSize ^Spliterator ll) max-size)\n                (do\n                  (.set rv idx (op ll))\n                  (recur (inc idx)))\n                (if-let [rhs (.trySplit ^Spliterator ll)]\n                  (do (.add rv (inc idx) rhs)\n                      (recur idx))\n                  (do\n                    (.set rv idx (op ll))\n                    (recur (inc idx))))))))))))\n\n(comment\n\n\n  (defn ^:no-doc ms-parallel-reduce\n    \"Perform a parallel reduction of a spliterator using the provided ExecutorService\"\n    [executor-service split ideal-split init-fn rfn merge-fn]\n    (let [split (->spliterator split)\n          n-elems (.estimateSize split)\n          pool (or executor-service (ForkJoinPool/commonPool))\n          ideal-split (long ideal-split)]\n      (if (or (<= n-elems ideal-split) (= n-elems Long/MAX_VALUE))\n        (split-reduce rfn (init-fn) split)\n        (let [data (split-to-max-size\n                    split ideal-split\n                    #(fjp/safe-fork-task pool (split-parallel-reduce pool % ideal-split init-fn rfn merge-fn)))\n              merge-fn #(reduce merge-fn (lznc/map fjp/managed-block-unwrap %))]\n          (loop [merge-data data]\n            (if (>= (count merge-data) ideal-split)\n              (recur (split-to-max-size\n                      merge-data ideal-split\n                      #(fjp/safe-fork-task pool (merge-fn %))))\n              (merge-fn merge-data)))))))\n  )\n"
  },
  {
    "path": "src/ham_fisted/thread_local.clj",
    "content": "(ns ham-fisted.thread-local)\n\n(defn thread-local\n  \"Create a new thread local variable\"\n  (^ThreadLocal [] (thread-local nil))\n  (^ThreadLocal [v] (ThreadLocal/withInitial\n                     (reify java.util.function.Supplier\n                       (get [this] v)))))\n"
  },
  {
    "path": "test/ham_fisted/api_test.clj",
    "content": "(ns ham-fisted.api-test\n  (:require [clojure.test :refer [deftest is]]\n            [ham-fisted.api :as hamf]\n            [ham-fisted.alists :as alists]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [ham-fisted.iterator :as hamf-iter]\n            [ham-fisted.set :as hamf-set])\n  (:import [java.util BitSet]\n           [java.util.function Consumer DoubleConsumer LongConsumer]\n           [clojure.lang IDeref]\n           [ham_fisted Reducible]))\n\n\n\n(deftest parallism-primitives-pass-errors\n  (is (thrown-with-msg? Exception #\"Error!!\"\n                        (doall (hamf/upmap\n                                (fn [^long idx]\n                                  (when (== idx 77) (throw (Exception. \"Error!!\"))) idx)\n                                (range 100)))))\n  (is (thrown-with-msg? Exception #\"Error!!\"\n                        (doall (hamf/pmap (fn [^long idx]\n                                            (when (== idx 77) (throw (Exception. \"Error!!\"))) idx)\n                                          (range 100)))))\n  (is (thrown-with-msg? Exception #\"Error!!\"\n                        (doall (hamf/upgroups 1000 (fn [^long sidx ^long eidx]\n                                                     (when (>= sidx 10)\n                                                       (throw (Exception. \"Error!!\")))\n                                                     sidx)\n                                              {:batch-size 100}))))\n  (is (thrown-with-msg? Exception #\"Error!!\"\n                        (doall (hamf/pgroups 1000 (fn [^long sidx ^long eidx]\n                                                    (when (>= sidx 10)\n                                                      (throw (Exception. \"Error!!\"))) sidx)\n                                             {:batch-size 100})))))\n\n\n(deftest group-by-nil\n  (is (= {} (hamf/group-by :a nil)))\n  (is (= {} (hamf/group-by-reduce :a + + + nil)))\n  (is (= {} (hamf/group-by :a {})))\n  (is (= {} (hamf/group-by-reduce :a + + + {})))\n  )\n\n\n(deftest map-filter-concat-nil\n  (is (= (map + nil) (lznc/map + nil)))\n  (is (= (filter + nil) (lznc/filter + nil)))\n  (is (= (concat) (lznc/concat)))\n  (is (= (concat nil) (lznc/concat nil))))\n\n\n(deftest conj-with-friends\n  (is (= (conj (map inc (list 1 2 3 4)) 4)\n         (conj (lznc/map inc (list 1 2 3 4)) 4)))\n  (is (= (conj (filter even? (list 1 2 3 4)) 4)\n         (conj (lznc/filter even? (list 1 2 3 4)) 4)))\n  (is (= (conj (concat [1 2 3] [4 5 6]) 4)\n         (conj (lznc/concat [1 2 3] [4 5 6]) 4)))\n  (is (= (conj (map-indexed + [1 2 3]) 4)\n         (conj (lznc/map-indexed + (apply list [1 2 3])) 4)))\n  (is (= (conj (map-indexed + nil) 4)\n         (conj (lznc/map-indexed + nil) 4))))\n\n\n(deftest empty-seq-preduce\n  (is (== 0.0 (hamf/sum (list))))\n  (is (== 19900.0 (hamf/sum (range 200))))\n  (is (= 1 (hamf-rf/preduce (constantly 1) + + nil)))\n  (is (= 1 (hamf-rf/preduce (constantly 1) + + (list)))))\n\n\n(deftest group-by-reduce-large-n\n  (is (= 113 (count (hamf/group-by #(rem (unchecked-long %1) 113) (range 10000)))))\n  (is (= 337 (count (hamf/group-by-reduce #(rem (unchecked-long %1) 337)\n                                          +\n                                          +\n                                          +\n                                          (range 10000))))))\n\n\n(deftest compare-seq-with-nonseq\n  (is (not (= (hamf/vec (range 10)) :a))))\n\n\n(deftest BitsetSet\n  (let [bs (doto (BitSet.)\n             (.set 1)\n             (.set 10))]\n    (is (= [1 10] (hamf/->random-access (hamf/int-array bs))))\n    (is (= [1.0 10.0] (->> bs\n                           (lznc/map (hamf-fn/long->double v (double v)))\n                           (hamf/vec))))\n    (is (not (nil? (hamf/->collection bs))))))\n\n\n(deftest char-array-reduction\n  (let [cv (hamf/char-array [20 30])]\n    (is (= [(char 20) (char 30)]\n           (reduce conj [] cv))))\n  (let [cv (hamf/char-array \"hey\")]\n    (is (= [\\h \\e \\y] (reduce conj [] cv)))))\n\n\n(deftest java-maps-are-iterable\n  (is (not (nil? (hamf/->collection (hamf/java-hashmap {:a 1 :b 2}))))))\n\n\n(deftest set-add-long-val\n  (let [alist (hamf/long-array-list)]\n    (.add alist Long/MAX_VALUE)\n    (is (= [Long/MAX_VALUE] alist))\n    (.set alist 0 Long/MAX_VALUE)\n    (is (= [Long/MAX_VALUE] alist))\n    (is (= [Long/MAX_VALUE] (vec alist)))\n    (let [sl (.subList alist 0 1)]\n      (is (= [Long/MAX_VALUE] sl))\n      (is (= [Long/MAX_VALUE] (vec sl))))))\n\n(deftest tostring-empty-range\n  (is (= \"[]\" (.toString (hamf/range 0))))\n  (is (= \"[]\" (.toString (hamf/range 0.0)))))\n\n\n(deftest map-filter-concat-reduced\n  (let [rfn (hamf-rf/long-accumulator acc v (if (< v 4) acc (reduced v)))]\n    (is (= 4 (reduce rfn 0 (lznc/map (hamf-fn/long-unary-operator v (inc v)) (hamf/range 20)))))\n    (is (= 4 (reduce rfn 0 (lznc/filter even? (hamf/range 20)))))\n    (is (= 4 (reduce rfn 0 (lznc/concat  (hamf/range 20) (hamf/range 20 50)))))\n    ))\n\n\n(deftest into-array-nil\n  (is (== 0 (count (hamf/into-array Double #(double %) nil)))))\n\n\n(deftest mmax-key-clojure-map\n  (is (= 3 (key (hamf/mmax-key val (frequencies (map #(rem % 7) (hamf/range 10000))))))))\n\n\n(deftest reduce-empty-range\n  (is (= 0 (reduce (fn [acc v] (inc acc)) 0 (hamf/range 0)))))\n\n\n(deftest assoc-basic-fail\n  (let [m1 (hamf/immut-map {:age 2, :sex 1, \"salary (binned)\" 4, :job 0, :salary 3})\n        m2 (assoc m1 :tech.v3.dataset.reductions/_tmp_col 5)]\n    (is (= (set (keys m1)) #{:age :sex \"salary (binned)\" :job :salary}))))\n\n(deftest set-api-compat\n  (is (= #{:a} (disj (hamf-set/difference (hamf/immut-set [:a :b :c])\n                                          (hamf/immut-set [:c :d :e]))\n                     :b)))\n  (is (= #{} (hamf/intersection (hamf/immut-set #{:a :b}) #{}))))\n\n\n(deftest test-partition-by\n  (is (= [[1 1 1] [2 2 2] [3 3 3]]\n         (vec (map vec (lznc/partition-by identity [1 1 1 2 2 2 3 3 3])))))\n  (is (= [[1 1 1] [2 2 2] [3 3 3]]\n         (hamf/mapv vec (lznc/partition-by identity [1 1 1 2 2 2 3 3 3]))))\n  (is (= (clojure.core/partition-by identity [])\n         (lznc/partition-by identity [])))\n  (is (= (clojure.core/partition-by identity nil)\n         (lznc/partition-by identity nil)))\n  ;;Ensure we catch incorrect usage when possible\n  (is (thrown? RuntimeException (into [] (lznc/partition-by identity [1 1 1 2 2 2 3 3 3])))))\n\n\n(deftype ^:private LongAccum [^:unsynchronized-mutable v]\n  LongConsumer\n  (accept [this val] (set! v (+ val v)))\n  Reducible\n  (reduce [this o] (+ v @o))\n  IDeref\n  (deref [this] v))\n\n\n(deftype ^:private DoubleAccum [^:unsynchronized-mutable v]\n  DoubleConsumer\n  (accept [this val] (set! v (+ val v)))\n  Reducible\n  (reduce [this o] (+ v @o))\n  IDeref\n  (deref [this] v))\n\n\n(deftype ^:private Accum [^:unsynchronized-mutable v]\n  Consumer\n  (accept [this val] (set! v (+ val v)))\n  Reducible\n  (reduce [this o] (+ v @o))\n  IDeref\n  (deref [this] v))\n\n\n(defn filter-sum-reducer\n  [type]\n  (case type\n    :int64 (hamf-rf/long-consumer-reducer #(LongAccum. 0))\n    :float64 (hamf-rf/double-consumer-reducer #(DoubleAccum. 0))\n    (hamf-rf/consumer-reducer #(Accum. 0.0))))\n\n\n(deftest compose-reducers\n  (is (= {:a 49995000}\n         (hamf-rf/preduce-reducers {:a (filter-sum-reducer :int64)}\n                                   {:rfn-datatype :int64}\n                                   (range 10000))))\n  (is (= {:a 49995000.0}\n         (hamf-rf/preduce-reducers {:a (filter-sum-reducer :float64)}\n                                   {:rfn-datatype :float64}\n                                   (range 10000))))\n  (is (= {:a 49995000.0}\n         (hamf-rf/preduce-reducers {:a (filter-sum-reducer nil)}\n                                   (range 10000)))))\n\n\n(deftest test-partition-all\n  (is (= [[0 1 2] [3 4 5] [6 7 8] [9]]\n         (vec (map vec (lznc/partition-all 3 (range 10))))))\n  ;;Ensure we catch incorrect usage when possible\n  (is (thrown? RuntimeException (into [] (lznc/partition-all 3 (range 10))))))\n\n\n(deftest parallel-frequenies\n  (is (= {0 715, 1 715, 2 715, 3 715, 4 714, 5 714, 6 714, 7 714, 8 714, 9 714, 10 714, 11 714, 12 714, 13 714}\n         (hamf/frequencies (lznc/map #(rem (long %) 14) (hamf/range 10000))))))\n\n\n(deftest range-seq\n  (is (= (vec (range 40))\n         (vec (apply list (hamf/range 40))))))\n\n(deftest drop-elems\n  (is (empty? (hamf/drop 10 [1 2 3 4 5]))))\n\n(deftest bulk-insert-constant\n  (let [src [0 1 2 3 4 100 100 100 5 6 7 8 9]]\n    (reduce (fn [acc v]\n              (if (not= v :boolean)\n                (is (= (alists/growable-array-list v src)\n                       (-> (alists/growable-array-list v (range 10))\n                           (hamf/add-constant! 5 3 100)))\n                    (str \"Test failed for datatype: \" v))\n                (let [src [true true false false true true]]\n                  (is (= (alists/growable-array-list v src)\n                         (-> (alists/growable-array-list v [true true true true])\n                             (hamf/add-constant! 2 2 false)))\n                      (str \"Test failed for datatype: \" v)))))\n            [] alists/array-list-types))\n  (let [src [0 1 2 3 4 5 6 7 8 9 100 100 100]]\n    (reduce (fn [acc v]\n              (if (not= v :boolean)\n                (is (= (alists/growable-array-list v src)\n                       (-> (alists/growable-array-list v (range 10))\n                           (hamf/add-constant! 10 3 100)))\n                    (str \"Test failed for datatype: \" v))\n                (let [src [true true true true false false]]\n                  (is (= (alists/growable-array-list v src)\n                         (-> (alists/growable-array-list v [true true true true])\n                             (hamf/add-constant! 4 2 false)))\n                      (str \"Test failed for datatype: \" v)))))\n            [] alists/array-list-types)))\n\n(deftest update-values\n  (is (= {:a false}\n         (hamf/update-values (array-map :a 1)\n                             (hamf-fn/bi-function k v false))))\n  (is (= {:a false}\n         (into {} (hamf/update-values (hamf/java-hashmap {:a 1})\n                                      (hamf-fn/bi-function k v false)))))\n  (is (= {:a false}\n         (hamf/update-values (hamf/mut-map {:a 1})\n                             (hamf-fn/bi-function k v false)))))\n\n(deftest incorrect-map-difference\n  (is (= (hamf/java-hashmap {:a 2})\n         (hamf/difference (hamf/java-hashmap {:a 2 :b 2})\n                          [:b :c]))))\n\n(deftest hash-map-compute\n  (is (= {}\n         (-> (let [ht (hamf/mut-map {1 2})]\n               (.compute ht 1 (hamf-fn/bi-function k v nil))\n               (persistent! ht)))))\n  (is (= {}\n         (-> (let [ht (hamf/mut-map {1 2})]\n               (is (= 2 (.remove ht 1)))\n               (persistent! ht))))))\n\n(deftest pmap-opts-empty-result\n  (is (= [1 2 3 4]\n         (vec (hamf/pmap-opts {:pool clojure.lang.Agent/soloExecutor\n                               :lookahead 2}\n                              identity\n                              [1 2 3 4])))))\n\n(deftest reduce-empty-apply-concat\n  (is (= 0 (reduce + 0 (lznc/apply-concat nil)))))\n\n(deftest drop-test\n  (is (= (drop 3 '(1 2 3 4)) (lznc/drop 3 '(1 2 3 4)))))\n\n(deftest take-test\n  (is (= (take 2 '(1 2 3 4)) (lznc/take 2 '(1 2 3 4)))))\n\n(deftest seq-iterable-not-counted\n  (is (not (counted? (hamf-iter/wrap-iter (.iterator (range)))))))\n\n(comment\n\n  (do\n    (def left-chunks (mapv hamf/long-array-list (partition-all 1000 (range 10000000))))\n    (def right-partitions (partition-all 100 (shuffle (range 100000))))\n    (require '[clj-async-profiler.core :as prof])\n    (prof/serve-ui 8080))\n  (def data (prof/profile (dotimes [idx 10]\n                            (time (->> (lznc/concat left-chunks right-partitions)\n                                       (lznc/apply-concat)\n                                       (hamf/sort-by (fn ^long [a] a))\n                                       (hamf/lsum))))))\n\n  (def data (vec '(1 2 3 4 5 6 7)))\n  (into [] (lznc/take 2) data)\n  (lznc/drop 2 data)\n  (drop 2 nil)\n  (lznc/drop 1 [1 2])\n  (lznc/take 2 data)\n  (time\n   (->> (apply concat left-chunks)\n        (drop 17)\n        (hamf/lsum)))\n\n  (prof/profile\n   (dotimes [idx 10]\n     (time\n      (->> (lznc/apply-concat left-chunks)\n           (lznc/take 10000000)\n           (hamf/sum)))))\n\n\n  )\n"
  },
  {
    "path": "test/ham_fisted/bloom_filter_test.clj",
    "content": "(ns ham-fisted.bloom-filter-test\n  (:require [ham-fisted.bloom-filter :as hamf-bf]\n            [clojure.test :refer [deftest is]])\n  (:import [java.util UUID]))\n\n\n\n(deftest uuid-test\n  (let [M (long 1e6)\n        uuids (vec (repeatedly M #(UUID/randomUUID)))\n        bf (hamf-bf/bloom-filter M 0.01)\n        pred (hamf-bf/make-obj-predicate bf)]\n    (reduce hamf-bf/insert-hash! bf (map hamf-bf/hash-obj uuids))\n    (is (pred (uuids 0)))\n    (let [false-pos (long (reduce (fn [eax _]\n                                    (if (pred (UUID/randomUUID))\n                                      (inc eax)\n                                      eax))\n                                  0\n                                  (range M)))\n          true-pos (long (reduce (fn [eax u]\n                                   (if (pred u)\n                                     (inc eax)\n                                     eax))\n                                 0\n                                 uuids))]\n      (is (< false-pos 2000))\n      (is (== M true-pos)))))\n"
  },
  {
    "path": "test/ham_fisted/cast_test.clj",
    "content": "(ns ham-fisted.cast-test\n  (:require [ham-fisted.api :as api]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [clojure.test :refer [deftest is]]))\n\n\n(deftest basic-casts\n  (is (thrown? Exception (api/long-array [0.0 ##NaN 0.0])))\n  (is (api/double-eq [0.0 ##NaN 0.0] (api/double-array [0 nil 0])))\n  (is (thrown? Exception (api/long-array (lznc/map (fn ^double [^double v]\n                                                     (+ v 2.0))\n                                                   [0.0 ##NaN 0.0]))))\n  (is (thrown? Exception (api/double-array (->> [0.0 ##NaN 0.0]\n                                                (lznc/map (fn ^double [^double v]\n                                                            (+ v 2.0)))\n                                                (lznc/filter (hamf-fn/long-predicate\n                                                              v (not (== 0 (rem v 3)))))))))\n  (is (thrown? Exception (vec (lznc/map (hamf-fn/long-unary-operator v (+ v 2))\n                                        [0.0 ##NaN 0.0]))))\n  (is (thrown? Exception (vec (->> [0.0 ##NaN 0.0]\n                                   (hamf-fn/double-unary-operator v (+ v 2.0))\n                                   (lznc/filter (hamf-fn/long-predicate v (not (== 0 (rem v 3)))))))))\n  (is (= [false false false] (api/->random-access (api/boolean-array [nil ##NaN nil]))))\n  (is (= [false false] (api/->random-access (api/boolean-array [nil nil])))))\n"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/examples.clj",
    "content": "(ns ham-fisted.defprotocol-test.examples\n  (:refer-clojure :exclude [defprotocol])\n  (:require [ham-fisted.defprotocol :refer [defprotocol]]))\n\n(defprotocol ExampleProtocol\n  \"example protocol used by clojure tests\"\n\n  (foo [a] \"method with one arg\")\n  (bar [a b] \"method with two args\")\n  (^String baz [a] [a b] \"method with multiple arities\")\n  (with-quux [a] \"method name with a hyphen\"))\n\n(defprotocol MarkerProtocol\n  \"a protocol with no methods\")\n\n(defprotocol MarkerProtocol2)\n\n(definterface ExampleInterface\n  (hinted [^int i])\n  (hinted [^String s]))\n\n(defprotocol LongsHintedProto\n  (^longs longs-hinted [_]))\n"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/hash_collisions_test.clj",
    "content": "(ns ham-fisted.defprotocol-test.hash-collisions-test\n  (:refer-clojure :exclude [defprotocol extend-type extend extend-protocol satisfies? extends?])\n  (:require [clojure.test :refer [deftest is]]\n            [ham-fisted.defprotocol :refer [defprotocol extend-type extend extend-protocol satisfies? extends?]]))\n\n(defprotocol TestProtocolA\n  (method-a [this] \"Test method A\"))\n\n(defprotocol TestProtocolB\n  (method-b [this] \"Test method B\"))\n\n(deftype TestType1 [])\n(deftype TestType2 [])\n(deftype TestType3 [])\n(deftype TestType4 [])\n(deftype TestType5 [])\n(deftype TestType6 [])\n(deftype TestType7 [])\n(deftype TestType8 [])\n(deftype TestType9 [])\n(deftype TestType10 [])\n(deftype TestType11 [])\n(deftype TestType12 [])\n(deftype TestType13 [])\n(deftype TestType14 [])\n(deftype TestType15 [])\n\n(def original-hash hash)\n\n(defn colliding-hash\n  \"Mock hash function which returns identical hash codes for the\n  classes TestType1 and TestType2, normal hashes for everything else.\"\n  [x]\n  (if (or (= x TestType1) (= x TestType2))\n    999 ;; artificial hash code, to cause a collision\n    (original-hash x)))\n\n(deftest protocols-with-hash-collisions\n  (with-redefs [hash colliding-hash]\n    (extend TestType1 TestProtocolA {:method-a (constantly 1)})\n    (extend TestType2 TestProtocolA {:method-a (constantly 2)})\n    (is (= 1 (method-a (TestType1.))))\n    (is (= 2 (method-a (TestType2.))))))\n\n(defn no-min-hash-in-13-bits\n  \"Mock hash function which returns hash codes for the classes\n  TestType1 through TestType15 such that they cannot be compressed\n  into a 13-bit min-hash table. Returns normal hashes for everything\n  else.\"\n  [x]\n  (cond\n    (= x TestType1) 1\n    (= x TestType2) 2\n    (= x TestType3) 4\n    (= x TestType4) 8\n    (= x TestType5) 16\n    (= x TestType6) 32\n    (= x TestType7) 64\n    (= x TestType8) 128\n    (= x TestType9) 256\n    (= x TestType10) 512\n    (= x TestType11) 1024\n    (= x TestType12) 2048\n    (= x TestType13) 4096\n    (= x TestType14) 8192\n    (= x TestType15) 16384\n    :else (original-hash x)))\n\n(deftest protocols-with-no-min-hash-in-13-bits\n  (with-redefs [hash no-min-hash-in-13-bits]\n    (extend TestType1 TestProtocolB {:method-b (constantly 1)})\n    (extend TestType2 TestProtocolB {:method-b (constantly 2)})\n    (extend TestType3 TestProtocolB {:method-b (constantly 3)})\n    (extend TestType4 TestProtocolB {:method-b (constantly 4)})\n    (extend TestType5 TestProtocolB {:method-b (constantly 5)})\n    (extend TestType6 TestProtocolB {:method-b (constantly 6)})\n    (extend TestType7 TestProtocolB {:method-b (constantly 7)})\n    (extend TestType8 TestProtocolB {:method-b (constantly 8)})\n    (extend TestType9 TestProtocolB {:method-b (constantly 9)})\n    (extend TestType10 TestProtocolB {:method-b (constantly 10)})\n    (extend TestType11 TestProtocolB {:method-b (constantly 11)})\n    (extend TestType12 TestProtocolB {:method-b (constantly 12)})\n    (extend TestType13 TestProtocolB {:method-b (constantly 13)})\n    (extend TestType14 TestProtocolB {:method-b (constantly 14)})\n    (extend TestType15 TestProtocolB {:method-b (constantly 15)})\n    (is (= 1 (method-b (TestType1.))))\n    (is (= 2 (method-b (TestType2.))))\n    (is (= 3 (method-b (TestType3.))))\n    (is (= 4 (method-b (TestType4.))))\n    (is (= 5 (method-b (TestType5.))))\n    (is (= 6 (method-b (TestType6.))))\n    (is (= 7 (method-b (TestType7.))))\n    (is (= 8 (method-b (TestType8.))))\n    (is (= 9 (method-b (TestType9.))))\n    (is (= 10 (method-b (TestType10.))))\n    (is (= 11 (method-b (TestType11.))))\n    (is (= 12 (method-b (TestType12.))))\n    (is (= 13 (method-b (TestType13.))))\n    (is (= 14 (method-b (TestType14.))))\n    (is (= 15 (method-b (TestType15.))))))\n"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/more_examples.clj",
    "content": "(ns ham-fisted.defprotocol-test.more-examples\n  (:require [ham-fisted.defprotocol :as hamf-defp]))\n\n(hamf-defp/defprotocol SimpleProtocol\n  \"example protocol used by clojure tests. Note that\n   foo collides with examples/ExampleProtocol.\"\n\n  (foo [a] \"\"))\n"
  },
  {
    "path": "test/ham_fisted/defprotocol_test/other_test.clj",
    "content": "(ns ham-fisted.defprotocol-test.other-test\n  (:refer-clojure :exclude [defprotocol extend-type extend extend-protocol satisfies? extends?])\n  (:require [clojure.test :refer [deftest is]]\n            [ham-fisted.defprotocol :refer [defprotocol extend-type extend extend-protocol satisfies? extends?]]\n            [ham-fisted.defprotocol-test])\n  (:refer-clojure :exclude [defprotocol extend-type extend extend-protocol satisfies? extends?]))\n\n(defn cf [val]\n  (let [aseq (ham-fisted.defprotocol-test/f val)]\n    (count aseq)))\n(extend-protocol ham-fisted.defprotocol-test/P String\n                 (f [s] (seq s)))\n(deftest test-resolve-type-hints-in-protocol-methods\n  (is (= 4 (cf \"test\"))))\n"
  },
  {
    "path": "test/ham_fisted/defprotocol_test.clj",
    "content": ";;   Copyright (c) Rich Hickey. All rights reserved.  The use and distribution terms for\n;;   this software are covered by the Eclipse Public License 1.0\n;;   (http://opensource.org/licenses/eclipse-1.0.php) which can be found in the file\n;;   epl-v10.html at the root of this distribution.  By using this software in any\n;;   fashion, you are agreeing to be bound by the terms of this license.  You must not\n;;   remove this notice, or any other, from this software.\n\n;; Author: Stuart Halloway\n;; Heavy modification - Chris Nuernberger\n(ns ham-fisted.defprotocol-test\n  (:require [ham-fisted.defprotocol-test.examples :refer :all]\n            [ham-fisted.defprotocol-test.more-examples :as other]\n            [ham-fisted.defprotocol :refer [defprotocol extend-type extend extend-protocol satisfies? extends?]\n             :as defprotocol]\n            [ham-fisted.api :as hamf]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [clojure.set :as set]\n            [clojure.test :refer [deftest testing are is do-report assert-expr report]])\n  (:import [ham_fisted.defprotocol_test.examples ExampleInterface]\n           [java.util LongSummaryStatistics]\n           [java.util.function LongConsumer])\n  (:refer-clojure :exclude [defprotocol extend-type extend extend-protocol satisfies? extends?])\n  )\n\n(set! *warn-on-reflection* true)\n\n(defn causes\n  [^Throwable throwable]\n  (loop [causes []\n         t throwable]\n    (if t (recur (conj causes t) (.getCause t)) causes)))\n\n;; this is how I wish clojure.test/thrown? worked...\n;; Does body throw expected exception, anywhere in the .getCause chain?\n(defmethod assert-expr 'fails-with-cause?\n  [msg [_ exception-class msg-re & body :as form]]\n  `(try\n     ~@body\n     (report {:type :fail, :message ~msg, :expected '~form, :actual nil})\n     (catch Throwable t#\n       (if (some (fn [cause#]\n                   (and\n                    (= ~exception-class (class cause#))\n                    (re-find ~msg-re (.getMessage ^Throwable cause#))))\n                 (causes t#))\n         (report {:type :pass, :message ~msg,\n                  :expected '~form, :actual t#})\n         (report {:type :fail, :message ~msg,\n                  :expected '~form, :actual t#})))))\n\n\n(defmethod clojure.test/assert-expr 'thrown-with-cause-msg? [msg form]\n  ;; (is (thrown-with-cause-msg? c re expr))\n  ;; Asserts that evaluating expr throws an exception of class c.\n  ;; Also asserts that the message string of the *cause* exception matches\n  ;; (with re-find) the regular expression re.\n  (let [klass (nth form 1)\n        re (nth form 2)\n        body (nthnext form 3)]\n    `(try ~@body\n          (do-report {:type :fail, :message ~msg, :expected '~form, :actual nil})\n          (catch ~klass e#\n            (let [m# (if (.getCause e#) (.. e# getCause getMessage) (.getMessage e#))]\n              (if (re-find ~re m#)\n                (do-report {:type :pass, :message ~msg,\n                            :expected '~form, :actual e#})\n                (do-report {:type :fail, :message ~msg,\n                            :expected '~form, :actual e#})))\n            e#))))\n\n\n(defn method-names\n  \"return sorted list of method names on a class\"\n  [c]\n  (->> (.getMethods ^Class c)\n       (map #(.getName ^java.lang.reflect.Method %))\n       (sort)))\n\n(defrecord EmptyRecord [])\n(defrecord TestRecord [a b])\n(defn r\n  ([a b] (TestRecord. a b))\n  ([a b meta ext] (TestRecord. a b meta ext)))\n(defrecord MapEntry [k v]\n  java.util.Map$Entry\n  (getKey [_] k)\n  (getValue [_] v))\n\n(deftest protocols-test\n  (testing \"protocol fns have useful metadata\"\n    (let [common-meta {:ns (find-ns 'ham-fisted.defprotocol-test.examples)\n                       :tag nil}]\n      (are [m f] (= (merge common-meta m)\n                    (dissoc (meta (var f))\n                            :line :column :file :hamf-protocol))\n        {:name 'foo :arglists '([a]) :doc \"method with one arg\"} foo\n        {:name 'bar :arglists '([a b]) :doc \"method with two args\"} bar\n        {:name 'baz :arglists '([a] [a b]) :doc \"method with multiple arities\" :tag 'java.lang.String} baz\n        {:name 'with-quux :arglists '([a]) :doc \"method name with a hyphen\"} with-quux)))\n  (testing \"protocol fns throw IllegalArgumentException if no impl matches\"\n    (is (thrown-with-msg?\n         IllegalArgumentException\n         #\"No implementation of method: :foo of protocol: #'ham-fisted.defprotocol-test.examples/ExampleProtocol found for class: java.lang.Long\"\n         (foo 10))))\n  (testing \"protocols generate a corresponding interface using _ instead of - for method names\"\n    (is (= [\"bar\" \"baz\" \"baz\" \"foo\" \"with_quux\"] (method-names ham_fisted.defprotocol_test.examples.ExampleProtocol))))\n  (testing \"protocol will work with instances of its interface (use for interop, not in Clojure!)\"\n    (let [obj (proxy [ham_fisted.defprotocol_test.examples.ExampleProtocol] []\n                (foo [] \"foo!\"))]\n      (is (= \"foo!\" (.foo obj)) \"call through interface\")\n      (is (= \"foo!\" (foo obj)) \"call through protocol\")))\n  (testing \"you can implement just part of a protocol if you want\"\n    (let [obj (reify ExampleProtocol\n                (baz [a b] \"two-arg baz!\"))]\n      (is (= \"two-arg baz!\" (baz obj nil)))\n      (is (thrown? AbstractMethodError (baz obj)))))\n  (testing \"error conditions checked when defining protocols\"\n    (is #_{:clj-kondo/ignore [:unresolved-symbol]}\n        (thrown-with-cause-msg?\n         Exception\n         #\"Definition of function m in protocol badprotdef must take at least one arg.\"\n         (eval '(defprotocol badprotdef (m [])))))\n    (is #_{:clj-kondo/ignore [:unresolved-symbol]}\n        (thrown-with-cause-msg?\n         Exception\n         #\"Function m in protocol badprotdef was redefined. Specify all arities in single definition.\"\n         (eval '(defprotocol badprotdef (m [this arg]) (m [this arg1 arg2]))))))\n  (testing \"you can redefine a protocol with different methods\"\n    (eval '(defprotocol Elusive (old-method [x])))\n    (eval '(defprotocol Elusive (new-method [x])))\n    (is (= :new-method (eval '(new-method (reify Elusive (new-method [x] :new-method))))))\n    (is #_{:clj-kondo/ignore [:unresolved-symbol]}\n        (fails-with-cause? IllegalArgumentException #\"No method of interface: .*\\.Elusive found for function: old-method of protocol: Elusive \\(The protocol method may have been defined before and removed\\.\\)\"\n                           (eval '(old-method (reify Elusive (new-method [x] :new-method))))))))\n\n(deftype HasMarkers []\n  ExampleProtocol\n  (foo [this] \"foo\")\n  MarkerProtocol\n  MarkerProtocol2)\n\n(deftype WillGetMarker []\n  ExampleProtocol\n  (foo [this] \"foo\"))\n\n(extend-type WillGetMarker MarkerProtocol)\n\n(deftest marker-tests\n  (testing \"That a marker protocol has no methods\"\n    (is (= '() (method-names ham_fisted.defprotocol_test.examples.MarkerProtocol))))\n  (testing \"That types with markers are reportedly satifying them.\"\n    (let [hm (HasMarkers.)\n          wgm (WillGetMarker.)]\n      (is (satisfies? MarkerProtocol hm))\n      (is (satisfies? MarkerProtocol2 hm))\n      (is (satisfies? MarkerProtocol wgm)))))\n\n(deftype ExtendTestWidget [name])\n(deftype HasProtocolInline []\n  ExampleProtocol\n  (foo [this] :inline))\n(deftest extend-test\n  (testing \"you can extend a protocol to a class\"\n    (extend String ExampleProtocol\n            {:foo identity})\n    (is (= \"pow\" (foo \"pow\"))))\n  (testing \"you can have two methods with the same name. Just use namespaces!\"\n    (extend String other/SimpleProtocol\n            {:foo (fn [s] (.toUpperCase ^String s))})\n    (is (= \"POW\" (other/foo \"pow\"))))\n  (testing \"you can extend deftype types\"\n    (extend\n        ExtendTestWidget\n      ExampleProtocol\n      {:foo (fn [this] (str \"widget \" (.name ^ExtendTestWidget this)))})\n    (is (= \"widget z\" (foo (ExtendTestWidget. \"z\"))))))\n\n(deftest illegal-extending\n  (testing \"you cannot extend a protocol to a type that implements the protocol inline\"\n    (is #_{:clj-kondo/ignore [:unresolved-symbol]}\n        (fails-with-cause? IllegalArgumentException #\".*HasProtocolInline already directly implements interface\"\n                           (eval '(extend ham_fisted.defprotocol_test.HasProtocolInline\n                                    ham-fisted.defprotocol-test.examples/ExampleProtocol\n                                    {:foo (fn [_] :extended)})))))\n  (testing \"you cannot extend to an interface\"\n    (is #_{:clj-kondo/ignore [:unresolved-symbol]}\n        (fails-with-cause? IllegalArgumentException #\"interface ham_fisted.defprotocol_test.examples.ExampleProtocol is not a protocol\"\n                           (eval '(extend ham_fisted.defprotocol_test.HasProtocolInline\n                                    ham_fisted.defprotocol_test.examples.ExampleProtocol\n                                    {:foo (fn [_] :extended)}))))))\n\n\n                                        ; see CLJ-845\n(defprotocol SyntaxQuoteTestProtocol\n  (sqtp [p]))\n\n(defmacro try-extend-type [c]\n  `(extend-type ~c\n     SyntaxQuoteTestProtocol\n     (sqtp [p#] p#)))\n\n(defmacro try-extend-protocol [c]\n  `(extend-protocol SyntaxQuoteTestProtocol\n     ~c\n     (sqtp [p#] p#)))\n\n(try-extend-type String)\n(try-extend-protocol clojure.lang.Keyword)\n\n(deftest test-no-ns-capture\n  (is (= \"foo\" (sqtp \"foo\")))\n  (is (= :foo (sqtp :foo))))\n\n(defprotocol Dasherizer\n  (-do-dashed [this]))\n(deftype Dashed []\n  Dasherizer\n  (-do-dashed [this] 10))\n\n(deftest test-leading-dashes\n  (is (= 10 (-do-dashed (Dashed.))))\n  (is (= [10] (map -do-dashed [(Dashed.)]))))\n\n;; see CLJ-1879\n\n(deftest test-base-reduce-kv\n  (is (= {1 :a 2 :b}\n         (reduce-kv #(assoc %1 %3 %2)\n                    {}\n                    (seq {:a 1 :b 2})))))\n\n(defn aget-long-hinted ^long [x] (aget (longs-hinted x) 0))\n\n(deftest test-longs-hinted-proto\n  (is (= 1\n         (aget-long-hinted\n          (reify LongsHintedProto\n            (longs-hinted [_] (long-array [1])))))))\n\n;; CLJ-1180 - resolve type hints in protocol methods\n\n(import 'clojure.lang.ISeq)\n(defprotocol P\n  (^ISeq f [_]))\n\n;;; continues in defprotocol_test/other.clj\n\n(defprotocol Ecount (^long ecount [m]))\n(extend Object Ecount {:ecount 5})\n(extend Number Ecount {:ecount (fn ^long [m] 0)})\n(extend-type Long Ecount (ecount [m] 10))\n\n;;Hamf protocols have to work with extend-type and reify\n(deftype TestType []\n  Ecount\n  (ecount [this] 200))\n\n(deftest primitive-hinted-test\n  (is (== 5 (ecount :a)))\n  (is (== 0 (ecount 1.0)))\n  (is (== 10 (ecount 1)))\n  (is (== 200 (ecount (TestType.))))\n  (is (thrown? Exception (eval '(clojure.core/extend-type String\n                                  Ecount\n                                  (ecount [m] (.length m)))))))\n\n(defprotocol SaneInheritance\n  (a [r])\n  (b [r]))\n\n(extend-type Object\n  SaneInheritance\n  (a [r] :object)\n  (b [r] :object))\n\n(extend-type String\n  SaneInheritance\n  (b [r] :string))\n\n(deftest sane-inheritance-test\n  (is (= :object (a \"hey\")))\n  (is (= :string (b \"hey\"))))\n\n\n(defprotocol HamfMemsize\n  (^long hamf-memsize [m]))\n\n(extend Double HamfMemsize {:hamf-memsize 24})\n(extend Long HamfMemsize {:hamf-memsize 24})\n(extend clojure.lang.Keyword HamfMemsize {:hamf-memsize 48})\n\n(extend-protocol HamfMemsize\n  String\n  (hamf-memsize [s] (+ 24 (.length ^String s)))\n  java.util.Collection\n  (hamf-memsize [c] (hamf/lsum (lznc/map (fn ^long [d] (+ 24 (hamf-memsize d))) c)))\n  java.util.Map\n  (hamf-memsize [c] (hamf/lsum (lznc/map (fn ^long [kv]\n                                           (+ 36 (+ (hamf-memsize (key kv)) (hamf-memsize (val kv)))))\n                                         c))))\n\n(clojure.core/defprotocol CoreMemsize\n  (core-memsize [m]))\n\n(clojure.core/extend-protocol CoreMemsize\n  Double (core-memsize [d] 24)\n  Long (core-memsize [l] 24)\n  clojure.lang.Keyword (core-memsize [k] 48)\n  String (core-memsize [s] (+ 24 (.length ^String s)))\n  java.util.Collection\n  (core-memsize [c]\n    (hamf/lsum (lznc/map (fn ^long [d] (+ 24 (long (core-memsize d)))) c))\n    #_(reduce\n       (fn [s v] (+ s 24 (core-memsize v)))\n       0\n       c))\n  java.util.Map\n  (core-memsize [m]\n    (hamf/lsum (lznc/map (fn ^long [kv]\n                           (+ 36 (+ (long (core-memsize (key kv)))\n                                    (long (core-memsize (val kv))))))\n                         m))\n    #_(reduce\n       (fn [s [k v]] (+ s 36 (core-memsize k) (core-memsize v)))\n       0\n       m)))\n\n(def test-datastructure\n  {:a \"hello\"\n   :b 24\n   :c (into [] (repeat 1000 (rand)))\n   :d (into [] (repeat 1000 1))})\n\n\n(def measure-data (into [] (repeat 10000 test-datastructure)))\n\n(defn multithread-test\n  [measure-fn]\n  (hamf/lsum (hamf/pmap measure-fn measure-data)))\n\n(defprotocol PDatatype (datatype [v]))\n(extend String PDatatype {:datatype :string})\n(extend clojure.lang.Keyword PDatatype {:datatype :keyword})\n(deftest object-constants\n  (is (= :string (datatype \"key\")))\n  (is (= :keyword (datatype :key))))\n\n(defn obj-cls->datatype\n  [obj-cls]\n  (if (identical? String obj-cls)\n    :string\n    :object))\n\n(extend (type (object-array 0))\n  PDatatype {:datatype (fn [obj]\n                         (-> (.getClass ^Object obj)\n                             (.getComponentType)\n                             (obj-cls->datatype)))})\n\n(extend (type (make-array clojure.lang.Keyword 0))\n  PDatatype {:datatype (constantly :keyword-array-overload)})\n\n(deftest test-object-array-protocols\n  (is (= :object (datatype (object-array 0))))\n  (is (= :string (datatype (make-array String 0))))\n  (is (= :keyword-array-overload (datatype (make-array clojure.lang.Keyword 0)))))\n\n(defprotocol PPrimitiveArgs\n  (^double pargs [m ^long b]))\n\n(extend-type String\n  PPrimitiveArgs\n  (pargs [m b]\n    (+ 1.0 (+ (.length m) b))))\n\n(deftest test-hinted\n  (is (instance? clojure.lang.IFn$OL hamf-memsize))\n  (is (instance? clojure.lang.IFn$OL -hamf-memsize-iface))\n  (is (instance? clojure.lang.IFn$OLD pargs))\n  (is (instance? clojure.lang.IFn$OLD -pargs-iface))\n  (is (= 14.0 (pargs \"hey\" 10))))\n\n\n(defprotocol SubBuffer\n  (sub-buffer [m ^long a ^long b]))\n\n(deftest test-sub-buffer\n  (is (instance? clojure.lang.IFn$OLLO sub-buffer))\n  (is (instance? clojure.lang.IFn$OLLO -sub-buffer-iface)))\n\n\n(comment\n  (require '[criterium.core :as crit])\n  ;;Single threaded calls show very little difference if any:\n  (crit/quick-bench (core-memsize test-datastructure))\n  ;; Evaluation count : 23868 in 6 samples of 3978 calls.\n  ;;              Execution time mean : 25.018494 µs\n  ;;     Execution time std-deviation : 26.939284 ns\n  ;;    Execution time lower quantile : 24.969740 µs ( 2.5%)\n  ;;    Execution time upper quantile : 25.046386 µs (97.5%)\n  ;;                    Overhead used : 1.539613 ns\n\n  ;; Multithreaded calls however:\n\n  (crit/quick-bench (hamf-memsize test-datastructure))\n  ;; Evaluation count : 22734 in 6 samples of 3789 calls.\n  ;;              Execution time mean : 26.336031 µs\n  ;;     Execution time std-deviation : 202.486707 ns\n  ;;    Execution time lower quantile : 25.953198 µs ( 2.5%)\n  ;;    Execution time upper quantile : 26.466131 µs (97.5%)\n  ;;                    Overhead used : 1.539613 ns\n\n  (crit/quick-bench (multithread-test core-memsize))\n  ;; Evaluation count : 6 in 6 samples of 1 calls.\n  ;;              Execution time mean : 634.046041 ms\n  ;;     Execution time std-deviation : 9.874821 ms\n  ;;    Execution time lower quantile : 622.889124 ms ( 2.5%)\n  ;;    Execution time upper quantile : 646.951202 ms (97.5%)\n  ;;                    Overhead used : 1.539613 ns\n\n  (crit/quick-bench (multithread-test hamf-memsize))\n  ;; Evaluation count : 18 in 6 samples of 3 calls.\n  ;;              Execution time mean : 45.689563 ms\n  ;;     Execution time std-deviation : 1.272542 ms\n  ;;    Execution time lower quantile : 44.302374 ms ( 2.5%)\n  ;;    Execution time upper quantile : 47.396205 ms (97.5%)\n  ;;                    Overhead used : 1.539613 ns\n\n\n  )\n"
  },
  {
    "path": "test/ham_fisted/fjp_test.clj",
    "content": "(ns ham-fisted.fjp-test\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.fjp :as fjp]\n            [ham-fisted.protocols :as proto]\n            [ham-fisted.function :as hamf-fn]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.language :refer [cond not]]\n            [ham-fisted.spliterator :as spliterator]\n            [clojure.test :refer [deftest is]])\n  (:import [java.util List Spliterator Spliterator$OfDouble Spliterator$OfLong]\n           [java.util.function Consumer DoubleConsumer LongConsumer]\n           [clojure.lang IDeref IFn$LLL IFn$DDD]\n           [ham_fisted Consumers$IDerefLongConsumer Consumers$IDerefDoubleConsumer])\n  (:refer-clojure :exclude [cond not]))\n\n(set! *warn-on-reflection* true)\n(set! *unchecked-math* :warn-on-boxed)\n\n(defn lp ^long [^long a ^long b] (+ a b))\n(defn dp ^double [^double a ^double b] (+ a b))\n\n(defn sum-reducer []\n  (reify\n    proto/Reducer\n    (->init-val-fn [_] #(long-array 1))\n    (->rfn [_] (fn [^longs lv ^long v] (let [_ (aset lv 0 (+ (aget lv 0) v))] lv)))\n    proto/ParallelReducer\n    (->merge-fn [_] (fn [^longs lv ^longs rv]\n                      (let [_ (aset lv 0 (+ (aget lv 0) (aget rv 0)))]\n                        lv)))\n    proto/Finalize\n    (finalize [this lv] (aget ^longs lv 0))))\n\n(deftest parallel-summation\n  (let [data (hamf/range 1000000)\n        total (hamf/lsum data)]\n    (is (= total\n           (spliterator/split-parallel-reduce\n            (fjp/common-pool) (proto/->spliterator data) 1000 (constantly 0) lp lp)))\n    (is (= total\n           (spliterator/split-parallel-reduce\n            clojure.lang.Agent/soloExecutor (proto/->spliterator data) 1000 (constantly 0) lp lp)))\n    (is (= total (hamf-rf/preduce (constantly 0) lp lp (proto/->spliterator data))))\n    (is (= total (hamf-rf/preduce-reducer (sum-reducer) (proto/->spliterator data))))))\n\n\n(comment\n  (def data (hamf/range 100000000))\n  (def vdata (into (hamf/immut-list) data))\n  (def vvdata (into [] data))\n  (= (spliterator/sum-fast vdata)\n     (spliterator/psum vdata))\n\n  (spliterator/split-to-max-size vdata 10 spliterator/elements)\n  (spliterator/elements (.spliterator vdata 25 35))\n  (require '[clj-async-profiler.core :as prof])\n  (crit/quick-bench (spliterator/sum-fast vdata))\n  (crit/quick-bench (spliterator/sum-fast vvdata))\n  (prof/serve-ui 8080)\n\n  (require '[criterium.core :as crit])\n  (crit/quick-bench (spliterator/psum vdata))\n  (crit/quick-bench (spliterator/psum vvdata))\n  \n  )\n"
  },
  {
    "path": "test/ham_fisted/hash_map_test.clj",
    "content": "(ns ham-fisted.hash-map-test\n  (:require [clojure.test :refer [deftest is testing are]]\n            [clojure.set :as set]\n            [ham-fisted.api :as api]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.function :as hamf-fn]\n            [criterium.core :as crit])\n  (:import [java.util ArrayList Collections Map Collection]\n           [java.util.function BiFunction BiConsumer]\n           [java.util.concurrent ForkJoinPool Future Callable]\n           [ham_fisted PersistentHashMap PersistentLongHashMap]))\n\n(defonce orig api/empty-map)\n\n\n(deftest simple-assoc\n  (let [orig api/empty-map]\n    (is (= 0 (count orig)))\n    (is (= {:a :b} (assoc orig :a :b)))\n    (is (= 1 (count (assoc orig :a :b))))\n    (is (= {} (-> (assoc orig :a :b)\n                  (dissoc :a))))\n    (is (= 0 (-> (assoc orig :a :b)\n                 (dissoc :a)\n                 (count)))))\n\n  (let [nilmap (assoc orig nil :b)]\n    (is (= {nil :b} nilmap))\n    (is (= nilmap {nil :b}))\n    (is (= {nil :b :a :b} (assoc nilmap :a :b)))\n    (is (= (assoc nilmap :a :b) {nil :b :a :b}))\n    (is (= 1 (count nilmap)))\n    (is (= 1 (count (dissoc nilmap :a))))\n    (is (= 2 (count (assoc nilmap :a :b))))\n    (is (= 0 (count (dissoc nilmap nil))))\n    (is (= #{nil :a} (set (keys (assoc nilmap :a :b)))))))\n\n\n(defonce test-data* (atom {}))\n\n\n(deftest random-assoc-dissoc\n  (let [n-elems 100\n        n-take (quot n-elems 10)\n        n-left (- n-elems n-take)\n        data (shuffle (range n-elems))\n        dissoc-vals (take n-take data)\n        data (set data)\n        dissoc-data (set/difference data (set dissoc-vals))]\n    (reset! test-data* {:data data\n                        :dissoc-vals dissoc-vals\n                        :dissoc-data dissoc-data})\n    (testing \"immutable\"\n      (let [alldata (reduce #(assoc %1 %2 %2)\n                            orig\n                            data)\n            disdata (reduce #(dissoc %1 %2) alldata dissoc-vals)]\n        (is (= n-left (count disdata)))\n        (is (= n-elems (count alldata)))\n        (is (= dissoc-data (set (keys disdata))))\n        (is (= data (set (keys alldata))))))\n    (testing \"hash table mutable\"\n      (let [alldata (api/mut-map (map #(vector % %)) data)\n            disdata (.clone alldata)\n            _ (is (= n-elems (count disdata)))\n            _ (reduce #(do (.remove ^Map %1 %2) %1) disdata dissoc-vals)]\n        (is (= n-left (count disdata)))\n        (is (= n-elems (count alldata)))\n        (is (= dissoc-data (set (keys disdata))))\n        (is (= data (set (keys alldata))))))\n    (testing \"long hash table mutable\"\n      (let [alldata (api/mut-long-map (map #(vector % %)) data)\n            disdata (.clone alldata)\n            _ (is (= n-elems (count disdata)))\n            _ (reduce #(do (.remove ^Map %1 %2) %1) disdata dissoc-vals)]\n        (is (= n-left (count disdata)))\n        (is (= n-elems (count alldata)))\n        (is (= dissoc-data (set (keys disdata))))\n        (is (= data (set (keys alldata))))))))\n\n\n\n(def map-constructors\n  {:mut-map api/mut-map\n   :immut-map api/immut-map\n   :java-hashmap api/java-hashmap})\n\n\n(deftest hash-map-reduce\n  (doseq [[k constructor] map-constructors]\n    (is (= 2 (reduce (fn [^long acc v]\n                       (if (> acc 0)\n                         (reduced (inc acc))\n                         (inc acc)))\n                     0\n                     (constructor {:a 1 :b 2 :c 3}))))))\n\n\n\n(defmacro benchmark-us\n  [op]\n  `(let [bdata# (crit/quick-benchmark ~op nil)]\n     {:mean-μs (* (double (first (:mean bdata#))) 1e6)\n      :variance-μs (* (double (first (:variance bdata#))) 1e6)}))\n\n\n(defn ->collection\n  ^Collection [data]\n  (if (instance? Collection data)\n    data\n    (seq data)))\n\n\n(defn ->array-list\n  ^ArrayList [data]\n  (if (instance? ArrayList data)\n    data\n    (let [retval (ArrayList.)]\n      (.addAll retval (->collection data))\n      retval)))\n\n\n(defn time-dataset\n  [data constructor]\n  (let [dlist (api/shuffle (api/object-array-list data))\n        ctime (benchmark-us (constructor dlist))\n        ^Map ds (constructor dlist)\n        nelems (count dlist)\n        atime (benchmark-us\n               (reduce (fn [acc v] (.get ds v)) nil data))\n        itime (benchmark-us\n               (reduce #(+ (long %1) (val %2)) 0 ds))]\n    {:construct-μs (:mean-μs ctime)\n     :access-μs (:mean-μs atime)\n     :iterate-μs (:mean-μs itime)}))\n\n\n(defn java-hashmap\n  [data]\n  (reduce (hamf-rf/indexed-accum\n           hm idx v (.put ^Map hm v idx) hm)\n          (api/java-hashmap (count data))\n          data))\n\n\n(defn hamf-hashmap\n  [data]\n  (persistent! (reduce (hamf-rf/indexed-accum\n                        hm idx v (.put ^Map hm v idx) hm)\n                       (api/mut-hashtable-map (count data))\n                       data)))\n\n\n\n(defn clj-transient\n  [data]\n  (persistent! (reduce (hamf-rf/indexed-accum\n                        hm idx v (assoc! hm v idx))\n                       (transient {})\n                       data)))\n\n\n(defn hamf-transient\n  [data]\n  (persistent! (reduce (hamf-rf/indexed-accum\n                        hm idx v (assoc! hm v idx))\n                       (transient api/empty-map)\n                       data)))\n\n\n(def datastructures\n  [[:java-hashmap java-hashmap]\n   [:hamf-hashmap hamf-hashmap]\n   [:clj-transient clj-transient]\n   [:hamf-transient hamf-transient]])\n\n\n\n(defn profile-datastructures\n  [data]\n  (->> (shuffle datastructures)\n       (map (fn [[ds-name ctor]]\n              (-> (time-dataset data ctor)\n                  (assoc :ds-name ds-name))))\n       (sort-by :construct-μs)))\n\n\n(defn- indexed-map\n  ^PersistentHashMap [data]\n  (persistent! (api/mut-map (map-indexed #(vector %2 %1) data))))\n\n\n(deftest union-test\n  (let [n-elems 100\n        hn-elems (quot n-elems 2)\n        src-data (take n-elems (distinct (repeatedly #(rand-int 1000000))))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        hm1 (indexed-map lhs)\n        bfn (reify BiFunction (apply [this a b] (+ a b)))\n        hm2 (indexed-map rhs)\n        un1 (.union hm1 hm2 bfn)\n        un2 (.union un1 hm2 bfn)\n        single-sum (reduce + (range hn-elems))]\n    (is (= (count un1) n-elems))\n    (is (= (set src-data) (set (keys un1))),\n        (str (set/difference (set src-data) (set (keys un1)))\n             (set/difference (set (keys un1)) (set src-data))))\n    (is (= (count un2) n-elems))\n    (is (= (* 2 single-sum) (reduce + (vals un1))))\n    (is (= (* 3 single-sum) (reduce + (vals un2))))))\n\n\n(deftest difference-test\n  (let [n-elems 100\n        hn-elems (quot n-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        llhs (->array-list (take (quot hn-elems 2) src-data))\n        hm1 (indexed-map lhs)\n        hm2 (indexed-map rhs)\n        df1 (.difference hm1 hm2)\n        df2 (.difference hm1 (indexed-map llhs))]\n    (is (= hn-elems (count df1)))\n    (is (= (quot hn-elems 2) (count df2)))\n    (is (= (set/difference (set lhs) (set llhs)) (set (keys df2))))))\n\n\n(deftest intersection-test\n  (let [n-elems 100\n        hn-elems (quot n-elems 2)\n        hhn-elems (quot hn-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        llhs (->array-list (take hhn-elems src-data))\n        bfn (reify BiFunction (apply [this a b] (+ a b)))\n        hm1 (indexed-map lhs)\n        hhm1 (indexed-map llhs)\n        hm2 (indexed-map rhs)\n        df1 (.intersection hm1 hm2 bfn)\n        df2 (.intersection hm1 hhm1 bfn)\n        hhn-sum (reduce + (range hhn-elems))]\n    (is (= 0 (count df1)))\n    (is (= (quot hn-elems 2) (count df2)))\n    (is (= (set/intersection (set lhs) (set llhs)) (set (keys df2))))\n    (is (= (* 2 hhn-sum) (reduce + (vals df2))))))\n\n\n(defn- long-indexed-map\n  ^PersistentLongHashMap [data]\n  (persistent! (api/mut-long-hashtable-map (map-indexed #(vector %2 %1) data))))\n\n\n(deftest long-union-test\n  (let [n-elems 100\n        hn-elems (quot n-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        hm1 (long-indexed-map lhs)\n        bfn (reify BiFunction (apply [this a b] (+ a b)))\n        hm2 (long-indexed-map rhs)\n        un1 (.union hm1 hm2 bfn)\n        un2 (.union un1 hm2 bfn)\n        single-sum (reduce + (range hn-elems))]\n    (is (= (count un1) n-elems))\n    (is (= (set src-data) (set (keys un1))))\n    (is (= (count un2) n-elems))\n    (is (= (* 2 single-sum) (reduce + (vals un1))))\n    (is (= (* 3 single-sum) (reduce + (vals un2))))))\n\n\n(deftest long-difference-test\n  (let [n-elems 100\n        hn-elems (quot n-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        llhs (->array-list (take (quot hn-elems 2) src-data))\n        hm1 (long-indexed-map lhs)\n        hm2 (long-indexed-map rhs)\n        df1 (.difference hm1 hm2)\n        df2 (.difference hm1 (long-indexed-map llhs))]\n    (is (= hn-elems (count df1)))\n    (is (= (quot hn-elems 2) (count df2)))\n    (is (= (set/difference (set lhs) (set llhs)) (set (keys df2))))))\n\n\n(deftest long-intersection-test\n  (let [n-elems 100\n        hn-elems (quot n-elems 2)\n        hhn-elems (quot hn-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        llhs (->array-list (take hhn-elems src-data))\n        bfn (reify BiFunction (apply [this a b] (+ a b)))\n        hm1 (long-indexed-map lhs)\n        hhm1 (long-indexed-map llhs)\n        hm2 (long-indexed-map rhs)\n        df1 (.intersection hm1 hm2 bfn)\n        df2 (.intersection hm1 hhm1 bfn)\n        hhn-sum (reduce + (range hhn-elems))]\n    (is (= 0 (count df1)))\n    (is (= (quot hn-elems 2) (count df2)))\n    (is (= (set/intersection (set lhs) (set llhs)) (set (keys df2))))\n    (is (= (* 2 hhn-sum) (reduce + (vals df2))))))\n\n\n(def union-data\n  {:java-hashmap {:construct-fn java-hashmap\n                  :merge-fn api/map-union-java-hashmap\n                  :reduce-fn api/union-reduce-java-hashmap}\n   ;;jdk-8 - 1000\n   ;; {:union-disj-μs 20.413211065573773,\n   ;;  :union-μs 41.34100116886689,\n   ;;  :name :java-hashmap}\n   ;; 100000\n   ;; {:union-disj-μs 5050.580285714286,\n   ;;  :union-μs 8292.417935897436,\n   ;;  :name :java-hashmap}\n   :hamf-hashmap {:construct-fn hamf-hashmap\n                  :merge-fn api/map-union\n                  :reduce-fn #(api/union-reduce-maps %1 %2)}\n\n   :clj-transient (let [make-merge-fn (fn [bifn]\n                                        (fn [lhs rhs]\n                                          (.apply ^BiFunction bifn lhs rhs)))]\n                    {:construct-fn clj-transient\n                     :merge-fn #(merge-with (make-merge-fn %1) %2 %3)\n                     :reduce-fn #(apply merge-with (make-merge-fn %1) %2)})})\n;;jdk-8 - 1000\n;; {:union-disj-μs 11.491328581829329,\n;;  :union-μs 30.876507346896837,\n;;  :name :hamf-hashmap}\n;; 100000\n;; {:union-disj-μs 2461.248479674797,\n;;  :union-μs 5106.405916666667,\n;;  :name :hamf-hashmap}\n\n\n\n(defn benchmark-union\n  [^long n-elems mapname]\n  (let [{:keys [construct-fn merge-fn]} (union-data mapname)\n        hn-elems (quot n-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        bfn (hamf-fn/->bi-function +)\n        lhs-m (construct-fn lhs)\n        rhs-m (construct-fn rhs)\n        merged-m (merge-fn bfn lhs-m rhs-m)]\n    {:union-disj-μs (:mean-μs (benchmark-us (merge-fn bfn lhs-m rhs-m)))\n     :union-μs (:mean-μs (benchmark-us (merge-fn bfn lhs-m merged-m)))\n     :name mapname}))\n\n\n(defn benchmark-reduce-union\n  [^long n-elems mapname]\n  (let [{:keys [construct-fn reduce-fn]} (union-data mapname)\n        hn-elems (quot n-elems 2)\n        src-data (repeatedly n-elems #(rand-int 100000000))\n        lhs (->array-list (take hn-elems src-data))\n        rhs (->array-list (drop hn-elems src-data))\n        bfn (reify BiFunction\n              (apply [this a b]\n                (unchecked-add (unchecked-long a)\n                               (unchecked-long b))))\n        lhs-m (construct-fn lhs)\n        rhs-m (construct-fn rhs)\n        map-seq (vec (interleave (repeat 10 lhs-m) (repeat 10 rhs-m)))]\n    {:union-μs (:mean-μs (benchmark-us (reduce-fn bfn map-seq)))\n     :name mapname}))\n\n\n\n(deftest hashcode-equal-hashmap\n  (is (= (.hasheq (api/mut-map [[:a 1] [:b 2]])) (.hasheq {:a 1 :b 2})))\n  (is (= (.hasheq (api/mut-map [[:a 1] [:b 2] [nil 3]])) (.hasheq {:a 1 :b 2 nil 3})))\n  (is (= (.hasheq (api/mut-map [[:a 1] [:b 2]])) (.hasheq (api/immut-map {:a 1 :b 2}))))\n  (is (not= (.hasheq (api/mut-map [[:a 1] [:b 3]])) (.hasheq {:a 1 :b 2})))\n  (is (.equals (api/immut-map [[:a 1] [:b 2]]) {:a 1 :b 2}))\n  (is (.equals (api/immut-map [[:a 1] [:b 2]]) (api/mut-map [[:a 1] [:b 2]])))\n  (is (not (.equals (api/immut-map [[:a 1] [:b 2]]) nil)))\n  (is (= (.hasheq (api/mut-set [:a :b])) (.hasheq #{:a :b})))\n  (is (not= (.hasheq (api/mut-set [:a :b :c])) (.hasheq #{:a :b})))\n  (is (.equals (api/immut-set [:a :b :c]) #{:a :b :c}))\n  (is (.equals (api/immut-set [:a :b :c]) (api/mut-set #{:a :b :c})))\n  (is (not (.equals (api/immut-set [:a :b :c]) nil))))\n\n\n\n;;Standard tests\n\n(defn- pers-map\n  [map-data]\n  (api/immut-map map-data))\n\n(defn- ary-map\n  [map-data]\n  (api/immut-map (api/object-array (flatten (seq map-data)))))\n\n(defn test-find-fn\n  [map-fn]\n  (are [x y] (= x y)\n    (find (map-fn {}) :a) nil\n\n    (find (map-fn {:a 1}) :a) [:a 1]\n    (find (map-fn {:a 1}) :b) nil\n    (find (map-fn {nil 1}) nil) [nil 1]\n\n    (find (map-fn {:a 1 :b 2}) :a) [:a 1]\n    (find (map-fn {:a 1 :b 2}) :b) [:b 2]\n    (find (map-fn {:a 1 :b 2}) :c) nil\n\n    (find (map-fn {}) nil) nil\n    (find (map-fn {:a 1}) nil) nil\n    (find (map-fn {:a 1 :b 2}) nil) nil))\n\n\n\n(deftest test-find-ary-map\n  (test-find-fn ary-map))\n\n(deftest test-find-pers-map\n  (test-find-fn pers-map))\n\n(defn test-contains?\n  [map-fn]\n  (are [x y] (= x y)\n    (contains? (map-fn {}) :a) false\n    (contains? (map-fn {}) nil) false\n\n    (contains? (map-fn {:a 1}) :a) true\n    (contains? (map-fn {:a 1}) :b) false\n    (contains? (map-fn {:a 1}) nil) false\n    (contains? (map-fn {nil 1}) nil) true\n\n    (contains? (map-fn {:a 1 :b 2}) :a) true\n    (contains? (map-fn {:a 1 :b 2}) :b) true\n    (contains? (map-fn {:a 1 :b 2}) :c) false\n    (contains? (map-fn {:a 1 :b 2}) nil) false))\n\n\n(deftest test-ary-map-contains? (test-contains? ary-map))\n\n(deftest test-pers-map-contains? (test-contains? pers-map))\n\n\n(defn diff [s1 s2]\n  (seq (reduce disj (set s1) (set s2))))\n\n\n(defn test-keys\n  [map-fn]\n  (are [x y] (= x y)\n\n    (keys (map-fn {})) nil\n    (keys (map-fn {:a 1})) '(:a)\n    (keys (map-fn {nil 1})) '(nil)\n    (diff (keys (map-fn {:a 1 :b 2})) '(:a :b)) nil\n    (keys (api/hash-map)) nil\n    (keys (api/hash-map :a 1)) '(:a)\n    (diff (keys (api/hash-map :a 1 :b 2)) '(:a :b)) nil)\n\n  (let [m (map-fn {:a 1 :b 2})\n        k (keys m)]\n    (is (= {:hi :there} (meta (with-meta k {:hi :there}))))))\n\n\n(deftest test-ary-map-keys (test-keys ary-map))\n(deftest test-pers-map-keys (test-keys pers-map))\n\n\n(defn test-vals\n  [map-fn]\n  (are [x y] (= x y)\n    (vals (map-fn {})) nil\n    (vals (map-fn {:a 1})) '(1)\n    (vals (map-fn {nil 1})) '(1)\n    (diff (vals (map-fn {:a 1 :b 2})) '(1 2)) nil              ; (vals {:a 1 :b 2}) '(1 2)\n\n    (vals (api/hash-map)) nil\n    (vals (api/hash-map :a 1)) '(1)\n    (diff (vals (api/hash-map :a 1 :b 2)) '(1 2)) nil)   ; (vals (hash-map :a 1 :b 2)) '(1 2)\n\n  (let [m (map-fn {:a 1 :b 2})\n        v (vals m)]\n    (is (= {:hi :there} (meta (with-meta v {:hi :there}))))))\n\n\n(deftest test-ary-map-vals (test-vals ary-map))\n(deftest test-pers-map-vals (test-vals pers-map))\n\n\n(deftest basic-linked-hashmap\n  (is (= [:a :b :c] (vec (keys (api/linked-hashmap [[:a 1][:b 2][:c 3]])))))\n  (is (not= [:a :b :c] (vec (keys (api/mut-map [[:a 1][:b 2][:c 3]])))))\n  (is (= [:a :b :c :d :e]\n         (vec (keys (.union (api/linked-hashmap [[:a 1][:b 2][:c 3]])\n                            (api/linked-hashmap [[:d 4] [:e 5]])\n                            (hamf-fn/bi-function v1 v2 inc))))))\n  (is (= [:a :b :c :d]\n         (vec (keys (.union (api/linked-hashmap [[:a (api/long-array-list [1 2])][:b (api/long-array-list [3 4])]\n                                                 [:c (api/long-array-list [4 5])]])\n                            (api/linked-hashmap [[:a (api/long-array-list [4 5])]\n                                                 [:d (api/long-array-list [6 7])]])\n                            (hamf-fn/bi-function v1 v2 (.addAll ^java.util.List v1 v2) v1))))))\n  (is (= (.get (api/linked-hashmap [[(int 1) :a]]) 1) :a)))\n\n\n\n(comment\n\n  (do\n    (def hm (HashMap.))\n    (def orig PersistentHashMap/EMPTY))\n\n\n  (dotimes [idx 100]\n    (.put hm idx idx))\n\n  (map iterator-seq (.splitKeys hm 8))\n\n  (dotimes [idx 10000]\n    (.put hm idx idx))\n\n  (crit/quick-bench (let [hm (HashMap.)]\n                      (dotimes [idx 2]\n                        (.put hm idx idx))))\n  ;;34ns\n  ;;jdk-17 - 24ns\n  (crit/quick-bench (let [hm (HashMap.)]\n                      (dotimes [idx 2]\n                        (.put hm idx idx))\n                      (dotimes [idx 2]\n                        (.get hm idx))))\n\n  (crit/quick-bench (let [hm (HashMap. PersistentHashMap/equivHashProvider)]\n                      (dotimes [idx 2]\n                        (.put hm idx idx))))\n  ;;70ns - twice as fast as clojure's transient for small case.  hasheq is the long\n  ;;poll in the tent.\n  ;;jdk-17 - 61ns\n\n  (crit/quick-bench (let [hm (HashMap. PersistentHashMap/equivHashProvider)]\n                      (dotimes [idx 2]\n                        (.put hm idx idx))\n                      (dotimes [idx 2]\n                        (.get hm idx))))\n\n  (crit/quick-bench (let [hm (java.util.HashMap.)]\n                      (dotimes [idx 2]\n                        (.put hm idx idx))))\n  ;;36ns\n  ;;jdk-17 31ns\n\n  (crit/quick-bench (loop [idx 0\n                           hm (transient {})]\n                      (if (< idx 2)\n                        (recur (unchecked-inc idx)\n                               (assoc! hm idx idx))\n                        (persistent! hm))))\n  ;;113ns\n  ;;jdk-17 - 136ns\n\n  (crit/quick-bench\n   (let [phm (loop [idx 0\n                    hm (transient {})]\n               (if (< idx 2)\n                 (recur (unchecked-inc idx)\n                        (assoc! hm idx idx))\n                 (persistent! hm)))]\n     (loop [idx 0]\n       (when (< idx 2)\n         (get phm idx)\n         (recur (unchecked-inc idx))))))\n\n  (crit/quick-bench (loop [idx 0\n                           hm (transient PersistentHashMap/EMPTY)]\n                      (if (< idx 2)\n                        (recur (unchecked-inc idx)\n                               (assoc! hm idx idx))\n                        (persistent! hm))))\n  ;;147ns - arrayhashmap is faster for this case but still a lot slower than\n  ;;using hashmap representation.\n  ;;jdk-17 - 137ns\n\n  (crit/quick-bench (persistent! (transient PersistentHashMap/EMPTY)))\n\n\n\n  (crit/quick-bench (let [hm (HashMap.)]\n                      (dotimes [idx 1000]\n                        (.put hm idx idx))))\n  ;;21us\n  ;;jdk-17 - 21us\n  (crit/quick-bench (let [hm (HashMap.)]\n                      (dotimes [idx 1000]\n                        (.put hm idx idx))\n                      (dotimes [idx 1000]\n                        (.get hm idx))))\n  ;;35us\n\n  (crit/quick-bench (let [hm (HashMap. PersistentHashMap/equivHashProvider)]\n                      (dotimes [idx 1000]\n                        (.put hm idx idx))))\n  ;;41us\n  ;;jdk-17 - 39us\n\n  (crit/quick-bench (let [hm (HashMap. PersistentHashMap/equivHashProvider)]\n                      (dotimes [idx 1000]\n                        (.put hm idx idx))\n                      (dotimes [idx 1000]\n                        (.get hm idx))))\n  ;; 75us\n\n  (crit/quick-bench (let [hm (java.util.HashMap.)]\n                      (dotimes [idx 1000]\n                        (.put hm idx idx))))\n  ;;17us\n  ;;jdk-17 - 21us\n  (crit/quick-bench (let [hm (java.util.HashMap.)]\n                      (dotimes [idx 1000]\n                        (.put hm idx idx))\n                      (dotimes [idx 1000]\n                        (.get hm idx))))\n  ;;20us\n\n  (crit/quick-bench (loop [idx 0\n                           hm (transient {})]\n                      (if (< idx 1000)\n                        (recur (unchecked-inc idx)\n                               (assoc! hm idx idx))\n                        (persistent! hm))))\n  ;;112us\n  ;;123us\n  (crit/quick-bench\n   (let [phm (loop [idx 0\n                    hm (transient {})]\n               (if (< idx 1000)\n                 (recur (unchecked-inc idx)\n                        (assoc! hm idx idx))\n                 (persistent! hm)))]\n     (loop [idx 0]\n       (when (< idx 1000)\n         (get phm idx)\n         (recur (unchecked-inc idx))))))\n  ;;168us\n\n  (crit/quick-bench (loop [idx 0\n                           hm (transient PersistentHashMap/EMPTY)]\n                      (if (< idx 1000)\n                        (recur (unchecked-inc idx)\n                               (assoc! hm idx idx))\n                        (persistent! hm))))\n  ;;47us\n  ;;jdk-17 50us\n\n  (crit/quick-bench\n   (let [phm (loop [idx 0\n                    hm (transient PersistentHashMap/EMPTY)]\n               (if (< idx 1000)\n                 (recur (unchecked-inc idx)\n                        (assoc! hm idx idx))\n                 (persistent! hm)))]\n     (loop [idx 0]\n       (when (< idx 1000)\n         (get phm idx)\n         (recur (unchecked-inc idx))))))\n  ;; 83us\n\n  ;;Useful to profile small things sometimes.\n  (dotimes [idx 100000000]\n    (loop [idx 0\n           hm (transient {})]\n      (if (< idx 20)\n        (recur (unchecked-inc idx)\n               (assoc! hm idx idx))\n        (persistent! hm))))\n\n\n  (def hm (let [hm (HashMap.)\n                _ (dotimes [idx 60]\n                    (.put hm idx idx))]\n            hm))\n  (let [nhm (HashBase.)]\n    (.keyspaceSplit hm 146 291 false nhm)\n    (.printNodes nhm))\n\n  (let [hm (HashMap.)\n        _ (dotimes [idx 60]\n            (.put hm idx idx))]\n    (map iterator-seq (.splitKeys hm 7)))\n\n  (def small-int-profile (profile-datastructures (repeatedly 2 #(rand-int 100000))))\n  ;;jdk-8\n  ;;({:construct-μs 0.04298386356008815,\n  ;;  :access-μs 0.040345482495456206,\n  ;;  :iterate-μs 0.05087595836156305,\n  ;;  :ds-name :hamf-hashmap}\n  ;; {:construct-μs 0.044846695459721565,\n  ;;  :access-μs 0.02446975706544951,\n  ;;  :iterate-μs 0.04827733417909167,\n  ;;  :ds-name :java-hashmap}\n  ;; {:construct-μs 0.10289826952319454,\n  ;;  :access-μs 0.08631483123589048,\n  ;;  :iterate-μs 0.05130890786182448,\n  ;;  :ds-name :hamf-equiv-hashmap}\n  ;; {:construct-μs 0.14209144548280342,\n  ;;  :access-μs 0.08244324142027323,\n  ;;  :iterate-μs 0.04715165522789527,\n  ;;  :ds-name :clj-transient}\n  ;; {:construct-μs 0.16351660268608148,\n  ;;  :access-μs 0.09678529907937389,\n  ;;  :iterate-μs 0.05798288225070914,\n  ;;  :ds-name :hamf-transient})\n\n  (def int-profile (profile-datastructures (repeatedly 1000 #(rand-int 100000))))\n  ;; jdk-8\n  ;; ({:construct-μs 23.099907694058732,\n  ;;   :access-μs 11.601162415160529,\n  ;;   :iterate-μs 8.334938366460666,\n  ;;   :ds-name :java-hashmap}\n  ;;  {:construct-μs 34.1529201495073,\n  ;;   :access-μs 12.681086848216172,\n  ;;   :iterate-μs 14.304917063893303,\n  ;;   :ds-name :hamf-hashmap}\n  ;;  {:construct-μs 63.69087151015229,\n  ;;   :access-μs 48.95698405726371,\n  ;;   :iterate-μs 17.277700236284005,\n  ;;   :ds-name :hamf-equiv-hashmap}\n  ;;  {:construct-μs 66.86508244206775,\n  ;;   :access-μs 50.38417851142474,\n  ;;   :iterate-μs 21.130427287409592,\n  ;;   :ds-name :hamf-transient}\n  ;;  {:construct-μs 110.31809377289377,\n  ;;   :access-μs 44.23049499782514,\n  ;;   :iterate-μs 35.53727620563613,\n  ;;   :ds-name :clj-transient})\n  ;; jdk-17\n  ;; ({:construct-μs 31.915435858163935,\n  ;;   :access-μs 12.193707814495532,\n  ;;   :iterate-μs 7.316710778209167,\n  ;;   :ds-name :java-hashmap}\n  ;;  {:construct-μs 45.07551537356322,\n  ;;   :access-μs 21.033255470685386,\n  ;;   :iterate-μs 22.979641088509506,\n  ;;   :ds-name :hamf-hashmap}\n  ;;  {:construct-μs 73.53580794223828,\n  ;;   :access-μs 49.47928398962892,\n  ;;   :iterate-μs 22.8927910698984,\n  ;;   :ds-name :hamf-equiv-hashmap}\n  ;;  {:construct-μs 77.98202366716494,\n  ;;   :access-μs 52.42915830218901,\n  ;;   :iterate-μs 20.852072754333744,\n  ;;   :ds-name :hamf-transient}\n  ;;  {:construct-μs 134.15703174603175,\n  ;;   :access-μs 47.73247937254903,\n  ;;   :iterate-μs 37.22873836295491,\n  ;;   :ds-name :clj-transient})\n\n  (def big-int-profile (profile-datastructures (repeatedly 100000 #(rand-int 100000))))\n  ;;jdk-8\n  ;; ({:construct-μs 4818.585603174603,\n  ;;   :access-μs 3115.862890625,\n  ;;   :iterate-μs 903.9770223214286,\n  ;;   :ds-name :java-hashmap}\n  ;;  {:construct-μs 8781.270125000001,\n  ;;   :access-μs 8000.021961538461,\n  ;;   :iterate-μs 1914.1505256410255,\n  ;;   :ds-name :hamf-hashmap}\n  ;;  {:construct-μs 12504.3571875,\n  ;;   :access-μs 11433.55188888889,\n  ;;   :iterate-μs 2047.054111111111,\n  ;;   :ds-name :hamf-equiv-hashmap}\n  ;;  {:construct-μs 12913.919562500001,\n  ;;   :access-μs 12543.427979166667,\n  ;;   :iterate-μs 2056.0890714285715,\n  ;;   :ds-name :hamf-transient}\n  ;;  {:construct-μs 13137.229833333335,\n  ;;   :access-μs 10124.450916666668,\n  ;;   :iterate-μs 3152.3616718750004,\n  ;;   :ds-name :clj-transient})\n\n  (def double-profile (profile-datastructures (repeatedly 1000 #(rand 100000))))\n  (def str-profile (profile-datastructures (map str (repeatedly 1000 #(rand-int 100000)))))\n  ;;jdk-8\n  ;;({:construct-μs 23.930453143122246,\n  ;;  :access-μs 13.627138225718937,\n  ;;  :ds-name :java-hashmap}\n  ;; {:construct-μs 43.07852368684701,\n  ;;  :access-μs 32.3816567357513,\n  ;;  :ds-name :hamf-hashmap}\n  ;; {:construct-μs 68.1719815066939,\n  ;;  :access-μs 58.411238927738935,\n  ;;  :ds-name :hamf-equiv-hashmap}\n  ;; {:construct-μs 73.45427547307133,\n  ;;  :access-μs 66.72418882978724,\n  ;;  :ds-name :hamf-transient}\n  ;; {:construct-μs 128.5458824027073,\n  ;;  :access-μs 53.36163036127426,\n  ;;  :ds-name :clj-transient})\n  (def kw-profile (profile-datastructures (map (comp keyword str)\n                                               (repeatedly 1000 #(rand-int 100000)))))\n  ;;jdk-8\n  ;; ({:construct-μs 37.88887029341394,\n  ;;   :access-μs 18.842061234058516,\n  ;;   :iterate-μs 12.900347590258127,\n  ;;   :ds-name :java-hashmap}\n  ;;  {:construct-μs 40.78816281271129,\n  ;;   :access-μs 31.311148279404215,\n  ;;   :iterate-μs 26.028699949122363,\n  ;;   :ds-name :hamf-equiv-hashmap}\n  ;;  {:construct-μs 44.76396859578287,\n  ;;   :access-μs 37.260138704523115,\n  ;;   :iterate-μs 25.54532113194623,\n  ;;   :ds-name :hamf-transient}\n  ;;  {:construct-μs 48.99040834149526,\n  ;;   :access-μs 36.94391981651376,\n  ;;   :iterate-μs 26.269819758868937,\n  ;;   :ds-name :hamf-hashmap}\n  ;;  {:construct-μs 98.01407147466925,\n  ;;   :access-μs 33.85242917783735,\n  ;;   :iterate-μs 37.85340298225746,\n  ;;   :ds-name :clj-transient})\n\n\n\n  ;; joinr test\n  (def db {:name {\"bilbo\" \"baggins\"}\n           :age  {\"bilbo\" 111}\n           :location {\"bilbo\" \"Shire\"}})\n\n  (defn mutable2d [m]\n    (let [hm (api/mut-hashtable-map nil m)]\n      (reduce-kv (fn [acc k v]\n                   (assoc! acc k (api/mut-hashtable-map))) hm hm)))\n\n  (defn eq-mutable2d [m]\n    (let [hm (api/mut-hashtable-map nil m)]\n      (reduce-kv (fn [acc k v]\n                   (assoc! acc k (api/mut-hashtable-map nil {:hash-provider api/equal-hash-provider} v))) hm hm)))\n\n  (def mdb (mutable2d db))\n\n  (def eq-mdb (eq-mutable2d db))\n\n  (def hdb (reduce-kv (fn [^java.util.Map acc k v]\n                        (doto acc\n                          (.put k\n                                (reduce-kv (fn [^java.util.Map inner k v]\n                                             (doto inner (.put k v))) (java.util.HashMap.) v)) (java.util.HashMap.)))\n                      (java.util.HashMap.) db))\n\n  (let [inner (.get mdb :name)]\n    (crit/quick-bench (.get ^Map inner \"bilbo\")))\n\n  (let [inner (.get hdb :name)]\n    (crit/quick-bench (.get ^Map inner \"bilbo\")))\n\n  (let [inner (.get db :name)]\n    (crit/quick-bench (.get ^Map inner \"bilbo\")))\n\n  (let [inner (.get eq-mdb :name)]\n    (println (type inner))\n    (crit/quick-bench (.get ^Map inner \"bilbo\")))\n\n  (do\n    (def ht (ham_fisted.HashTable. api/equal-hash-provider))\n    (.put ht \"bilbo\" \"baggins\"))\n\n  (crit/quick-bench (.get ^ham_fisted.HashTable ht \"bilbo\")))\n"
  },
  {
    "path": "test/ham_fisted/hlet_test.clj",
    "content": "(ns ham-fisted.hlet-test\n  (:require [ham-fisted.api :as hamf]\n            [ham-fisted.primitive-invoke :as pi]\n            [ham-fisted.hlet :as h]\n            [clojure.test :refer [deftest is]]))\n\n\n(set! *unchecked-math* :warn-on-boxed)\n\n\n\n(deftest basic-hlet\n  (h/let [[x y] (dbls (if true\n                        (hamf/double-array [1 2])\n                        (hamf/double-array [3 4])))\n          look-fn (pi/->ddd (fn ^double [^double a ^double b] (+ a b)))\n          ;;test singular case\n          sx (dbls (rand-int 100))]\n    (is (= 3.0 (pi/ddd look-fn x y)))))\n\n\n(comment\n  (require '[clj-java-decompiler.core :refer [disassemble]])\n\n  (disassemble (h/let [[x y] (dbls (if true\n                                     (hamf/double-array [1 2])\n                                     (hamf/double-array [3 4])))\n                       look-fn (pi/->ddd (fn ^double [^double a ^double b] (+ a b)))]\n                 (look-fn x y)\n                 (pi/ddd look-fn x y)))\n\n  )\n"
  },
  {
    "path": "test/ham_fisted/parallel_test.clj",
    "content": "(ns ham-fisted.parallel-test\n  (:require [ham-fisted.api :as api]\n            [ham-fisted.reduce :as hamf-rf]\n            [ham-fisted.mut-map :as hamf-map]\n            [ham-fisted.lazy-noncaching :as lznc]\n            [clojure.test :refer [deftest is]])\n  (:import [ham_fisted Sum]))\n\n\n(deftest spliterator-preduce\n  (let [data (api/immut-map (lznc/map #(api/vector % %) (range 10000)))\n        sum-data (fn [opts m]\n                   (-> (hamf-rf/preduce #(Sum.) hamf-rf/double-consumer-accumulator\n                                        (fn [^Sum l ^Sum r] (.merge l r) l)\n                                        opts\n                                        m)\n                       (deref)\n                       :sum\n                       (long)))\n        opts {:min-n 5 :ordered? true}]\n    (is (= 49995000 (sum-data opts (api/keys data))))\n    (is (= 49995000 (sum-data opts (api/vals data))))\n    (is (= 49995000 (sum-data (assoc opts :ordered? false) (api/keys data))))\n    (is (= 49995000 (sum-data (assoc opts :ordered? false) (api/vals data))))\n    (is (= 49995000 (sum-data (assoc opts :ordered? false) (hamf-map/keyset data))))\n    (is (= 49995000 (sum-data (assoc opts :ordered? false) (hamf-map/values data))))\n    (let [small (api/immut-map (lznc/map #(api/vector % %) (range 8)))]\n      (is (= 28 (sum-data opts (api/keys small))))\n      (is (= 28 (sum-data opts (api/vals small)))))))\n\n\n\n;;There was an issue with small upmaps hanging\n(deftest small-upmap\n  (is (= (api/range 5)\n         (api/sort (api/upmap #(+ % 1) (range -1 4))))))\n\n(deftest small-pmap\n  (is (= (api/range 10)\n         (api/pmap #(+ % 1) (range -1 9)))))\n\n(deftest small-pmap-io\n  (is (= [] (api/pmap-io 16 identity []))))\n\n;;This caused a hang before wrapping queue io with boxes.\n(deftest upmap-nil-return\n  (is (every? nil? (api/upgroups 10000\n                                 (fn [^long sidx ^long eidx]\n                                   nil)))))\n\n(deftest custom-pmap-pool\n  (let [p (java.util.concurrent.Executors/newCachedThreadPool)]\n    (is (= 5050.0 (api/sum (api/pmap-opts {:n-lookahead 2 :pool p :min-n 0} #(do #_(println (.getName (Thread/currentThread))) (+ % 1)) (range 100)))))))\n"
  },
  {
    "path": "test/ham_fisted/persistent_vector_test.clj",
    "content": "(ns ham-fisted.persistent-vector-test\n  (:require [clojure.test :refer [deftest is testing are] :as test]\n            [clj-memory-meter.core :as mm]\n            [ham-fisted.api :as hamf]\n            [ham-fisted.lazy-noncaching :as lznc])\n  (:import [ham_fisted MutList ImmutList MutTreeList TreeList]\n           [java.util List ArrayList Collections]))\n\n\n(deftest vec-nil\n  (is (= (clojure.core/vec nil) (hamf/vec nil))))\n\n\n(def vec-fns\n  {:api-vec {:convert-fn identity :vec-fn hamf/vec}\n   :api-vec-sublist {:convert-fn identity\n                     :vec-fn (fn\n                               ([]\n                                (hamf/subvec (hamf/vec [1 2 4]) 3))\n                               ([data]\n                                (hamf/subvec (hamf/vec (lznc/concat [1 2 4] data)) 3)))}\n   :immut-vec {:convert-fn identity :vec-fn (comp persistent! hamf/mut-list)}\n   :immut-vec-sublist {:convert-fn identity\n                       :vec-fn (fn\n                                 ([]\n                                  (hamf/subvec (persistent!\n                                                (hamf/mut-list (range 100)))\n                                               100))\n                                 ([data]\n                                  (hamf/subvec (persistent!\n                                                (hamf/mut-list\n                                                 (lznc/concat (range 100) data)))\n                                               100)))}\n   :api-mut-list  {:convert-fn identity :vec-fn hamf/mut-list}\n   :api-mut-sublist  {:convert-fn identity\n                      :vec-fn (fn\n                                ([]\n                                 (hamf/subvec\n                                  (hamf/mut-list\n                                   (range 100))\n                                  100))\n                                ([data]\n                                 (hamf/subvec\n                                  (hamf/mut-list\n                                   (lznc/concat (range 100) data))\n                                  100)))}\n   :byte-vec {:convert-fn unchecked-byte :vec-fn (comp hamf/->random-access hamf/byte-array)}\n   :byte-vec-list {:convert-fn unchecked-byte :vec-fn (comp hamf/->random-access hamf/byte-array-list)}\n   :short-vec {:convert-fn identity :vec-fn (comp hamf/->random-access hamf/short-array)}\n   :short-vec-list {:convert-fn identity :vec-fn (comp hamf/->random-access hamf/short-array-list)}\n   :char-vec {:convert-fn char :vec-fn\n              (fn ([] (hamf/->random-access (hamf/char-array)))\n                ([data] (hamf/->random-access (hamf/char-array (hamf/mapv char data)))))}\n   :char-vec-list {:convert-fn char :vec-fn\n                   (fn ([] (hamf/->random-access (hamf/char-array-list)))\n                     ([data] (hamf/->random-access (hamf/char-array-list (hamf/mapv char data)))))}\n   :int-vec {:convert-fn identity :vec-fn (fn ([] (hamf/ivec)) ([data] (hamf/ivec data)))}\n   :int-list-vec {:convert-fn identity :vec-fn hamf/int-array-list}\n   :long-vec {:convert-fn identity :vec-fn (fn ([] (hamf/lvec)) ([data] (hamf/lvec data)))}\n   :long-list-vec {:convert-fn identity :vec-fn hamf/long-array-list}\n   :float-vec {:convert-fn float :vec-fn (fn ([] (hamf/fvec)) ([data] (hamf/fvec data)))}\n   :float-list-vec {:convert-fn float :vec-fn (comp hamf/->random-access hamf/float-array-list)}\n   :double-vec {:convert-fn double :vec-fn (fn ([] (hamf/dvec)) ([data] (hamf/dvec data)))}\n   :double-list-vec {:convert-fn double :vec-fn hamf/double-array-list}\n   })\n\n\n(defn test-reversed-vec-fn\n  [k {:keys [convert-fn vec-fn]}]\n  (let [r (range 6)\n        v (vec-fn r)\n        reversed (.rseq v)]\n    (testing \"RSeq methods\"\n      (is (= (hamf/mapv convert-fn [5 4 3 2 1 0]) reversed) (str k \" \" v \" \" reversed))\n      (is (= (convert-fn 5) (.first reversed)) k)\n      (is (= (hamf/mapv convert-fn [4 3 2 1 0]) (.next reversed)) k)\n      (is (= (hamf/mapv convert-fn [3 2 1 0]) (.. reversed next next)) k)\n      (is (= 6 (.count reversed)) k))\n    (testing \"clojure calling through\"\n      (is (= (convert-fn 5) (first reversed)) k)\n      (is (= (convert-fn 5) (nth reversed 0))) k)\n    (testing \"empty reverses to nil\"\n      (is (nil? (.. v empty rseq))))))\n\n\n(deftest test-reversed-vec\n  (doseq [[k v] vec-fns]\n    (test-reversed-vec-fn k v)))\n\n\n(defn all-add\n  ([convert-fn a b]\n   (convert-fn (+ (long a) (long b))))\n  ([convert-fn a b c]\n   (convert-fn (+ (long a) (long b) (long c)))))\n\n\n(deftest test-subvector-reduce\n  (doseq [[k v] vec-fns]\n    (let [{:keys [convert-fn vec-fn]} v]\n      (is (= (convert-fn 60)\n             (let [prim-vec (vec-fn (lznc/map convert-fn (hamf/range 1000)))]\n               (convert-fn (reduce (partial all-add convert-fn)\n                                   (hamf/subvec prim-vec 10 15)))))\n          k)\n      (is (= (convert-fn 60)\n             (let [prim-vec (hamf/vec (range 1000))]\n               (reduce (partial all-add convert-fn)\n                       (hamf/subvec prim-vec 10 15))))\n          k))))\n\n\n(deftest test-vec-associative\n  (doseq [[k v] vec-fns]\n    (let [{:keys [convert-fn vec-fn]} v]\n      (let [empty-v (vec-fn)\n            v       (vec-fn (range 1 6))]\n        (testing \"Associative.containsKey\"\n          (are [x] (.containsKey v x)\n            0 1 2 3 4)\n          (are [x] (not (.containsKey v x))\n            -1 -100 nil [] \"\" #\"\" #{} 5 100)\n          (are [x] (not (.containsKey empty-v x))\n            0 1))\n        (testing \"contains?\"\n          (are [x] (contains? v x)\n            0 2 4)\n          (are [x] (not (contains? v x))\n            -1 -100 nil \"\" 5 100)\n          (are [x] (not (contains? empty-v x))\n            0 1))\n        (testing \"Associative.entryAt\"\n          (are [idx val] (= (clojure.lang.MapEntry. idx (convert-fn val))\n                            (.entryAt v idx))\n            0 1\n            2 3\n            4 5)\n          (are [idx] (nil? (.entryAt v idx))\n            -5 -1 5 10 nil \"\")\n          (are [idx] (nil? (.entryAt empty-v idx))\n            0 1))))))\n\n\n(defn =vec\n  [expected v] (and (vector? v) (= expected v)))\n\n\n(deftest test-mapv\n  (are [r c1] (=vec r (hamf/mapv + c1))\n    [1 2 3] [1 2 3])\n  (are [r c1 c2] (=vec r (hamf/mapv + c1 c2))\n    [2 3 4] [1 2 3] (repeat 1))\n  (are [r c1 c2 c3] (=vec r (hamf/mapv + c1 c2 c3))\n    [3 4 5] [1 2 3] (repeat 1) (repeat 1))\n  (are [r c1 c2 c3 c4] (=vec r (hamf/mapv + c1 c2 c3 c4))\n    [4 5 6] [1 2 3] [1 1 1] [1 1 1] [1 1 1]))\n\n(deftest test-filterv\n  (are [r c1] (=vec r (hamf/filterv even? c1))\n    (hamf/vector) (hamf/vector 1 3 5)\n    (hamf/vector 2 4) (hamf/vector 1 2 3 4 5)))\n\n(deftest test-subvec\n  (doseq [[k v] vec-fns]\n    (let [{:keys [convert-fn vec-fn]} v]\n      (let [v1 (vec-fn (hamf/range 100))\n            v2 (hamf/subvec v1 50 57)]\n        ;;nth, IFn interfaces allow negative (from the end) indexing\n        (is (thrown? IndexOutOfBoundsException (.get v2 -1)))\n        (is (thrown? IndexOutOfBoundsException (v2 7)) k)\n        (is (= (v1 50) (v2 0)))\n        (is (= (v1 56) (v2 6))))\n      (let [v1 (vec-fn (hamf/range 10))\n            v2 (hamf/subvec v1 2 7)]\n        ;;nth, IFn interfaces allow negative (from the end) indexing\n        (is (thrown? IndexOutOfBoundsException (.get v2 -1)))\n        (is (thrown? IndexOutOfBoundsException (v2 7)) k)\n        (is (= (v1 2) (v2 0)))\n        (is (= (v1 6) (v2 4)))))))\n\n\n(deftest test-vec\n  (is (= [1 2] (hamf/vec (first {1 2}))))\n  (is (= [0 1 2 3] (hamf/vec [0 1 2 3])))\n  (is (= [0 1 2 3] (hamf/vec (list 0 1 2 3))))\n  (is (= [[1 2] [3 4]] (vec (sorted-map 1 2 3 4))))\n  (is (= [0 1 2 3] (hamf/vec (range 4))))\n  (is (= [\\a \\b \\c \\d] (hamf/vec \"abcd\")))\n  (is (= [0 1 2 3] (hamf/vec (object-array (range 4)))))\n  (is (= [1 2 3 4] (hamf/vec (eduction (map inc) (range 4)))))\n  (is (= [0 1 2 3] (hamf/vec (reify clojure.lang.IReduceInit\n                               (reduce [_ f start]\n                                 (reduce f start (range 4))))))))\n\n(deftest test-vector-eqv-to-non-counted-types\n  (is (not= (range) (hamf/vector 0 1 2)))\n  (is (not= (hamf/vector 0 1 2) (range)))\n  (is (not= (hamf/vec (range 100)) (range)))\n  (is (= (hamf/vec (range 100)) (hamf/range 100)))\n  (is (= (hamf/vector 0 1 2) (take 3 (range))))\n  (is (= (hamf/vector 0 1 2) (new java.util.ArrayList [0 1 2])))\n  (is (not= (hamf/vector 1 2) (take 1 (cycle [1 2]))))\n  (is (= (hamf/vector 1 2 3 nil 4 5 6 nil) (eduction cat [[1 2 3 nil] [4 5 6 nil]]))))\n\n\n(deftest test-reduce-kv-vectors\n  (is (= 25 (reduce-kv + 10 (hamf/vector 2 4 6))))\n  (is (= 25 (reduce-kv + 10 (hamf/subvec (hamf/vector 0 2 4 6) 1))))\n  (doseq [[k v] vec-fns]\n    (when-not (#{:byte-vec :byte-vec-list} k)\n      (let [{:keys [convert-fn vec-fn]} v]\n        (is (= 9811 (long (reduce-kv (partial all-add convert-fn)\n                                     10 (vec-fn (hamf/range 1 100)))))\n            k)\n        (is (= 9811 (long (reduce-kv (partial all-add convert-fn)\n                                     10 (hamf/subvec (vec-fn (hamf/range 100)) 1))))\n            k)))))\n\n\n(deftest test-reduced?-in-container\n  (doseq [[k v] vec-fns]\n    (when-not (#{:byte-vec :byte-vec-list} k)\n      (let [{:keys [convert-fn vec-fn]} v]\n        (is (= 4 (reduce (fn [acc v]\n                           (let [v (long v)]\n                             (if (< v 4)\n                               v\n                               (reduced v))))\n                         0 (vec-fn (hamf/range 1 100))))\n            k)))))\n\n\n(deftest test-reduce-kv-array\n  (is (= 25 (reduce-kv + 10 (hamf/->random-access (hamf/int-array [2 4 6])))))\n  (is (= 25 (reduce-kv + 10 (hamf/subvec (hamf/->random-access (hamf/int-array [0 2 4 6])) 1)))))\n\n\n(deftest test-reduce-vectors\n  (is (= 22 (reduce + 10 (hamf/vector 2 4 6))))\n  (is (= 22 (reduce + 10 (hamf/subvec (hamf/vector 0 2 4 6) 1))))\n  (is (= 4960 (reduce + 10 (hamf/vec (hamf/range 1 100)))))\n  (is (= 4960 (reduce + 10 (hamf/subvec (hamf/vec (hamf/range 100)) 1)))))\n\n\n(deftest test-reduce-arrays\n  (is (= 22 (reduce + 10 (hamf/int-array [2 4 6]))))\n  (is (= 22 (reduce + 10 (hamf/subvec (hamf/int-array [0 2 4 6]) 1)))))\n\n\n(deftest concatv-special-cases\n  (is (= (reduce + 0 (hamf/concatv [] (list 1 2 3) nil nil\n                                   (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                                   (hamf/vec (hamf/range 50))))\n         (reduce + 0 (concat [] (list 1 2 3) nil nil\n                             (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                             (hamf/vec (hamf/range 50))))))\n  (is (= (reduce + 0 (lznc/concat [] (list 1 2 3) nil nil\n                                  (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                                  (hamf/vec (hamf/range 50))))\n         (reduce + 0 (concat [] (list 1 2 3) nil nil\n                             (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                             (hamf/vec (hamf/range 50))))))\n  (is (= (hamf/concatv [] (list 1 2 3) nil nil\n                       (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                       (hamf/vec (hamf/range 50)))\n         (concat [] (list 1 2 3) nil nil\n                 (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                 (hamf/vec (hamf/range 50)))))\n  (is (= (lznc/concat [] (list 1 2 3) nil nil\n                      (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                      (hamf/vec (hamf/range 50)))\n         (concat [] (list 1 2 3) nil nil\n                 (clojure.core/vector 1 2 3 4 5) (hamf/array-list [1 2 3 4])\n                 (hamf/vec (hamf/range 50)))))\n  (is (= (hamf/vec (hamf/concata [] (list 1 2 3) nil nil\n                                 (clojure.core/vector 1 2 3 4 5)\n                                 (hamf/object-array-list [1 2 3 4])\n                                 (hamf/vec (hamf/range 50))))\n         (concat [] (list 1 2 3) nil nil\n                 (clojure.core/vector 1 2 3 4 5) (hamf/object-array-list [1 2 3 4])\n                 (hamf/vec (hamf/range 50))))))\n\n(deftest tree-list-creation\n  (let [data (hamf/object-array (hamf/range 100))\n        vdata (clojure.core/vec data)]\n    (is (= vdata (ham_fisted.TreeList/create true nil data)))\n    (is (= vdata (ham_fisted.MutTreeList/create true nil data)))))\n\n\n(deftest binary-search\n  (let [data (hamf/shuffle (hamf/range 100))]\n    (doseq [[k {:keys [convert-fn vec-fn]}] vec-fns]\n      (let [init-data (vec-fn data)\n            ;;make sure sort always works\n            newvdata (hamf/sort init-data)\n            ;;transform back\n            vdata (vec-fn newvdata)\n            subv (hamf/subvec vdata 50)]\n        ;;Ensure that non-accelerated sort results are identical to\n        ;;accelerated sort results\n        (is (= vdata (hamf/sort compare init-data)) k)\n        (is (= 50 (hamf/binary-search vdata (convert-fn 50))) k)\n        (when-not (#{:char-vec :char-vec-list} k)\n          (is (= 51 (hamf/binary-search vdata 50.1 compare)) k))\n        (when-not (#{:char-vec :char-vec-list} k)\n          (is (= 0 (hamf/binary-search vdata -1)) k))\n        (is (= 100 (hamf/binary-search vdata (convert-fn 120))) k)\n        (is (= 0 (hamf/binary-search subv (convert-fn 50))) k)\n        (when-not (#{:char-vec :char-vec-list} k)\n          (is (= 1 (hamf/binary-search subv 50.1 compare)) k))\n        (when-not (#{:char-vec :char-vec-list} k)\n          (is (= 0 (hamf/binary-search subv -1)) k))\n        (is (= 50 (hamf/binary-search subv (convert-fn 120))) k)))))\n\n\n(deftest boolean-arrays\n  (is (== 2.0 (hamf/sum (hamf/boolean-array [true false true false]))))\n  (is (= [true false true false] (hamf/->random-access (hamf/boolean-array [1 0 1 0])))))\n\n\n(deftest float-regression\n  (is (= 2 (count (hamf/float-array (lznc/filter (fn [^double v]\n                                                   (not (Double/isNaN v)))\n                                                 [1 ##NaN 2]))))))\n\n(deftest sublists-are-smaller-test\n  (let [t (into (TreeList.) (range (* 1000 1000)))]\n    #_(println (* 2 (mm/measure (hamf/subvec t 100000 200000) :bytes true))\n               (* 1 (mm/measure t :bytes true)))\n    (is (< (* 2 (mm/measure (hamf/subvec t 100000 200000) :bytes true))\n           (* 1 (mm/measure t :bytes true))))))\n\n\n(comment\n  (def vec-fn (get-in vec-fns [:api-mut-sublist :vec-fn]))\n  (def data (hamf/shuffle (hamf/range 100)))\n  (def vv (vec-fn data))\n\n  (def m (doto (MutList.) (.addAll (range 36))))\n  (def m ImmutList/EMPTY)\n\n  (def data (doto (ArrayList.)\n              (.addAll (range 1000))))\n\n  (crit/quick-bench (doto (ArrayList.)\n                      (.addAll data)))\n  ;; Evaluation count : 907674 in 6 samples of 151279 calls.\n  ;;            Execution time mean : 662.299153 ns\n  ;;   Execution time std-deviation : 4.369292 ns\n  ;;  Execution time lower quantile : 653.753118 ns ( 2.5%)\n  ;;  Execution time upper quantile : 665.603474 ns (97.5%)\n  ;;                  Overhead used : 1.966980 ns\n\n\n  (crit/quick-bench (doto (MutList.) (.addAll data)))\n  ;; Evaluation count : 395256 in 6 samples of 65876 calls.\n  ;;            Execution time mean : 1.517687 µs\n  ;;   Execution time std-deviation : 0.809702 ns\n  ;;  Execution time lower quantile : 1.516407 µs ( 2.5%)\n  ;;  Execution time upper quantile : 1.518463 µs (97.5%)\n  ;;                  Overhead used : 1.969574 ns\n  (crit/quick-bench (hamf/mut-list data)) ;;same\n\n  (def vdata (vec data))\n  (crit/quick-bench (doto (MutList.) (.addAll vdata)))\n\n  (def m (hamf/mut-list data))\n\n  (defn index-test\n    [^List m]\n    (let [nelems (.size m)]\n      (crit/quick-bench (dotimes [idx nelems]\n                          (.get m idx)))))\n  (index-test data) ;; 770ns\n  (index-test m) ;; 1.7us\n  (index-test vdata) ;;5.3us\n\n\n  (crit/quick-bench (.toArray data)) ;;1.08us\n  (crit/quick-bench (.toArray m)) ;;2.4us\n  (crit/quick-bench (.toArray vdata)) ;;6.2us\n\n  (def adata (.toArray data))\n  (crit/quick-bench (hamf/mut-list adata))\n  ;; Execution time mean : 775.067887 ns\n  ;; Execution time std-deviation : 2.413493 ns\n  ;; Execution time lower quantile : 770.746577 ns ( 2.5%)\n  ;; Execution time upper quantile : 777.223862 ns (97.5%)\n  ;; Overhead used : 1.965715 ns\n\n  (crit/quick-bench (hamf/into [] data))\n  ;; Evaluation count : 31608 in 6 samples of 5268 calls.\n  ;;            Execution time mean : 19.045789 µs\n  ;;   Execution time std-deviation : 28.268048 ns\n  ;;  Execution time lower quantile : 19.001188 µs ( 2.5%)\n  ;;  Execution time upper quantile : 19.073174 µs (97.5%)\n  ;;                  Overhead used : 1.965715 ns\n\n  (crit/quick-bench (hamf/into hamf/empty-vec adata))\n  ;; Evaluation count : 31608 in 6 samples of 5268 calls.\n  ;;            Execution time mean : 19.045789 µs\n  ;;   Execution time std-deviation : 28.268048 ns\n  ;;  Execution time lower quantile : 19.001188 µs ( 2.5%)\n  ;;  Execution time upper quantile : 19.073174 µs (97.5%)\n  ;;                  Overhead used : 1.965715 ns\n\n  )\n"
  },
  {
    "path": "test/ham_fisted/test_setup.clj",
    "content": "(ns ham-fisted.test-setup\n  \"Things we need to do in order to run tests with a smile\"\n  (:require [kaocha.hierarchy :as hierarchy]))\n\n(hierarchy/derive! ::ignore :kaocha/known-key)\n\n(defn defuse-zero-assertions\n  \"Don't fail the test suite if we hide an `is` within a `doseq`.\n\n  See also https://cljdoc.org/d/lambdaisland/kaocha/1.80.1274/doc/-clojure-test-assertion-extensions#detecting-missing-assertions\"\n  [event]\n  (if (= (:type event) :kaocha.type.var/zero-assertions)\n    (assoc event :type ::ignore)\n    event))\n"
  },
  {
    "path": "test/ham_fisted/vec_like_test.clj",
    "content": "(ns ham-fisted.vec-like-test\n  (:require [ham-fisted.api :as hamf]\n            [clojure.test :refer [deftest is] :as test])\n  (:import [ham_fisted TreeList IMutList Iter MutTreeList]\n           [java.util List]))\n\n(defn sublist-tumbler\n  [^List data]\n  (let [ne (count data)\n        idx0 (rand-int ne)\n        idx1 (rand-int ne)\n        eidx (max idx0 idx1)\n        sidx (min idx0 idx1)\n        ss (.subList data sidx eidx)\n        answer (into [] (->> (drop sidx data) (take (- eidx sidx))))\n        result (try (into [] ss) (catch Exception e (println e)))]\n    (when-not (= answer result)\n      (throw (ex-info \"sublist failed:\" {:data data\n                                         :answer answer\n                                         :result result\n                                         :sidx sidx\n                                         :eidx eidx})))))\n\n(deftest sublist-test\n  (let [tr (reduce conj (TreeList.) (range 1000000))]\n    (dotimes [idx 50] (sublist-tumbler tr))\n    (is (= (count tr) 1000000))))\n\n(defn add-all-reducible\n  ^IMutList [^IMutList l data]\n  (.addAllReducible l data)\n  l)\n\n(defn ->iter\n  [data]\n  (when data\n    (if (instance? Iter data)\n      data\n      (Iter/fromIterator (.iterator ^Iterable data)))))\n\n(defn cons-all\n  ^TreeList [^TreeList l data]\n  (.consAll l (->iter data)))\n\n(deftype RangeIter [^long n\n                    ^{:unsynchronized-mutable true\n                      :tag long} idx]\n  Iter\n  (get [this] (Long/valueOf idx))\n  (next [this]\n    (set! idx (inc idx))\n    (when (< idx n)\n      this)))\n\n\n(comment\n  (def tr (reduce conj (TreeList.) (range 35)))\n\n  (require '[criterium.core :as crit])\n  (def rr (into [] (range 1000000)))\n  (crit/quick-bench (reduce conj (ham_fisted.TreeList.) rr))\n  (crit/quick-bench (reduce conj [] rr))\n  (crit/quick-bench (hamf/object-array (into [] rr)))\n  (crit/quick-bench (add-all-reducible (hamf/object-array-list) rr))\n  (crit/quick-bench (hamf/object-array (add-all-reducible (ham_fisted.MutTreeList.) rr)))\n  (crit/quick-bench (cons-all (ham_fisted.TreeList.) rr))\n  (crit/quick-bench (cons-all (ham_fisted.TreeList.) (RangeIter. (count rr) 0)))\n  (crit/quick-bench (add-all-reducible (ham_fisted.BatchedList.) rr))\n\n  (def tr (reduce conj (ham_fisted.TreeList.) rr))\n  (def pv (reduce conj [] rr))\n  (def tr (reduce conj (ham_fisted.TreeList.) (range 32768)))\n\n  (defn verify-structure\n    [^TreeList tt]\n\n    )\n  (do\n    (def tr (reduce conj (TreeList.) (range 1000000)))\n    (when-let [ee (try (dotimes [idx 50] (sublist-tumbler tr))\n                       (catch Throwable e e))]\n      (let []\n        (def exd (ex-data ee))\n        (def sidx 763476)\n        (def eidx 877568)\n        (def tt (.subList tr sidx eidx))\n        (def arrays (vec (iterator-seq (.arrayIterator (.data tt) (.offset tt) (+ (.offset tt) (.size tt))))))))\n    )\n\n  (do\n    (require '[clj-async-profiler.core :as prof])\n    (prof/profile {:interval 10000} (dotimes [idx 50] (add-all-reducible (ham_fisted.BatchedList.) rr)))\n    (prof/serve-ui 8080))\n  )\n"
  },
  {
    "path": "tests.edn",
    "content": "#kaocha/v1 {:capture-output?                 false\n            :kaocha/fail-fast?               false\n            :plugins                         [:kaocha.plugin/profiling\n                                              :kaocha.plugin/print-invocations\n                                              :kaocha.plugin/junit-xml\n                                              :kaocha.plugin/cloverage\n                                              :kaocha.plugin/hooks\n                                              :preloads]\n            :kaocha.plugin.junit-xml/target-file \"target/junit.xml\"\n            :kaocha.plugin.junit-xml/add-location-metadata? true\n            :cloverage/opts {:ns-exclude-regex []\n                             :text? true\n                             :lcov? true\n                             :high-watermark 80\n                             :fail-threshold 0\n                             :output \"target/coverage\"\n                             :low-watermark 50\n                             :summary? true\n                             :coveralls? false\n                             :emma-xml? false\n                             :html? true\n                             :nop? false\n                             :codecov? true}\n            :kaocha.hooks/pre-report         [ham-fisted.test-setup/defuse-zero-assertions]\n            :kaocha.plugin.preloads/ns-names [ham-fisted.test-setup]\n            :tests                           [{:id                              :unit\n                                               :plugins                         [:kaocha.plugin/profiling\n                                                                                 :kaocha.plugin/print-invocations\n                                                                                 :kaocha.plugin/junit-xml\n                                                                                 :kaocha.plugin/hooks\n                                                                                 :preloads]\n                                               :kaocha/source-paths             [\"src\"]\n                                               :kaocha/test-paths               [\"test\"]\n                                               :ns-patterns                     [\".*-test\"]}\n                                              {:id                              :coverage\n                                               :plugins                         [:kaocha.plugin/profiling\n                                                                                 :kaocha.plugin/print-invocations\n                                                                                 :kaocha.plugin/junit-xml\n                                                                                 :kaocha.plugin/cloverage\n                                                                                 :kaocha.plugin/hooks\n                                                                                 :preloads]\n                                               :kaocha/source-paths             [\"src\"]\n                                               :kaocha/test-paths               [\"test\"]\n                                               :ns-patterns                     [\".*-test\"]}]}\n"
  },
  {
    "path": "topics/Reductions.md",
    "content": "# Reductions\n\nThe ham-fisted project extends the concept of Clojure's `reduce` in a few ways,\ntaking influence from java streams and Clojure transducers.  The most important\nway is a formal definition of a parallel reduction (analogous to `pmap` for `map`).\n\n\nMost interesting is the 3 argument form of `(reduce rfn init coll)`.  Problems\nexist with the 2 argument form `(reduce rfn coll)` as the reduction function -\n`rfn`'s leftmost argument is sometimes a value from the collection and at other\ntimes an accumulated value.  Some reductions have the property that the\naccumulator is in the set of objects in the collection (such as numeric `+`),\nthese reductions are not the most general. They are a special case of a\nreduction where the accumulator may be a different type entirely than the values\nin the collection.\n\n\n## Parallelizable Containers\n\nEfficient parallel reductions depend on parallelizable containers.\n\nJava has three types of containers that operate efficiently in parallel.\n\n1) Finite random access containers (ex: an array)\n2) Containers that can provide spliterators (ex: hashtable)\n3) A concatenation of containers suitable for parallel computation over the parts\n\nThese three types of containers we can parallelize; random access containers,\nmaps and sets (or more generally anything with a correct spliterator\nimplementation), and concatenations of sub-containers each of which may not\nitself have a parallelizable reduction.\n\n\n## Parallelized Reduction\n\nA parallelized reduction works by splitting up elements of the data source.\nMany reduction contexts operate simultaneous each of which will perform a serial\nreduction.  A separate step merges the results back together.  This may be\nthought of as the \"true\" map-reduce, but either way it may be useful to compare\na parallelized reduction in detail to a serial reduction.\n\n\nTo perform a parallel reduction, four things must be provided:\n\n* `init-val-fn` - a function to produce initial accumulators for each reduction context\n* `rfn` - a function that takes an accumulator and a value and updates the accumulator ---  This\n  is the typical reduction function passed as the first argument to Clojure's `reduce`\n* `merge-fn` - a function that takes two accumulators and merges them to produces one\n  result accumulator.\n* `coll` - a collection of items to reduce to a single output\n\n\nHere are the function signatures (Keep in mind ... `preduce`:`reduce` :: `pmap`:`map`):\n\n```clojure\n(defn preduce [init-val-fn rfn merge-fn coll] ...)\n```\n\nNotably Java streams have a 'collect' method that takes the same four arguments\nwhere the collection is the `this` object:\n\n```java\ninterface Stream<E> {\n<R> R collect(Supplier<R> supplier,\n              BiConsumer<R,? super T> accumulator,\n              BiConsumer<R,R> combiner);\n}\n```\n\n\nThe parallelizable reduction operates as a a serial reduction if the init-val-fn\nis called exactly once with no arguments and the entire collection is passed\nalong with rfn to reduce:\n\n```clojure\n(reduce rfn (init-val-fn) coll)\n```\n\nFrom there `preduce` essentially switches on the type of coll and performs one\nof four distinct types of reductions:\n\n * serial\n * parallel over and index space\n * parallel over and spliterator space\n * parallel over sub-containers\n\n\n## Map, Filter, Concat Chains\n\n\nIt is common in functional programming to implement data transformations as\nchains of `map`, `filter`, and `concat` operations.  Analyzing sequences of\nthese operations is insight with regards to reduction in general and\nparallelization of reductions.\n\n\nThe first insight is found in the Clojure transducer pathways and involves collapsing\nthe reduction function when possible for map and filter applications.  Let's start with\na reduction of the form `(->> coll (map x) (filter y) (reduce ...))`.\n\nThe filter operator can specialize its reduce implementation by producing a new reduction\nfunction and reducing over its source collection:\n\n```java\npublic Object reduce(IFn rfn, Object init) {\n\treturn source.reduce(new IFn() {\n\t  public Object invoke(Object acc, Object v) {\n\t    if(pred.test(v))\n\t\t  return rfn.invoke(acc, v);\n\t    else\n\t\t  return acc;\n\t  }\n\t}, init);\n}\n```\n\nThis results in 'collapsing' the reduction allowing the source to perform the\niteration across its elements and simply dynamically creating a slightly more\ncomplex reduction function, `rfn`.  A similar pathway exists for `map` as we can\nalways delegate up the chain making a slightly more complex reduction function\nas long as we are reducing over a single source of data.  This optimization\nleads to many fewer function calls and intermediate collections when compared\nwith naive implementations of `map` and `filter`. Clojure's transducers do this\nautomatically.\n\nCollapsing the reduction also allows us to parallelize reductions like the initial one\nstated before as if the filter object has a parallelReduction method that does an identical\ncollapsing pathway then if the source is parallelizable then the reduction itself can\nstill parallelize:\n\n```java\npublic Object parallelReduction(IFn initValFn, IFn rfn, IFn mergeFn) {\n  return source.parallelReduction(initValFn, new IFn() {...}, mergeFn);\n}\n```\n\nIf the source collection itself allows for parallel reduction, then it's\npossible to achieve similar 'collapsing' in `preduce`.  Clojure's transducers do\nnot have this particular optimization for parallel reduction, but Java streams\ndo.\n\n\nAlso worth noting, these optimizations are only available if we use the 4\nargument form of reduce *and* if we assume that `map`, `filter`, and `concat` are lazy\nand non-caching.\n\n\nWith those assumptions in place it is possible to parallelize a reduction over\nthe entries, keys or values of map using simple primitive composition:\n\n```clojure\nuser> (require '[ham-fisted.api :as hamf])\nnil\nuser> (require '[ham-fisted.lazy-noncaching :as lznc])\nnil\nuser> (def data (hamf/immut-map (lznc/map #(vector % %) (range 20000))))\n#'user/data\nuser> (type data)\nham_fisted.PersistentHashMap\nuser> (hamf/preduce + + + (lznc/map key data))\n199990000\n```\n\n## Stream-based Reductions\n\nJava streams have a notion of parallel reduction built-in. Their design suffers\nfrom two flaws, one minor and one major.\n\nThe first minor flaw is that you can ask a stream for a parallel version of\nitself and it will give you one if possible else return a copy of itself.\nUnfortunately this only works on the first stream in a pipeline so for instance:\n\n```java\n  coll.stream().map().filter().parallel().collect();\n```\n\nyields a serial reduction while:\n\n```java\n  coll.stream().parallel().map().filter().collect();\n```\n\nyields a parallel reduction.\n\nThis is unfortunate because it means you must go back in time to get a parallel\nversion of the stream if you want to perform a parallel collection; something\nthat may or may not be easily done at the point in time when you decide you do\nin fact want to parallel reduction (especially in library code).\n\nThe second and more major flaw is that stream-based parallelization does not\nallow the user to pass in their own fork-join pool at any point. This limits use\nto the built in pool where it's pad form to park threads or do blocking\noperations.\n\n\n## reducers.clj And Parallel Folds\n\nClojure has an alpha namespace that provides a parallel reduction, [reducers.clj](https://github.com/clojure/clojure/blob/master/src/clj/clojure/core/reducers.clj).  The signature\nfor this method is:\n\n```clojure\n(defn fold\n  \"Reduces a collection using a (potentially parallel) reduce-combine\n  strategy. The collection is partitioned into groups of approximately\n  n (default 512), each of which is reduced with reducef (with a seed\n  value obtained by calling (combinef) with no arguments). The results\n  of these reductions are then reduced with combinef (default\n  reducef). combinef must be associative, and, when called with no\n  arguments, (combinef) must produce its identity element. These\n  operations may be performed in parallel, but the results will\n  preserve order.\"\n  {:added \"1.5\"}\n  ([reducef coll] (fold reducef reducef coll))\n  ([combinef reducef coll] (fold 512 combinef reducef coll))\n  ([n combinef reducef coll]\n     (coll-fold coll n combinef reducef)))\n```\n\nIn this case we use overloads of `combinef` or `reducef` to provider the initial accumulator\n(called the identity element), the rfn, finalization and the merge function.  `combinef` called\nwith no arguments provides each thread context's accumulator and called with two arguments\nperforms a merge of two accumulators.  `reducef` called with 2 arguments provides\nthe reduction from a value into the accumulator and when called with one argument\nfinalizes both the potentially stateful reducing function and finalizes the\naccumulator.  It prescribes the parallelization system but users can override a protocol\nto do it themselves.\n\nThis the same major drawback as the java stream system, namely users cannot provide\ntheir own pool for parallelization.\n\nAn interesting decision was made here as to whether one can actually parallelize the\nreduction or not.  Transducers, the elements providing `reducef`, may be stateful\nsuch as `(take 15)`.  One interesting difference is that state is done with a closure in\nthe reduction function as opposed to providing a custom accumulator that wraps the user's\naccumulator but tracks state.\n\nOne aspect we haven't discussed but that is also handled here in an interesting\nmanner is that whether a reduction can be parallelized or not is a function both\nof the container *and* of the reducer.  `reducers.clj` does a sort of\ndouble-dispatch where the transducer may choose to implement the parallel\nreduction, called `coll-fold` or not and is queried first and if it allows\nparallel reduction then the collection itself is dispatched.  Overall this is a\ngreat, safe choice because it disallows completely parallel dispatch if the\ntransducer or the collection do not support it.\n\n\n## Parallel Reducers\n\nIf we combine all three functions: `init-val-fn`, `rfn`, and `merge-fn` into one object\nthen we get a ParallelReducer, defined in protocols.clj.  This protocol allows the\nuser to pass a single object into a parallelized reduction as opposed to three functions\nwhich is useful when we want to have many reducers reduce over a single source of data.\nA `finalize` method is added in order to allow compositions of reducers, and to allow\nreducers to hide state and information from end users:\n\n```clojure\n(defprotocol ParallelReducer\n  \"Parallel reducers are simple a single object that you can pass into preduce as\n  opposed to 3 separate functions.\"\n  (->init-val-fn [item]\n    \"Returns the initial values for a parallel reduction.  This function\ntakes no arguments and returns the initial reduction value.\")\n  (->rfn [item]\n    \"Returns the reduction function for a parallel reduction. This function takes\ntwo arguments, the initial value and a value from the collection and returns a new\ninitial value.\")\n  (->merge-fn [item]\n    \"Returns the merge function for a parallel reduction.  This function takes\ntwo initial values and returns a new initial value.\")\n  (finalize [item v]\n    \"A finalize function called on the result of the reduction after it is\nreduced but before it is returned to the user.  Identity is a reasonable default.\"))\n```\n\nThere are defaults to the reducer protocol for an IFn which assumes it can be\ncalled with no arguments for a initial value and two arguments for both\nreduction and merge.  This works for things like `+` and `*`.  Additionally\nthere are implementations provided for the ham_fisted Sum (Kahans compensated)\nand SimpleSum\n[DoubleConsumer](https://docs.oracle.com/javase/8/docs/api/java/util/function/DoubleConsumer.html)\nclasses.\n\n\nWith the three functions bundled into one logical protocol or object it is easy then\nto create complex (aggregate) and efficient parallelized reductions:\n\n```clojure\nuser> (require '[ham-fisted.reduce :as hamf-rf])\nnil\nuser> (hamf-rf/preduce-reducers {:sum + :product *} (range 1 20))\n{:product 121645100408832000, :sum 190}\nuser>\n```\n\nThis goes over the data in parallel, exactly once.\n\n\n## Consumers, Transducers, and `rfn` Chains\n\nIf we look at the reduction in terms of a push model as opposed to a pull model\nwhere the stream will push data into a consumer then we can implement similar\nchains or map and filter.  These are based on creating a new consumer that takes\nthe older consumer and the filter predicate or mapping function.  In this way\none can implement a pipeline on the input stream, or perhaps diverging pipelines\non each reduction function in a multiple reducer scenario.  Since the init and\nmerge functions operate in accumulator space, which remains unchanged, one can\ndevelop up increasingly sophisticated reduction functions and still perform a\nparallelized reduction.  Naturally, everything is composed in reverse (push\ninstead of pull), which is the reason that `comp` works in reverse when working\nwith transducers.\n\nIn fact, given that the covers are pulled back on composing reduction functions,\nthe definition of the single argument `clojure.core/filter` becomes more clear:\n\n```clojure\n(defn filter\n  \"Returns a lazy sequence of the items in coll for which\n  (pred item) returns logical true. pred must be free of side-effects.\n  Returns a transducer when no collection is provided.\"\n  {:added \"1.0\"\n   :static true}\n  ([pred]\n    (fn [rf]\n      (fn\n        ([] (rf))\n        ([result] (rf result))\n        ([result input]\n           (if (pred input)\n             (rf result input)\n             result)))))))\n```\n\nIt returns a function that, when given a reduction function, returns a new reduction\nfunction that when called in the two argument form is identical to the result above\n(although expressed in pure Clojure as opposed to Java).\n\n\nStarting with the concept that a reduction begins at the collection, flows\ndownward through the pipeline and bottoms out at the reducer then the\nlazy-noncaching namespace and Java streams implement parallelization flowing\nfrom the container downward. Separately consumer chains and transducers\nimplement the pipeline flowing up from the reducer itself.  Thus building the\npipeline either downward from the source or upward from the final reduction\nproduces subtly different properties.  Regardless, every system must disable\nparallelization where it will cause an incorrect answer (to ensure correctness)\n- such as in a stateful transducer.\n\n\nBroadly speaking, however, it can be faster to enable full parallelization and\nfilter invalid results than it is to force an early serialization our problem\nand thus lose lots of our parallelization potential.  When concerned with\nperformance, attempt to move transformations as much as possible into a\nparallelizable domain.\n\n\nFor the `take-n` use case specifically mentioned above and potentially for others we\ncan parallelize the reduction and do the take-n both in the parallelized phase and\nin the merge phase assuming we are using an ordered parallelization, so that doesn't\nitself necessarily force a serialized reduction but there are of course\ntransformations and reductions that do.  There are intermediate points however that are\nperhaps somewhat wasteful in terms of cpu load but do allow for more parallelization - a\ntradeoff that is sometimes worth it. Generically speaking we can visualize this sort\nof a tradeoff as triangle of three points where one point is data locality, one\npoint parallelism, and one point redundancy.  Specifically if we are willing to\ntrade some cpu efficiency for some redundancy, for instance, then we often get more\nparallelization.  Likewise if we are willing to save/load data from 'far' away from\nthe CPU, then we can cut down on redundancy but at the cost of locality.  For more\non this line of thinking please take a moment and read at least some of Jonathan Ragan-Kelly's\n[excellent PhD thesis](http://people.csail.mit.edu/jrk/jrkthesis.pdf) - a better explanation\nof the above line of reasoning begins on page 20.\n\n\n## Primitive Typed Serial Reductions\n\nThis comes last for a good reason :-) - it doesn't make a huge difference in performance\nbut it should be noted allowing objects to implemented typed reductions:\n\n```java\ndefault Object doubleReduction(IFn.ODO op, Object init);\ndefault Object longReduction(IFn.OLO op, Object init)\n```\n\nwhere the next incoming value is a primitive object but the accumulator is still\na generic object allows us to use things like `DoubleConsumers` and\n`LongConsumers` and avoid boxing the stream.  Furthermore if the aforementioned\n`map` and `filter` primitives are careful about their rfn composition we can\nmaintain a completely primitive typed pipeline through an entire processing\nchain.\n\n\n## One Final Note About Performance\n\nCollapsing reductions brings the source iteration pathway closer to the final\nreduction pathway in terms of machine stack space which allows HotSpot to\noptimize the entire chain more readily.  Regardless of how good HotSpot gets,\nhowever, parallelizing will nearly always result in a larger win but both work\ntogether to enable peak performance on the JVM given arbitrary partially typed\ncompositions of sequences and reductions.\n\nWhen increasing the data size yet again, one can of course use the same design\nto distribute the computations to different machines.  As some people have\nfigured out, however, simply implementing the transformations you need\nefficiently reduces or completely eliminates the need to distribute computation\nin the first place leading to a simpler, easier to test and more robust system.\n\nIdeally we can make achieving great performance for various algorithms clear and easy and\nthus avoid myriad of issues regarding distributing computing in the first place.\n\n* The first rule of distributed systems is to avoid distributing your computation in the first place - [1](https://bravenewgeek.com/service-disoriented-architecture/), [2](https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing).\n* The first law of distributed objects is to avoid using distributed objects. [3](https://martinfowler.com/bliki/FirstLaw.html).\n"
  }
]