]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
fixup! fix theme for orgmode on 27.1
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sat, 2 Jan 2021 17:47:40 +0000 (18:47 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sat, 2 Jan 2021 17:47:40 +0000 (18:47 +0100)
12 files changed:
bba.org
custom.el
elpa/dash-20200119.2310/dash-autoloads.el [deleted file]
elpa/dash-20200119.2310/dash-pkg.el [deleted file]
elpa/dash-20200119.2310/dash.el [deleted file]
elpa/dash-20200119.2310/dash.info [deleted file]
elpa/dash-20200119.2310/dir [deleted file]
elpa/dash-20210101.1712/dash-autoloads.el [new file with mode: 0644]
elpa/dash-20210101.1712/dash-pkg.el [new file with mode: 0644]
elpa/dash-20210101.1712/dash.el [new file with mode: 0644]
elpa/dash-20210101.1712/dash.info [new file with mode: 0644]
elpa/dash-20210101.1712/dir [new file with mode: 0644]

diff --git a/bba.org b/bba.org
index 18ef6857581669523d3152f226735a3a8d739a15..09c6142da9abdb8c51901e4480342957fad589c4 100644 (file)
--- a/bba.org
+++ b/bba.org
@@ -405,7 +405,7 @@ Some key bindings taken from [[https://ebzzry.github.io/emacs-pairs.html][emacs-
   (if (>= emacs-major-version 24)
       (progn
         (add-to-list 'load-path "~/.emacs.d/elpa/smartparens-20200105.1259")
-        (add-to-list 'load-path "~/.emacs.d/elpa/dash-20200119.2310")
+        (add-to-list 'load-path "~/.emacs.d/elpa/dash-20210101.1712")
         (require 'smartparens)
         (smartparens-global-mode 1)
         (defmacro def-pairs (pairs)
index 3fb1fe337f134a36f82b85a1bc944eb77eb92385..98135cf5453bb6d039fa35604dea2553291dda26 100644 (file)
--- a/custom.el
+++ b/custom.el
@@ -50,8 +50,8 @@
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
- '(org-block ((t (:inherit shadow :background "#29759c" :foreground "#84cbef" :distant-forground "#131313"))))
- '(org-block-begin-line ((t (:background "#07538a" :foreground "#84cbef"))))
+ '(org-block ((t (:inherit shadow :background "#29759c" :foreground "#84cbef" :distant-forground "#131313" :extend t))))
+ '(org-block-begin-line ((t (:background "#07538a" :foreground "#84cbef" :extend t))))
  '(org-block-end-line ((t (:inherit org-block-begin-line))))
  '(org-document-title ((t (:inherit default :foreground "#62a9cd" :font "Arial" :height 1.5 :underline nil))))
  '(org-level-1 ((t (:inherit default :foreground "#62a9cd" :font "Arial" :height 1.6))))
diff --git a/elpa/dash-20200119.2310/dash-autoloads.el b/elpa/dash-20200119.2310/dash-autoloads.el
deleted file mode 100644 (file)
index c5e7902..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-;;; dash-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "dash" "dash.el" (0 0 0 0))
-;;; Generated autoloads from dash.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "dash" '("dash-" "-keep" "-butlast" "-non" "-only-some" "-zip" "-e" "->" "-a" "-gr" "-when-let" "-d" "-l" "-s" "-p" "-r" "-m" "-i" "-f" "-u" "-value-to-list" "-t" "--" "-c" "!cons" "!cdr")))
-
-;;;***
-\f
-;;;### (autoloads nil nil ("dash-pkg.el") (0 0 0 0))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; dash-autoloads.el ends here
diff --git a/elpa/dash-20200119.2310/dash-pkg.el b/elpa/dash-20200119.2310/dash-pkg.el
deleted file mode 100644 (file)
index 91f8535..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-(define-package "dash" "20200119.2310" "A modern list library for Emacs" 'nil :keywords
-  '("lists")
-  :authors
-  '(("Magnar Sveen" . "magnarsNOSPAMgmail.com"))
-  :maintainer
-  '("Magnar Sveen" . "magnarsNOSPAMgmail.com"))
-;; Local Variables:
-;; no-byte-compile: t
-;; End:
diff --git a/elpa/dash-20200119.2310/dash.el b/elpa/dash-20200119.2310/dash.el
deleted file mode 100644 (file)
index bc713ce..0000000
+++ /dev/null
@@ -1,3072 +0,0 @@
-;;; dash.el --- A modern list library for Emacs  -*- lexical-binding: t -*-
-
-;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
-
-;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
-;; Version: 2.17.0
-;; Keywords: lists
-
-;; This program is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation, either version 3 of the License, or
-;; (at your option) any later version.
-
-;; This program is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-
-;;; Commentary:
-
-;; A modern list api for Emacs.
-;;
-;; See documentation on https://github.com/magnars/dash.el#functions
-;;
-;; **Please note** The lexical binding in this file is not utilised at the
-;; moment. We will take full advantage of lexical binding in an upcoming 3.0
-;; release of Dash. In the meantime, we've added the pragma to avoid a bug that
-;; you can read more about in https://github.com/magnars/dash.el/issues/130.
-;;
-
-;;; Code:
-
-;; TODO: `gv' was introduced in Emacs 24.3, so remove this and all
-;; calls to `defsetf' when support for earlier versions is dropped.
-(eval-when-compile
-  (unless (fboundp 'gv-define-setter)
-    (require 'cl)))
-
-(defgroup dash ()
-  "Customize group for dash.el"
-  :group 'lisp
-  :prefix "dash-")
-
-(defun dash--enable-fontlock (symbol value)
-  (when value
-    (dash-enable-font-lock))
-  (set-default symbol value))
-
-(defcustom dash-enable-fontlock nil
-  "If non-nil, enable fontification of dash functions, macros and
-special values."
-  :type 'boolean
-  :set 'dash--enable-fontlock
-  :group 'dash)
-
-(defmacro !cons (car cdr)
-  "Destructive: Set CDR to the cons of CAR and CDR."
-  `(setq ,cdr (cons ,car ,cdr)))
-
-(defmacro !cdr (list)
-  "Destructive: Set LIST to the cdr of LIST."
-  `(setq ,list (cdr ,list)))
-
-(defmacro --each (list &rest body)
-  "Anaphoric form of `-each'."
-  (declare (debug (form body))
-           (indent 1))
-  (let ((l (make-symbol "list")))
-    `(let ((,l ,list)
-           (it-index 0))
-       (while ,l
-         (let ((it (car ,l)))
-           ,@body)
-         (setq it-index (1+ it-index))
-         (!cdr ,l)))))
-
-(defmacro -doto (eval-initial-value &rest forms)
-  "Eval a form, then insert that form as the 2nd argument to other forms.
-The EVAL-INITIAL-VALUE form is evaluated once. Its result is
-passed to FORMS, which are then evaluated sequentially. Returns
-the target form."
-  (declare (indent 1))
-  (let ((retval (make-symbol "value")))
-    `(let ((,retval ,eval-initial-value))
-       ,@(mapcar (lambda (form)
-                   (if (sequencep form)
-                       `(,(-first-item form) ,retval ,@(cdr form))
-                     `(funcall form ,retval)))
-                 forms)
-       ,retval)))
-
-(defmacro --doto (eval-initial-value &rest forms)
-  "Anaphoric form of `-doto'.
-Note: `it' is not required in each form."
-  (declare (indent 1))
-  `(let ((it ,eval-initial-value))
-     ,@forms
-     it))
-
-(defun -each (list fn)
-  "Call FN with every item in LIST. Return nil, used for side-effects only."
-  (--each list (funcall fn it)))
-
-(put '-each 'lisp-indent-function 1)
-
-(defalias '--each-indexed '--each)
-
-(defun -each-indexed (list fn)
-  "Call (FN index item) for each item in LIST.
-
-In the anaphoric form `--each-indexed', the index is exposed as symbol `it-index'.
-
-See also: `-map-indexed'."
-  (--each list (funcall fn it-index it)))
-(put '-each-indexed 'lisp-indent-function 1)
-
-(defmacro --each-while (list pred &rest body)
-  "Anaphoric form of `-each-while'."
-  (declare (debug (form form body))
-           (indent 2))
-  (let ((l (make-symbol "list"))
-        (c (make-symbol "continue")))
-    `(let ((,l ,list)
-           (,c t)
-           (it-index 0))
-       (while (and ,l ,c)
-         (let ((it (car ,l)))
-           (if (not ,pred) (setq ,c nil) ,@body))
-         (setq it-index (1+ it-index))
-         (!cdr ,l)))))
-
-(defun -each-while (list pred fn)
-  "Call FN with every item in LIST while (PRED item) is non-nil.
-Return nil, used for side-effects only."
-  (--each-while list (funcall pred it) (funcall fn it)))
-
-(put '-each-while 'lisp-indent-function 2)
-
-(defmacro --each-r (list &rest body)
-  "Anaphoric form of `-each-r'."
-  (declare (debug (form body))
-           (indent 1))
-  (let ((v (make-symbol "vector")))
-    ;; Implementation note: building vector is considerably faster
-    ;; than building a reversed list (vector takes less memory, so
-    ;; there is less GC), plus length comes naturally.  In-place
-    ;; 'nreverse' would be faster still, but BODY would be able to see
-    ;; that, even if modification was reversed before we return.
-    `(let* ((,v (vconcat ,list))
-            (it-index (length ,v))
-            it)
-       (while (> it-index 0)
-         (setq it-index (1- it-index))
-         (setq it (aref ,v it-index))
-         ,@body))))
-
-(defun -each-r (list fn)
-  "Call FN with every item in LIST in reversed order.
- Return nil, used for side-effects only."
-  (--each-r list (funcall fn it)))
-
-(defmacro --each-r-while (list pred &rest body)
-  "Anaphoric form of `-each-r-while'."
-  (declare (debug (form form body))
-           (indent 2))
-  (let ((v (make-symbol "vector")))
-    `(let* ((,v (vconcat ,list))
-            (it-index (length ,v))
-            it)
-       (while (> it-index 0)
-         (setq it-index (1- it-index))
-         (setq it (aref ,v it-index))
-         (if (not ,pred)
-             (setq it-index -1)
-           ,@body)))))
-
-(defun -each-r-while (list pred fn)
-  "Call FN with every item in reversed LIST while (PRED item) is non-nil.
-Return nil, used for side-effects only."
-  (--each-r-while list (funcall pred it) (funcall fn it)))
-
-(defmacro --dotimes (num &rest body)
-  "Repeatedly executes BODY (presumably for side-effects) with symbol `it' bound to integers from 0 through NUM-1."
-  (declare (debug (form body))
-           (indent 1))
-  (let ((n (make-symbol "num")))
-    `(let ((,n ,num)
-           (it 0))
-       (while (< it ,n)
-         ,@body
-         (setq it (1+ it))))))
-
-(defun -dotimes (num fn)
-  "Repeatedly calls FN (presumably for side-effects) passing in integers from 0 through NUM-1."
-  (--dotimes num (funcall fn it)))
-
-(put '-dotimes 'lisp-indent-function 1)
-
-(defun -map (fn list)
-  "Return a new list consisting of the result of applying FN to the items in LIST."
-  (mapcar fn list))
-
-(defmacro --map (form list)
-  "Anaphoric form of `-map'."
-  (declare (debug (form form)))
-  `(mapcar (lambda (it) ,form) ,list))
-
-(defmacro --reduce-from (form initial-value list)
-  "Anaphoric form of `-reduce-from'."
-  (declare (debug (form form form)))
-  `(let ((acc ,initial-value))
-     (--each ,list (setq acc ,form))
-     acc))
-
-(defun -reduce-from (fn initial-value list)
-  "Return the result of applying FN to INITIAL-VALUE and the
-first item in LIST, then applying FN to that result and the 2nd
-item, etc. If LIST contains no items, return INITIAL-VALUE and
-do not call FN.
-
-In the anaphoric form `--reduce-from', the accumulated value is
-exposed as symbol `acc'.
-
-See also: `-reduce', `-reduce-r'"
-  (--reduce-from (funcall fn acc it) initial-value list))
-
-(defmacro --reduce (form list)
-  "Anaphoric form of `-reduce'."
-  (declare (debug (form form)))
-  (let ((lv (make-symbol "list-value")))
-    `(let ((,lv ,list))
-       (if ,lv
-           (--reduce-from ,form (car ,lv) (cdr ,lv))
-         (let (acc it) ,form)))))
-
-(defun -reduce (fn list)
-  "Return the result of applying FN to the first 2 items in LIST,
-then applying FN to that result and the 3rd item, etc. If LIST
-contains no items, return the result of calling FN with no
-arguments. If LIST contains a single item, return that item
-and do not call FN.
-
-In the anaphoric form `--reduce', the accumulated value is
-exposed as symbol `acc'.
-
-See also: `-reduce-from', `-reduce-r'"
-  (if list
-      (-reduce-from fn (car list) (cdr list))
-    (funcall fn)))
-
-(defmacro --reduce-r-from (form initial-value list)
-  "Anaphoric version of `-reduce-r-from'."
-  (declare (debug (form form form)))
-  `(--reduce-from ,form ,initial-value (reverse ,list)))
-
-(defun -reduce-r-from (fn initial-value list)
-  "Replace conses with FN, nil with INITIAL-VALUE and evaluate
-the resulting expression. If LIST is empty, INITIAL-VALUE is
-returned and FN is not called.
-
-Note: this function works the same as `-reduce-from' but the
-operation associates from right instead of from left.
-
-See also: `-reduce-r', `-reduce'"
-  (--reduce-r-from (funcall fn it acc) initial-value list))
-
-(defmacro --reduce-r (form list)
-  "Anaphoric version of `-reduce-r'."
-  (declare (debug (form form)))
-  `(--reduce ,form (reverse ,list)))
-
-(defun -reduce-r (fn list)
-  "Replace conses with FN and evaluate the resulting expression.
-The final nil is ignored. If LIST contains no items, return the
-result of calling FN with no arguments. If LIST contains a single
-item, return that item and do not call FN.
-
-The first argument of FN is the new item, the second is the
-accumulated value.
-
-Note: this function works the same as `-reduce' but the operation
-associates from right instead of from left.
-
-See also: `-reduce-r-from', `-reduce'"
-  (if list
-      (--reduce-r (funcall fn it acc) list)
-    (funcall fn)))
-
-(defun -reductions-from (fn init list)
-  "Return a list of the intermediate values of the reduction.
-
-See `-reduce-from' for explanation of the arguments.
-
-See also: `-reductions', `-reductions-r', `-reduce-r'"
-  (nreverse (--reduce-from (cons (funcall fn (car acc) it) acc) (list init) list)))
-
-(defun -reductions (fn list)
-  "Return a list of the intermediate values of the reduction.
-
-See `-reduce' for explanation of the arguments.
-
-See also: `-reductions-from', `-reductions-r', `-reduce-r'"
-  (and list (-reductions-from fn (car list) (cdr list))))
-
-(defun -reductions-r-from (fn init list)
-  "Return a list of the intermediate values of the reduction.
-
-See `-reduce-r-from' for explanation of the arguments.
-
-See also: `-reductions-r', `-reductions', `-reduce'"
-  (--reduce-r-from (cons (funcall fn it (car acc)) acc) (list init) list))
-
-(defun -reductions-r (fn list)
-  "Return a list of the intermediate values of the reduction.
-
-See `-reduce-r' for explanation of the arguments.
-
-See also: `-reductions-r-from', `-reductions', `-reduce'"
-  (when list
-    (let ((rev (reverse list)))
-      (--reduce-from (cons (funcall fn it (car acc)) acc)
-                     (list (car rev))
-                     (cdr rev)))))
-
-(defmacro --filter (form list)
-  "Anaphoric form of `-filter'.
-
-See also: `--remove'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result")))
-    `(let (,r)
-       (--each ,list (when ,form (!cons it ,r)))
-       (nreverse ,r))))
-
-(defun -filter (pred list)
-  "Return a new list of the items in LIST for which PRED returns a non-nil value.
-
-Alias: `-select'
-
-See also: `-keep', `-remove'."
-  (--filter (funcall pred it) list))
-
-(defalias '-select '-filter)
-(defalias '--select '--filter)
-
-(defmacro --remove (form list)
-  "Anaphoric form of `-remove'.
-
-See also `--filter'."
-  (declare (debug (form form)))
-  `(--filter (not ,form) ,list))
-
-(defun -remove (pred list)
-  "Return a new list of the items in LIST for which PRED returns nil.
-
-Alias: `-reject'
-
-See also: `-filter'."
-  (--remove (funcall pred it) list))
-
-(defalias '-reject '-remove)
-(defalias '--reject '--remove)
-
-(defun -remove-first (pred list)
-  "Return a new list with the first item matching PRED removed.
-
-Alias: `-reject-first'
-
-See also: `-remove', `-map-first'"
-  (let (front)
-    (while (and list (not (funcall pred (car list))))
-      (push (car list) front)
-      (!cdr list))
-    (if list
-        (-concat (nreverse front) (cdr list))
-      (nreverse front))))
-
-(defmacro --remove-first (form list)
-  "Anaphoric form of `-remove-first'."
-  (declare (debug (form form)))
-  `(-remove-first (lambda (it) ,form) ,list))
-
-(defalias '-reject-first '-remove-first)
-(defalias '--reject-first '--remove-first)
-
-(defun -remove-last (pred list)
-  "Return a new list with the last item matching PRED removed.
-
-Alias: `-reject-last'
-
-See also: `-remove', `-map-last'"
-  (nreverse (-remove-first pred (reverse list))))
-
-(defmacro --remove-last (form list)
-  "Anaphoric form of `-remove-last'."
-  (declare (debug (form form)))
-  `(-remove-last (lambda (it) ,form) ,list))
-
-(defalias '-reject-last '-remove-last)
-(defalias '--reject-last '--remove-last)
-
-(defun -remove-item (item list)
-  "Remove all occurrences of ITEM from LIST.
-
-Comparison is done with `equal'."
-  (declare (pure t) (side-effect-free t))
-  (--remove (equal it item) list))
-
-(defmacro --keep (form list)
-  "Anaphoric form of `-keep'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result"))
-        (m (make-symbol "mapped")))
-    `(let (,r)
-       (--each ,list (let ((,m ,form)) (when ,m (!cons ,m ,r))))
-       (nreverse ,r))))
-
-(defun -keep (fn list)
-  "Return a new list of the non-nil results of applying FN to the items in LIST.
-
-If you want to select the original items satisfying a predicate use `-filter'."
-  (--keep (funcall fn it) list))
-
-(defun -non-nil (list)
-  "Return all non-nil elements of LIST."
-  (declare (pure t) (side-effect-free t))
-  (-remove 'null list))
-
-(defmacro --map-indexed (form list)
-  "Anaphoric form of `-map-indexed'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result")))
-    `(let (,r)
-       (--each ,list
-         (!cons ,form ,r))
-       (nreverse ,r))))
-
-(defun -map-indexed (fn list)
-  "Return a new list consisting of the result of (FN index item) for each item in LIST.
-
-In the anaphoric form `--map-indexed', the index is exposed as symbol `it-index'.
-
-See also: `-each-indexed'."
-  (--map-indexed (funcall fn it-index it) list))
-
-(defmacro --map-when (pred rep list)
-  "Anaphoric form of `-map-when'."
-  (declare (debug (form form form)))
-  (let ((r (make-symbol "result")))
-    `(let (,r)
-       (--each ,list (!cons (if ,pred ,rep it) ,r))
-       (nreverse ,r))))
-
-(defun -map-when (pred rep list)
-  "Return a new list where the elements in LIST that do not match the PRED function
-are unchanged, and where the elements in LIST that do match the PRED function are mapped
-through the REP function.
-
-Alias: `-replace-where'
-
-See also: `-update-at'"
-  (--map-when (funcall pred it) (funcall rep it) list))
-
-(defalias '-replace-where '-map-when)
-(defalias '--replace-where '--map-when)
-
-(defun -map-first (pred rep list)
-  "Replace first item in LIST satisfying PRED with result of REP called on this item.
-
-See also: `-map-when', `-replace-first'"
-  (let (front)
-    (while (and list (not (funcall pred (car list))))
-      (push (car list) front)
-      (!cdr list))
-    (if list
-        (-concat (nreverse front) (cons (funcall rep (car list)) (cdr list)))
-      (nreverse front))))
-
-(defmacro --map-first (pred rep list)
-  "Anaphoric form of `-map-first'."
-  `(-map-first (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
-
-(defun -map-last (pred rep list)
-  "Replace last item in LIST satisfying PRED with result of REP called on this item.
-
-See also: `-map-when', `-replace-last'"
-  (nreverse (-map-first pred rep (reverse list))))
-
-(defmacro --map-last (pred rep list)
-  "Anaphoric form of `-map-last'."
-  `(-map-last (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
-
-(defun -replace (old new list)
-  "Replace all OLD items in LIST with NEW.
-
-Elements are compared using `equal'.
-
-See also: `-replace-at'"
-  (declare (pure t) (side-effect-free t))
-  (--map-when (equal it old) new list))
-
-(defun -replace-first (old new list)
-  "Replace the first occurrence of OLD with NEW in LIST.
-
-Elements are compared using `equal'.
-
-See also: `-map-first'"
-  (declare (pure t) (side-effect-free t))
-  (--map-first (equal old it) new list))
-
-(defun -replace-last (old new list)
-  "Replace the last occurrence of OLD with NEW in LIST.
-
-Elements are compared using `equal'.
-
-See also: `-map-last'"
-  (declare (pure t) (side-effect-free t))
-  (--map-last (equal old it) new list))
-
-(defmacro --mapcat (form list)
-  "Anaphoric form of `-mapcat'."
-  (declare (debug (form form)))
-  `(apply 'append (--map ,form ,list)))
-
-(defun -mapcat (fn list)
-  "Return the concatenation of the result of mapping FN over LIST.
-Thus function FN should return a list."
-  (--mapcat (funcall fn it) list))
-
-(defun -flatten (l)
-  "Take a nested list L and return its contents as a single, flat list.
-
-Note that because `nil' represents a list of zero elements (an
-empty list), any mention of nil in L will disappear after
-flattening.  If you need to preserve nils, consider `-flatten-n'
-or map them to some unique symbol and then map them back.
-
-Conses of two atoms are considered \"terminals\", that is, they
-aren't flattened further.
-
-See also: `-flatten-n'"
-  (declare (pure t) (side-effect-free t))
-  (if (and (listp l) (listp (cdr l)))
-      (-mapcat '-flatten l)
-    (list l)))
-
-(defmacro --iterate (form init n)
-  "Anaphoric version of `-iterate'."
-  (declare (debug (form form form)))
-  `(-iterate (lambda (it) ,form) ,init ,n))
-
-(defun -flatten-n (num list)
-  "Flatten NUM levels of a nested LIST.
-
-See also: `-flatten'"
-  (declare (pure t) (side-effect-free t))
-  (-last-item (--iterate (--mapcat (-list it) it) list (1+ num))))
-
-(defun -concat (&rest lists)
-  "Return a new list with the concatenation of the elements in the supplied LISTS."
-  (declare (pure t) (side-effect-free t))
-  (apply 'append lists))
-
-(defalias '-copy 'copy-sequence
-  "Create a shallow copy of LIST.
-
-\(fn LIST)")
-
-(defun -splice (pred fun list)
-  "Splice lists generated by FUN in place of elements matching PRED in LIST.
-
-FUN takes the element matching PRED as input.
-
-This function can be used as replacement for `,@' in case you
-need to splice several lists at marked positions (for example
-with keywords).
-
-See also: `-splice-list', `-insert-at'"
-  (let (r)
-    (--each list
-      (if (funcall pred it)
-          (let ((new (funcall fun it)))
-            (--each new (!cons it r)))
-        (!cons it r)))
-    (nreverse r)))
-
-(defmacro --splice (pred form list)
-  "Anaphoric form of `-splice'."
-  `(-splice (lambda (it) ,pred) (lambda (it) ,form) ,list))
-
-(defun -splice-list (pred new-list list)
-  "Splice NEW-LIST in place of elements matching PRED in LIST.
-
-See also: `-splice', `-insert-at'"
-  (-splice pred (lambda (_) new-list) list))
-
-(defmacro --splice-list (pred new-list list)
-  "Anaphoric form of `-splice-list'."
-  `(-splice-list (lambda (it) ,pred) ,new-list ,list))
-
-(defun -cons* (&rest args)
-  "Make a new list from the elements of ARGS.
-
-The last 2 members of ARGS are used as the final cons of the
-result so if the final member of ARGS is not a list the result is
-a dotted list."
-  (declare (pure t) (side-effect-free t))
-  (-reduce-r 'cons args))
-
-(defun -snoc (list elem &rest elements)
-  "Append ELEM to the end of the list.
-
-This is like `cons', but operates on the end of list.
-
-If ELEMENTS is non nil, append these to the list as well."
-  (-concat list (list elem) elements))
-
-(defmacro --first (form list)
-  "Anaphoric form of `-first'."
-  (declare (debug (form form)))
-  (let ((n (make-symbol "needle")))
-    `(let (,n)
-       (--each-while ,list (not ,n)
-         (when ,form (setq ,n it)))
-       ,n)))
-
-(defun -first (pred list)
-  "Return the first x in LIST where (PRED x) is non-nil, else nil.
-
-To get the first item in the list no questions asked, use `car'.
-
-Alias: `-find'"
-  (--first (funcall pred it) list))
-
-(defalias '-find '-first)
-(defalias '--find '--first)
-
-(defmacro --some (form list)
-  "Anaphoric form of `-some'."
-  (declare (debug (form form)))
-  (let ((n (make-symbol "needle")))
-    `(let (,n)
-       (--each-while ,list (not ,n)
-         (setq ,n ,form))
-       ,n)))
-
-(defun -some (pred list)
-  "Return (PRED x) for the first LIST item where (PRED x) is non-nil, else nil.
-
-Alias: `-any'"
-  (--some (funcall pred it) list))
-
-(defalias '-any '-some)
-(defalias '--any '--some)
-
-(defmacro --last (form list)
-  "Anaphoric form of `-last'."
-  (declare (debug (form form)))
-  (let ((n (make-symbol "needle")))
-    `(let (,n)
-       (--each ,list
-         (when ,form (setq ,n it)))
-       ,n)))
-
-(defun -last (pred list)
-  "Return the last x in LIST where (PRED x) is non-nil, else nil."
-  (--last (funcall pred it) list))
-
-(defalias '-first-item 'car
-  "Return the first item of LIST, or nil on an empty list.
-
-See also: `-second-item', `-last-item'.
-
-\(fn LIST)")
-
-;; Ensure that calls to `-first-item' are compiled to a single opcode,
-;; just like `car'.
-(put '-first-item 'byte-opcode 'byte-car)
-(put '-first-item 'byte-compile 'byte-compile-one-arg)
-
-(defalias '-second-item 'cadr
-  "Return the second item of LIST, or nil if LIST is too short.
-
-See also: `-third-item'.
-
-\(fn LIST)")
-
-(defalias '-third-item
-  (if (fboundp 'caddr)
-      #'caddr
-    (lambda (list) (car (cddr list))))
-  "Return the third item of LIST, or nil if LIST is too short.
-
-See also: `-fourth-item'.
-
-\(fn LIST)")
-
-(defun -fourth-item (list)
-  "Return the fourth item of LIST, or nil if LIST is too short.
-
-See also: `-fifth-item'."
-  (declare (pure t) (side-effect-free t))
-  (car (cdr (cdr (cdr list)))))
-
-(defun -fifth-item (list)
-  "Return the fifth item of LIST, or nil if LIST is too short.
-
-See also: `-last-item'."
-  (declare (pure t) (side-effect-free t))
-  (car (cdr (cdr (cdr (cdr list))))))
-
-(defun -last-item (list)
-  "Return the last item of LIST, or nil on an empty list."
-  (declare (pure t) (side-effect-free t))
-  (car (last list)))
-
-;; Use `with-no-warnings' to suppress unbound `-last-item' or
-;; undefined `gv--defsetter' warnings arising from both
-;; `gv-define-setter' and `defsetf' in certain Emacs versions.
-(with-no-warnings
-  (if (fboundp 'gv-define-setter)
-      (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val))
-    (defsetf -last-item (x) (val) `(setcar (last ,x) ,val))))
-
-(defun -butlast (list)
-  "Return a list of all items in list except for the last."
-  ;; no alias as we don't want magic optional argument
-  (declare (pure t) (side-effect-free t))
-  (butlast list))
-
-(defmacro --count (pred list)
-  "Anaphoric form of `-count'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result")))
-    `(let ((,r 0))
-       (--each ,list (when ,pred (setq ,r (1+ ,r))))
-       ,r)))
-
-(defun -count (pred list)
-  "Counts the number of items in LIST where (PRED item) is non-nil."
-  (--count (funcall pred it) list))
-
-(defun ---truthy? (val)
-  (declare (pure t) (side-effect-free t))
-  (not (null val)))
-
-(defmacro --any? (form list)
-  "Anaphoric form of `-any?'."
-  (declare (debug (form form)))
-  `(---truthy? (--some ,form ,list)))
-
-(defun -any? (pred list)
-  "Return t if (PRED x) is non-nil for any x in LIST, else nil.
-
-Alias: `-any-p', `-some?', `-some-p'"
-  (--any? (funcall pred it) list))
-
-(defalias '-some? '-any?)
-(defalias '--some? '--any?)
-(defalias '-any-p '-any?)
-(defalias '--any-p '--any?)
-(defalias '-some-p '-any?)
-(defalias '--some-p '--any?)
-
-(defmacro --all? (form list)
-  "Anaphoric form of `-all?'."
-  (declare (debug (form form)))
-  (let ((a (make-symbol "all")))
-    `(let ((,a t))
-       (--each-while ,list ,a (setq ,a ,form))
-       (---truthy? ,a))))
-
-(defun -all? (pred list)
-  "Return t if (PRED x) is non-nil for all x in LIST, else nil.
-
-Alias: `-all-p', `-every?', `-every-p'"
-  (--all? (funcall pred it) list))
-
-(defalias '-every? '-all?)
-(defalias '--every? '--all?)
-(defalias '-all-p '-all?)
-(defalias '--all-p '--all?)
-(defalias '-every-p '-all?)
-(defalias '--every-p '--all?)
-
-(defmacro --none? (form list)
-  "Anaphoric form of `-none?'."
-  (declare (debug (form form)))
-  `(--all? (not ,form) ,list))
-
-(defun -none? (pred list)
-  "Return t if (PRED x) is nil for all x in LIST, else nil.
-
-Alias: `-none-p'"
-  (--none? (funcall pred it) list))
-
-(defalias '-none-p '-none?)
-(defalias '--none-p '--none?)
-
-(defmacro --only-some? (form list)
-  "Anaphoric form of `-only-some?'."
-  (declare (debug (form form)))
-  (let ((y (make-symbol "yes"))
-        (n (make-symbol "no")))
-    `(let (,y ,n)
-       (--each-while ,list (not (and ,y ,n))
-         (if ,form (setq ,y t) (setq ,n t)))
-       (---truthy? (and ,y ,n)))))
-
-(defun -only-some? (pred list)
-  "Return `t` if at least one item of LIST matches PRED and at least one item of LIST does not match PRED.
-Return `nil` both if all items match the predicate or if none of the items match the predicate.
-
-Alias: `-only-some-p'"
-  (--only-some? (funcall pred it) list))
-
-(defalias '-only-some-p '-only-some?)
-(defalias '--only-some-p '--only-some?)
-
-(defun -slice (list from &optional to step)
-  "Return copy of LIST, starting from index FROM to index TO.
-
-FROM or TO may be negative.  These values are then interpreted
-modulo the length of the list.
-
-If STEP is a number, only each STEPth item in the resulting
-section is returned.  Defaults to 1."
-  (declare (pure t) (side-effect-free t))
-  (let ((length (length list))
-        (new-list nil))
-    ;; to defaults to the end of the list
-    (setq to (or to length))
-    (setq step (or step 1))
-    ;; handle negative indices
-    (when (< from 0)
-      (setq from (mod from length)))
-    (when (< to 0)
-      (setq to (mod to length)))
-
-    ;; iterate through the list, keeping the elements we want
-    (--each-while list (< it-index to)
-      (when (and (>= it-index from)
-                 (= (mod (- from it-index) step) 0))
-        (push it new-list)))
-    (nreverse new-list)))
-
-(defun -take (n list)
-  "Return a new list of the first N items in LIST, or all items if there are fewer than N.
-
-See also: `-take-last'"
-  (declare (pure t) (side-effect-free t))
-  (let (result)
-    (--dotimes n
-      (when list
-        (!cons (car list) result)
-        (!cdr list)))
-    (nreverse result)))
-
-(defun -take-last (n list)
-  "Return the last N items of LIST in order.
-
-See also: `-take'"
-  (declare (pure t) (side-effect-free t))
-  (copy-sequence (last list n)))
-
-(defalias '-drop 'nthcdr
-  "Return the tail of LIST without the first N items.
-
-See also: `-drop-last'
-
-\(fn N LIST)")
-
-(defun -drop-last (n list)
-  "Remove the last N items of LIST and return a copy.
-
-See also: `-drop'"
-  ;; No alias because we don't want magic optional argument
-  (declare (pure t) (side-effect-free t))
-  (butlast list n))
-
-(defmacro --take-while (form list)
-  "Anaphoric form of `-take-while'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result")))
-    `(let (,r)
-       (--each-while ,list ,form (!cons it ,r))
-       (nreverse ,r))))
-
-(defun -take-while (pred list)
-  "Return a new list of successive items from LIST while (PRED item) returns a non-nil value."
-  (--take-while (funcall pred it) list))
-
-(defmacro --drop-while (form list)
-  "Anaphoric form of `-drop-while'."
-  (declare (debug (form form)))
-  (let ((l (make-symbol "list")))
-    `(let ((,l ,list))
-       (while (and ,l (let ((it (car ,l))) ,form))
-         (!cdr ,l))
-       ,l)))
-
-(defun -drop-while (pred list)
-  "Return the tail of LIST starting from the first item for which (PRED item) returns nil."
-  (--drop-while (funcall pred it) list))
-
-(defun -split-at (n list)
-  "Return a list of ((-take N LIST) (-drop N LIST)), in no more than one pass through the list."
-  (declare (pure t) (side-effect-free t))
-  (let (result)
-    (--dotimes n
-      (when list
-        (!cons (car list) result)
-        (!cdr list)))
-    (list (nreverse result) list)))
-
-(defun -rotate (n list)
-  "Rotate LIST N places to the right.  With N negative, rotate to the left.
-The time complexity is O(n)."
-  (declare (pure t) (side-effect-free t))
-  (when list
-    (let* ((len (length list))
-           (n-mod-len (mod n len))
-           (new-tail-len (- len n-mod-len)))
-      (append (-drop new-tail-len list) (-take new-tail-len list)))))
-
-(defun -insert-at (n x list)
-  "Return a list with X inserted into LIST at position N.
-
-See also: `-splice', `-splice-list'"
-  (declare (pure t) (side-effect-free t))
-  (let ((split-list (-split-at n list)))
-    (nconc (car split-list) (cons x (cadr split-list)))))
-
-(defun -replace-at (n x list)
-  "Return a list with element at Nth position in LIST replaced with X.
-
-See also: `-replace'"
-  (declare (pure t) (side-effect-free t))
-  (let ((split-list (-split-at n list)))
-    (nconc (car split-list) (cons x (cdr (cadr split-list))))))
-
-(defun -update-at (n func list)
-  "Return a list with element at Nth position in LIST replaced with `(func (nth n list))`.
-
-See also: `-map-when'"
-  (let ((split-list (-split-at n list)))
-    (nconc (car split-list) (cons (funcall func (car (cadr split-list))) (cdr (cadr split-list))))))
-
-(defmacro --update-at (n form list)
-  "Anaphoric version of `-update-at'."
-  (declare (debug (form form form)))
-  `(-update-at ,n (lambda (it) ,form) ,list))
-
-(defun -remove-at (n list)
-  "Return a list with element at Nth position in LIST removed.
-
-See also: `-remove-at-indices', `-remove'"
-  (declare (pure t) (side-effect-free t))
-  (-remove-at-indices (list n) list))
-
-(defun -remove-at-indices (indices list)
-  "Return a list whose elements are elements from LIST without
-elements selected as `(nth i list)` for all i
-from INDICES.
-
-See also: `-remove-at', `-remove'"
-  (declare (pure t) (side-effect-free t))
-  (let* ((indices (-sort '< indices))
-         (diffs (cons (car indices) (-map '1- (-zip-with '- (cdr indices) indices))))
-         r)
-    (--each diffs
-      (let ((split (-split-at it list)))
-        (!cons (car split) r)
-        (setq list (cdr (cadr split)))))
-    (!cons list r)
-    (apply '-concat (nreverse r))))
-
-(defmacro --split-with (pred list)
-  "Anaphoric form of `-split-with'."
-  (declare (debug (form form)))
-  (let ((l (make-symbol "list"))
-        (r (make-symbol "result"))
-        (c (make-symbol "continue")))
-    `(let ((,l ,list)
-           (,r nil)
-           (,c t))
-       (while (and ,l ,c)
-         (let ((it (car ,l)))
-           (if (not ,pred)
-               (setq ,c nil)
-             (!cons it ,r)
-             (!cdr ,l))))
-       (list (nreverse ,r) ,l))))
-
-(defun -split-with (pred list)
-  "Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)), in no more than one pass through the list."
-  (--split-with (funcall pred it) list))
-
-(defmacro -split-on (item list)
-  "Split the LIST each time ITEM is found.
-
-Unlike `-partition-by', the ITEM is discarded from the results.
-Empty lists are also removed from the result.
-
-Comparison is done by `equal'.
-
-See also `-split-when'"
-  (declare (debug (form form)))
-  `(-split-when (lambda (it) (equal it ,item)) ,list))
-
-(defmacro --split-when (form list)
-  "Anaphoric version of `-split-when'."
-  (declare (debug (form form)))
-  `(-split-when (lambda (it) ,form) ,list))
-
-(defun -split-when (fn list)
-  "Split the LIST on each element where FN returns non-nil.
-
-Unlike `-partition-by', the \"matched\" element is discarded from
-the results.  Empty lists are also removed from the result.
-
-This function can be thought of as a generalization of
-`split-string'."
-  (let (r s)
-    (while list
-      (if (not (funcall fn (car list)))
-          (push (car list) s)
-        (when s (push (nreverse s) r))
-        (setq s nil))
-      (!cdr list))
-    (when s (push (nreverse s) r))
-    (nreverse r)))
-
-(defmacro --separate (form list)
-  "Anaphoric form of `-separate'."
-  (declare (debug (form form)))
-  (let ((y (make-symbol "yes"))
-        (n (make-symbol "no")))
-    `(let (,y ,n)
-       (--each ,list (if ,form (!cons it ,y) (!cons it ,n)))
-       (list (nreverse ,y) (nreverse ,n)))))
-
-(defun -separate (pred list)
-  "Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one pass through the list."
-  (--separate (funcall pred it) list))
-
-(defun ---partition-all-in-steps-reversed (n step list)
-  "Private: Used by -partition-all-in-steps and -partition-in-steps."
-  (when (< step 1)
-    (error "Step must be a positive number, or you're looking at some juicy infinite loops."))
-  (let ((result nil))
-    (while list
-      (!cons (-take n list) result)
-      (setq list (-drop step list)))
-    result))
-
-(defun -partition-all-in-steps (n step list)
-  "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
-The last groups may contain less than N items."
-  (declare (pure t) (side-effect-free t))
-  (nreverse (---partition-all-in-steps-reversed n step list)))
-
-(defun -partition-in-steps (n step list)
-  "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
-If there are not enough items to make the last group N-sized,
-those items are discarded."
-  (declare (pure t) (side-effect-free t))
-  (let ((result (---partition-all-in-steps-reversed n step list)))
-    (while (and result (< (length (car result)) n))
-      (!cdr result))
-    (nreverse result)))
-
-(defun -partition-all (n list)
-  "Return a new list with the items in LIST grouped into N-sized sublists.
-The last group may contain less than N items."
-  (declare (pure t) (side-effect-free t))
-  (-partition-all-in-steps n n list))
-
-(defun -partition (n list)
-  "Return a new list with the items in LIST grouped into N-sized sublists.
-If there are not enough items to make the last group N-sized,
-those items are discarded."
-  (declare (pure t) (side-effect-free t))
-  (-partition-in-steps n n list))
-
-(defmacro --partition-by (form list)
-  "Anaphoric form of `-partition-by'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result"))
-        (s (make-symbol "sublist"))
-        (v (make-symbol "value"))
-        (n (make-symbol "new-value"))
-        (l (make-symbol "list")))
-    `(let ((,l ,list))
-       (when ,l
-         (let* ((,r nil)
-                (it (car ,l))
-                (,s (list it))
-                (,v ,form)
-                (,l (cdr ,l)))
-           (while ,l
-             (let* ((it (car ,l))
-                    (,n ,form))
-               (unless (equal ,v ,n)
-                 (!cons (nreverse ,s) ,r)
-                 (setq ,s nil)
-                 (setq ,v ,n))
-               (!cons it ,s)
-               (!cdr ,l)))
-           (!cons (nreverse ,s) ,r)
-           (nreverse ,r))))))
-
-(defun -partition-by (fn list)
-  "Apply FN to each item in LIST, splitting it each time FN returns a new value."
-  (--partition-by (funcall fn it) list))
-
-(defmacro --partition-by-header (form list)
-  "Anaphoric form of `-partition-by-header'."
-  (declare (debug (form form)))
-  (let ((r (make-symbol "result"))
-        (s (make-symbol "sublist"))
-        (h (make-symbol "header-value"))
-        (b (make-symbol "seen-body?"))
-        (n (make-symbol "new-value"))
-        (l (make-symbol "list")))
-    `(let ((,l ,list))
-       (when ,l
-         (let* ((,r nil)
-                (it (car ,l))
-                (,s (list it))
-                (,h ,form)
-                (,b nil)
-                (,l (cdr ,l)))
-           (while ,l
-             (let* ((it (car ,l))
-                    (,n ,form))
-               (if (equal ,h ,n)
-                   (when ,b
-                     (!cons (nreverse ,s) ,r)
-                     (setq ,s nil)
-                     (setq ,b nil))
-                 (setq ,b t))
-               (!cons it ,s)
-               (!cdr ,l)))
-           (!cons (nreverse ,s) ,r)
-           (nreverse ,r))))))
-
-(defun -partition-by-header (fn list)
-  "Apply FN to the first item in LIST. That is the header
-value. Apply FN to each item in LIST, splitting it each time FN
-returns the header value, but only after seeing at least one
-other value (the body)."
-  (--partition-by-header (funcall fn it) list))
-
-(defun -partition-after-pred (pred list)
-  "Partition directly after each time PRED is true on an element of LIST."
-  (when list
-    (let ((rest (-partition-after-pred pred
-                                       (cdr list))))
-      (if (funcall pred (car list))
-          ;;split after (car list)
-          (cons (list (car list))
-                rest)
-
-        ;;don't split after (car list)
-        (cons (cons (car list)
-                    (car rest))
-              (cdr rest))))))
-
-(defun -partition-before-pred (pred list)
-  "Partition directly before each time PRED is true on an element of LIST."
-  (nreverse (-map #'reverse
-                  (-partition-after-pred pred (reverse list)))))
-
-(defun -partition-after-item (item list)
-  "Partition directly after each time ITEM appears in LIST."
-  (-partition-after-pred (lambda (ele) (equal ele item))
-                         list))
-
-(defun -partition-before-item (item list)
-  "Partition directly before each time ITEM appears in LIST."
-  (-partition-before-pred (lambda (ele) (equal ele item))
-                          list))
-
-(defmacro --group-by (form list)
-  "Anaphoric form of `-group-by'."
-  (declare (debug t))
-  (let ((n (make-symbol "n"))
-        (k (make-symbol "k"))
-        (grp (make-symbol "grp")))
-    `(nreverse
-      (-map
-       (lambda (,n)
-         (cons (car ,n)
-               (nreverse (cdr ,n))))
-       (--reduce-from
-        (let* ((,k (,@form))
-               (,grp (assoc ,k acc)))
-          (if ,grp
-              (setcdr ,grp (cons it (cdr ,grp)))
-            (push
-             (list ,k it)
-             acc))
-          acc)
-        nil ,list)))))
-
-(defun -group-by (fn list)
-  "Separate LIST into an alist whose keys are FN applied to the
-elements of LIST.  Keys are compared by `equal'."
-  (--group-by (funcall fn it) list))
-
-(defun -interpose (sep list)
-  "Return a new list of all elements in LIST separated by SEP."
-  (declare (pure t) (side-effect-free t))
-  (let (result)
-    (when list
-      (!cons (car list) result)
-      (!cdr list))
-    (while list
-      (setq result (cons (car list) (cons sep result)))
-      (!cdr list))
-    (nreverse result)))
-
-(defun -interleave (&rest lists)
-  "Return a new list of the first item in each list, then the second etc."
-  (declare (pure t) (side-effect-free t))
-  (when lists
-    (let (result)
-      (while (-none? 'null lists)
-        (--each lists (!cons (car it) result))
-        (setq lists (-map 'cdr lists)))
-      (nreverse result))))
-
-(defmacro --zip-with (form list1 list2)
-  "Anaphoric form of `-zip-with'.
-
-The elements in list1 are bound as symbol `it', the elements in list2 as symbol `other'."
-  (declare (debug (form form form)))
-  (let ((r (make-symbol "result"))
-        (l1 (make-symbol "list1"))
-        (l2 (make-symbol "list2")))
-    `(let ((,r nil)
-           (,l1 ,list1)
-           (,l2 ,list2))
-       (while (and ,l1 ,l2)
-         (let ((it (car ,l1))
-               (other (car ,l2)))
-           (!cons ,form ,r)
-           (!cdr ,l1)
-           (!cdr ,l2)))
-       (nreverse ,r))))
-
-(defun -zip-with (fn list1 list2)
-  "Zip the two lists LIST1 and LIST2 using a function FN.  This
-function is applied pairwise taking as first argument element of
-LIST1 and as second argument element of LIST2 at corresponding
-position.
-
-The anaphoric form `--zip-with' binds the elements from LIST1 as symbol `it',
-and the elements from LIST2 as symbol `other'."
-  (--zip-with (funcall fn it other) list1 list2))
-
-(defun -zip-lists (&rest lists)
-  "Zip LISTS together.  Group the head of each list, followed by the
-second elements of each list, and so on. The lengths of the returned
-groupings are equal to the length of the shortest input list.
-
-The return value is always list of lists, which is a difference
-from `-zip-pair' which returns a cons-cell in case two input
-lists are provided.
-
-See also: `-zip'"
-  (declare (pure t) (side-effect-free t))
-  (when lists
-    (let (results)
-      (while (-none? 'null lists)
-        (setq results (cons (mapcar 'car lists) results))
-        (setq lists (mapcar 'cdr lists)))
-      (nreverse results))))
-
-(defun -zip (&rest lists)
-  "Zip LISTS together.  Group the head of each list, followed by the
-second elements of each list, and so on. The lengths of the returned
-groupings are equal to the length of the shortest input list.
-
-If two lists are provided as arguments, return the groupings as a list
-of cons cells. Otherwise, return the groupings as a list of lists.
-
-Use `-zip-lists' if you need the return value to always be a list
-of lists.
-
-Alias: `-zip-pair'
-
-See also: `-zip-lists'"
-  (declare (pure t) (side-effect-free t))
-  (when lists
-    (let (results)
-      (while (-none? 'null lists)
-        (setq results (cons (mapcar 'car lists) results))
-        (setq lists (mapcar 'cdr lists)))
-      (setq results (nreverse results))
-      (if (= (length lists) 2)
-          ;; to support backward compatibility, return
-          ;; a cons cell if two lists were provided
-          (--map (cons (car it) (cadr it)) results)
-        results))))
-
-(defalias '-zip-pair '-zip)
-
-(defun -zip-fill (fill-value &rest lists)
-  "Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
-lengths of the returned groupings are equal to the length of the
-longest input list."
-  (declare (pure t) (side-effect-free t))
-  (apply '-zip (apply '-pad (cons fill-value lists))))
-
-(defun -unzip (lists)
-  "Unzip LISTS.
-
-This works just like `-zip' but takes a list of lists instead of
-a variable number of arguments, such that
-
-  (-unzip (-zip L1 L2 L3 ...))
-
-is identity (given that the lists are the same length).
-
-Note in particular that calling this on a list of two lists will
-return a list of cons-cells such that the aboce identity works.
-
-See also: `-zip'"
-  (apply '-zip lists))
-
-(defun -cycle (list)
-  "Return an infinite copy of LIST that will cycle through the
-elements and repeat from the beginning."
-  (declare (pure t) (side-effect-free t))
-  (let ((newlist (-map 'identity list)))
-    (nconc newlist newlist)))
-
-(defun -pad (fill-value &rest lists)
-  "Appends FILL-VALUE to the end of each list in LISTS such that they
-will all have the same length."
-  (let* ((annotations (-annotate 'length lists))
-         (n (-max (-map 'car annotations))))
-    (--map (append (cdr it) (-repeat (- n (car it)) fill-value)) annotations)))
-
-(defun -annotate (fn list)
-  "Return a list of cons cells where each cell is FN applied to each
-element of LIST paired with the unmodified element of LIST."
-  (-zip (-map fn list) list))
-
-(defmacro --annotate (form list)
-  "Anaphoric version of `-annotate'."
-  (declare (debug (form form)))
-  `(-annotate (lambda (it) ,form) ,list))
-
-(defun dash--table-carry (lists restore-lists &optional re)
-  "Helper for `-table' and `-table-flat'.
-
-If a list overflows, carry to the right and reset the list."
-  (while (not (or (car lists)
-                  (equal lists '(nil))))
-    (setcar lists (car restore-lists))
-    (pop (cadr lists))
-    (!cdr lists)
-    (!cdr restore-lists)
-    (when re
-      (push (nreverse (car re)) (cadr re))
-      (setcar re nil)
-      (!cdr re))))
-
-(defun -table (fn &rest lists)
-  "Compute outer product of LISTS using function FN.
-
-The function FN should have the same arity as the number of
-supplied lists.
-
-The outer product is computed by applying fn to all possible
-combinations created by taking one element from each list in
-order.  The dimension of the result is (length lists).
-
-See also: `-table-flat'"
-  (let ((restore-lists (copy-sequence lists))
-        (last-list (last lists))
-        (re (make-list (length lists) nil)))
-    (while (car last-list)
-      (let ((item (apply fn (-map 'car lists))))
-        (push item (car re))
-        (setcar lists (cdar lists)) ;; silence byte compiler
-        (dash--table-carry lists restore-lists re)))
-    (nreverse (car (last re)))))
-
-(defun -table-flat (fn &rest lists)
-  "Compute flat outer product of LISTS using function FN.
-
-The function FN should have the same arity as the number of
-supplied lists.
-
-The outer product is computed by applying fn to all possible
-combinations created by taking one element from each list in
-order.  The results are flattened, ignoring the tensor structure
-of the result.  This is equivalent to calling:
-
-  (-flatten-n (1- (length lists)) (apply \\='-table fn lists))
-
-but the implementation here is much more efficient.
-
-See also: `-flatten-n', `-table'"
-  (let ((restore-lists (copy-sequence lists))
-        (last-list (last lists))
-        re)
-    (while (car last-list)
-      (let ((item (apply fn (-map 'car lists))))
-        (push item re)
-        (setcar lists (cdar lists)) ;; silence byte compiler
-        (dash--table-carry lists restore-lists)))
-    (nreverse re)))
-
-(defun -partial (fn &rest args)
-  "Take a function FN and fewer than the normal arguments to FN,
-and return a fn that takes a variable number of additional ARGS.
-When called, the returned function calls FN with ARGS first and
-then additional args."
-  (apply 'apply-partially fn args))
-
-(defun -elem-index (elem list)
-  "Return the index of the first element in the given LIST which
-is equal to the query element ELEM, or nil if there is no
-such element."
-  (declare (pure t) (side-effect-free t))
-  (car (-elem-indices elem list)))
-
-(defun -elem-indices (elem list)
-  "Return the indices of all elements in LIST equal to the query
-element ELEM, in ascending order."
-  (declare (pure t) (side-effect-free t))
-  (-find-indices (-partial 'equal elem) list))
-
-(defun -find-indices (pred list)
-  "Return the indices of all elements in LIST satisfying the
-predicate PRED, in ascending order."
-  (apply 'append (--map-indexed (when (funcall pred it) (list it-index)) list)))
-
-(defmacro --find-indices (form list)
-  "Anaphoric version of `-find-indices'."
-  (declare (debug (form form)))
-  `(-find-indices (lambda (it) ,form) ,list))
-
-(defun -find-index (pred list)
-  "Take a predicate PRED and a LIST and return the index of the
-first element in the list satisfying the predicate, or nil if
-there is no such element.
-
-See also `-first'."
-  (car (-find-indices pred list)))
-
-(defmacro --find-index (form list)
-  "Anaphoric version of `-find-index'."
-  (declare (debug (form form)))
-  `(-find-index (lambda (it) ,form) ,list))
-
-(defun -find-last-index (pred list)
-  "Take a predicate PRED and a LIST and return the index of the
-last element in the list satisfying the predicate, or nil if
-there is no such element.
-
-See also `-last'."
-  (-last-item (-find-indices pred list)))
-
-(defmacro --find-last-index (form list)
-  "Anaphoric version of `-find-last-index'."
-  `(-find-last-index (lambda (it) ,form) ,list))
-
-(defun -select-by-indices (indices list)
-  "Return a list whose elements are elements from LIST selected
-as `(nth i list)` for all i from INDICES."
-  (declare (pure t) (side-effect-free t))
-  (let (r)
-    (--each indices
-      (!cons (nth it list) r))
-    (nreverse r)))
-
-(defun -select-columns (columns table)
-  "Select COLUMNS from TABLE.
-
-TABLE is a list of lists where each element represents one row.
-It is assumed each row has the same length.
-
-Each row is transformed such that only the specified COLUMNS are
-selected.
-
-See also: `-select-column', `-select-by-indices'"
-  (declare (pure t) (side-effect-free t))
-  (--map (-select-by-indices columns it) table))
-
-(defun -select-column (column table)
-  "Select COLUMN from TABLE.
-
-TABLE is a list of lists where each element represents one row.
-It is assumed each row has the same length.
-
-The single selected column is returned as a list.
-
-See also: `-select-columns', `-select-by-indices'"
-  (declare (pure t) (side-effect-free t))
-  (--mapcat (-select-by-indices (list column) it) table))
-
-(defmacro -> (x &optional form &rest more)
-  "Thread the expr through the forms. Insert X as the second item
-in the first form, making a list of it if it is not a list
-already. If there are more forms, insert the first form as the
-second item in second form, etc."
-  (declare (debug (form &rest [&or symbolp (sexp &rest form)])))
-  (cond
-   ((null form) x)
-   ((null more) (if (listp form)
-                    `(,(car form) ,x ,@(cdr form))
-                  (list form x)))
-   (:else `(-> (-> ,x ,form) ,@more))))
-
-(defmacro ->> (x &optional form &rest more)
-  "Thread the expr through the forms. Insert X as the last item
-in the first form, making a list of it if it is not a list
-already. If there are more forms, insert the first form as the
-last item in second form, etc."
-  (declare (debug ->))
-  (cond
-   ((null form) x)
-   ((null more) (if (listp form)
-                    `(,@form ,x)
-                  (list form x)))
-   (:else `(->> (->> ,x ,form) ,@more))))
-
-(defmacro --> (x &rest forms)
-  "Starting with the value of X, thread each expression through FORMS.
-
-Insert X at the position signified by the symbol `it' in the first
-form.  If there are more forms, insert the first form at the position
-signified by `it' in in second form, etc."
-  (declare (debug (form body)))
-  `(-as-> ,x it ,@forms))
-
-(defmacro -as-> (value variable &rest forms)
-  "Starting with VALUE, thread VARIABLE through FORMS.
-
-In the first form, bind VARIABLE to VALUE.  In the second form, bind
-VARIABLE to the result of the first form, and so forth."
-  (declare (debug (form symbolp body)))
-  (if (null forms)
-      `,value
-    `(let ((,variable ,value))
-       (-as-> ,(if (symbolp (car forms))
-                 (list (car forms) variable)
-               (car forms))
-            ,variable
-              ,@(cdr forms)))))
-
-(defmacro -some-> (x &optional form &rest more)
-  "When expr is non-nil, thread it through the first form (via `->'),
-and when that result is non-nil, through the next form, etc."
-  (declare (debug ->)
-           (indent 1))
-  (if (null form) x
-    (let ((result (make-symbol "result")))
-      `(-some-> (-when-let (,result ,x)
-                  (-> ,result ,form))
-                ,@more))))
-
-(defmacro -some->> (x &optional form &rest more)
-  "When expr is non-nil, thread it through the first form (via `->>'),
-and when that result is non-nil, through the next form, etc."
-  (declare (debug ->)
-           (indent 1))
-  (if (null form) x
-    (let ((result (make-symbol "result")))
-      `(-some->> (-when-let (,result ,x)
-                   (->> ,result ,form))
-                 ,@more))))
-
-(defmacro -some--> (x &optional form &rest more)
-  "When expr in non-nil, thread it through the first form (via `-->'),
-and when that result is non-nil, through the next form, etc."
-  (declare (debug ->)
-           (indent 1))
-  (if (null form) x
-    (let ((result (make-symbol "result")))
-      `(-some--> (-when-let (,result ,x)
-                   (--> ,result ,form))
-                 ,@more))))
-
-(defun -grade-up (comparator list)
-  "Grade elements of LIST using COMPARATOR relation, yielding a
-permutation vector such that applying this permutation to LIST
-sorts it in ascending order."
-  ;; ugly hack to "fix" lack of lexical scope
-  (let ((comp `(lambda (it other) (funcall ',comparator (car it) (car other)))))
-    (->> (--map-indexed (cons it it-index) list)
-         (-sort comp)
-         (-map 'cdr))))
-
-(defun -grade-down (comparator list)
-  "Grade elements of LIST using COMPARATOR relation, yielding a
-permutation vector such that applying this permutation to LIST
-sorts it in descending order."
-  ;; ugly hack to "fix" lack of lexical scope
-  (let ((comp `(lambda (it other) (funcall ',comparator (car other) (car it)))))
-    (->> (--map-indexed (cons it it-index) list)
-         (-sort comp)
-         (-map 'cdr))))
-
-(defvar dash--source-counter 0
-  "Monotonic counter for generated symbols.")
-
-(defun dash--match-make-source-symbol ()
-  "Generate a new dash-source symbol.
-
-All returned symbols are guaranteed to be unique."
-  (prog1 (make-symbol (format "--dash-source-%d--" dash--source-counter))
-    (setq dash--source-counter (1+ dash--source-counter))))
-
-(defun dash--match-ignore-place-p (symbol)
-  "Return non-nil if SYMBOL is a symbol and starts with _."
-  (and (symbolp symbol)
-       (eq (aref (symbol-name symbol) 0) ?_)))
-
-(defun dash--match-cons-skip-cdr (skip-cdr source)
-  "Helper function generating idiomatic shifting code."
-  (cond
-   ((= skip-cdr 0)
-    `(pop ,source))
-   (t
-    `(prog1 ,(dash--match-cons-get-car skip-cdr source)
-       (setq ,source ,(dash--match-cons-get-cdr (1+ skip-cdr) source))))))
-
-(defun dash--match-cons-get-car (skip-cdr source)
-  "Helper function generating idiomatic code to get nth car."
-  (cond
-   ((= skip-cdr 0)
-    `(car ,source))
-   ((= skip-cdr 1)
-    `(cadr ,source))
-   (t
-    `(nth ,skip-cdr ,source))))
-
-(defun dash--match-cons-get-cdr (skip-cdr source)
-  "Helper function generating idiomatic code to get nth cdr."
-  (cond
-   ((= skip-cdr 0)
-    source)
-   ((= skip-cdr 1)
-    `(cdr ,source))
-   (t
-    `(nthcdr ,skip-cdr ,source))))
-
-(defun dash--match-cons (match-form source)
-  "Setup a cons matching environment and call the real matcher."
-  (let ((s (dash--match-make-source-symbol))
-        (n 0)
-        (m match-form))
-    (while (and (consp m)
-                (dash--match-ignore-place-p (car m)))
-      (setq n (1+ n)) (!cdr m))
-    (cond
-     ;; when we only have one pattern in the list, we don't have to
-     ;; create a temporary binding (--dash-source--) for the source
-     ;; and just use the input directly
-     ((and (consp m)
-           (not (cdr m)))
-      (dash--match (car m) (dash--match-cons-get-car n source)))
-     ;; handle other special types
-     ((> n 0)
-      (dash--match m (dash--match-cons-get-cdr n source)))
-     ;; this is the only entry-point for dash--match-cons-1, that's
-     ;; why we can't simply use the above branch, it would produce
-     ;; infinite recursion
-     (t
-      (cons (list s source) (dash--match-cons-1 match-form s))))))
-
-(defun dash--get-expand-function (type)
-  "Get expand function name for TYPE."
-  (intern-soft (format "dash-expand:%s" type)))
-
-(defun dash--match-cons-1 (match-form source &optional props)
-  "Match MATCH-FORM against SOURCE.
-
-MATCH-FORM is a proper or improper list.  Each element of
-MATCH-FORM is either a symbol, which gets bound to the respective
-value in source or another match form which gets destructured
-recursively.
-
-If the cdr of last cons cell in the list is `nil', matching stops
-there.
-
-SOURCE is a proper or improper list."
-  (let ((skip-cdr (or (plist-get props :skip-cdr) 0)))
-    (cond
-     ((consp match-form)
-      (cond
-       ((cdr match-form)
-        (cond
-         ((and (symbolp (car match-form))
-               (functionp (dash--get-expand-function (car match-form))))
-          (dash--match-kv (dash--match-kv-normalize-match-form match-form) (dash--match-cons-get-cdr skip-cdr source)))
-         ((dash--match-ignore-place-p (car match-form))
-          (dash--match-cons-1 (cdr match-form) source
-                              (plist-put props :skip-cdr (1+ skip-cdr))))
-         (t
-          (-concat (dash--match (car match-form) (dash--match-cons-skip-cdr skip-cdr source))
-                   (dash--match-cons-1 (cdr match-form) source)))))
-       (t ;; Last matching place, no need for shift
-        (dash--match (car match-form) (dash--match-cons-get-car skip-cdr source)))))
-     ((eq match-form nil)
-      nil)
-     (t ;; Handle improper lists.  Last matching place, no need for shift
-      (dash--match match-form (dash--match-cons-get-cdr skip-cdr source))))))
-
-(defun dash--vector-tail (seq start)
-  "Return the tail of SEQ starting at START."
-  (cond
-   ((vectorp seq)
-    (let* ((re-length (- (length seq) start))
-           (re (make-vector re-length 0)))
-      (--dotimes re-length (aset re it (aref seq (+ it start))))
-      re))
-   ((stringp seq)
-    (substring seq start))))
-
-(defun dash--match-vector (match-form source)
-  "Setup a vector matching environment and call the real matcher."
-  (let ((s (dash--match-make-source-symbol)))
-    (cond
-     ;; don't bind `s' if we only have one sub-pattern
-     ((= (length match-form) 1)
-      (dash--match (aref match-form 0) `(aref ,source 0)))
-     ;; if the source is a symbol, we don't need to re-bind it
-     ((symbolp source)
-      (dash--match-vector-1 match-form source))
-     ;; don't bind `s' if we only have one sub-pattern which is not ignored
-     ((let* ((ignored-places (mapcar 'dash--match-ignore-place-p match-form))
-             (ignored-places-n (length (-remove 'null ignored-places))))
-        (when (= ignored-places-n (1- (length match-form)))
-          (let ((n (-find-index 'null ignored-places)))
-            (dash--match (aref match-form n) `(aref ,source ,n))))))
-     (t
-      (cons (list s source) (dash--match-vector-1 match-form s))))))
-
-(defun dash--match-vector-1 (match-form source)
-  "Match MATCH-FORM against SOURCE.
-
-MATCH-FORM is a vector.  Each element of MATCH-FORM is either a
-symbol, which gets bound to the respective value in source or
-another match form which gets destructured recursively.
-
-If second-from-last place in MATCH-FORM is the symbol &rest, the
-next element of the MATCH-FORM is matched against the tail of
-SOURCE, starting at index of the &rest symbol.  This is
-conceptually the same as the (head . tail) match for improper
-lists, where dot plays the role of &rest.
-
-SOURCE is a vector.
-
-If the MATCH-FORM vector is shorter than SOURCE vector, only
-the (length MATCH-FORM) places are bound, the rest of the SOURCE
-is discarded."
-  (let ((i 0)
-        (l (length match-form))
-        (re))
-    (while (< i l)
-      (let ((m (aref match-form i)))
-        (push (cond
-               ((and (symbolp m)
-                     (eq m '&rest))
-                (prog1 (dash--match
-                        (aref match-form (1+ i))
-                        `(dash--vector-tail ,source ,i))
-                  (setq i l)))
-               ((and (symbolp m)
-                     ;; do not match symbols starting with _
-                     (not (eq (aref (symbol-name m) 0) ?_)))
-                (list (list m `(aref ,source ,i))))
-               ((not (symbolp m))
-                (dash--match m `(aref ,source ,i))))
-              re)
-        (setq i (1+ i))))
-    (-flatten-n 1 (nreverse re))))
-
-(defun dash--match-kv-normalize-match-form (pattern)
-  "Normalize kv PATTERN.
-
-This method normalizes PATTERN to the format expected by
-`dash--match-kv'.  See `-let' for the specification."
-  (let ((normalized (list (car pattern)))
-        (skip nil)
-        (fill-placeholder (make-symbol "--dash-fill-placeholder--")))
-    (-each (apply '-zip (-pad fill-placeholder (cdr pattern) (cddr pattern)))
-      (lambda (pair)
-        (let ((current (car pair))
-              (next (cdr pair)))
-          (if skip
-              (setq skip nil)
-            (if (or (eq fill-placeholder next)
-                    (not (or (and (symbolp next)
-                                  (not (keywordp next))
-                                  (not (eq next t))
-                                  (not (eq next nil)))
-                             (and (consp next)
-                                  (not (eq (car next) 'quote)))
-                             (vectorp next))))
-                (progn
-                  (cond
-                   ((keywordp current)
-                    (push current normalized)
-                    (push (intern (substring (symbol-name current) 1)) normalized))
-                   ((stringp current)
-                    (push current normalized)
-                    (push (intern current) normalized))
-                   ((and (consp current)
-                         (eq (car current) 'quote))
-                    (push current normalized)
-                    (push (cadr current) normalized))
-                   (t (error "-let: found key `%s' in kv destructuring but its pattern `%s' is invalid and can not be derived from the key" current next)))
-                  (setq skip nil))
-              (push current normalized)
-              (push next normalized)
-              (setq skip t))))))
-    (nreverse normalized)))
-
-(defun dash--match-kv (match-form source)
-  "Setup a kv matching environment and call the real matcher.
-
-kv can be any key-value store, such as plist, alist or hash-table."
-  (let ((s (dash--match-make-source-symbol)))
-    (cond
-     ;; don't bind `s' if we only have one sub-pattern (&type key val)
-     ((= (length match-form) 3)
-      (dash--match-kv-1 (cdr match-form) source (car match-form)))
-     ;; if the source is a symbol, we don't need to re-bind it
-     ((symbolp source)
-      (dash--match-kv-1 (cdr match-form) source (car match-form)))
-     (t
-      (cons (list s source) (dash--match-kv-1 (cdr match-form) s (car match-form)))))))
-
-(defun dash-expand:&hash (key source)
-  "Generate extracting KEY from SOURCE for &hash destructuring."
-  `(gethash ,key ,source))
-
-(defun dash-expand:&plist (key source)
-  "Generate extracting KEY from SOURCE for &plist destructuring."
-  `(plist-get ,source ,key))
-
-(defun dash-expand:&alist (key source)
-  "Generate extracting KEY from SOURCE for &alist destructuring."
-  `(cdr (assoc ,key ,source)))
-
-(defun dash-expand:&hash? (key source)
-  "Generate extracting KEY from SOURCE for &hash? destructuring.
-Similar to &hash but check whether the map is not nil."
-  (let ((src (make-symbol "src")))
-    `(let ((,src ,source))
-       (when ,src (gethash ,key ,src)))))
-
-(defalias 'dash-expand:&keys 'dash-expand:&plist)
-
-(defun dash--match-kv-1 (match-form source type)
-  "Match MATCH-FORM against SOURCE of type TYPE.
-
-MATCH-FORM is a proper list of the form (key1 place1 ... keyN
-placeN).  Each placeK is either a symbol, which gets bound to the
-value of keyK retrieved from the key-value store, or another
-match form which gets destructured recursively.
-
-SOURCE is a key-value store of type TYPE, which can be a plist,
-an alist or a hash table.
-
-TYPE is a token specifying the type of the key-value store.
-Valid values are &plist, &alist and &hash."
-  (-flatten-n 1 (-map
-                 (lambda (kv)
-                   (let* ((k (car kv))
-                          (v (cadr kv))
-                          (getter
-                           (funcall (dash--get-expand-function type) k source)))
-                     (cond
-                      ((symbolp v)
-                       (list (list v getter)))
-                      (t (dash--match v getter)))))
-                 (-partition 2 match-form))))
-
-(defun dash--match-symbol (match-form source)
-  "Bind a symbol.
-
-This works just like `let', there is no destructuring."
-  (list (list match-form source)))
-
-(defun dash--match (match-form source)
-  "Match MATCH-FORM against SOURCE.
-
-This function tests the MATCH-FORM and dispatches to specific
-matchers based on the type of the expression.
-
-Key-value stores are disambiguated by placing a token &plist,
-&alist or &hash as a first item in the MATCH-FORM."
-  (cond
-   ((symbolp match-form)
-    (dash--match-symbol match-form source))
-   ((consp match-form)
-    (cond
-     ;; Handle the "x &as" bindings first.
-     ((and (consp (cdr match-form))
-           (symbolp (car match-form))
-           (eq '&as (cadr match-form)))
-      (let ((s (car match-form)))
-        (cons (list s source)
-              (dash--match (cddr match-form) s))))
-     ((functionp (dash--get-expand-function (car match-form)))
-      (dash--match-kv (dash--match-kv-normalize-match-form match-form) source))
-     (t (dash--match-cons match-form source))))
-   ((vectorp match-form)
-    ;; We support the &as binding in vectors too
-    (cond
-     ((and (> (length match-form) 2)
-           (symbolp (aref match-form 0))
-           (eq '&as (aref match-form 1)))
-      (let ((s (aref match-form 0)))
-        (cons (list s source)
-              (dash--match (dash--vector-tail match-form 2) s))))
-     (t (dash--match-vector match-form source))))))
-
-(defun dash--normalize-let-varlist (varlist)
-  "Normalize VARLIST so that every binding is a list.
-
-`let' allows specifying a binding which is not a list but simply
-the place which is then automatically bound to nil, such that all
-three of the following are identical and evaluate to nil.
-
-  (let (a) a)
-  (let ((a)) a)
-  (let ((a nil)) a)
-
-This function normalizes all of these to the last form."
-  (--map (if (consp it) it (list it nil)) varlist))
-
-(defmacro -let* (varlist &rest body)
-  "Bind variables according to VARLIST then eval BODY.
-
-VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
-PATTERN is matched against the SOURCE structurally.  SOURCE is
-only evaluated once for each PATTERN.
-
-Each SOURCE can refer to the symbols already bound by this
-VARLIST.  This is useful if you want to destructure SOURCE
-recursively but also want to name the intermediate structures.
-
-See `-let' for the list of all possible patterns."
-  (declare (debug ((&rest [&or (sexp form) sexp]) body))
-           (indent 1))
-  (let* ((varlist (dash--normalize-let-varlist varlist))
-         (bindings (--mapcat (dash--match (car it) (cadr it)) varlist)))
-    `(let* ,bindings
-       ,@body)))
-
-(defmacro -let (varlist &rest body)
-  "Bind variables according to VARLIST then eval BODY.
-
-VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
-PATTERN is matched against the SOURCE \"structurally\".  SOURCE
-is only evaluated once for each PATTERN.  Each PATTERN is matched
-recursively, and can therefore contain sub-patterns which are
-matched against corresponding sub-expressions of SOURCE.
-
-All the SOURCEs are evalled before any symbols are
-bound (i.e. \"in parallel\").
-
-If VARLIST only contains one (PATTERN SOURCE) element, you can
-optionally specify it using a vector and discarding the
-outer-most parens.  Thus
-
-  (-let ((PATTERN SOURCE)) ..)
-
-becomes
-
-  (-let [PATTERN SOURCE] ..).
-
-`-let' uses a convention of not binding places (symbols) starting
-with _ whenever it's possible.  You can use this to skip over
-entries you don't care about.  However, this is not *always*
-possible (as a result of implementation) and these symbols might
-get bound to undefined values.
-
-Following is the overview of supported patterns.  Remember that
-patterns can be matched recursively, so every a, b, aK in the
-following can be a matching construct and not necessarily a
-symbol/variable.
-
-Symbol:
-
-  a - bind the SOURCE to A.  This is just like regular `let'.
-
-Conses and lists:
-
-  (a) - bind `car' of cons/list to A
-
-  (a . b) - bind car of cons to A and `cdr' to B
-
-  (a b) - bind car of list to A and `cadr' to B
-
-  (a1 a2 a3  ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3 ...
-
-  (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
-
-Vectors:
-
-  [a] - bind 0th element of a non-list sequence to A (works with
-        vectors, strings, bit arrays...)
-
-  [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st to
-                   A1, 2nd to A2, ...
-                   If the PATTERN is shorter than SOURCE, the values at
-                   places not in PATTERN are ignored.
-                   If the PATTERN is longer than SOURCE, an `error' is
-                   thrown.
-
-  [a1 a2 a3 ... &rest rest] - as above, but bind the rest of
-                              the sequence to REST.  This is
-                              conceptually the same as improper list
-                              matching (a1 a2 ... aN . rest)
-
-Key/value stores:
-
-  (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
-                                 SOURCE plist to aK.  If the
-                                 value is not found, aK is nil.
-                                 Uses `plist-get' to fetch values.
-
-  (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
-                                 SOURCE alist to aK.  If the
-                                 value is not found, aK is nil.
-                                 Uses `assoc' to fetch values.
-
-  (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
-                                SOURCE hash table to aK.  If the
-                                value is not found, aK is nil.
-                                Uses `gethash' to fetch values.
-
-Further, special keyword &keys supports \"inline\" matching of
-plist-like key-value pairs, similarly to &keys keyword of
-`cl-defun'.
-
-  (a1 a2 ... aN &keys key1 b1 ... keyN bK)
-
-This binds N values from the list to a1 ... aN, then interprets
-the cdr as a plist (see key/value matching above).
-
-A shorthand notation for kv-destructuring exists which allows the
-patterns be optionally left out and derived from the key name in
-the following fashion:
-
-- a key :foo is converted into `foo' pattern,
-- a key 'bar is converted into `bar' pattern,
-- a key \"baz\" is converted into `baz' pattern.
-
-That is, the entire value under the key is bound to the derived
-variable without any further destructuring.
-
-This is possible only when the form following the key is not a
-valid pattern (i.e. not a symbol, a cons cell or a vector).
-Otherwise the matching proceeds as usual and in case of an
-invalid spec fails with an error.
-
-Thus the patterns are normalized as follows:
-
-   ;; derive all the missing patterns
-   (&plist :foo 'bar \"baz\") => (&plist :foo foo 'bar bar \"baz\" baz)
-
-   ;; we can specify some but not others
-   (&plist :foo 'bar explicit-bar) => (&plist :foo foo 'bar explicit-bar)
-
-   ;; nothing happens, we store :foo in x
-   (&plist :foo x) => (&plist :foo x)
-
-   ;; nothing happens, we match recursively
-   (&plist :foo (a b c)) => (&plist :foo (a b c))
-
-You can name the source using the syntax SYMBOL &as PATTERN.
-This syntax works with lists (proper or improper), vectors and
-all types of maps.
-
-  (list &as a b c) (list 1 2 3)
-
-binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
-
-Similarly:
-
-  (bounds &as beg . end) (cons 1 2)
-
-binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
-
-  (items &as first . rest) (list 1 2 3)
-
-binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
-
-  [vect &as _ b c] [1 2 3]
-
-binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as usual).
-
-  (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
-
-binds B to 2 and PLIST to (:a 1 :b 2 :c 3).  Same for &alist and &hash.
-
-This is especially useful when we want to capture the result of a
-computation and destructure at the same time.  Consider the
-form (function-returning-complex-structure) returning a list of
-two vectors with two items each.  We want to capture this entire
-result and pass it to another computation, but at the same time
-we want to get the second item from each vector.  We can achieve
-it with pattern
-
-  (result &as [_ a] [_ b]) (function-returning-complex-structure)
-
-Note: Clojure programmers may know this feature as the \":as
-binding\".  The difference is that we put the &as at the front
-because we need to support improper list binding."
-  (declare (debug ([&or (&rest [&or (sexp form) sexp])
-                        (vector [&rest [sexp form]])]
-                   body))
-           (indent 1))
-  (if (vectorp varlist)
-      `(let* ,(dash--match (aref varlist 0) (aref varlist 1))
-         ,@body)
-    (let* ((varlist (dash--normalize-let-varlist varlist))
-           (inputs (--map-indexed (list (make-symbol (format "input%d" it-index)) (cadr it)) varlist))
-           (new-varlist (--map (list (caar it) (cadr it)) (-zip varlist inputs))))
-      `(let ,inputs
-         (-let* ,new-varlist ,@body)))))
-
-(defmacro -lambda (match-form &rest body)
-  "Return a lambda which destructures its input as MATCH-FORM and executes BODY.
-
-Note that you have to enclose the MATCH-FORM in a pair of parens,
-such that:
-
-  (-lambda (x) body)
-  (-lambda (x y ...) body)
-
-has the usual semantics of `lambda'.  Furthermore, these get
-translated into normal lambda, so there is no performance
-penalty.
-
-See `-let' for the description of destructuring mechanism."
-  (declare (doc-string 2) (indent defun)
-           (debug (&define sexp
-                           [&optional stringp]
-                           [&optional ("interactive" interactive)]
-                           def-body)))
-  (cond
-   ((not (consp match-form))
-    (signal 'wrong-type-argument "match-form must be a list"))
-   ;; no destructuring, so just return regular lambda to make things faster
-   ((-all? 'symbolp match-form)
-    `(lambda ,match-form ,@body))
-   (t
-    (let* ((inputs (--map-indexed (list it (make-symbol (format "input%d" it-index))) match-form)))
-      ;; TODO: because inputs to the lambda are evaluated only once,
-      ;; -let* need not to create the extra bindings to ensure that.
-      ;; We should find a way to optimize that.  Not critical however.
-      `(lambda ,(--map (cadr it) inputs)
-         (-let* ,inputs ,@body))))))
-
-(defmacro -setq (&rest forms)
-  "Bind each MATCH-FORM to the value of its VAL.
-
-MATCH-FORM destructuring is done according to the rules of `-let'.
-
-This macro allows you to bind multiple variables by destructuring
-the value, so for example:
-
-  (-setq (a b) x
-         (&plist :c c) plist)
-
-expands roughly speaking to the following code
-
-  (setq a (car x)
-        b (cadr x)
-        c (plist-get plist :c))
-
-Care is taken to only evaluate each VAL once so that in case of
-multiple assignments it does not cause unexpected side effects.
-
-\(fn [MATCH-FORM VAL]...)"
-  (declare (debug (&rest sexp form))
-           (indent 1))
-  (when (= (mod (length forms) 2) 1)
-    (error "Odd number of arguments"))
-  (let* ((forms-and-sources
-          ;; First get all the necessary mappings with all the
-          ;; intermediate bindings.
-          (-map (lambda (x) (dash--match (car x) (cadr x)))
-                (-partition 2 forms)))
-         ;; To preserve the logic of dynamic scoping we must ensure
-         ;; that we `setq' the variables outside of the `let*' form
-         ;; which holds the destructured intermediate values.  For
-         ;; this we generate for each variable a placeholder which is
-         ;; bound to (lexically) the result of the destructuring.
-         ;; Then outside of the helper `let*' form we bind all the
-         ;; original variables to their respective placeholders.
-         ;; TODO: There is a lot of room for possible optimization,
-         ;; for start playing with `special-variable-p' to eliminate
-         ;; unnecessary re-binding.
-         (variables-to-placeholders
-          (-mapcat
-           (lambda (bindings)
-             (-map
-              (lambda (binding)
-                (let ((var (car binding)))
-                  (list var (make-symbol (concat "--dash-binding-" (symbol-name var) "--")))))
-              (--filter (not (string-prefix-p "--" (symbol-name (car it)))) bindings)))
-           forms-and-sources)))
-    `(let ,(-map 'cadr variables-to-placeholders)
-       (let* ,(-flatten-n 1 forms-and-sources)
-         (setq ,@(-flatten (-map 'reverse variables-to-placeholders))))
-       (setq ,@(-flatten variables-to-placeholders)))))
-
-(defmacro -if-let* (vars-vals then &rest else)
-  "If all VALS evaluate to true, bind them to their corresponding
-VARS and do THEN, otherwise do ELSE. VARS-VALS should be a list
-of (VAR VAL) pairs.
-
-Note: binding is done according to `-let*'.  VALS are evaluated
-sequentially, and evaluation stops after the first nil VAL is
-encountered."
-  (declare (debug ((&rest (sexp form)) form body))
-           (indent 2))
-  (->> vars-vals
-       (--mapcat (dash--match (car it) (cadr it)))
-       (--reduce-r-from
-        (let ((var (car it))
-              (val (cadr it)))
-          `(let ((,var ,val))
-             (if ,var ,acc ,@else)))
-        then)))
-
-(defmacro -if-let (var-val then &rest else)
-  "If VAL evaluates to non-nil, bind it to VAR and do THEN,
-otherwise do ELSE.
-
-Note: binding is done according to `-let'.
-
-\(fn (VAR VAL) THEN &rest ELSE)"
-  (declare (debug ((sexp form) form body))
-           (indent 2))
-  `(-if-let* (,var-val) ,then ,@else))
-
-(defmacro --if-let (val then &rest else)
-  "If VAL evaluates to non-nil, bind it to symbol `it' and do THEN,
-otherwise do ELSE."
-  (declare (debug (form form body))
-           (indent 2))
-  `(-if-let (it ,val) ,then ,@else))
-
-(defmacro -when-let* (vars-vals &rest body)
-  "If all VALS evaluate to true, bind them to their corresponding
-VARS and execute body. VARS-VALS should be a list of (VAR VAL)
-pairs.
-
-Note: binding is done according to `-let*'.  VALS are evaluated
-sequentially, and evaluation stops after the first nil VAL is
-encountered."
-  (declare (debug ((&rest (sexp form)) body))
-           (indent 1))
-  `(-if-let* ,vars-vals (progn ,@body)))
-
-(defmacro -when-let (var-val &rest body)
-  "If VAL evaluates to non-nil, bind it to VAR and execute body.
-
-Note: binding is done according to `-let'.
-
-\(fn (VAR VAL) &rest BODY)"
-  (declare (debug ((sexp form) body))
-           (indent 1))
-  `(-if-let ,var-val (progn ,@body)))
-
-(defmacro --when-let (val &rest body)
-  "If VAL evaluates to non-nil, bind it to symbol `it' and
-execute body."
-  (declare (debug (form body))
-           (indent 1))
-  `(--if-let ,val (progn ,@body)))
-
-(defvar -compare-fn nil
-  "Tests for equality use this function or `equal' if this is nil.
-It should only be set using dynamic scope with a let, like:
-
-  (let ((-compare-fn #\\='=)) (-union numbers1 numbers2 numbers3)")
-
-(defun -distinct (list)
-  "Return a new list with all duplicates removed.
-The test for equality is done with `equal',
-or with `-compare-fn' if that's non-nil.
-
-Alias: `-uniq'"
-  ;; Implementation note: The speedup gained from hash table lookup
-  ;; starts to outweigh its overhead for lists of length greater than
-  ;; 32.  See discussion in PR #305.
-  (let* ((len (length list))
-         (lut (and (> len 32)
-                   ;; Check that `-compare-fn' is a valid hash-table
-                   ;; lookup function or `nil'.
-                   (memq -compare-fn '(nil equal eq eql))
-                   (make-hash-table :test (or -compare-fn #'equal)
-                                    :size len))))
-    (if lut
-        (--filter (unless (gethash it lut)
-                    (puthash it t lut))
-                  list)
-      (--each list (unless (-contains? lut it) (!cons it lut)))
-      (nreverse lut))))
-
-(defalias '-uniq '-distinct)
-
-(defun -union (list list2)
-  "Return a new list containing the elements of LIST and elements of LIST2 that are not in LIST.
-The test for equality is done with `equal',
-or with `-compare-fn' if that's non-nil."
-  ;; We fall back to iteration implementation if the comparison
-  ;; function isn't one of `eq', `eql' or `equal'.
-  (let* ((result (reverse list))
-         ;; TODO: get rid of this dynamic variable, pass it as an
-         ;; argument instead.
-         (-compare-fn (if (bound-and-true-p -compare-fn)
-                          -compare-fn
-                        'equal)))
-    (if (memq -compare-fn '(eq eql equal))
-        (let ((ht (make-hash-table :test -compare-fn)))
-          (--each list (puthash it t ht))
-          (--each list2 (unless (gethash it ht) (!cons it result))))
-      (--each list2 (unless (-contains? result it) (!cons it result))))
-    (nreverse result)))
-
-(defun -intersection (list list2)
-  "Return a new list containing only the elements that are members of both LIST and LIST2.
-The test for equality is done with `equal',
-or with `-compare-fn' if that's non-nil."
-  (--filter (-contains? list2 it) list))
-
-(defun -difference (list list2)
-  "Return a new list with only the members of LIST that are not in LIST2.
-The test for equality is done with `equal',
-or with `-compare-fn' if that's non-nil."
-  (--filter (not (-contains? list2 it)) list))
-
-(defun -powerset (list)
-  "Return the power set of LIST."
-  (if (null list) '(())
-    (let ((last (-powerset (cdr list))))
-      (append (mapcar (lambda (x) (cons (car list) x)) last)
-              last))))
-
-(defun -permutations (list)
-  "Return the permutations of LIST."
-  (if (null list) '(())
-    (apply #'append
-           (mapcar (lambda (x)
-                     (mapcar (lambda (perm) (cons x perm))
-                             (-permutations (remove x list))))
-                   list))))
-
-(defun -inits (list)
-  "Return all prefixes of LIST."
-  (let ((res (list list)))
-    (setq list (reverse list))
-    (while list
-      (push (reverse (!cdr list)) res))
-    res))
-
-(defun -tails (list)
-  "Return all suffixes of LIST"
-  (-reductions-r-from 'cons nil list))
-
-(defun -common-prefix (&rest lists)
-  "Return the longest common prefix of LISTS."
-  (declare (pure t) (side-effect-free t))
-  (--reduce (--take-while (and acc (equal (pop acc) it)) it)
-            lists))
-
-(defun -common-suffix (&rest lists)
-  "Return the longest common suffix of LISTS."
-  (nreverse (apply #'-common-prefix (mapcar #'reverse lists))))
-
-(defun -contains? (list element)
-  "Return non-nil if LIST contains ELEMENT.
-
-The test for equality is done with `equal', or with `-compare-fn'
-if that's non-nil.
-
-Alias: `-contains-p'"
-  (not
-   (null
-    (cond
-     ((null -compare-fn)    (member element list))
-     ((eq -compare-fn 'eq)  (memq element list))
-     ((eq -compare-fn 'eql) (memql element list))
-     (t
-      (let ((lst list))
-        (while (and lst
-                    (not (funcall -compare-fn element (car lst))))
-          (setq lst (cdr lst)))
-        lst))))))
-
-(defalias '-contains-p '-contains?)
-
-(defun -same-items? (list list2)
-  "Return true if LIST and LIST2 has the same items.
-
-The order of the elements in the lists does not matter.
-
-Alias: `-same-items-p'"
-  (let ((length-a (length list))
-        (length-b (length list2)))
-    (and
-     (= length-a length-b)
-     (= length-a (length (-intersection list list2))))))
-
-(defalias '-same-items-p '-same-items?)
-
-(defun -is-prefix? (prefix list)
-  "Return non-nil if PREFIX is prefix of LIST.
-
-Alias: `-is-prefix-p'"
-  (declare (pure t) (side-effect-free t))
-  (--each-while list (equal (car prefix) it)
-    (!cdr prefix))
-  (not prefix))
-
-(defun -is-suffix? (suffix list)
-  "Return non-nil if SUFFIX is suffix of LIST.
-
-Alias: `-is-suffix-p'"
-  (declare (pure t) (side-effect-free t))
-  (-is-prefix? (reverse suffix) (reverse list)))
-
-(defun -is-infix? (infix list)
-  "Return non-nil if INFIX is infix of LIST.
-
-This operation runs in O(n^2) time
-
-Alias: `-is-infix-p'"
-  (declare (pure t) (side-effect-free t))
-  (let (done)
-    (while (and (not done) list)
-      (setq done (-is-prefix? infix list))
-      (!cdr list))
-    done))
-
-(defalias '-is-prefix-p '-is-prefix?)
-(defalias '-is-suffix-p '-is-suffix?)
-(defalias '-is-infix-p '-is-infix?)
-
-(defun -sort (comparator list)
-  "Sort LIST, stably, comparing elements using COMPARATOR.
-Return the sorted list.  LIST is NOT modified by side effects.
-COMPARATOR is called with two elements of LIST, and should return non-nil
-if the first element should sort before the second."
-  (sort (copy-sequence list) comparator))
-
-(defmacro --sort (form list)
-  "Anaphoric form of `-sort'."
-  (declare (debug (form form)))
-  `(-sort (lambda (it other) ,form) ,list))
-
-(defun -list (&rest args)
-  "Return a list with ARGS.
-
-If first item of ARGS is already a list, simply return ARGS.  If
-not, return a list with ARGS as elements."
-  (declare (pure t) (side-effect-free t))
-  (let ((arg (car args)))
-    (if (listp arg) arg args)))
-
-(defun -repeat (n x)
-  "Return a list with X repeated N times.
-Return nil if N is less than 1."
-  (declare (pure t) (side-effect-free t))
-  (let (ret)
-    (--dotimes n (!cons x ret))
-    ret))
-
-(defun -sum (list)
-  "Return the sum of LIST."
-  (declare (pure t) (side-effect-free t))
-  (apply '+ list))
-
-(defun -running-sum (list)
-  "Return a list with running sums of items in LIST.
-
-LIST must be non-empty."
-  (declare (pure t) (side-effect-free t))
-  (unless (consp list)
-    (error "LIST must be non-empty"))
-  (-reductions '+ list))
-
-(defun -product (list)
-  "Return the product of LIST."
-  (declare (pure t) (side-effect-free t))
-  (apply '* list))
-
-(defun -running-product (list)
-  "Return a list with running products of items in LIST.
-
-LIST must be non-empty."
-  (declare (pure t) (side-effect-free t))
-  (unless (consp list)
-    (error "LIST must be non-empty"))
-  (-reductions '* list))
-
-(defun -max (list)
-  "Return the largest value from LIST of numbers or markers."
-  (declare (pure t) (side-effect-free t))
-  (apply 'max list))
-
-(defun -min (list)
-  "Return the smallest value from LIST of numbers or markers."
-  (declare (pure t) (side-effect-free t))
-  (apply 'min list))
-
-(defun -max-by (comparator list)
-  "Take a comparison function COMPARATOR and a LIST and return
-the greatest element of the list by the comparison function.
-
-See also combinator `-on' which can transform the values before
-comparing them."
-  (--reduce (if (funcall comparator it acc) it acc) list))
-
-(defun -min-by (comparator list)
-  "Take a comparison function COMPARATOR and a LIST and return
-the least element of the list by the comparison function.
-
-See also combinator `-on' which can transform the values before
-comparing them."
-  (--reduce (if (funcall comparator it acc) acc it) list))
-
-(defmacro --max-by (form list)
-  "Anaphoric version of `-max-by'.
-
-The items for the comparator form are exposed as \"it\" and \"other\"."
-  (declare (debug (form form)))
-  `(-max-by (lambda (it other) ,form) ,list))
-
-(defmacro --min-by (form list)
-  "Anaphoric version of `-min-by'.
-
-The items for the comparator form are exposed as \"it\" and \"other\"."
-  (declare (debug (form form)))
-  `(-min-by (lambda (it other) ,form) ,list))
-
-(defun -iterate (fun init n)
-  "Return a list of iterated applications of FUN to INIT.
-
-This means a list of form:
-
-  (init (fun init) (fun (fun init)) ...)
-
-N is the length of the returned list."
-  (if (= n 0) nil
-    (let ((r (list init)))
-      (--dotimes (1- n)
-        (push (funcall fun (car r)) r))
-      (nreverse r))))
-
-(defun -fix (fn list)
-  "Compute the (least) fixpoint of FN with initial input LIST.
-
-FN is called at least once, results are compared with `equal'."
-  (let ((re (funcall fn list)))
-    (while (not (equal list re))
-      (setq list re)
-      (setq re (funcall fn re)))
-    re))
-
-(defmacro --fix (form list)
-  "Anaphoric form of `-fix'."
-  `(-fix (lambda (it) ,form) ,list))
-
-(defun -unfold (fun seed)
-  "Build a list from SEED using FUN.
-
-This is \"dual\" operation to `-reduce-r': while -reduce-r
-consumes a list to produce a single value, `-unfold' takes a
-seed value and builds a (potentially infinite!) list.
-
-FUN should return `nil' to stop the generating process, or a
-cons (A . B), where A will be prepended to the result and B is
-the new seed."
-  (let ((last (funcall fun seed)) r)
-    (while last
-      (push (car last) r)
-      (setq last (funcall fun (cdr last))))
-    (nreverse r)))
-
-(defmacro --unfold (form seed)
-  "Anaphoric version of `-unfold'."
-  (declare (debug (form form)))
-  `(-unfold (lambda (it) ,form) ,seed))
-
-(defun -cons-pair? (con)
-  "Return non-nil if CON is true cons pair.
-That is (A . B) where B is not a list.
-
-Alias: `-cons-pair-p'"
-  (declare (pure t) (side-effect-free t))
-  (and (listp con)
-       (not (listp (cdr con)))))
-
-(defalias '-cons-pair-p '-cons-pair?)
-
-(defun -cons-to-list (con)
-  "Convert a cons pair to a list with `car' and `cdr' of the pair respectively."
-  (declare (pure t) (side-effect-free t))
-  (list (car con) (cdr con)))
-
-(defun -value-to-list (val)
-  "Convert a value to a list.
-
-If the value is a cons pair, make a list with two elements, `car'
-and `cdr' of the pair respectively.
-
-If the value is anything else, wrap it in a list."
-  (declare (pure t) (side-effect-free t))
-  (cond
-   ((-cons-pair? val) (-cons-to-list val))
-   (t (list val))))
-
-(defun -tree-mapreduce-from (fn folder init-value tree)
-  "Apply FN to each element of TREE, and make a list of the results.
-If elements of TREE are lists themselves, apply FN recursively to
-elements of these nested lists.
-
-Then reduce the resulting lists using FOLDER and initial value
-INIT-VALUE. See `-reduce-r-from'.
-
-This is the same as calling `-tree-reduce-from' after `-tree-map'
-but is twice as fast as it only traverse the structure once."
-  (cond
-   ((not tree) nil)
-   ((-cons-pair? tree) (funcall fn tree))
-   ((listp tree)
-    (-reduce-r-from folder init-value (mapcar (lambda (x) (-tree-mapreduce-from fn folder init-value x)) tree)))
-   (t (funcall fn tree))))
-
-(defmacro --tree-mapreduce-from (form folder init-value tree)
-  "Anaphoric form of `-tree-mapreduce-from'."
-  (declare (debug (form form form form)))
-  `(-tree-mapreduce-from (lambda (it) ,form) (lambda (it acc) ,folder) ,init-value ,tree))
-
-(defun -tree-mapreduce (fn folder tree)
-  "Apply FN to each element of TREE, and make a list of the results.
-If elements of TREE are lists themselves, apply FN recursively to
-elements of these nested lists.
-
-Then reduce the resulting lists using FOLDER and initial value
-INIT-VALUE. See `-reduce-r-from'.
-
-This is the same as calling `-tree-reduce' after `-tree-map'
-but is twice as fast as it only traverse the structure once."
-  (cond
-   ((not tree) nil)
-   ((-cons-pair? tree) (funcall fn tree))
-   ((listp tree)
-    (-reduce-r folder (mapcar (lambda (x) (-tree-mapreduce fn folder x)) tree)))
-   (t (funcall fn tree))))
-
-(defmacro --tree-mapreduce (form folder tree)
-  "Anaphoric form of `-tree-mapreduce'."
-  (declare (debug (form form form)))
-  `(-tree-mapreduce (lambda (it) ,form) (lambda (it acc) ,folder) ,tree))
-
-(defun -tree-map (fn tree)
-  "Apply FN to each element of TREE while preserving the tree structure."
-  (cond
-   ((not tree) nil)
-   ((-cons-pair? tree) (funcall fn tree))
-   ((listp tree)
-    (mapcar (lambda (x) (-tree-map fn x)) tree))
-   (t (funcall fn tree))))
-
-(defmacro --tree-map (form tree)
-  "Anaphoric form of `-tree-map'."
-  (declare (debug (form form)))
-  `(-tree-map (lambda (it) ,form) ,tree))
-
-(defun -tree-reduce-from (fn init-value tree)
-  "Use FN to reduce elements of list TREE.
-If elements of TREE are lists themselves, apply the reduction recursively.
-
-FN is first applied to INIT-VALUE and first element of the list,
-then on this result and second element from the list etc.
-
-The initial value is ignored on cons pairs as they always contain
-two elements."
-  (cond
-   ((not tree) nil)
-   ((-cons-pair? tree) tree)
-   ((listp tree)
-    (-reduce-r-from fn init-value (mapcar (lambda (x) (-tree-reduce-from fn init-value x)) tree)))
-   (t tree)))
-
-(defmacro --tree-reduce-from (form init-value tree)
-  "Anaphoric form of `-tree-reduce-from'."
-  (declare (debug (form form form)))
-  `(-tree-reduce-from (lambda (it acc) ,form) ,init-value ,tree))
-
-(defun -tree-reduce (fn tree)
-  "Use FN to reduce elements of list TREE.
-If elements of TREE are lists themselves, apply the reduction recursively.
-
-FN is first applied to first element of the list and second
-element, then on this result and third element from the list etc.
-
-See `-reduce-r' for how exactly are lists of zero or one element handled."
-  (cond
-   ((not tree) nil)
-   ((-cons-pair? tree) tree)
-   ((listp tree)
-    (-reduce-r fn (mapcar (lambda (x) (-tree-reduce fn x)) tree)))
-   (t tree)))
-
-(defmacro --tree-reduce (form tree)
-  "Anaphoric form of `-tree-reduce'."
-  (declare (debug (form form)))
-  `(-tree-reduce (lambda (it acc) ,form) ,tree))
-
-(defun -tree-map-nodes (pred fun tree)
-  "Call FUN on each node of TREE that satisfies PRED.
-
-If PRED returns nil, continue descending down this node.  If PRED
-returns non-nil, apply FUN to this node and do not descend
-further."
-  (if (funcall pred tree)
-      (funcall fun tree)
-    (if (and (listp tree)
-             (not (-cons-pair? tree)))
-        (-map (lambda (x) (-tree-map-nodes pred fun x)) tree)
-      tree)))
-
-(defmacro --tree-map-nodes (pred form tree)
-  "Anaphoric form of `-tree-map-nodes'."
-  `(-tree-map-nodes (lambda (it) ,pred) (lambda (it) ,form) ,tree))
-
-(defun -tree-seq (branch children tree)
-  "Return a sequence of the nodes in TREE, in depth-first search order.
-
-BRANCH is a predicate of one argument that returns non-nil if the
-passed argument is a branch, that is, a node that can have children.
-
-CHILDREN is a function of one argument that returns the children
-of the passed branch node.
-
-Non-branch nodes are simply copied."
-  (cons tree
-        (when (funcall branch tree)
-          (-mapcat (lambda (x) (-tree-seq branch children x))
-                   (funcall children tree)))))
-
-(defmacro --tree-seq (branch children tree)
-  "Anaphoric form of `-tree-seq'."
-  `(-tree-seq (lambda (it) ,branch) (lambda (it) ,children) ,tree))
-
-(defun -clone (list)
-  "Create a deep copy of LIST.
-The new list has the same elements and structure but all cons are
-replaced with new ones.  This is useful when you need to clone a
-structure such as plist or alist."
-  (declare (pure t) (side-effect-free t))
-  (-tree-map 'identity list))
-
-(defun dash-enable-font-lock ()
-  "Add syntax highlighting to dash functions, macros and magic values."
-  (eval-after-load 'lisp-mode
-    '(progn
-       (let ((new-keywords '(
-                             "!cons"
-                             "!cdr"
-                             "-each"
-                             "--each"
-                             "-each-indexed"
-                             "--each-indexed"
-                             "-each-while"
-                             "--each-while"
-                             "-doto"
-                             "-dotimes"
-                             "--dotimes"
-                             "-map"
-                             "--map"
-                             "-reduce-from"
-                             "--reduce-from"
-                             "-reduce"
-                             "--reduce"
-                             "-reduce-r-from"
-                             "--reduce-r-from"
-                             "-reduce-r"
-                             "--reduce-r"
-                             "-reductions-from"
-                             "-reductions-r-from"
-                             "-reductions"
-                             "-reductions-r"
-                             "-filter"
-                             "--filter"
-                             "-select"
-                             "--select"
-                             "-remove"
-                             "--remove"
-                             "-reject"
-                             "--reject"
-                             "-remove-first"
-                             "--remove-first"
-                             "-reject-first"
-                             "--reject-first"
-                             "-remove-last"
-                             "--remove-last"
-                             "-reject-last"
-                             "--reject-last"
-                             "-remove-item"
-                             "-non-nil"
-                             "-keep"
-                             "--keep"
-                             "-map-indexed"
-                             "--map-indexed"
-                             "-splice"
-                             "--splice"
-                             "-splice-list"
-                             "--splice-list"
-                             "-map-when"
-                             "--map-when"
-                             "-replace-where"
-                             "--replace-where"
-                             "-map-first"
-                             "--map-first"
-                             "-map-last"
-                             "--map-last"
-                             "-replace"
-                             "-replace-first"
-                             "-replace-last"
-                             "-flatten"
-                             "-flatten-n"
-                             "-concat"
-                             "-mapcat"
-                             "--mapcat"
-                             "-copy"
-                             "-cons*"
-                             "-snoc"
-                             "-first"
-                             "--first"
-                             "-find"
-                             "--find"
-                             "-some"
-                             "--some"
-                             "-any"
-                             "--any"
-                             "-last"
-                             "--last"
-                             "-first-item"
-                             "-second-item"
-                             "-third-item"
-                             "-fourth-item"
-                             "-fifth-item"
-                             "-last-item"
-                             "-butlast"
-                             "-count"
-                             "--count"
-                             "-any?"
-                             "--any?"
-                             "-some?"
-                             "--some?"
-                             "-any-p"
-                             "--any-p"
-                             "-some-p"
-                             "--some-p"
-                             "-some->"
-                             "-some->>"
-                             "-some-->"
-                             "-all?"
-                             "-all-p"
-                             "--all?"
-                             "--all-p"
-                             "-every?"
-                             "--every?"
-                             "-all-p"
-                             "--all-p"
-                             "-every-p"
-                             "--every-p"
-                             "-none?"
-                             "--none?"
-                             "-none-p"
-                             "--none-p"
-                             "-only-some?"
-                             "--only-some?"
-                             "-only-some-p"
-                             "--only-some-p"
-                             "-slice"
-                             "-take"
-                             "-drop"
-                             "-drop-last"
-                             "-take-last"
-                             "-take-while"
-                             "--take-while"
-                             "-drop-while"
-                             "--drop-while"
-                             "-split-at"
-                             "-rotate"
-                             "-insert-at"
-                             "-replace-at"
-                             "-update-at"
-                             "--update-at"
-                             "-remove-at"
-                             "-remove-at-indices"
-                             "-split-with"
-                             "--split-with"
-                             "-split-on"
-                             "-split-when"
-                             "--split-when"
-                             "-separate"
-                             "--separate"
-                             "-partition-all-in-steps"
-                             "-partition-in-steps"
-                             "-partition-all"
-                             "-partition"
-                             "-partition-after-item"
-                             "-partition-after-pred"
-                             "-partition-before-item"
-                             "-partition-before-pred"
-                             "-partition-by"
-                             "--partition-by"
-                             "-partition-by-header"
-                             "--partition-by-header"
-                             "-group-by"
-                             "--group-by"
-                             "-interpose"
-                             "-interleave"
-                             "-unzip"
-                             "-zip-with"
-                             "--zip-with"
-                             "-zip"
-                             "-zip-fill"
-                             "-zip-lists"
-                             "-zip-pair"
-                             "-cycle"
-                             "-pad"
-                             "-annotate"
-                             "--annotate"
-                             "-table"
-                             "-table-flat"
-                             "-partial"
-                             "-elem-index"
-                             "-elem-indices"
-                             "-find-indices"
-                             "--find-indices"
-                             "-find-index"
-                             "--find-index"
-                             "-find-last-index"
-                             "--find-last-index"
-                             "-select-by-indices"
-                             "-select-columns"
-                             "-select-column"
-                             "-grade-up"
-                             "-grade-down"
-                             "->"
-                             "->>"
-                             "-->"
-                             "-as->"
-                             "-when-let"
-                             "-when-let*"
-                             "--when-let"
-                             "-if-let"
-                             "-if-let*"
-                             "--if-let"
-                             "-let*"
-                             "-let"
-                             "-lambda"
-                             "-distinct"
-                             "-uniq"
-                             "-union"
-                             "-intersection"
-                             "-difference"
-                             "-powerset"
-                             "-permutations"
-                             "-inits"
-                             "-tails"
-                             "-common-prefix"
-                             "-common-suffix"
-                             "-contains?"
-                             "-contains-p"
-                             "-same-items?"
-                             "-same-items-p"
-                             "-is-prefix-p"
-                             "-is-prefix?"
-                             "-is-suffix-p"
-                             "-is-suffix?"
-                             "-is-infix-p"
-                             "-is-infix?"
-                             "-sort"
-                             "--sort"
-                             "-list"
-                             "-repeat"
-                             "-sum"
-                             "-running-sum"
-                             "-product"
-                             "-running-product"
-                             "-max"
-                             "-min"
-                             "-max-by"
-                             "--max-by"
-                             "-min-by"
-                             "--min-by"
-                             "-iterate"
-                             "--iterate"
-                             "-fix"
-                             "--fix"
-                             "-unfold"
-                             "--unfold"
-                             "-cons-pair?"
-                             "-cons-pair-p"
-                             "-cons-to-list"
-                             "-value-to-list"
-                             "-tree-mapreduce-from"
-                             "--tree-mapreduce-from"
-                             "-tree-mapreduce"
-                             "--tree-mapreduce"
-                             "-tree-map"
-                             "--tree-map"
-                             "-tree-reduce-from"
-                             "--tree-reduce-from"
-                             "-tree-reduce"
-                             "--tree-reduce"
-                             "-tree-seq"
-                             "--tree-seq"
-                             "-tree-map-nodes"
-                             "--tree-map-nodes"
-                             "-clone"
-                             "-rpartial"
-                             "-juxt"
-                             "-applify"
-                             "-on"
-                             "-flip"
-                             "-const"
-                             "-cut"
-                             "-orfn"
-                             "-andfn"
-                             "-iteratefn"
-                             "-fixfn"
-                             "-prodfn"
-                             ))
-             (special-variables '(
-                                  "it"
-                                  "it-index"
-                                  "acc"
-                                  "other"
-                                  )))
-         (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "\\_<" (regexp-opt special-variables 'paren) "\\_>")
-                                                     1 font-lock-variable-name-face)) 'append)
-         (font-lock-add-keywords 'emacs-lisp-mode `((,(concat "(\\s-*" (regexp-opt new-keywords 'paren) "\\_>")
-                                                     1 font-lock-keyword-face)) 'append))
-       (--each (buffer-list)
-         (with-current-buffer it
-           (when (and (eq major-mode 'emacs-lisp-mode)
-                      (boundp 'font-lock-mode)
-                      font-lock-mode)
-             (font-lock-refresh-defaults)))))))
-
-(provide 'dash)
-;;; dash.el ends here
diff --git a/elpa/dash-20200119.2310/dash.info b/elpa/dash-20200119.2310/dash.info
deleted file mode 100644 (file)
index ee791c4..0000000
+++ /dev/null
@@ -1,3410 +0,0 @@
-This is dash.info, produced by makeinfo version 6.5 from dash.texi.
-
-This manual is for â€˜dash.el’ version 2.12.1.
-
-   Copyright Â© 2012-2015 Magnar Sveen
-
-     This program is free software; you can redistribute it and/or
-     modify it under the terms of the GNU General Public License as
-     published by the Free Software Foundation, either version 3 of the
-     License, or (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program.  If not, see
-     <http://www.gnu.org/licenses/>.
-INFO-DIR-SECTION Emacs
-START-INFO-DIR-ENTRY
-* Dash: (dash.info). A modern list library for GNU Emacs
-END-INFO-DIR-ENTRY
-
-\1f
-File: dash.info,  Node: Top,  Next: Installation,  Up: (dir)
-
-dash
-****
-
-This manual is for â€˜dash.el’ version 2.12.1.
-
-   Copyright Â© 2012-2015 Magnar Sveen
-
-     This program is free software; you can redistribute it and/or
-     modify it under the terms of the GNU General Public License as
-     published by the Free Software Foundation, either version 3 of the
-     License, or (at your option) any later version.
-
-     This program is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-     General Public License for more details.
-
-     You should have received a copy of the GNU General Public License
-     along with this program.  If not, see
-     <http://www.gnu.org/licenses/>.
-
-* Menu:
-
-* Installation::
-* Functions::
-* Development::
-* Index::
-
-— The Detailed Node Listing â€”
-
-Installation
-
-* Using in a package::
-* Syntax highlighting of dash functions::
-
-Functions
-
-* Maps::
-* Sublist selection::
-* List to list::
-* Reductions::
-* Unfolding::
-* Predicates::
-* Partitioning::
-* Indexing::
-* Set operations::
-* Other list operations::
-* Tree operations::
-* Threading macros::
-* Binding::
-* Side-effects::
-* Destructive operations::
-* Function combinators::
-
-Development
-
-* Contribute::          How to contribute
-* Changes::             List of significant changes by version
-* Contributors::        List of contributors
-
-\1f
-File: dash.info,  Node: Installation,  Next: Functions,  Prev: Top,  Up: Top
-
-1 Installation
-**************
-
-It’s available on Melpa (https://melpa.org/); use â€˜M-x package-install’:
-
-‘M-x package-install <RET> dash’
-     Install the dash library.
-
-‘M-x package-install <RET> dash-functional’
-     Optional, if you want the function combinators.
-
-   Alternatively, you can just dump dash.el or dash-functional.el in
-your load path somewhere.
-
-* Menu:
-
-* Using in a package::
-* Syntax highlighting of dash functions::
-
-\1f
-File: dash.info,  Node: Using in a package,  Next: Syntax highlighting of dash functions,  Up: Installation
-
-1.1 Using in a package
-======================
-
-Add this to the big comment block at the top:
-
-     ;; Package-Requires: ((dash "2.12.1"))
-
-To get function combinators:
-
-     ;; Package-Requires: ((dash "2.12.1") (dash-functional "1.2.0") (emacs "24"))
-
-\1f
-File: dash.info,  Node: Syntax highlighting of dash functions,  Prev: Using in a package,  Up: Installation
-
-1.2 Syntax highlighting of dash functions
-=========================================
-
-Font lock of dash functions in emacs lisp buffers is now optional.
-Include this in your emacs settings to get syntax highlighting:
-
-     (eval-after-load 'dash '(dash-enable-font-lock))
-
-\1f
-File: dash.info,  Node: Functions,  Next: Development,  Prev: Installation,  Up: Top
-
-2 Functions
-***********
-
-This chapter contains reference documentation for the dash application
-programming interface (API). All functions and constructs in the library
-are prefixed with a dash (-).
-
-   There are also anaphoric versions of functions where that makes
-sense, prefixed with two dashes instead of one.
-
-   For instance, while â€˜-map’ takes a function to map over the list, one
-can also use the anaphoric form with double dashes - which will then be
-executed with â€˜it’ exposed as the list item.  Here’s an example:
-
-     (-map (lambda (n) (* n n)) '(1 2 3 4)) ;; normal version
-
-     (--map (* it it) '(1 2 3 4)) ;; anaphoric version
-
-Of course, the original can also be written like
-
-     (defun square (n) (* n n))
-
-     (-map 'square '(1 2 3 4))
-
-which demonstrates the usefulness of both versions.
-
-* Menu:
-
-* Maps::
-* Sublist selection::
-* List to list::
-* Reductions::
-* Unfolding::
-* Predicates::
-* Partitioning::
-* Indexing::
-* Set operations::
-* Other list operations::
-* Tree operations::
-* Threading macros::
-* Binding::
-* Side-effects::
-* Destructive operations::
-* Function combinators::
-
-\1f
-File: dash.info,  Node: Maps,  Next: Sublist selection,  Up: Functions
-
-2.1 Maps
-========
-
-Functions in this category take a transforming function, which is then
-applied sequentially to each or selected elements of the input list.
-The results are collected in order and returned as new list.
-
- -- Function: -map (fn list)
-     Return a new list consisting of the result of applying FN to the
-     items in LIST.
-
-          (-map (lambda (num) (* num num)) '(1 2 3 4))
-              â‡’ '(1 4 9 16)
-          (-map 'square '(1 2 3 4))
-              â‡’ '(1 4 9 16)
-          (--map (* it it) '(1 2 3 4))
-              â‡’ '(1 4 9 16)
-
- -- Function: -map-when (pred rep list)
-     Return a new list where the elements in LIST that do not match the
-     PRED function are unchanged, and where the elements in LIST that do
-     match the PRED function are mapped through the REP function.
-
-     Alias: â€˜-replace-where’
-
-     See also: â€˜-update-at’ (*note -update-at::)
-
-          (-map-when 'even? 'square '(1 2 3 4))
-              â‡’ '(1 4 3 16)
-          (--map-when (> it 2) (* it it) '(1 2 3 4))
-              â‡’ '(1 2 9 16)
-          (--map-when (= it 2) 17 '(1 2 3 4))
-              â‡’ '(1 17 3 4)
-
- -- Function: -map-first (pred rep list)
-     Replace first item in LIST satisfying PRED with result of REP
-     called on this item.
-
-     See also: â€˜-map-when’ (*note -map-when::), â€˜-replace-first’ (*note
-     -replace-first::)
-
-          (-map-first 'even? 'square '(1 2 3 4))
-              â‡’ '(1 4 3 4)
-          (--map-first (> it 2) (* it it) '(1 2 3 4))
-              â‡’ '(1 2 9 4)
-          (--map-first (= it 2) 17 '(1 2 3 2))
-              â‡’ '(1 17 3 2)
-
- -- Function: -map-last (pred rep list)
-     Replace last item in LIST satisfying PRED with result of REP called
-     on this item.
-
-     See also: â€˜-map-when’ (*note -map-when::), â€˜-replace-last’ (*note
-     -replace-last::)
-
-          (-map-last 'even? 'square '(1 2 3 4))
-              â‡’ '(1 2 3 16)
-          (--map-last (> it 2) (* it it) '(1 2 3 4))
-              â‡’ '(1 2 3 16)
-          (--map-last (= it 2) 17 '(1 2 3 2))
-              â‡’ '(1 2 3 17)
-
- -- Function: -map-indexed (fn list)
-     Return a new list consisting of the result of (FN index item) for
-     each item in LIST.
-
-     In the anaphoric form â€˜--map-indexed’, the index is exposed as
-     symbol â€˜it-index’.
-
-     See also: â€˜-each-indexed’ (*note -each-indexed::).
-
-          (-map-indexed (lambda (index item) (- item index)) '(1 2 3 4))
-              â‡’ '(1 1 1 1)
-          (--map-indexed (- it it-index) '(1 2 3 4))
-              â‡’ '(1 1 1 1)
-
- -- Function: -annotate (fn list)
-     Return a list of cons cells where each cell is FN applied to each
-     element of LIST paired with the unmodified element of LIST.
-
-          (-annotate '1+ '(1 2 3))
-              â‡’ '((2 . 1) (3 . 2) (4 . 3))
-          (-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world")))
-              â‡’ '((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
-          (--annotate (< 1 it) '(0 1 2 3))
-              â‡’ '((nil . 0) (nil . 1) (t . 2) (t . 3))
-
- -- Function: -splice (pred fun list)
-     Splice lists generated by FUN in place of elements matching PRED in
-     LIST.
-
-     FUN takes the element matching PRED as input.
-
-     This function can be used as replacement for â€˜,@’ in case you need
-     to splice several lists at marked positions (for example with
-     keywords).
-
-     See also: â€˜-splice-list’ (*note -splice-list::), â€˜-insert-at’
-     (*note -insert-at::)
-
-          (-splice 'even? (lambda (x) (list x x)) '(1 2 3 4))
-              â‡’ '(1 2 2 3 4 4)
-          (--splice 't (list it it) '(1 2 3 4))
-              â‡’ '(1 1 2 2 3 3 4 4)
-          (--splice (equal it :magic) '((list of) (magical) (code)) '((foo) (bar) :magic (baz)))
-              â‡’ '((foo) (bar) (list of) (magical) (code) (baz))
-
- -- Function: -splice-list (pred new-list list)
-     Splice NEW-LIST in place of elements matching PRED in LIST.
-
-     See also: â€˜-splice’ (*note -splice::), â€˜-insert-at’ (*note
-     -insert-at::)
-
-          (-splice-list 'keywordp '(a b c) '(1 :foo 2))
-              â‡’ '(1 a b c 2)
-          (-splice-list 'keywordp nil '(1 :foo 2))
-              â‡’ '(1 2)
-          (--splice-list (keywordp it) '(a b c) '(1 :foo 2))
-              â‡’ '(1 a b c 2)
-
- -- Function: -mapcat (fn list)
-     Return the concatenation of the result of mapping FN over LIST.
-     Thus function FN should return a list.
-
-          (-mapcat 'list '(1 2 3))
-              â‡’ '(1 2 3)
-          (-mapcat (lambda (item) (list 0 item)) '(1 2 3))
-              â‡’ '(0 1 0 2 0 3)
-          (--mapcat (list 0 it) '(1 2 3))
-              â‡’ '(0 1 0 2 0 3)
-
- -- Function: -copy (arg)
-     Create a shallow copy of LIST.
-
-     (fn LIST)
-
-          (-copy '(1 2 3))
-              â‡’ '(1 2 3)
-          (let ((a '(1 2 3))) (eq a (-copy a)))
-              â‡’ nil
-
-\1f
-File: dash.info,  Node: Sublist selection,  Next: List to list,  Prev: Maps,  Up: Functions
-
-2.2 Sublist selection
-=====================
-
-Functions returning a sublist of the original list.
-
- -- Function: -filter (pred list)
-     Return a new list of the items in LIST for which PRED returns a
-     non-nil value.
-
-     Alias: â€˜-select’
-
-     See also: â€˜-keep’ (*note -keep::), â€˜-remove’ (*note -remove::).
-
-          (-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
-              â‡’ '(2 4)
-          (-filter 'even? '(1 2 3 4))
-              â‡’ '(2 4)
-          (--filter (= 0 (% it 2)) '(1 2 3 4))
-              â‡’ '(2 4)
-
- -- Function: -remove (pred list)
-     Return a new list of the items in LIST for which PRED returns nil.
-
-     Alias: â€˜-reject’
-
-     See also: â€˜-filter’ (*note -filter::).
-
-          (-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
-              â‡’ '(1 3)
-          (-remove 'even? '(1 2 3 4))
-              â‡’ '(1 3)
-          (--remove (= 0 (% it 2)) '(1 2 3 4))
-              â‡’ '(1 3)
-
- -- Function: -remove-first (pred list)
-     Return a new list with the first item matching PRED removed.
-
-     Alias: â€˜-reject-first’
-
-     See also: â€˜-remove’ (*note -remove::), â€˜-map-first’ (*note
-     -map-first::)
-
-          (-remove-first 'even? '(1 3 5 4 7 8 10))
-              â‡’ '(1 3 5 7 8 10)
-          (-remove-first 'stringp '(1 2 "first" "second" "third"))
-              â‡’ '(1 2 "second" "third")
-          (--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10))
-              â‡’ '(1 2 3 5 6 7 8 9 10)
-
- -- Function: -remove-last (pred list)
-     Return a new list with the last item matching PRED removed.
-
-     Alias: â€˜-reject-last’
-
-     See also: â€˜-remove’ (*note -remove::), â€˜-map-last’ (*note
-     -map-last::)
-
-          (-remove-last 'even? '(1 3 5 4 7 8 10 11))
-              â‡’ '(1 3 5 4 7 8 11)
-          (-remove-last 'stringp '(1 2 "last" "second" "third"))
-              â‡’ '(1 2 "last" "second")
-          (--remove-last (> it 3) '(1 2 3 4 5 6 7 8 9 10))
-              â‡’ '(1 2 3 4 5 6 7 8 9)
-
- -- Function: -remove-item (item list)
-     Remove all occurrences of ITEM from LIST.
-
-     Comparison is done with â€˜equal’.
-
-          (-remove-item 3 '(1 2 3 2 3 4 5 3))
-              â‡’ '(1 2 2 4 5)
-          (-remove-item 'foo '(foo bar baz foo))
-              â‡’ '(bar baz)
-          (-remove-item "bob" '("alice" "bob" "eve" "bob" "dave"))
-              â‡’ '("alice" "eve" "dave")
-
- -- Function: -non-nil (list)
-     Return all non-nil elements of LIST.
-
-          (-non-nil '(1 nil 2 nil nil 3 4 nil 5 nil))
-              â‡’ '(1 2 3 4 5)
-
- -- Function: -slice (list from &optional to step)
-     Return copy of LIST, starting from index FROM to index TO.
-
-     FROM or TO may be negative.  These values are then interpreted
-     modulo the length of the list.
-
-     If STEP is a number, only each STEPth item in the resulting section
-     is returned.  Defaults to 1.
-
-          (-slice '(1 2 3 4 5) 1)
-              â‡’ '(2 3 4 5)
-          (-slice '(1 2 3 4 5) 0 3)
-              â‡’ '(1 2 3)
-          (-slice '(1 2 3 4 5 6 7 8 9) 1 -1 2)
-              â‡’ '(2 4 6 8)
-
- -- Function: -take (n list)
-     Return a new list of the first N items in LIST, or all items if
-     there are fewer than N.
-
-     See also: â€˜-take-last’ (*note -take-last::)
-
-          (-take 3 '(1 2 3 4 5))
-              â‡’ '(1 2 3)
-          (-take 17 '(1 2 3 4 5))
-              â‡’ '(1 2 3 4 5)
-
- -- Function: -take-last (n list)
-     Return the last N items of LIST in order.
-
-     See also: â€˜-take’ (*note -take::)
-
-          (-take-last 3 '(1 2 3 4 5))
-              â‡’ '(3 4 5)
-          (-take-last 17 '(1 2 3 4 5))
-              â‡’ '(1 2 3 4 5)
-          (-take-last 1 '(1 2 3 4 5))
-              â‡’ '(5)
-
- -- Function: -drop (n list)
-     Return the tail of LIST without the first N items.
-
-     See also: â€˜-drop-last’ (*note -drop-last::)
-
-     (fn N LIST)
-
-          (-drop 3 '(1 2 3 4 5))
-              â‡’ '(4 5)
-          (-drop 17 '(1 2 3 4 5))
-              â‡’ '()
-
- -- Function: -drop-last (n list)
-     Remove the last N items of LIST and return a copy.
-
-     See also: â€˜-drop’ (*note -drop::)
-
-          (-drop-last 3 '(1 2 3 4 5))
-              â‡’ '(1 2)
-          (-drop-last 17 '(1 2 3 4 5))
-              â‡’ '()
-
- -- Function: -take-while (pred list)
-     Return a new list of successive items from LIST while (PRED item)
-     returns a non-nil value.
-
-          (-take-while 'even? '(1 2 3 4))
-              â‡’ '()
-          (-take-while 'even? '(2 4 5 6))
-              â‡’ '(2 4)
-          (--take-while (< it 4) '(1 2 3 4 3 2 1))
-              â‡’ '(1 2 3)
-
- -- Function: -drop-while (pred list)
-     Return the tail of LIST starting from the first item for which
-     (PRED item) returns nil.
-
-          (-drop-while 'even? '(1 2 3 4))
-              â‡’ '(1 2 3 4)
-          (-drop-while 'even? '(2 4 5 6))
-              â‡’ '(5 6)
-          (--drop-while (< it 4) '(1 2 3 4 3 2 1))
-              â‡’ '(4 3 2 1)
-
- -- Function: -select-by-indices (indices list)
-     Return a list whose elements are elements from LIST selected as
-     â€˜(nth i list)‘ for all i from INDICES.
-
-          (-select-by-indices '(4 10 2 3 6) '("v" "e" "l" "o" "c" "i" "r" "a" "p" "t" "o" "r"))
-              â‡’ '("c" "o" "l" "o" "r")
-          (-select-by-indices '(2 1 0) '("a" "b" "c"))
-              â‡’ '("c" "b" "a")
-          (-select-by-indices '(0 1 2 0 1 3 3 1) '("f" "a" "r" "l"))
-              â‡’ '("f" "a" "r" "f" "a" "l" "l" "a")
-
- -- Function: -select-columns (columns table)
-     Select COLUMNS from TABLE.
-
-     TABLE is a list of lists where each element represents one row.  It
-     is assumed each row has the same length.
-
-     Each row is transformed such that only the specified COLUMNS are
-     selected.
-
-     See also: â€˜-select-column’ (*note -select-column::),
-     â€˜-select-by-indices’ (*note -select-by-indices::)
-
-          (-select-columns '(0 2) '((1 2 3) (a b c) (:a :b :c)))
-              â‡’ '((1 3) (a c) (:a :c))
-          (-select-columns '(1) '((1 2 3) (a b c) (:a :b :c)))
-              â‡’ '((2) (b) (:b))
-          (-select-columns nil '((1 2 3) (a b c) (:a :b :c)))
-              â‡’ '(nil nil nil)
-
- -- Function: -select-column (column table)
-     Select COLUMN from TABLE.
-
-     TABLE is a list of lists where each element represents one row.  It
-     is assumed each row has the same length.
-
-     The single selected column is returned as a list.
-
-     See also: â€˜-select-columns’ (*note -select-columns::),
-     â€˜-select-by-indices’ (*note -select-by-indices::)
-
-          (-select-column 1 '((1 2 3) (a b c) (:a :b :c)))
-              â‡’ '(2 b :b)
-
-\1f
-File: dash.info,  Node: List to list,  Next: Reductions,  Prev: Sublist selection,  Up: Functions
-
-2.3 List to list
-================
-
-Functions returning a modified copy of the input list.
-
- -- Function: -keep (fn list)
-     Return a new list of the non-nil results of applying FN to the
-     items in LIST.
-
-     If you want to select the original items satisfying a predicate use
-     â€˜-filter’ (*note -filter::).
-
-          (-keep 'cdr '((1 2 3) (4 5) (6)))
-              â‡’ '((2 3) (5))
-          (-keep (lambda (num) (when (> num 3) (* 10 num))) '(1 2 3 4 5 6))
-              â‡’ '(40 50 60)
-          (--keep (when (> it 3) (* 10 it)) '(1 2 3 4 5 6))
-              â‡’ '(40 50 60)
-
- -- Function: -concat (&rest lists)
-     Return a new list with the concatenation of the elements in the
-     supplied LISTS.
-
-          (-concat '(1))
-              â‡’ '(1)
-          (-concat '(1) '(2))
-              â‡’ '(1 2)
-          (-concat '(1) '(2 3) '(4))
-              â‡’ '(1 2 3 4)
-
- -- Function: -flatten (l)
-     Take a nested list L and return its contents as a single, flat
-     list.
-
-     Note that because â€˜nil’ represents a list of zero elements (an
-     empty list), any mention of nil in L will disappear after
-     flattening.  If you need to preserve nils, consider â€˜-flatten-n’
-     (*note -flatten-n::) or map them to some unique symbol and then map
-     them back.
-
-     Conses of two atoms are considered "terminals", that is, they
-     aren’t flattened further.
-
-     See also: â€˜-flatten-n’ (*note -flatten-n::)
-
-          (-flatten '((1)))
-              â‡’ '(1)
-          (-flatten '((1 (2 3) (((4 (5)))))))
-              â‡’ '(1 2 3 4 5)
-          (-flatten '(1 2 (3 . 4)))
-              â‡’ '(1 2 (3 . 4))
-
- -- Function: -flatten-n (num list)
-     Flatten NUM levels of a nested LIST.
-
-     See also: â€˜-flatten’ (*note -flatten::)
-
-          (-flatten-n 1 '((1 2) ((3 4) ((5 6)))))
-              â‡’ '(1 2 (3 4) ((5 6)))
-          (-flatten-n 2 '((1 2) ((3 4) ((5 6)))))
-              â‡’ '(1 2 3 4 (5 6))
-          (-flatten-n 3 '((1 2) ((3 4) ((5 6)))))
-              â‡’ '(1 2 3 4 5 6)
-
- -- Function: -replace (old new list)
-     Replace all OLD items in LIST with NEW.
-
-     Elements are compared using â€˜equal’.
-
-     See also: â€˜-replace-at’ (*note -replace-at::)
-
-          (-replace 1 "1" '(1 2 3 4 3 2 1))
-              â‡’ '("1" 2 3 4 3 2 "1")
-          (-replace "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
-              â‡’ '("a" "nice" "bar" "sentence" "about" "bar")
-          (-replace 1 2 nil)
-              â‡’ nil
-
- -- Function: -replace-first (old new list)
-     Replace the first occurrence of OLD with NEW in LIST.
-
-     Elements are compared using â€˜equal’.
-
-     See also: â€˜-map-first’ (*note -map-first::)
-
-          (-replace-first 1 "1" '(1 2 3 4 3 2 1))
-              â‡’ '("1" 2 3 4 3 2 1)
-          (-replace-first "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
-              â‡’ '("a" "nice" "bar" "sentence" "about" "foo")
-          (-replace-first 1 2 nil)
-              â‡’ nil
-
- -- Function: -replace-last (old new list)
-     Replace the last occurrence of OLD with NEW in LIST.
-
-     Elements are compared using â€˜equal’.
-
-     See also: â€˜-map-last’ (*note -map-last::)
-
-          (-replace-last 1 "1" '(1 2 3 4 3 2 1))
-              â‡’ '(1 2 3 4 3 2 "1")
-          (-replace-last "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
-              â‡’ '("a" "nice" "foo" "sentence" "about" "bar")
-          (-replace-last 1 2 nil)
-              â‡’ nil
-
- -- Function: -insert-at (n x list)
-     Return a list with X inserted into LIST at position N.
-
-     See also: â€˜-splice’ (*note -splice::), â€˜-splice-list’ (*note
-     -splice-list::)
-
-          (-insert-at 1 'x '(a b c))
-              â‡’ '(a x b c)
-          (-insert-at 12 'x '(a b c))
-              â‡’ '(a b c x)
-
- -- Function: -replace-at (n x list)
-     Return a list with element at Nth position in LIST replaced with X.
-
-     See also: â€˜-replace’ (*note -replace::)
-
-          (-replace-at 0 9 '(0 1 2 3 4 5))
-              â‡’ '(9 1 2 3 4 5)
-          (-replace-at 1 9 '(0 1 2 3 4 5))
-              â‡’ '(0 9 2 3 4 5)
-          (-replace-at 4 9 '(0 1 2 3 4 5))
-              â‡’ '(0 1 2 3 9 5)
-
- -- Function: -update-at (n func list)
-     Return a list with element at Nth position in LIST replaced with
-     â€˜(func (nth n list))‘.
-
-     See also: â€˜-map-when’ (*note -map-when::)
-
-          (-update-at 0 (lambda (x) (+ x 9)) '(0 1 2 3 4 5))
-              â‡’ '(9 1 2 3 4 5)
-          (-update-at 1 (lambda (x) (+ x 8)) '(0 1 2 3 4 5))
-              â‡’ '(0 9 2 3 4 5)
-          (--update-at 2 (length it) '("foo" "bar" "baz" "quux"))
-              â‡’ '("foo" "bar" 3 "quux")
-
- -- Function: -remove-at (n list)
-     Return a list with element at Nth position in LIST removed.
-
-     See also: â€˜-remove-at-indices’ (*note -remove-at-indices::),
-     â€˜-remove’ (*note -remove::)
-
-          (-remove-at 0 '("0" "1" "2" "3" "4" "5"))
-              â‡’ '("1" "2" "3" "4" "5")
-          (-remove-at 1 '("0" "1" "2" "3" "4" "5"))
-              â‡’ '("0" "2" "3" "4" "5")
-          (-remove-at 2 '("0" "1" "2" "3" "4" "5"))
-              â‡’ '("0" "1" "3" "4" "5")
-
- -- Function: -remove-at-indices (indices list)
-     Return a list whose elements are elements from LIST without
-     elements selected as â€˜(nth i list)‘ for all i from INDICES.
-
-     See also: â€˜-remove-at’ (*note -remove-at::), â€˜-remove’ (*note
-     -remove::)
-
-          (-remove-at-indices '(0) '("0" "1" "2" "3" "4" "5"))
-              â‡’ '("1" "2" "3" "4" "5")
-          (-remove-at-indices '(0 2 4) '("0" "1" "2" "3" "4" "5"))
-              â‡’ '("1" "3" "5")
-          (-remove-at-indices '(0 5) '("0" "1" "2" "3" "4" "5"))
-              â‡’ '("1" "2" "3" "4")
-
-\1f
-File: dash.info,  Node: Reductions,  Next: Unfolding,  Prev: List to list,  Up: Functions
-
-2.4 Reductions
-==============
-
-Functions reducing lists into single value.
-
- -- Function: -reduce-from (fn initial-value list)
-     Return the result of applying FN to INITIAL-VALUE and the first
-     item in LIST, then applying FN to that result and the 2nd item,
-     etc.  If LIST contains no items, return INITIAL-VALUE and do not
-     call FN.
-
-     In the anaphoric form â€˜--reduce-from’, the accumulated value is
-     exposed as symbol â€˜acc’.
-
-     See also: â€˜-reduce’ (*note -reduce::), â€˜-reduce-r’ (*note
-     -reduce-r::)
-
-          (-reduce-from '- 10 '(1 2 3))
-              â‡’ 4
-          (-reduce-from (lambda (memo item) (format "(%s - %d)" memo item)) "10" '(1 2 3))
-              â‡’ "(((10 - 1) - 2) - 3)"
-          (--reduce-from (concat acc " " it) "START" '("a" "b" "c"))
-              â‡’ "START a b c"
-
- -- Function: -reduce-r-from (fn initial-value list)
-     Replace conses with FN, nil with INITIAL-VALUE and evaluate the
-     resulting expression.  If LIST is empty, INITIAL-VALUE is returned
-     and FN is not called.
-
-     Note: this function works the same as â€˜-reduce-from’ (*note
-     -reduce-from::) but the operation associates from right instead of
-     from left.
-
-     See also: â€˜-reduce-r’ (*note -reduce-r::), â€˜-reduce’ (*note
-     -reduce::)
-
-          (-reduce-r-from '- 10 '(1 2 3))
-              â‡’ -8
-          (-reduce-r-from (lambda (item memo) (format "(%d - %s)" item memo)) "10" '(1 2 3))
-              â‡’ "(1 - (2 - (3 - 10)))"
-          (--reduce-r-from (concat it " " acc) "END" '("a" "b" "c"))
-              â‡’ "a b c END"
-
- -- Function: -reduce (fn list)
-     Return the result of applying FN to the first 2 items in LIST, then
-     applying FN to that result and the 3rd item, etc.  If LIST contains
-     no items, return the result of calling FN with no arguments.  If
-     LIST contains a single item, return that item and do not call FN.
-
-     In the anaphoric form â€˜--reduce’, the accumulated value is exposed
-     as symbol â€˜acc’.
-
-     See also: â€˜-reduce-from’ (*note -reduce-from::), â€˜-reduce-r’ (*note
-     -reduce-r::)
-
-          (-reduce '- '(1 2 3 4))
-              â‡’ -8
-          (-reduce 'list '(1 2 3 4))
-              â‡’ '(((1 2) 3) 4)
-          (--reduce (format "%s-%d" acc it) '(1 2 3))
-              â‡’ "1-2-3"
-
- -- Function: -reduce-r (fn list)
-     Replace conses with FN and evaluate the resulting expression.  The
-     final nil is ignored.  If LIST contains no items, return the result
-     of calling FN with no arguments.  If LIST contains a single item,
-     return that item and do not call FN.
-
-     The first argument of FN is the new item, the second is the
-     accumulated value.
-
-     Note: this function works the same as â€˜-reduce’ (*note -reduce::)
-     but the operation associates from right instead of from left.
-
-     See also: â€˜-reduce-r-from’ (*note -reduce-r-from::), â€˜-reduce’
-     (*note -reduce::)
-
-          (-reduce-r '- '(1 2 3 4))
-              â‡’ -2
-          (-reduce-r (lambda (item memo) (format "%s-%d" memo item)) '(1 2 3))
-              â‡’ "3-2-1"
-          (--reduce-r (format "%s-%d" acc it) '(1 2 3))
-              â‡’ "3-2-1"
-
- -- Function: -reductions-from (fn init list)
-     Return a list of the intermediate values of the reduction.
-
-     See â€˜-reduce-from’ (*note -reduce-from::) for explanation of the
-     arguments.
-
-     See also: â€˜-reductions’ (*note -reductions::), â€˜-reductions-r’
-     (*note -reductions-r::), â€˜-reduce-r’ (*note -reduce-r::)
-
-          (-reductions-from (lambda (a i) (format "(%s FN %d)" a i)) "INIT" '(1 2 3 4))
-              â‡’ '("INIT" "(INIT FN 1)" "((INIT FN 1) FN 2)" "(((INIT FN 1) FN 2) FN 3)" "((((INIT FN 1) FN 2) FN 3) FN 4)")
-          (-reductions-from 'max 0 '(2 1 4 3))
-              â‡’ '(0 2 2 4 4)
-          (-reductions-from '* 1 '(1 2 3 4))
-              â‡’ '(1 1 2 6 24)
-
- -- Function: -reductions-r-from (fn init list)
-     Return a list of the intermediate values of the reduction.
-
-     See â€˜-reduce-r-from’ (*note -reduce-r-from::) for explanation of
-     the arguments.
-
-     See also: â€˜-reductions-r’ (*note -reductions-r::), â€˜-reductions’
-     (*note -reductions::), â€˜-reduce’ (*note -reduce::)
-
-          (-reductions-r-from (lambda (i a) (format "(%d FN %s)" i a)) "INIT" '(1 2 3 4))
-              â‡’ '("(1 FN (2 FN (3 FN (4 FN INIT))))" "(2 FN (3 FN (4 FN INIT)))" "(3 FN (4 FN INIT))" "(4 FN INIT)" "INIT")
-          (-reductions-r-from 'max 0 '(2 1 4 3))
-              â‡’ '(4 4 4 3 0)
-          (-reductions-r-from '* 1 '(1 2 3 4))
-              â‡’ '(24 24 12 4 1)
-
- -- Function: -reductions (fn list)
-     Return a list of the intermediate values of the reduction.
-
-     See â€˜-reduce’ (*note -reduce::) for explanation of the arguments.
-
-     See also: â€˜-reductions-from’ (*note -reductions-from::),
-     â€˜-reductions-r’ (*note -reductions-r::), â€˜-reduce-r’ (*note
-     -reduce-r::)
-
-          (-reductions (lambda (a i) (format "(%s FN %d)" a i)) '(1 2 3 4))
-              â‡’ '(1 "(1 FN 2)" "((1 FN 2) FN 3)" "(((1 FN 2) FN 3) FN 4)")
-          (-reductions '+ '(1 2 3 4))
-              â‡’ '(1 3 6 10)
-          (-reductions '* '(1 2 3 4))
-              â‡’ '(1 2 6 24)
-
- -- Function: -reductions-r (fn list)
-     Return a list of the intermediate values of the reduction.
-
-     See â€˜-reduce-r’ (*note -reduce-r::) for explanation of the
-     arguments.
-
-     See also: â€˜-reductions-r-from’ (*note -reductions-r-from::),
-     â€˜-reductions’ (*note -reductions::), â€˜-reduce’ (*note -reduce::)
-
-          (-reductions-r (lambda (i a) (format "(%d FN %s)" i a)) '(1 2 3 4))
-              â‡’ '("(1 FN (2 FN (3 FN 4)))" "(2 FN (3 FN 4))" "(3 FN 4)" 4)
-          (-reductions-r '+ '(1 2 3 4))
-              â‡’ '(10 9 7 4)
-          (-reductions-r '* '(1 2 3 4))
-              â‡’ '(24 24 12 4)
-
- -- Function: -count (pred list)
-     Counts the number of items in LIST where (PRED item) is non-nil.
-
-          (-count 'even? '(1 2 3 4 5))
-              â‡’ 2
-          (--count (< it 4) '(1 2 3 4))
-              â‡’ 3
-
- -- Function: -sum (list)
-     Return the sum of LIST.
-
-          (-sum '())
-              â‡’ 0
-          (-sum '(1))
-              â‡’ 1
-          (-sum '(1 2 3 4))
-              â‡’ 10
-
- -- Function: -running-sum (list)
-     Return a list with running sums of items in LIST.
-
-     LIST must be non-empty.
-
-          (-running-sum '(1 2 3 4))
-              â‡’ '(1 3 6 10)
-          (-running-sum '(1))
-              â‡’ '(1)
-          (-running-sum '())
-              â‡’ error
-
- -- Function: -product (list)
-     Return the product of LIST.
-
-          (-product '())
-              â‡’ 1
-          (-product '(1))
-              â‡’ 1
-          (-product '(1 2 3 4))
-              â‡’ 24
-
- -- Function: -running-product (list)
-     Return a list with running products of items in LIST.
-
-     LIST must be non-empty.
-
-          (-running-product '(1 2 3 4))
-              â‡’ '(1 2 6 24)
-          (-running-product '(1))
-              â‡’ '(1)
-          (-running-product '())
-              â‡’ error
-
- -- Function: -inits (list)
-     Return all prefixes of LIST.
-
-          (-inits '(1 2 3 4))
-              â‡’ '(nil (1) (1 2) (1 2 3) (1 2 3 4))
-          (-inits nil)
-              â‡’ '(nil)
-          (-inits '(1))
-              â‡’ '(nil (1))
-
- -- Function: -tails (list)
-     Return all suffixes of LIST
-
-          (-tails '(1 2 3 4))
-              â‡’ '((1 2 3 4) (2 3 4) (3 4) (4) nil)
-          (-tails nil)
-              â‡’ '(nil)
-          (-tails '(1))
-              â‡’ '((1) nil)
-
- -- Function: -common-prefix (&rest lists)
-     Return the longest common prefix of LISTS.
-
-          (-common-prefix '(1))
-              â‡’ '(1)
-          (-common-prefix '(1 2) '(3 4) '(1 2))
-              â‡’ nil
-          (-common-prefix '(1 2) '(1 2 3) '(1 2 3 4))
-              â‡’ '(1 2)
-
- -- Function: -common-suffix (&rest lists)
-     Return the longest common suffix of LISTS.
-
-          (-common-suffix '(1))
-              â‡’ '(1)
-          (-common-suffix '(1 2) '(3 4) '(1 2))
-              â‡’ nil
-          (-common-suffix '(1 2 3 4) '(2 3 4) '(3 4))
-              â‡’ '(3 4)
-
- -- Function: -min (list)
-     Return the smallest value from LIST of numbers or markers.
-
-          (-min '(0))
-              â‡’ 0
-          (-min '(3 2 1))
-              â‡’ 1
-          (-min '(1 2 3))
-              â‡’ 1
-
- -- Function: -min-by (comparator list)
-     Take a comparison function COMPARATOR and a LIST and return the
-     least element of the list by the comparison function.
-
-     See also combinator â€˜-on’ (*note -on::) which can transform the
-     values before comparing them.
-
-          (-min-by '> '(4 3 6 1))
-              â‡’ 1
-          (--min-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
-              â‡’ '(1 2 3)
-          (--min-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
-              â‡’ '(2)
-
- -- Function: -max (list)
-     Return the largest value from LIST of numbers or markers.
-
-          (-max '(0))
-              â‡’ 0
-          (-max '(3 2 1))
-              â‡’ 3
-          (-max '(1 2 3))
-              â‡’ 3
-
- -- Function: -max-by (comparator list)
-     Take a comparison function COMPARATOR and a LIST and return the
-     greatest element of the list by the comparison function.
-
-     See also combinator â€˜-on’ (*note -on::) which can transform the
-     values before comparing them.
-
-          (-max-by '> '(4 3 6 1))
-              â‡’ 6
-          (--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
-              â‡’ '(3 2)
-          (--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
-              â‡’ '(1 2 3)
-
-\1f
-File: dash.info,  Node: Unfolding,  Next: Predicates,  Prev: Reductions,  Up: Functions
-
-2.5 Unfolding
-=============
-
-Operations dual to reductions, building lists from seed value rather
-than consuming a list to produce a single value.
-
- -- Function: -iterate (fun init n)
-     Return a list of iterated applications of FUN to INIT.
-
-     This means a list of form:
-
-     (init (fun init) (fun (fun init)) ...)
-
-     N is the length of the returned list.
-
-          (-iterate '1+ 1 10)
-              â‡’ '(1 2 3 4 5 6 7 8 9 10)
-          (-iterate (lambda (x) (+ x x)) 2 5)
-              â‡’ '(2 4 8 16 32)
-          (--iterate (* it it) 2 5)
-              â‡’ '(2 4 16 256 65536)
-
- -- Function: -unfold (fun seed)
-     Build a list from SEED using FUN.
-
-     This is "dual" operation to â€˜-reduce-r’ (*note -reduce-r::): while
-     -reduce-r consumes a list to produce a single value, â€˜-unfold’
-     (*note -unfold::) takes a seed value and builds a (potentially
-     infinite!)  list.
-
-     FUN should return â€˜nil’ to stop the generating process, or a cons
-     (A .  B), where A will be prepended to the result and B is the new
-     seed.
-
-          (-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10)
-              â‡’ '(10 9 8 7 6 5 4 3 2 1)
-          (--unfold (when it (cons it (cdr it))) '(1 2 3 4))
-              â‡’ '((1 2 3 4) (2 3 4) (3 4) (4))
-          (--unfold (when it (cons it (butlast it))) '(1 2 3 4))
-              â‡’ '((1 2 3 4) (1 2 3) (1 2) (1))
-
-\1f
-File: dash.info,  Node: Predicates,  Next: Partitioning,  Prev: Unfolding,  Up: Functions
-
-2.6 Predicates
-==============
-
- -- Function: -any? (pred list)
-     Return t if (PRED x) is non-nil for any x in LIST, else nil.
-
-     Alias: â€˜-any-p’, â€˜-some?’, â€˜-some-p’
-
-          (-any? 'even? '(1 2 3))
-              â‡’ t
-          (-any? 'even? '(1 3 5))
-              â‡’ nil
-          (-any? 'null '(1 3 5))
-              â‡’ nil
-
- -- Function: -all? (pred list)
-     Return t if (PRED x) is non-nil for all x in LIST, else nil.
-
-     Alias: â€˜-all-p’, â€˜-every?’, â€˜-every-p’
-
-          (-all? 'even? '(1 2 3))
-              â‡’ nil
-          (-all? 'even? '(2 4 6))
-              â‡’ t
-          (--all? (= 0 (% it 2)) '(2 4 6))
-              â‡’ t
-
- -- Function: -none? (pred list)
-     Return t if (PRED x) is nil for all x in LIST, else nil.
-
-     Alias: â€˜-none-p’
-
-          (-none? 'even? '(1 2 3))
-              â‡’ nil
-          (-none? 'even? '(1 3 5))
-              â‡’ t
-          (--none? (= 0 (% it 2)) '(1 2 3))
-              â‡’ nil
-
- -- Function: -only-some? (pred list)
-     Return â€˜t‘ if at least one item of LIST matches PRED and at least
-     one item of LIST does not match PRED.  Return â€˜nil‘ both if all
-     items match the predicate or if none of the items match the
-     predicate.
-
-     Alias: â€˜-only-some-p’
-
-          (-only-some? 'even? '(1 2 3))
-              â‡’ t
-          (-only-some? 'even? '(1 3 5))
-              â‡’ nil
-          (-only-some? 'even? '(2 4 6))
-              â‡’ nil
-
- -- Function: -contains? (list element)
-     Return non-nil if LIST contains ELEMENT.
-
-     The test for equality is done with â€˜equal’, or with â€˜-compare-fn’
-     if that’s non-nil.
-
-     Alias: â€˜-contains-p’
-
-          (-contains? '(1 2 3) 1)
-              â‡’ t
-          (-contains? '(1 2 3) 2)
-              â‡’ t
-          (-contains? '(1 2 3) 4)
-              â‡’ nil
-
- -- Function: -same-items? (list list2)
-     Return true if LIST and LIST2 has the same items.
-
-     The order of the elements in the lists does not matter.
-
-     Alias: â€˜-same-items-p’
-
-          (-same-items? '(1 2 3) '(1 2 3))
-              â‡’ t
-          (-same-items? '(1 2 3) '(3 2 1))
-              â‡’ t
-          (-same-items? '(1 2 3) '(1 2 3 4))
-              â‡’ nil
-
- -- Function: -is-prefix? (prefix list)
-     Return non-nil if PREFIX is prefix of LIST.
-
-     Alias: â€˜-is-prefix-p’
-
-          (-is-prefix? '(1 2 3) '(1 2 3 4 5))
-              â‡’ t
-          (-is-prefix? '(1 2 3 4 5) '(1 2 3))
-              â‡’ nil
-          (-is-prefix? '(1 3) '(1 2 3 4 5))
-              â‡’ nil
-
- -- Function: -is-suffix? (suffix list)
-     Return non-nil if SUFFIX is suffix of LIST.
-
-     Alias: â€˜-is-suffix-p’
-
-          (-is-suffix? '(3 4 5) '(1 2 3 4 5))
-              â‡’ t
-          (-is-suffix? '(1 2 3 4 5) '(3 4 5))
-              â‡’ nil
-          (-is-suffix? '(3 5) '(1 2 3 4 5))
-              â‡’ nil
-
- -- Function: -is-infix? (infix list)
-     Return non-nil if INFIX is infix of LIST.
-
-     This operation runs in O(n^2) time
-
-     Alias: â€˜-is-infix-p’
-
-          (-is-infix? '(1 2 3) '(1 2 3 4 5))
-              â‡’ t
-          (-is-infix? '(2 3 4) '(1 2 3 4 5))
-              â‡’ t
-          (-is-infix? '(3 4 5) '(1 2 3 4 5))
-              â‡’ t
-
-\1f
-File: dash.info,  Node: Partitioning,  Next: Indexing,  Prev: Predicates,  Up: Functions
-
-2.7 Partitioning
-================
-
-Functions partitioning the input list into a list of lists.
-
- -- Function: -split-at (n list)
-     Return a list of ((-take N LIST) (-drop N LIST)), in no more than
-     one pass through the list.
-
-          (-split-at 3 '(1 2 3 4 5))
-              â‡’ '((1 2 3) (4 5))
-          (-split-at 17 '(1 2 3 4 5))
-              â‡’ '((1 2 3 4 5) nil)
-
- -- Function: -split-with (pred list)
-     Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)),
-     in no more than one pass through the list.
-
-          (-split-with 'even? '(1 2 3 4))
-              â‡’ '(nil (1 2 3 4))
-          (-split-with 'even? '(2 4 5 6))
-              â‡’ '((2 4) (5 6))
-          (--split-with (< it 4) '(1 2 3 4 3 2 1))
-              â‡’ '((1 2 3) (4 3 2 1))
-
- -- Macro: -split-on (item list)
-     Split the LIST each time ITEM is found.
-
-     Unlike â€˜-partition-by’ (*note -partition-by::), the ITEM is
-     discarded from the results.  Empty lists are also removed from the
-     result.
-
-     Comparison is done by â€˜equal’.
-
-     See also â€˜-split-when’ (*note -split-when::)
-
-          (-split-on '| '(Nil | Leaf a | Node [Tree a]))
-              â‡’ '((Nil) (Leaf a) (Node [Tree a]))
-          (-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e"))
-              â‡’ '(("a" "b") ("c") ("d" "e"))
-          (-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e"))
-              â‡’ '(("a" "b") ("d" "e"))
-
- -- Function: -split-when (fn list)
-     Split the LIST on each element where FN returns non-nil.
-
-     Unlike â€˜-partition-by’ (*note -partition-by::), the "matched"
-     element is discarded from the results.  Empty lists are also
-     removed from the result.
-
-     This function can be thought of as a generalization of
-     â€˜split-string’.
-
-          (-split-when 'even? '(1 2 3 4 5 6))
-              â‡’ '((1) (3) (5))
-          (-split-when 'even? '(1 2 3 4 6 8 9))
-              â‡’ '((1) (3) (9))
-          (--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args))
-              â‡’ '((a b) (c d) (args))
-
- -- Function: -separate (pred list)
-     Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one
-     pass through the list.
-
-          (-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7))
-              â‡’ '((2 4 6) (1 3 5 7))
-          (--separate (< it 5) '(3 7 5 9 3 2 1 4 6))
-              â‡’ '((3 3 2 1 4) (7 5 9 6))
-          (-separate 'cdr '((1 2) (1) (1 2 3) (4)))
-              â‡’ '(((1 2) (1 2 3)) ((1) (4)))
-
- -- Function: -partition (n list)
-     Return a new list with the items in LIST grouped into N-sized
-     sublists.  If there are not enough items to make the last group
-     N-sized, those items are discarded.
-
-          (-partition 2 '(1 2 3 4 5 6))
-              â‡’ '((1 2) (3 4) (5 6))
-          (-partition 2 '(1 2 3 4 5 6 7))
-              â‡’ '((1 2) (3 4) (5 6))
-          (-partition 3 '(1 2 3 4 5 6 7))
-              â‡’ '((1 2 3) (4 5 6))
-
- -- Function: -partition-all (n list)
-     Return a new list with the items in LIST grouped into N-sized
-     sublists.  The last group may contain less than N items.
-
-          (-partition-all 2 '(1 2 3 4 5 6))
-              â‡’ '((1 2) (3 4) (5 6))
-          (-partition-all 2 '(1 2 3 4 5 6 7))
-              â‡’ '((1 2) (3 4) (5 6) (7))
-          (-partition-all 3 '(1 2 3 4 5 6 7))
-              â‡’ '((1 2 3) (4 5 6) (7))
-
- -- Function: -partition-in-steps (n step list)
-     Return a new list with the items in LIST grouped into N-sized
-     sublists at offsets STEP apart.  If there are not enough items to
-     make the last group N-sized, those items are discarded.
-
-          (-partition-in-steps 2 1 '(1 2 3 4))
-              â‡’ '((1 2) (2 3) (3 4))
-          (-partition-in-steps 3 2 '(1 2 3 4))
-              â‡’ '((1 2 3))
-          (-partition-in-steps 3 2 '(1 2 3 4 5))
-              â‡’ '((1 2 3) (3 4 5))
-
- -- Function: -partition-all-in-steps (n step list)
-     Return a new list with the items in LIST grouped into N-sized
-     sublists at offsets STEP apart.  The last groups may contain less
-     than N items.
-
-          (-partition-all-in-steps 2 1 '(1 2 3 4))
-              â‡’ '((1 2) (2 3) (3 4) (4))
-          (-partition-all-in-steps 3 2 '(1 2 3 4))
-              â‡’ '((1 2 3) (3 4))
-          (-partition-all-in-steps 3 2 '(1 2 3 4 5))
-              â‡’ '((1 2 3) (3 4 5) (5))
-
- -- Function: -partition-by (fn list)
-     Apply FN to each item in LIST, splitting it each time FN returns a
-     new value.
-
-          (-partition-by 'even? '())
-              â‡’ '()
-          (-partition-by 'even? '(1 1 2 2 2 3 4 6 8))
-              â‡’ '((1 1) (2 2 2) (3) (4 6 8))
-          (--partition-by (< it 3) '(1 2 3 4 3 2 1))
-              â‡’ '((1 2) (3 4 3) (2 1))
-
- -- Function: -partition-by-header (fn list)
-     Apply FN to the first item in LIST.  That is the header value.
-     Apply FN to each item in LIST, splitting it each time FN returns
-     the header value, but only after seeing at least one other value
-     (the body).
-
-          (--partition-by-header (= it 1) '(1 2 3 1 2 1 2 3 4))
-              â‡’ '((1 2 3) (1 2) (1 2 3 4))
-          (--partition-by-header (> it 0) '(1 2 0 1 0 1 2 3 0))
-              â‡’ '((1 2 0) (1 0) (1 2 3 0))
-          (-partition-by-header 'even? '(2 1 1 1 4 1 3 5 6 6 1))
-              â‡’ '((2 1 1 1) (4 1 3 5) (6 6 1))
-
- -- Function: -partition-after-pred (pred list)
-     Partition directly after each time PRED is true on an element of
-     LIST.
-
-          (-partition-after-pred #'odd? '())
-              â‡’ '()
-          (-partition-after-pred #'odd? '(1))
-              â‡’ '((1))
-          (-partition-after-pred #'odd? '(0 1))
-              â‡’ '((0 1))
-
- -- Function: -partition-before-pred (pred list)
-     Partition directly before each time PRED is true on an element of
-     LIST.
-
-          (-partition-before-pred #'odd? '())
-              â‡’ '()
-          (-partition-before-pred #'odd? '(1))
-              â‡’ '((1))
-          (-partition-before-pred #'odd? '(0 1))
-              â‡’ '((0) (1))
-
- -- Function: -partition-before-item (item list)
-     Partition directly before each time ITEM appears in LIST.
-
-          (-partition-before-item 3 '())
-              â‡’ '()
-          (-partition-before-item 3 '(1))
-              â‡’ '((1))
-          (-partition-before-item 3 '(3))
-              â‡’ '((3))
-
- -- Function: -partition-after-item (item list)
-     Partition directly after each time ITEM appears in LIST.
-
-          (-partition-after-item 3 '())
-              â‡’ '()
-          (-partition-after-item 3 '(1))
-              â‡’ '((1))
-          (-partition-after-item 3 '(3))
-              â‡’ '((3))
-
- -- Function: -group-by (fn list)
-     Separate LIST into an alist whose keys are FN applied to the
-     elements of LIST.  Keys are compared by â€˜equal’.
-
-          (-group-by 'even? '())
-              â‡’ '()
-          (-group-by 'even? '(1 1 2 2 2 3 4 6 8))
-              â‡’ '((nil 1 1 3) (t 2 2 2 4 6 8))
-          (--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e"))
-              â‡’ '(("a" "a/b" "a/e") ("c" "c/d"))
-
-\1f
-File: dash.info,  Node: Indexing,  Next: Set operations,  Prev: Partitioning,  Up: Functions
-
-2.8 Indexing
-============
-
-Return indices of elements based on predicates, sort elements by indices
-etc.
-
- -- Function: -elem-index (elem list)
-     Return the index of the first element in the given LIST which is
-     equal to the query element ELEM, or nil if there is no such
-     element.
-
-          (-elem-index 2 '(6 7 8 2 3 4))
-              â‡’ 3
-          (-elem-index "bar" '("foo" "bar" "baz"))
-              â‡’ 1
-          (-elem-index '(1 2) '((3) (5 6) (1 2) nil))
-              â‡’ 2
-
- -- Function: -elem-indices (elem list)
-     Return the indices of all elements in LIST equal to the query
-     element ELEM, in ascending order.
-
-          (-elem-indices 2 '(6 7 8 2 3 4 2 1))
-              â‡’ '(3 6)
-          (-elem-indices "bar" '("foo" "bar" "baz"))
-              â‡’ '(1)
-          (-elem-indices '(1 2) '((3) (1 2) (5 6) (1 2) nil))
-              â‡’ '(1 3)
-
- -- Function: -find-index (pred list)
-     Take a predicate PRED and a LIST and return the index of the first
-     element in the list satisfying the predicate, or nil if there is no
-     such element.
-
-     See also â€˜-first’ (*note -first::).
-
-          (-find-index 'even? '(2 4 1 6 3 3 5 8))
-              â‡’ 0
-          (--find-index (< 5 it) '(2 4 1 6 3 3 5 8))
-              â‡’ 3
-          (-find-index (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
-              â‡’ 1
-
- -- Function: -find-last-index (pred list)
-     Take a predicate PRED and a LIST and return the index of the last
-     element in the list satisfying the predicate, or nil if there is no
-     such element.
-
-     See also â€˜-last’ (*note -last::).
-
-          (-find-last-index 'even? '(2 4 1 6 3 3 5 8))
-              â‡’ 7
-          (--find-last-index (< 5 it) '(2 7 1 6 3 8 5 2))
-              â‡’ 5
-          (-find-last-index (-partial 'string-lessp "baz") '("q" "foo" "baz"))
-              â‡’ 1
-
- -- Function: -find-indices (pred list)
-     Return the indices of all elements in LIST satisfying the predicate
-     PRED, in ascending order.
-
-          (-find-indices 'even? '(2 4 1 6 3 3 5 8))
-              â‡’ '(0 1 3 7)
-          (--find-indices (< 5 it) '(2 4 1 6 3 3 5 8))
-              â‡’ '(3 7)
-          (-find-indices (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
-              â‡’ '(1)
-
- -- Function: -grade-up (comparator list)
-     Grade elements of LIST using COMPARATOR relation, yielding a
-     permutation vector such that applying this permutation to LIST
-     sorts it in ascending order.
-
-          (-grade-up '< '(3 1 4 2 1 3 3))
-              â‡’ '(1 4 3 0 5 6 2)
-          (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-up '< l) l))
-              â‡’ '(1 1 2 3 3 3 4)
-
- -- Function: -grade-down (comparator list)
-     Grade elements of LIST using COMPARATOR relation, yielding a
-     permutation vector such that applying this permutation to LIST
-     sorts it in descending order.
-
-          (-grade-down '< '(3 1 4 2 1 3 3))
-              â‡’ '(2 0 5 6 3 1 4)
-          (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-down '< l) l))
-              â‡’ '(4 3 3 3 2 1 1)
-
-\1f
-File: dash.info,  Node: Set operations,  Next: Other list operations,  Prev: Indexing,  Up: Functions
-
-2.9 Set operations
-==================
-
-Operations pretending lists are sets.
-
- -- Function: -union (list list2)
-     Return a new list containing the elements of LIST and elements of
-     LIST2 that are not in LIST.  The test for equality is done with
-     â€˜equal’, or with â€˜-compare-fn’ if that’s non-nil.
-
-          (-union '(1 2 3) '(3 4 5))
-              â‡’ '(1 2 3 4 5)
-          (-union '(1 2 3 4) '())
-              â‡’ '(1 2 3 4)
-          (-union '(1 1 2 2) '(3 2 1))
-              â‡’ '(1 1 2 2 3)
-
- -- Function: -difference (list list2)
-     Return a new list with only the members of LIST that are not in
-     LIST2.  The test for equality is done with â€˜equal’, or with
-     â€˜-compare-fn’ if that’s non-nil.
-
-          (-difference '() '())
-              â‡’ '()
-          (-difference '(1 2 3) '(4 5 6))
-              â‡’ '(1 2 3)
-          (-difference '(1 2 3 4) '(3 4 5 6))
-              â‡’ '(1 2)
-
- -- Function: -intersection (list list2)
-     Return a new list containing only the elements that are members of
-     both LIST and LIST2.  The test for equality is done with â€˜equal’,
-     or with â€˜-compare-fn’ if that’s non-nil.
-
-          (-intersection '() '())
-              â‡’ '()
-          (-intersection '(1 2 3) '(4 5 6))
-              â‡’ '()
-          (-intersection '(1 2 3 4) '(3 4 5 6))
-              â‡’ '(3 4)
-
- -- Function: -powerset (list)
-     Return the power set of LIST.
-
-          (-powerset '())
-              â‡’ '(nil)
-          (-powerset '(x y z))
-              â‡’ '((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
-
- -- Function: -permutations (list)
-     Return the permutations of LIST.
-
-          (-permutations '())
-              â‡’ '(nil)
-          (-permutations '(1 2))
-              â‡’ '((1 2) (2 1))
-          (-permutations '(a b c))
-              â‡’ '((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
-
- -- Function: -distinct (list)
-     Return a new list with all duplicates removed.  The test for
-     equality is done with â€˜equal’, or with â€˜-compare-fn’ if that’s
-     non-nil.
-
-     Alias: â€˜-uniq’
-
-          (-distinct '())
-              â‡’ '()
-          (-distinct '(1 2 2 4))
-              â‡’ '(1 2 4)
-          (-distinct '(t t t))
-              â‡’ '(t)
-
-\1f
-File: dash.info,  Node: Other list operations,  Next: Tree operations,  Prev: Set operations,  Up: Functions
-
-2.10 Other list operations
-==========================
-
-Other list functions not fit to be classified elsewhere.
-
- -- Function: -rotate (n list)
-     Rotate LIST N places to the right.  With N negative, rotate to the
-     left.  The time complexity is O(n).
-
-          (-rotate 3 '(1 2 3 4 5 6 7))
-              â‡’ '(5 6 7 1 2 3 4)
-          (-rotate -3 '(1 2 3 4 5 6 7))
-              â‡’ '(4 5 6 7 1 2 3)
-          (-rotate 16 '(1 2 3 4 5 6 7))
-              â‡’ '(6 7 1 2 3 4 5)
-
- -- Function: -repeat (n x)
-     Return a list with X repeated N times.  Return nil if N is less
-     than 1.
-
-          (-repeat 3 :a)
-              â‡’ '(:a :a :a)
-          (-repeat 1 :a)
-              â‡’ '(:a)
-          (-repeat 0 :a)
-              â‡’ nil
-
- -- Function: -cons* (&rest args)
-     Make a new list from the elements of ARGS.
-
-     The last 2 members of ARGS are used as the final cons of the result
-     so if the final member of ARGS is not a list the result is a dotted
-     list.
-
-          (-cons* 1 2)
-              â‡’ '(1 . 2)
-          (-cons* 1 2 3)
-              â‡’ '(1 2 . 3)
-          (-cons* 1)
-              â‡’ 1
-
- -- Function: -snoc (list elem &rest elements)
-     Append ELEM to the end of the list.
-
-     This is like â€˜cons’, but operates on the end of list.
-
-     If ELEMENTS is non nil, append these to the list as well.
-
-          (-snoc '(1 2 3) 4)
-              â‡’ '(1 2 3 4)
-          (-snoc '(1 2 3) 4 5 6)
-              â‡’ '(1 2 3 4 5 6)
-          (-snoc '(1 2 3) '(4 5 6))
-              â‡’ '(1 2 3 (4 5 6))
-
- -- Function: -interpose (sep list)
-     Return a new list of all elements in LIST separated by SEP.
-
-          (-interpose "-" '())
-              â‡’ '()
-          (-interpose "-" '("a"))
-              â‡’ '("a")
-          (-interpose "-" '("a" "b" "c"))
-              â‡’ '("a" "-" "b" "-" "c")
-
- -- Function: -interleave (&rest lists)
-     Return a new list of the first item in each list, then the second
-     etc.
-
-          (-interleave '(1 2) '("a" "b"))
-              â‡’ '(1 "a" 2 "b")
-          (-interleave '(1 2) '("a" "b") '("A" "B"))
-              â‡’ '(1 "a" "A" 2 "b" "B")
-          (-interleave '(1 2 3) '("a" "b"))
-              â‡’ '(1 "a" 2 "b")
-
- -- Function: -zip-with (fn list1 list2)
-     Zip the two lists LIST1 and LIST2 using a function FN.  This
-     function is applied pairwise taking as first argument element of
-     LIST1 and as second argument element of LIST2 at corresponding
-     position.
-
-     The anaphoric form â€˜--zip-with’ binds the elements from LIST1 as
-     symbol â€˜it’, and the elements from LIST2 as symbol â€˜other’.
-
-          (-zip-with '+ '(1 2 3) '(4 5 6))
-              â‡’ '(5 7 9)
-          (-zip-with 'cons '(1 2 3) '(4 5 6))
-              â‡’ '((1 . 4) (2 . 5) (3 . 6))
-          (--zip-with (concat it " and " other) '("Batman" "Jekyll") '("Robin" "Hyde"))
-              â‡’ '("Batman and Robin" "Jekyll and Hyde")
-
- -- Function: -zip (&rest lists)
-     Zip LISTS together.  Group the head of each list, followed by the
-     second elements of each list, and so on.  The lengths of the
-     returned groupings are equal to the length of the shortest input
-     list.
-
-     If two lists are provided as arguments, return the groupings as a
-     list of cons cells.  Otherwise, return the groupings as a list of
-     lists.
-
-     Use â€˜-zip-lists’ (*note -zip-lists::) if you need the return value
-     to always be a list of lists.
-
-     Alias: â€˜-zip-pair’
-
-     See also: â€˜-zip-lists’ (*note -zip-lists::)
-
-          (-zip '(1 2 3) '(4 5 6))
-              â‡’ '((1 . 4) (2 . 5) (3 . 6))
-          (-zip '(1 2 3) '(4 5 6 7))
-              â‡’ '((1 . 4) (2 . 5) (3 . 6))
-          (-zip '(1 2) '(3 4 5) '(6))
-              â‡’ '((1 3 6))
-
- -- Function: -zip-lists (&rest lists)
-     Zip LISTS together.  Group the head of each list, followed by the
-     second elements of each list, and so on.  The lengths of the
-     returned groupings are equal to the length of the shortest input
-     list.
-
-     The return value is always list of lists, which is a difference
-     from â€˜-zip-pair’ which returns a cons-cell in case two input lists
-     are provided.
-
-     See also: â€˜-zip’ (*note -zip::)
-
-          (-zip-lists '(1 2 3) '(4 5 6))
-              â‡’ '((1 4) (2 5) (3 6))
-          (-zip-lists '(1 2 3) '(4 5 6 7))
-              â‡’ '((1 4) (2 5) (3 6))
-          (-zip-lists '(1 2) '(3 4 5) '(6))
-              â‡’ '((1 3 6))
-
- -- Function: -zip-fill (fill-value &rest lists)
-     Zip LISTS, with FILL-VALUE padded onto the shorter lists.  The
-     lengths of the returned groupings are equal to the length of the
-     longest input list.
-
-          (-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9))
-              â‡’ '((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
-
- -- Function: -unzip (lists)
-     Unzip LISTS.
-
-     This works just like â€˜-zip’ (*note -zip::) but takes a list of
-     lists instead of a variable number of arguments, such that
-
-     (-unzip (-zip L1 L2 L3 ...))
-
-     is identity (given that the lists are the same length).
-
-     Note in particular that calling this on a list of two lists will
-     return a list of cons-cells such that the aboce identity works.
-
-     See also: â€˜-zip’ (*note -zip::)
-
-          (-unzip (-zip '(1 2 3) '(a b c) '("e" "f" "g")))
-              â‡’ '((1 2 3) (a b c) ("e" "f" "g"))
-          (-unzip '((1 2) (3 4) (5 6) (7 8) (9 10)))
-              â‡’ '((1 3 5 7 9) (2 4 6 8 10))
-          (-unzip '((1 2) (3 4)))
-              â‡’ '((1 . 3) (2 . 4))
-
- -- Function: -cycle (list)
-     Return an infinite copy of LIST that will cycle through the
-     elements and repeat from the beginning.
-
-          (-take 5 (-cycle '(1 2 3)))
-              â‡’ '(1 2 3 1 2)
-          (-take 7 (-cycle '(1 "and" 3)))
-              â‡’ '(1 "and" 3 1 "and" 3 1)
-          (-zip (-cycle '(1 2 3)) '(1 2))
-              â‡’ '((1 . 1) (2 . 2))
-
- -- Function: -pad (fill-value &rest lists)
-     Appends FILL-VALUE to the end of each list in LISTS such that they
-     will all have the same length.
-
-          (-pad 0 '())
-              â‡’ '(nil)
-          (-pad 0 '(1))
-              â‡’ '((1))
-          (-pad 0 '(1 2 3) '(4 5))
-              â‡’ '((1 2 3) (4 5 0))
-
- -- Function: -table (fn &rest lists)
-     Compute outer product of LISTS using function FN.
-
-     The function FN should have the same arity as the number of
-     supplied lists.
-
-     The outer product is computed by applying fn to all possible
-     combinations created by taking one element from each list in order.
-     The dimension of the result is (length lists).
-
-     See also: â€˜-table-flat’ (*note -table-flat::)
-
-          (-table '* '(1 2 3) '(1 2 3))
-              â‡’ '((1 2 3) (2 4 6) (3 6 9))
-          (-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
-              â‡’ '((7 15) (10 22))
-          (apply '-table 'list (-repeat 3 '(1 2)))
-              â‡’ '((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))
-
- -- Function: -table-flat (fn &rest lists)
-     Compute flat outer product of LISTS using function FN.
-
-     The function FN should have the same arity as the number of
-     supplied lists.
-
-     The outer product is computed by applying fn to all possible
-     combinations created by taking one element from each list in order.
-     The results are flattened, ignoring the tensor structure of the
-     result.  This is equivalent to calling:
-
-     (-flatten-n (1- (length lists)) (apply â€™-table fn lists))
-
-     but the implementation here is much more efficient.
-
-     See also: â€˜-flatten-n’ (*note -flatten-n::), â€˜-table’ (*note
-     -table::)
-
-          (-table-flat 'list '(1 2 3) '(a b c))
-              â‡’ '((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
-          (-table-flat '* '(1 2 3) '(1 2 3))
-              â‡’ '(1 2 3 2 4 6 3 6 9)
-          (apply '-table-flat 'list (-repeat 3 '(1 2)))
-              â‡’ '((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))
-
- -- Function: -first (pred list)
-     Return the first x in LIST where (PRED x) is non-nil, else nil.
-
-     To get the first item in the list no questions asked, use â€˜car’.
-
-     Alias: â€˜-find’
-
-          (-first 'even? '(1 2 3))
-              â‡’ 2
-          (-first 'even? '(1 3 5))
-              â‡’ nil
-          (-first 'null '(1 3 5))
-              â‡’ nil
-
- -- Function: -some (pred list)
-     Return (PRED x) for the first LIST item where (PRED x) is non-nil,
-     else nil.
-
-     Alias: â€˜-any’
-
-          (-some 'even? '(1 2 3))
-              â‡’ t
-          (-some 'null '(1 2 3))
-              â‡’ nil
-          (-some 'null '(1 2 nil))
-              â‡’ t
-
- -- Function: -last (pred list)
-     Return the last x in LIST where (PRED x) is non-nil, else nil.
-
-          (-last 'even? '(1 2 3 4 5 6 3 3 3))
-              â‡’ 6
-          (-last 'even? '(1 3 7 5 9))
-              â‡’ nil
-          (--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
-              â‡’ "short"
-
- -- Function: -first-item (list)
-     Return the first item of LIST, or nil on an empty list.
-
-     See also: â€˜-second-item’ (*note -second-item::), â€˜-last-item’
-     (*note -last-item::).
-
-     (fn LIST)
-
-          (-first-item '(1 2 3))
-              â‡’ 1
-          (-first-item nil)
-              â‡’ nil
-          (let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
-              â‡’ '(5 2 3)
-
- -- Function: -second-item (arg1)
-     Return the second item of LIST, or nil if LIST is too short.
-
-     See also: â€˜-third-item’ (*note -third-item::).
-
-     (fn LIST)
-
-          (-second-item '(1 2 3))
-              â‡’ 2
-          (-second-item nil)
-              â‡’ nil
-
- -- Function: -third-item (arg1)
-     Return the third item of LIST, or nil if LIST is too short.
-
-     See also: â€˜-fourth-item’ (*note -fourth-item::).
-
-     (fn LIST)
-
-          (-third-item '(1 2 3))
-              â‡’ 3
-          (-third-item nil)
-              â‡’ nil
-
- -- Function: -fourth-item (list)
-     Return the fourth item of LIST, or nil if LIST is too short.
-
-     See also: â€˜-fifth-item’ (*note -fifth-item::).
-
-          (-fourth-item '(1 2 3 4))
-              â‡’ 4
-          (-fourth-item nil)
-              â‡’ nil
-
- -- Function: -fifth-item (list)
-     Return the fifth item of LIST, or nil if LIST is too short.
-
-     See also: â€˜-last-item’ (*note -last-item::).
-
-          (-fifth-item '(1 2 3 4 5))
-              â‡’ 5
-          (-fifth-item nil)
-              â‡’ nil
-
- -- Function: -last-item (list)
-     Return the last item of LIST, or nil on an empty list.
-
-          (-last-item '(1 2 3))
-              â‡’ 3
-          (-last-item nil)
-              â‡’ nil
-          (let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
-              â‡’ '(1 2 5)
-
- -- Function: -butlast (list)
-     Return a list of all items in list except for the last.
-
-          (-butlast '(1 2 3))
-              â‡’ '(1 2)
-          (-butlast '(1 2))
-              â‡’ '(1)
-          (-butlast '(1))
-              â‡’ nil
-
- -- Function: -sort (comparator list)
-     Sort LIST, stably, comparing elements using COMPARATOR.  Return the
-     sorted list.  LIST is NOT modified by side effects.  COMPARATOR is
-     called with two elements of LIST, and should return non-nil if the
-     first element should sort before the second.
-
-          (-sort '< '(3 1 2))
-              â‡’ '(1 2 3)
-          (-sort '> '(3 1 2))
-              â‡’ '(3 2 1)
-          (--sort (< it other) '(3 1 2))
-              â‡’ '(1 2 3)
-
- -- Function: -list (&rest args)
-     Return a list with ARGS.
-
-     If first item of ARGS is already a list, simply return ARGS.  If
-     not, return a list with ARGS as elements.
-
-          (-list 1)
-              â‡’ '(1)
-          (-list 1 2 3)
-              â‡’ '(1 2 3)
-          (-list '(1 2 3))
-              â‡’ '(1 2 3)
-
- -- Function: -fix (fn list)
-     Compute the (least) fixpoint of FN with initial input LIST.
-
-     FN is called at least once, results are compared with â€˜equal’.
-
-          (-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3 4 5 6)))
-              â‡’ '((1) (2) (3) (4) (5) (6))
-          (let ((data '(("starwars" "scifi") ("jedi" "starwars" "warrior")))) (--fix (-uniq (--mapcat (cons it (cdr (assoc it data))) it)) '("jedi" "book")))
-              â‡’ '("jedi" "starwars" "warrior" "scifi" "book")
-
-\1f
-File: dash.info,  Node: Tree operations,  Next: Threading macros,  Prev: Other list operations,  Up: Functions
-
-2.11 Tree operations
-====================
-
-Functions pretending lists are trees.
-
- -- Function: -tree-seq (branch children tree)
-     Return a sequence of the nodes in TREE, in depth-first search
-     order.
-
-     BRANCH is a predicate of one argument that returns non-nil if the
-     passed argument is a branch, that is, a node that can have
-     children.
-
-     CHILDREN is a function of one argument that returns the children of
-     the passed branch node.
-
-     Non-branch nodes are simply copied.
-
-          (-tree-seq 'listp 'identity '(1 (2 3) 4 (5 (6 7))))
-              â‡’ '((1 (2 3) 4 (5 (6 7))) 1 (2 3) 2 3 4 (5 (6 7)) 5 (6 7) 6 7)
-          (-tree-seq 'listp 'reverse '(1 (2 3) 4 (5 (6 7))))
-              â‡’ '((1 (2 3) 4 (5 (6 7))) (5 (6 7)) (6 7) 7 6 5 4 (2 3) 3 2 1)
-          (--tree-seq (vectorp it) (append it nil) [1 [2 3] 4 [5 [6 7]]])
-              â‡’ '([1 [2 3] 4 [5 [6 7]]] 1 [2 3] 2 3 4 [5 [6 7]] 5 [6 7] 6 7)
-
- -- Function: -tree-map (fn tree)
-     Apply FN to each element of TREE while preserving the tree
-     structure.
-
-          (-tree-map '1+ '(1 (2 3) (4 (5 6) 7)))
-              â‡’ '(2 (3 4) (5 (6 7) 8))
-          (-tree-map '(lambda (x) (cons x (expt 2 x))) '(1 (2 3) 4))
-              â‡’ '((1 . 2) ((2 . 4) (3 . 8)) (4 . 16))
-          (--tree-map (length it) '("<body>" ("<p>" "text" "</p>") "</body>"))
-              â‡’ '(6 (3 4 4) 7)
-
- -- Function: -tree-map-nodes (pred fun tree)
-     Call FUN on each node of TREE that satisfies PRED.
-
-     If PRED returns nil, continue descending down this node.  If PRED
-     returns non-nil, apply FUN to this node and do not descend further.
-
-          (-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6 7] 8)))
-              â‡’ '(1 5 4 (5 13 8))
-          (-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar) :baz 8)))
-              â‡’ '(1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
-          (--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode 'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c d))))
-              â‡’ '(with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
-
- -- Function: -tree-reduce (fn tree)
-     Use FN to reduce elements of list TREE.  If elements of TREE are
-     lists themselves, apply the reduction recursively.
-
-     FN is first applied to first element of the list and second
-     element, then on this result and third element from the list etc.
-
-     See â€˜-reduce-r’ (*note -reduce-r::) for how exactly are lists of
-     zero or one element handled.
-
-          (-tree-reduce '+ '(1 (2 3) (4 5)))
-              â‡’ 15
-          (-tree-reduce 'concat '("strings" (" on" " various") ((" levels"))))
-              â‡’ "strings on various levels"
-          (--tree-reduce (cond ((stringp it) (concat it " " acc)) (t (let ((sn (symbol-name it))) (concat "<" sn ">" acc "</" sn ">")))) '(body (p "some words") (div "more" (b "bold") "words")))
-              â‡’ "<body><p>some words</p> <div>more <b>bold</b> words</div></body>"
-
- -- Function: -tree-reduce-from (fn init-value tree)
-     Use FN to reduce elements of list TREE.  If elements of TREE are
-     lists themselves, apply the reduction recursively.
-
-     FN is first applied to INIT-VALUE and first element of the list,
-     then on this result and second element from the list etc.
-
-     The initial value is ignored on cons pairs as they always contain
-     two elements.
-
-          (-tree-reduce-from '+ 1 '(1 (1 1) ((1))))
-              â‡’ 8
-          (--tree-reduce-from (-concat acc (list it)) nil '(1 (2 3 (4 5)) (6 7)))
-              â‡’ '((7 6) ((5 4) 3 2) 1)
-
- -- Function: -tree-mapreduce (fn folder tree)
-     Apply FN to each element of TREE, and make a list of the results.
-     If elements of TREE are lists themselves, apply FN recursively to
-     elements of these nested lists.
-
-     Then reduce the resulting lists using FOLDER and initial value
-     INIT-VALUE.  See â€˜-reduce-r-from’ (*note -reduce-r-from::).
-
-     This is the same as calling â€˜-tree-reduce’ (*note -tree-reduce::)
-     after â€˜-tree-map’ (*note -tree-map::) but is twice as fast as it
-     only traverse the structure once.
-
-          (-tree-mapreduce 'list 'append '(1 (2 (3 4) (5 6)) (7 (8 9))))
-              â‡’ '(1 2 3 4 5 6 7 8 9)
-          (--tree-mapreduce 1 (+ it acc) '(1 (2 (4 9) (2 1)) (7 (4 3))))
-              â‡’ 9
-          (--tree-mapreduce 0 (max acc (1+ it)) '(1 (2 (4 9) (2 1)) (7 (4 3))))
-              â‡’ 3
-
- -- Function: -tree-mapreduce-from (fn folder init-value tree)
-     Apply FN to each element of TREE, and make a list of the results.
-     If elements of TREE are lists themselves, apply FN recursively to
-     elements of these nested lists.
-
-     Then reduce the resulting lists using FOLDER and initial value
-     INIT-VALUE.  See â€˜-reduce-r-from’ (*note -reduce-r-from::).
-
-     This is the same as calling â€˜-tree-reduce-from’ (*note
-     -tree-reduce-from::) after â€˜-tree-map’ (*note -tree-map::) but is
-     twice as fast as it only traverse the structure once.
-
-          (-tree-mapreduce-from 'identity '* 1 '(1 (2 (3 4) (5 6)) (7 (8 9))))
-              â‡’ 362880
-          (--tree-mapreduce-from (+ it it) (cons it acc) nil '(1 (2 (4 9) (2 1)) (7 (4 3))))
-              â‡’ '(2 (4 (8 18) (4 2)) (14 (8 6)))
-          (concat "{" (--tree-mapreduce-from (cond ((-cons-pair? it) (concat (symbol-name (car it)) " -> " (symbol-name (cdr it)))) (t (concat (symbol-name it) " : {"))) (concat it (unless (or (equal acc "}") (equal (substring it (1- (length it))) "{")) ", ") acc) "}" '((elips-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
-              â‡’ "{elips-mode : {foo : {bar -> booze{, baz -> qux{, c-mode : {foo -> bla, bum -> bam}}"
-
- -- Function: -clone (list)
-     Create a deep copy of LIST.  The new list has the same elements and
-     structure but all cons are replaced with new ones.  This is useful
-     when you need to clone a structure such as plist or alist.
-
-          (let* ((a '(1 2 3)) (b (-clone a))) (nreverse a) b)
-              â‡’ '(1 2 3)
-
-\1f
-File: dash.info,  Node: Threading macros,  Next: Binding,  Prev: Tree operations,  Up: Functions
-
-2.12 Threading macros
-=====================
-
- -- Macro: -> (x &optional form &rest more)
-     Thread the expr through the forms.  Insert X as the second item in
-     the first form, making a list of it if it is not a list already.
-     If there are more forms, insert the first form as the second item
-     in second form, etc.
-
-          (-> '(2 3 5))
-              â‡’ '(2 3 5)
-          (-> '(2 3 5) (append '(8 13)))
-              â‡’ '(2 3 5 8 13)
-          (-> '(2 3 5) (append '(8 13)) (-slice 1 -1))
-              â‡’ '(3 5 8)
-
- -- Macro: ->> (x &optional form &rest more)
-     Thread the expr through the forms.  Insert X as the last item in
-     the first form, making a list of it if it is not a list already.
-     If there are more forms, insert the first form as the last item in
-     second form, etc.
-
-          (->> '(1 2 3) (-map 'square))
-              â‡’ '(1 4 9)
-          (->> '(1 2 3) (-map 'square) (-remove 'even?))
-              â‡’ '(1 9)
-          (->> '(1 2 3) (-map 'square) (-reduce '+))
-              â‡’ 14
-
- -- Macro: --> (x &rest forms)
-     Starting with the value of X, thread each expression through FORMS.
-
-     Insert X at the position signified by the symbol â€˜it’ in the first
-     form.  If there are more forms, insert the first form at the
-     position signified by â€˜it’ in in second form, etc.
-
-          (--> "def" (concat "abc" it "ghi"))
-              â‡’ "abcdefghi"
-          (--> "def" (concat "abc" it "ghi") (upcase it))
-              â‡’ "ABCDEFGHI"
-          (--> "def" (concat "abc" it "ghi") upcase)
-              â‡’ "ABCDEFGHI"
-
- -- Macro: -as-> (value variable &rest forms)
-     Starting with VALUE, thread VARIABLE through FORMS.
-
-     In the first form, bind VARIABLE to VALUE.  In the second form,
-     bind VARIABLE to the result of the first form, and so forth.
-
-          (-as-> 3 my-var (1+ my-var) (list my-var) (mapcar (lambda (ele) (* 2 ele)) my-var))
-              â‡’ '(8)
-          (-as-> 3 my-var 1+)
-              â‡’ 4
-          (-as-> 3 my-var)
-              â‡’ 3
-
- -- Macro: -some-> (x &optional form &rest more)
-     When expr is non-nil, thread it through the first form (via â€˜->’
-     (*note ->::)), and when that result is non-nil, through the next
-     form, etc.
-
-          (-some-> '(2 3 5))
-              â‡’ '(2 3 5)
-          (-some-> 5 square)
-              â‡’ 25
-          (-some-> 5 even? square)
-              â‡’ nil
-
- -- Macro: -some->> (x &optional form &rest more)
-     When expr is non-nil, thread it through the first form (via â€˜->>’
-     (*note ->>::)), and when that result is non-nil, through the next
-     form, etc.
-
-          (-some->> '(1 2 3) (-map 'square))
-              â‡’ '(1 4 9)
-          (-some->> '(1 3 5) (-last 'even?) (+ 100))
-              â‡’ nil
-          (-some->> '(2 4 6) (-last 'even?) (+ 100))
-              â‡’ 106
-
- -- Macro: -some--> (x &optional form &rest more)
-     When expr in non-nil, thread it through the first form (via â€˜-->’
-     (*note -->::)), and when that result is non-nil, through the next
-     form, etc.
-
-          (-some--> "def" (concat "abc" it "ghi"))
-              â‡’ "abcdefghi"
-          (-some--> nil (concat "abc" it "ghi"))
-              â‡’ nil
-          (-some--> '(1 3 5) (-filter 'even? it) (append it it) (-map 'square it))
-              â‡’ nil
-
-\1f
-File: dash.info,  Node: Binding,  Next: Side-effects,  Prev: Threading macros,  Up: Functions
-
-2.13 Binding
-============
-
-Convenient versions of â€˜let‘ and â€˜let*‘ constructs combined with flow
-control.
-
- -- Macro: -when-let (var-val &rest body)
-     If VAL evaluates to non-nil, bind it to VAR and execute body.
-
-     Note: binding is done according to â€˜-let’ (*note -let::).
-
-     (fn (VAR VAL) &rest BODY)
-
-          (-when-let (match-index (string-match "d" "abcd")) (+ match-index 2))
-              â‡’ 5
-          (-when-let ((&plist :foo foo) (list :foo "foo")) foo)
-              â‡’ "foo"
-          (-when-let ((&plist :foo foo) (list :bar "bar")) foo)
-              â‡’ nil
-
- -- Macro: -when-let* (vars-vals &rest body)
-     If all VALS evaluate to true, bind them to their corresponding VARS
-     and execute body.  VARS-VALS should be a list of (VAR VAL) pairs.
-
-     Note: binding is done according to â€˜-let*’ (*note -let*::).  VALS
-     are evaluated sequentially, and evaluation stops after the first
-     nil VAL is encountered.
-
-          (-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z))
-              â‡’ 15
-          (-when-let* ((x 5) (y nil) (z 7)) (+ x y z))
-              â‡’ nil
-
- -- Macro: -if-let (var-val then &rest else)
-     If VAL evaluates to non-nil, bind it to VAR and do THEN, otherwise
-     do ELSE.
-
-     Note: binding is done according to â€˜-let’ (*note -let::).
-
-     (fn (VAR VAL) THEN &rest ELSE)
-
-          (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7)
-              â‡’ 7
-          (--if-let (even? 4) it nil)
-              â‡’ t
-
- -- Macro: -if-let* (vars-vals then &rest else)
-     If all VALS evaluate to true, bind them to their corresponding VARS
-     and do THEN, otherwise do ELSE.  VARS-VALS should be a list of (VAR
-     VAL) pairs.
-
-     Note: binding is done according to â€˜-let*’ (*note -let*::).  VALS
-     are evaluated sequentially, and evaluation stops after the first
-     nil VAL is encountered.
-
-          (-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo")
-              â‡’ 15
-          (-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo")
-              â‡’ "foo"
-          (-if-let* (((_ _ x) '(nil nil 7))) x)
-              â‡’ 7
-
- -- Macro: -let (varlist &rest body)
-     Bind variables according to VARLIST then eval BODY.
-
-     VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
-     PATTERN is matched against the SOURCE "structurally".  SOURCE is
-     only evaluated once for each PATTERN.  Each PATTERN is matched
-     recursively, and can therefore contain sub-patterns which are
-     matched against corresponding sub-expressions of SOURCE.
-
-     All the SOURCEs are evalled before any symbols are bound (i.e.  "in
-     parallel").
-
-     If VARLIST only contains one (PATTERN SOURCE) element, you can
-     optionally specify it using a vector and discarding the outer-most
-     parens.  Thus
-
-     (-let ((PATTERN SOURCE)) ..)
-
-     becomes
-
-     (-let [PATTERN SOURCE] ..).
-
-     â€˜-let’ (*note -let::) uses a convention of not binding places
-     (symbols) starting with _ whenever it’s possible.  You can use this
-     to skip over entries you don’t care about.  However, this is not
-     *always* possible (as a result of implementation) and these symbols
-     might get bound to undefined values.
-
-     Following is the overview of supported patterns.  Remember that
-     patterns can be matched recursively, so every a, b, aK in the
-     following can be a matching construct and not necessarily a
-     symbol/variable.
-
-     Symbol:
-
-     a - bind the SOURCE to A.  This is just like regular â€˜let’.
-
-     Conses and lists:
-
-     (a) - bind â€˜car’ of cons/list to A
-
-     (a .  b) - bind car of cons to A and â€˜cdr’ to B
-
-     (a b) - bind car of list to A and â€˜cadr’ to B
-
-     (a1 a2 a3 ...)  - bind 0th car of list to A1, 1st to A2, 2nd to A3
-     ...
-
-     (a1 a2 a3 ...  aN .  rest) - as above, but bind the Nth cdr to
-     REST.
-
-     Vectors:
-
-     [a] - bind 0th element of a non-list sequence to A (works with
-     vectors, strings, bit arrays...)
-
-     [a1 a2 a3 ...]  - bind 0th element of non-list sequence to A0, 1st
-     to A1, 2nd to A2, ...  If the PATTERN is shorter than SOURCE, the
-     values at places not in PATTERN are ignored.  If the PATTERN is
-     longer than SOURCE, an â€˜error’ is thrown.
-
-     [a1 a2 a3 ...  &rest rest] - as above, but bind the rest of the
-     sequence to REST.  This is conceptually the same as improper list
-     matching (a1 a2 ...  aN .  rest)
-
-     Key/value stores:
-
-     (&plist key0 a0 ...  keyN aN) - bind value mapped by keyK in the
-     SOURCE plist to aK. If the value is not found, aK is nil.  Uses
-     â€˜plist-get’ to fetch values.
-
-     (&alist key0 a0 ...  keyN aN) - bind value mapped by keyK in the
-     SOURCE alist to aK. If the value is not found, aK is nil.  Uses
-     â€˜assoc’ to fetch values.
-
-     (&hash key0 a0 ...  keyN aN) - bind value mapped by keyK in the
-     SOURCE hash table to aK. If the value is not found, aK is nil.
-     Uses â€˜gethash’ to fetch values.
-
-     Further, special keyword &keys supports "inline" matching of
-     plist-like key-value pairs, similarly to &keys keyword of
-     â€˜cl-defun’.
-
-     (a1 a2 ...  aN &keys key1 b1 ...  keyN bK)
-
-     This binds N values from the list to a1 ...  aN, then interprets
-     the cdr as a plist (see key/value matching above).
-
-     A shorthand notation for kv-destructuring exists which allows the
-     patterns be optionally left out and derived from the key name in
-     the following fashion:
-
-     - a key :foo is converted into â€˜foo’ pattern, - a key â€™bar is
-     converted into â€˜bar’ pattern, - a key "baz" is converted into â€˜baz’
-     pattern.
-
-     That is, the entire value under the key is bound to the derived
-     variable without any further destructuring.
-
-     This is possible only when the form following the key is not a
-     valid pattern (i.e.  not a symbol, a cons cell or a vector).
-     Otherwise the matching proceeds as usual and in case of an invalid
-     spec fails with an error.
-
-     Thus the patterns are normalized as follows:
-
-     ;; derive all the missing patterns (&plist :foo â€™bar "baz") =>
-     (&plist :foo foo â€™bar bar "baz" baz)
-
-     ;; we can specify some but not others (&plist :foo â€™bar
-     explicit-bar) => (&plist :foo foo â€™bar explicit-bar)
-
-     ;; nothing happens, we store :foo in x (&plist :foo x) => (&plist
-     :foo x)
-
-     ;; nothing happens, we match recursively (&plist :foo (a b c)) =>
-     (&plist :foo (a b c))
-
-     You can name the source using the syntax SYMBOL &as PATTERN.  This
-     syntax works with lists (proper or improper), vectors and all types
-     of maps.
-
-     (list &as a b c) (list 1 2 3)
-
-     binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
-
-     Similarly:
-
-     (bounds &as beg .  end) (cons 1 2)
-
-     binds BEG to 1, END to 2 and BOUNDS to (1 .  2).
-
-     (items &as first .  rest) (list 1 2 3)
-
-     binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
-
-     [vect &as _ b c] [1 2 3]
-
-     binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as
-     usual).
-
-     (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
-
-     binds B to 2 and PLIST to (:a 1 :b 2 :c 3).  Same for &alist and
-     &hash.
-
-     This is especially useful when we want to capture the result of a
-     computation and destructure at the same time.  Consider the form
-     (function-returning-complex-structure) returning a list of two
-     vectors with two items each.  We want to capture this entire result
-     and pass it to another computation, but at the same time we want to
-     get the second item from each vector.  We can achieve it with
-     pattern
-
-     (result &as [_ a] [_ b]) (function-returning-complex-structure)
-
-     Note: Clojure programmers may know this feature as the ":as
-     binding".  The difference is that we put the &as at the front
-     because we need to support improper list binding.
-
-          (-let (([a (b c) d] [1 (2 3) 4])) (list a b c d))
-              â‡’ '(1 2 3 4)
-          (-let [(a b c . d) (list 1 2 3 4 5 6)] (list a b c d))
-              â‡’ '(1 2 3 (4 5 6))
-          (-let [(&plist :foo foo :bar bar) (list :baz 3 :foo 1 :qux 4 :bar 2)] (list foo bar))
-              â‡’ '(1 2)
-
- -- Macro: -let* (varlist &rest body)
-     Bind variables according to VARLIST then eval BODY.
-
-     VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
-     PATTERN is matched against the SOURCE structurally.  SOURCE is only
-     evaluated once for each PATTERN.
-
-     Each SOURCE can refer to the symbols already bound by this VARLIST.
-     This is useful if you want to destructure SOURCE recursively but
-     also want to name the intermediate structures.
-
-     See â€˜-let’ (*note -let::) for the list of all possible patterns.
-
-          (-let* (((a . b) (cons 1 2)) ((c . d) (cons 3 4))) (list a b c d))
-              â‡’ '(1 2 3 4)
-          (-let* (((a . b) (cons 1 (cons 2 3))) ((c . d) b)) (list a b c d))
-              â‡’ '(1 (2 . 3) 2 3)
-          (-let* (((&alist "foo" foo "bar" bar) (list (cons "foo" 1) (cons "bar" (list 'a 'b 'c)))) ((a b c) bar)) (list foo a b c bar))
-              â‡’ '(1 a b c (a b c))
-
- -- Macro: -lambda (match-form &rest body)
-     Return a lambda which destructures its input as MATCH-FORM and
-     executes BODY.
-
-     Note that you have to enclose the MATCH-FORM in a pair of parens,
-     such that:
-
-     (-lambda (x) body) (-lambda (x y ...)  body)
-
-     has the usual semantics of â€˜lambda’.  Furthermore, these get
-     translated into normal lambda, so there is no performance penalty.
-
-     See â€˜-let’ (*note -let::) for the description of destructuring
-     mechanism.
-
-          (-map (-lambda ((x y)) (+ x y)) '((1 2) (3 4) (5 6)))
-              â‡’ '(3 7 11)
-          (-map (-lambda ([x y]) (+ x y)) '([1 2] [3 4] [5 6]))
-              â‡’ '(3 7 11)
-          (funcall (-lambda ((_ . a) (_ . b)) (-concat a b)) '(1 2 3) '(4 5 6))
-              â‡’ '(2 3 5 6)
-
- -- Macro: -setq (&rest forms)
-     Bind each MATCH-FORM to the value of its VAL.
-
-     MATCH-FORM destructuring is done according to the rules of â€˜-let’
-     (*note -let::).
-
-     This macro allows you to bind multiple variables by destructuring
-     the value, so for example:
-
-     (-setq (a b) x (&plist :c c) plist)
-
-     expands roughly speaking to the following code
-
-     (setq a (car x) b (cadr x) c (plist-get plist :c))
-
-     Care is taken to only evaluate each VAL once so that in case of
-     multiple assignments it does not cause unexpected side effects.
-
-     (fn [MATCH-FORM VAL]...)
-
-          (progn (-setq a 1) a)
-              â‡’ 1
-          (progn (-setq (a b) (list 1 2)) (list a b))
-              â‡’ '(1 2)
-          (progn (-setq (&plist :c c) (list :c "c")) c)
-              â‡’ "c"
-
-\1f
-File: dash.info,  Node: Side-effects,  Next: Destructive operations,  Prev: Binding,  Up: Functions
-
-2.14 Side-effects
-=================
-
-Functions iterating over lists for side-effect only.
-
- -- Function: -each (list fn)
-     Call FN with every item in LIST.  Return nil, used for side-effects
-     only.
-
-          (let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))))
-              â‡’ nil
-          (let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
-              â‡’ '(3 2 1)
-          (let (s) (--each '(1 2 3) (setq s (cons it s))) s)
-              â‡’ '(3 2 1)
-
- -- Function: -each-while (list pred fn)
-     Call FN with every item in LIST while (PRED item) is non-nil.
-     Return nil, used for side-effects only.
-
-          (let (s) (-each-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
-              â‡’ '(4 2)
-          (let (s) (--each-while '(1 2 3 4) (< it 3) (!cons it s)) s)
-              â‡’ '(2 1)
-
- -- Function: -each-indexed (list fn)
-     Call (FN index item) for each item in LIST.
-
-     In the anaphoric form â€˜--each-indexed’, the index is exposed as
-     symbol â€˜it-index’.
-
-     See also: â€˜-map-indexed’ (*note -map-indexed::).
-
-          (let (s) (-each-indexed '(a b c) (lambda (index item) (setq s (cons (list item index) s)))) s)
-              â‡’ '((c 2) (b 1) (a 0))
-          (let (s) (--each-indexed '(a b c) (setq s (cons (list it it-index) s))) s)
-              â‡’ '((c 2) (b 1) (a 0))
-
- -- Function: -each-r (list fn)
-     Call FN with every item in LIST in reversed order.  Return nil,
-     used for side-effects only.
-
-          (let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))))
-              â‡’ nil
-          (let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
-              â‡’ '(1 2 3)
-          (let (s) (--each-r '(1 2 3) (setq s (cons it s))) s)
-              â‡’ '(1 2 3)
-
- -- Function: -each-r-while (list pred fn)
-     Call FN with every item in reversed LIST while (PRED item) is
-     non-nil.  Return nil, used for side-effects only.
-
-          (let (s) (-each-r-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
-              â‡’ '(6)
-          (let (s) (--each-r-while '(1 2 3 4) (>= it 3) (!cons it s)) s)
-              â‡’ '(3 4)
-
- -- Function: -dotimes (num fn)
-     Repeatedly calls FN (presumably for side-effects) passing in
-     integers from 0 through NUM-1.
-
-          (let (s) (-dotimes 3 (lambda (n) (!cons n s))) s)
-              â‡’ '(2 1 0)
-          (let (s) (--dotimes 5 (!cons it s)) s)
-              â‡’ '(4 3 2 1 0)
-
- -- Macro: -doto (eval-initial-value &rest forms)
-     Eval a form, then insert that form as the 2nd argument to other
-     forms.  The EVAL-INITIAL-VALUE form is evaluated once.  Its result
-     is passed to FORMS, which are then evaluated sequentially.  Returns
-     the target form.
-
-          (-doto '(1 2 3) (!cdr) (!cdr))
-              â‡’ '(3)
-          (-doto '(1 . 2) (setcar 3) (setcdr 4))
-              â‡’ '(3 . 4)
-
- -- Macro: --doto (eval-initial-value &rest forms)
-     Anaphoric form of â€˜-doto’ (*note -doto::).  Note: â€˜it’ is not
-     required in each form.
-
-          (gethash "key" (--doto (make-hash-table :test 'equal) (puthash "key" "value" it)))
-              â‡’ "value"
-
-\1f
-File: dash.info,  Node: Destructive operations,  Next: Function combinators,  Prev: Side-effects,  Up: Functions
-
-2.15 Destructive operations
-===========================
-
- -- Macro: !cons (car cdr)
-     Destructive: Set CDR to the cons of CAR and CDR.
-
-          (let (l) (!cons 5 l) l)
-              â‡’ '(5)
-          (let ((l '(3))) (!cons 5 l) l)
-              â‡’ '(5 3)
-
- -- Macro: !cdr (list)
-     Destructive: Set LIST to the cdr of LIST.
-
-          (let ((l '(3))) (!cdr l) l)
-              â‡’ '()
-          (let ((l '(3 5))) (!cdr l) l)
-              â‡’ '(5)
-
-\1f
-File: dash.info,  Node: Function combinators,  Prev: Destructive operations,  Up: Functions
-
-2.16 Function combinators
-=========================
-
-These combinators require Emacs 24 for its lexical scope.  So they are
-offered in a separate package: â€˜dash-functional‘.
-
- -- Function: -partial (fn &rest args)
-     Takes a function FN and fewer than the normal arguments to FN, and
-     returns a fn that takes a variable number of additional ARGS.  When
-     called, the returned function calls FN with ARGS first and then
-     additional args.
-
-          (funcall (-partial '- 5) 3)
-              â‡’ 2
-          (funcall (-partial '+ 5 2) 3)
-              â‡’ 10
-
- -- Function: -rpartial (fn &rest args)
-     Takes a function FN and fewer than the normal arguments to FN, and
-     returns a fn that takes a variable number of additional ARGS.  When
-     called, the returned function calls FN with the additional args
-     first and then ARGS.
-
-          (funcall (-rpartial '- 5) 8)
-              â‡’ 3
-          (funcall (-rpartial '- 5 2) 10)
-              â‡’ 3
-
- -- Function: -juxt (&rest fns)
-     Takes a list of functions and returns a fn that is the
-     juxtaposition of those fns.  The returned fn takes a variable
-     number of args, and returns a list containing the result of
-     applying each fn to the args (left-to-right).
-
-          (funcall (-juxt '+ '-) 3 5)
-              â‡’ '(8 -2)
-          (-map (-juxt 'identity 'square) '(1 2 3))
-              â‡’ '((1 1) (2 4) (3 9))
-
- -- Function: -compose (&rest fns)
-     Takes a list of functions and returns a fn that is the composition
-     of those fns.  The returned fn takes a variable number of
-     arguments, and returns the result of applying each fn to the result
-     of applying the previous fn to the arguments (right-to-left).
-
-          (funcall (-compose 'square '+) 2 3)
-              â‡’ (square (+ 2 3))
-          (funcall (-compose 'identity 'square) 3)
-              â‡’ (square 3)
-          (funcall (-compose 'square 'identity) 3)
-              â‡’ (square 3)
-
- -- Function: -applify (fn)
-     Changes an n-arity function FN to a 1-arity function that expects a
-     list with n items as arguments
-
-          (-map (-applify '+) '((1 1 1) (1 2 3) (5 5 5)))
-              â‡’ '(3 6 15)
-          (-map (-applify (lambda (a b c) `(,a (,b (,c))))) '((1 1 1) (1 2 3) (5 5 5)))
-              â‡’ '((1 (1 (1))) (1 (2 (3))) (5 (5 (5))))
-          (funcall (-applify '<) '(3 6))
-              â‡’ t
-
- -- Function: -on (operator transformer)
-     Return a function of two arguments that first applies TRANSFORMER
-     to each of them and then applies OPERATOR on the results (in the
-     same order).
-
-     In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
-
-          (-sort (-on '< 'length) '((1 2 3) (1) (1 2)))
-              â‡’ '((1) (1 2) (1 2 3))
-          (-min-by (-on '> 'length) '((1 2 3) (4) (1 2)))
-              â‡’ '(4)
-          (-min-by (-on 'string-lessp 'number-to-string) '(2 100 22))
-              â‡’ 22
-
- -- Function: -flip (func)
-     Swap the order of arguments for binary function FUNC.
-
-     In types: (a -> b -> c) -> b -> a -> c
-
-          (funcall (-flip '<) 2 1)
-              â‡’ t
-          (funcall (-flip '-) 3 8)
-              â‡’ 5
-          (-sort (-flip '<) '(4 3 6 1))
-              â‡’ '(6 4 3 1)
-
- -- Function: -const (c)
-     Return a function that returns C ignoring any additional arguments.
-
-     In types: a -> b -> a
-
-          (funcall (-const 2) 1 3 "foo")
-              â‡’ 2
-          (-map (-const 1) '("a" "b" "c" "d"))
-              â‡’ '(1 1 1 1)
-          (-sum (-map (-const 1) '("a" "b" "c" "d")))
-              â‡’ 4
-
- -- Macro: -cut (&rest params)
-     Take n-ary function and n arguments and specialize some of them.
-     Arguments denoted by <> will be left unspecialized.
-
-     See SRFI-26 for detailed description.
-
-          (funcall (-cut list 1 <> 3 <> 5) 2 4)
-              â‡’ '(1 2 3 4 5)
-          (-map (-cut funcall <> 5) '(1+ 1- (lambda (x) (/ 1.0 x))))
-              â‡’ '(6 4 0.2)
-          (-map (-cut <> 1 2 3) (list 'list 'vector 'string))
-              â‡’ '((1 2 3) [1 2 3] "\ 1\ 2\ 3")
-
- -- Function: -not (pred)
-     Take a unary predicate PRED and return a unary predicate that
-     returns t if PRED returns nil and nil if PRED returns non-nil.
-
-          (funcall (-not 'even?) 5)
-              â‡’ t
-          (-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8))
-              â‡’ '(1 2 3 4)
-
- -- Function: -orfn (&rest preds)
-     Take list of unary predicates PREDS and return a unary predicate
-     with argument x that returns non-nil if at least one of the PREDS
-     returns non-nil on x.
-
-     In types: [a -> Bool] -> a -> Bool
-
-          (-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10))
-              â‡’ '(1 2 3 4 6 8 10)
-          (funcall (-orfn 'stringp 'even?) "foo")
-              â‡’ t
-
- -- Function: -andfn (&rest preds)
-     Take list of unary predicates PREDS and return a unary predicate
-     with argument x that returns non-nil if all of the PREDS returns
-     non-nil on x.
-
-     In types: [a -> Bool] -> a -> Bool
-
-          (funcall (-andfn (-cut < <> 10) 'even?) 6)
-              â‡’ t
-          (funcall (-andfn (-cut < <> 10) 'even?) 12)
-              â‡’ nil
-          (-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
-              â‡’ '(1 3 5)
-
- -- Function: -iteratefn (fn n)
-     Return a function FN composed N times with itself.
-
-     FN is a unary function.  If you need to use a function of higher
-     arity, use â€˜-applify’ (*note -applify::) first to turn it into a
-     unary function.
-
-     With n = 0, this acts as identity function.
-
-     In types: (a -> a) -> Int -> a -> a.
-
-     This function satisfies the following law:
-
-     (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init
-     (1+ n))).
-
-          (funcall (-iteratefn (lambda (x) (* x x)) 3) 2)
-              â‡’ 256
-          (funcall (-iteratefn '1+ 3) 1)
-              â‡’ 4
-          (funcall (-iteratefn 'cdr 3) '(1 2 3 4 5))
-              â‡’ '(4 5)
-
- -- Function: -fixfn (fn &optional equal-test halt-test)
-     Return a function that computes the (least) fixpoint of FN.
-
-     FN must be a unary function.  The returned lambda takes a single
-     argument, X, the initial value for the fixpoint iteration.  The
-     iteration halts when either of the following conditions is
-     satisfied:
-
-     1.  Iteration converges to the fixpoint, with equality being tested
-     using EQUAL-TEST.  If EQUAL-TEST is not specified, â€˜equal’ is used.
-     For functions over the floating point numbers, it may be necessary
-     to provide an appropriate appoximate comparison test.
-
-     2.  HALT-TEST returns a non-nil value.  HALT-TEST defaults to a
-     simple counter that returns t after â€˜-fixfn-max-iterations’, to
-     guard against infinite iteration.  Otherwise, HALT-TEST must be a
-     function that accepts a single argument, the current value of X,
-     and returns non-nil as long as iteration should continue.  In this
-     way, a more sophisticated convergence test may be supplied by the
-     caller.
-
-     The return value of the lambda is either the fixpoint or, if
-     iteration halted before converging, a cons with car â€˜halted’ and
-     cdr the final output from HALT-TEST.
-
-     In types: (a -> a) -> a -> a.
-
-          (funcall (-fixfn 'cos 'approx-equal) 0.7)
-              â‡’ 0.7390851332151607
-          (funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
-              â‡’ 1.8555845286409378
-          (funcall (-fixfn 'sin 'approx-equal) 0.1)
-              â‡’ '(halted . t)
-
- -- Function: -prodfn (&rest fns)
-     Take a list of n functions and return a function that takes a list
-     of length n, applying i-th function to i-th element of the input
-     list.  Returns a list of length n.
-
-     In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
-
-     This function satisfies the following laws:
-
-     (-compose (-prodfn f g ...)  (-prodfn f’ g’ ...))  = (-prodfn
-     (-compose f f’) (-compose g g’) ...)  (-prodfn f g ...)  = (-juxt
-     (-compose f (-partial â€™nth 0)) (-compose g (-partial â€™nth 1)) ...)
-     (-compose (-prodfn f g ...)  (-juxt f’ g’ ...))  = (-juxt (-compose
-     f f’) (-compose g g’) ...)  (-compose (-partial â€™nth n) (-prod f1
-     f2 ...))  = (-compose fn (-partial â€™nth n))
-
-          (funcall (-prodfn '1+ '1- 'number-to-string) '(1 2 3))
-              â‡’ '(2 1 "3")
-          (-map (-prodfn '1+ '1-) '((1 2) (3 4) (5 6) (7 8)))
-              â‡’ '((2 1) (4 3) (6 5) (8 7))
-          (apply '+ (funcall (-prodfn 'length 'string-to-number) '((1 2 3) "15")))
-              â‡’ 18
-
-\1f
-File: dash.info,  Node: Development,  Next: Index,  Prev: Functions,  Up: Top
-
-3 Development
-*************
-
-The dash repository is hosted on GitHub:
-<https://github.com/magnars/dash.el>
-
-* Menu:
-
-* Contribute::          How to contribute
-* Changes::             List of significant changes by version
-* Contributors::        List of contributors
-
-\1f
-File: dash.info,  Node: Contribute,  Next: Changes,  Up: Development
-
-3.1 Contribute
-==============
-
-Yes, please do.  Pure functions in the list manipulation realm only,
-please.  There’s a suite of tests in dev/examples.el, so remember to add
-tests for your function, or it might get broken later.
-
-   Run the tests with â€˜./run-tests.sh’.  Create the docs with
-‘./create-docs.sh’.  I highly recommend that you install these as a
-pre-commit hook, so that the tests are always running and the docs are
-always in sync:
-
-cp pre-commit.sh .git/hooks/pre-commit
-
-   Oh, and don’t edit â€˜README.md’ directly, it is auto-generated.
-Change â€˜readme-template.md’ or â€˜examples-to-docs.el’ instead.  The same
-goes for the info manual.
-
-\1f
-File: dash.info,  Node: Changes,  Next: Contributors,  Prev: Contribute,  Up: Development
-
-3.2 Changes
-===========
-
-Changes in 2.10:
-
-   â€¢ Add â€˜-let’ destructuring to â€˜-if-let’ and â€˜-when-let’ (Fredrik
-     Bergroth)
-
-Changes in 2.9:
-
-   â€¢ Add â€˜-let’, â€˜-let*’ and â€˜-lambda’ with destructuring
-   â€¢ Add â€˜-tree-seq’ and â€˜-tree-map-nodes’
-   â€¢ Add â€˜-non-nil’
-   â€¢ Add â€˜-fix’
-   â€¢ Add â€˜-fixfn’ (dash-functional 1.2)
-   â€¢ Add â€˜-copy’ (Wilfred Hughes)
-
-Changes in 2.8:
-
-   â€¢ Add â€˜-butlast’
-
-Changes in 2.7:
-
-   â€¢ â€˜-zip’ now supports more than two lists (Steve Lamb)
-   â€¢ Add â€˜-cycle’, â€˜-pad’, â€˜-annotate’, â€˜-zip-fill’ (Steve Lamb)
-   â€¢ Add â€˜-table’, â€˜-table-flat’ (finite cartesian product)
-   â€¢ Add â€˜-flatten-n’
-   â€¢ â€˜-slice’ now supports "step" argument
-   â€¢ Add functional combinators â€˜-iteratefn’, â€˜-prodfn’
-   â€¢ Add â€˜-replace’, â€˜-splice’, â€˜-splice-list’ which generalize
-     â€˜-replace-at’ and â€˜-insert-at’
-   â€¢ Add â€˜-compose’, â€˜-iteratefn’ and â€˜-prodfn’ (dash-functional 1.1)
-
-Changes in 2.6:
-
-   â€¢ Add â€˜-is-prefix-p’, â€˜-is-suffix-p’, â€˜-is-infix-p’ (Matus Goljer)
-   â€¢ Add â€˜-iterate’, â€˜-unfold’ (Matus Goljer)
-   â€¢ Add â€˜-split-on’, â€˜-split-when’ (Matus Goljer)
-   â€¢ Add â€˜-find-last-index’ (Matus Goljer)
-   â€¢ Add â€˜-list’ (Johan Andersson)
-
-Changes in 2.5:
-
-   â€¢ Add â€˜-same-items?’ (Johan Andersson)
-   â€¢ A few bugfixes
-
-Changes in 2.4:
-
-   â€¢ Add â€˜-snoc’ (Matus Goljer)
-   â€¢ Add â€˜-replace-at’, â€˜-update-at’, â€˜-remove-at’, and
-     â€˜-remove-at-indices’ (Matus Goljer)
-
-Changes in 2.3:
-
-   â€¢ Add tree operations (Matus Goljer)
-   â€¢ Make font-lock optional
-
-Changes in 2.2:
-
-   â€¢ Add â€˜-compose’ (Christina Whyte)
-
-Changes in 2.1:
-
-   â€¢ Add indexing operations (Matus Goljer)
-
-Changes in 2.0:
-
-   â€¢ Split out â€˜dash-functional.el’ (Matus Goljer)
-   â€¢ Add â€˜-andfn’, â€˜-orfn’, â€˜-not’, â€˜-cut’, â€˜-const’, â€˜-flip’ and â€˜-on’.
-     (Matus Goljer)
-   â€¢ Fix â€˜-min’, â€˜-max’, â€˜-min-by’ and â€˜-max-by’ (Matus Goljer)
-
-Changes in 1.8:
-
-   â€¢ Add â€˜-first-item’ and â€˜-last-item’ (Wilfred Hughes)
-
-Changes in 1.7:
-
-   â€¢ Add â€˜-rotate’ (Matus Goljer)
-
-Changes in 1.6:
-
-   â€¢ Add â€˜-min’, â€˜-max’, â€˜-min-by’ and â€˜-max-by’ (Johan Andersson)
-
-Changes in 1.5:
-
-   â€¢ Add â€˜-sum’ and â€˜-product’ (Johan Andersson)
-
-Changes in 1.4:
-
-   â€¢ Add â€˜-sort’
-   â€¢ Add â€˜-reduce-r’ (Matus Goljer)
-   â€¢ Add â€˜-reduce-r-from’ (Matus Goljer)
-
-Changes in 1.3:
-
-   â€¢ Add â€˜-partition-in-steps’
-   â€¢ Add â€˜-partition-all-in-steps’
-
-Changes in 1.2:
-
-   â€¢ Add â€˜-last’ (Matus Goljer)
-   â€¢ Add â€˜-insert-at’ (Emanuel Evans)
-   â€¢ Add â€˜-when-let’ and â€˜-if-let’ (Emanuel Evans)
-   â€¢ Add â€˜-when-let*’ and â€˜-if-let*’ (Emanuel Evans)
-   â€¢ Some bugfixes
-
-\1f
-File: dash.info,  Node: Contributors,  Prev: Changes,  Up: Development
-
-3.3 Contributors
-================
-
-   â€¢ Matus Goljer (https://github.com/Fuco1) contributed lots of
-     features and functions.
-   â€¢ Takafumi Arakaki (https://github.com/tkf) contributed â€˜-group-by’.
-   â€¢ tali713 (https://github.com/tali713) is the author of â€˜-applify’.
-   â€¢ Víctor M. Valenzuela (https://github.com/vemv) contributed
-     â€˜-repeat’.
-   â€¢ Nic Ferrier (https://github.com/nicferrier) contributed â€˜-cons*’.
-   â€¢ Wilfred Hughes (https://github.com/Wilfred) contributed â€˜-slice’,
-     â€˜-first-item’ and â€˜-last-item’.
-   â€¢ Emanuel Evans (https://github.com/shosti) contributed â€˜-if-let’,
-     â€˜-when-let’ and â€˜-insert-at’.
-   â€¢ Johan Andersson (https://github.com/rejeep) contributed â€˜-sum’,
-     â€˜-product’ and â€˜-same-items?’
-   â€¢ Christina Whyte (https://github.com/kurisuwhyte) contributed
-     â€˜-compose’
-   â€¢ Steve Lamb (https://github.com/steventlamb) contributed â€˜-cycle’,
-     â€˜-pad’, â€˜-annotate’, â€˜-zip-fill’ and an n-ary version of â€˜-zip’.
-   â€¢ Fredrik Bergroth (https://github.com/fbergroth) made the â€˜-if-let’
-     family use â€˜-let’ destructuring and improved script for generating
-     documentation.
-   â€¢ Mark Oteiza (https://github.com/holomorph) contributed the script
-     to create an info manual.
-   â€¢ Vasilij Schneidermann (https://github.com/wasamasa) contributed
-     â€˜-some’.
-   â€¢ William West (https://github.com/occidens) made â€˜-fixfn’ more
-     robust at handling floats.
-
-   Thanks!
-
-\1f
-File: dash.info,  Node: Index,  Prev: Development,  Up: Top
-
-Index
-*****
-
-\0\b[index\0\b]
-* Menu:
-
-* !cdr:                                  Destructive operations.
-                                                              (line  14)
-* !cons:                                 Destructive operations.
-                                                              (line   6)
-* -->:                                   Threading macros.    (line  32)
-* --doto:                                Side-effects.        (line  81)
-* ->:                                    Threading macros.    (line   6)
-* ->>:                                   Threading macros.    (line  19)
-* -all?:                                 Predicates.          (line  18)
-* -andfn:                                Function combinators.
-                                                              (line 138)
-* -annotate:                             Maps.                (line  79)
-* -any?:                                 Predicates.          (line   6)
-* -applify:                              Function combinators.
-                                                              (line  55)
-* -as->:                                 Threading macros.    (line  46)
-* -butlast:                              Other list operations.
-                                                              (line 340)
-* -clone:                                Tree operations.     (line 122)
-* -common-prefix:                        Reductions.          (line 223)
-* -common-suffix:                        Reductions.          (line 233)
-* -compose:                              Function combinators.
-                                                              (line  42)
-* -concat:                               List to list.        (line  22)
-* -cons*:                                Other list operations.
-                                                              (line  30)
-* -const:                                Function combinators.
-                                                              (line  92)
-* -contains?:                            Predicates.          (line  57)
-* -copy:                                 Maps.                (line 134)
-* -count:                                Reductions.          (line 151)
-* -cut:                                  Function combinators.
-                                                              (line 104)
-* -cycle:                                Other list operations.
-                                                              (line 168)
-* -difference:                           Set operations.      (line  20)
-* -distinct:                             Set operations.      (line  62)
-* -dotimes:                              Side-effects.        (line  61)
-* -doto:                                 Side-effects.        (line  70)
-* -drop:                                 Sublist selection.   (line 124)
-* -drop-last:                            Sublist selection.   (line 136)
-* -drop-while:                           Sublist selection.   (line 157)
-* -each:                                 Side-effects.        (line   8)
-* -each-indexed:                         Side-effects.        (line  28)
-* -each-r:                               Side-effects.        (line  41)
-* -each-r-while:                         Side-effects.        (line  52)
-* -each-while:                           Side-effects.        (line  19)
-* -elem-index:                           Indexing.            (line   9)
-* -elem-indices:                         Indexing.            (line  21)
-* -fifth-item:                           Other list operations.
-                                                              (line 320)
-* -filter:                               Sublist selection.   (line   8)
-* -find-index:                           Indexing.            (line  32)
-* -find-indices:                         Indexing.            (line  60)
-* -find-last-index:                      Indexing.            (line  46)
-* -first:                                Other list operations.
-                                                              (line 234)
-* -first-item:                           Other list operations.
-                                                              (line 271)
-* -fix:                                  Other list operations.
-                                                              (line 376)
-* -fixfn:                                Function combinators.
-                                                              (line 175)
-* -flatten:                              List to list.        (line  33)
-* -flatten-n:                            List to list.        (line  55)
-* -flip:                                 Function combinators.
-                                                              (line  80)
-* -fourth-item:                          Other list operations.
-                                                              (line 310)
-* -grade-down:                           Indexing.            (line  81)
-* -grade-up:                             Indexing.            (line  71)
-* -group-by:                             Partitioning.        (line 187)
-* -if-let:                               Binding.             (line  36)
-* -if-let*:                              Binding.             (line  49)
-* -inits:                                Reductions.          (line 203)
-* -insert-at:                            List to list.        (line 109)
-* -interleave:                           Other list operations.
-                                                              (line  68)
-* -interpose:                            Other list operations.
-                                                              (line  58)
-* -intersection:                         Set operations.      (line  32)
-* -is-infix?:                            Predicates.          (line 110)
-* -is-prefix?:                           Predicates.          (line  86)
-* -is-suffix?:                           Predicates.          (line  98)
-* -iterate:                              Unfolding.           (line   9)
-* -iteratefn:                            Function combinators.
-                                                              (line 152)
-* -juxt:                                 Function combinators.
-                                                              (line  31)
-* -keep:                                 List to list.        (line   8)
-* -lambda:                               Binding.             (line 252)
-* -last:                                 Other list operations.
-                                                              (line 261)
-* -last-item:                            Other list operations.
-                                                              (line 330)
-* -let:                                  Binding.             (line  65)
-* -let*:                                 Binding.             (line 232)
-* -list:                                 Other list operations.
-                                                              (line 363)
-* -map:                                  Maps.                (line  10)
-* -map-first:                            Maps.                (line  37)
-* -map-indexed:                          Maps.                (line  65)
-* -map-last:                             Maps.                (line  51)
-* -map-when:                             Maps.                (line  21)
-* -mapcat:                               Maps.                (line 123)
-* -max:                                  Reductions.          (line 267)
-* -max-by:                               Reductions.          (line 277)
-* -min:                                  Reductions.          (line 243)
-* -min-by:                               Reductions.          (line 253)
-* -non-nil:                              Sublist selection.   (line  79)
-* -none?:                                Predicates.          (line  30)
-* -not:                                  Function combinators.
-                                                              (line 117)
-* -on:                                   Function combinators.
-                                                              (line  66)
-* -only-some?:                           Predicates.          (line  42)
-* -orfn:                                 Function combinators.
-                                                              (line 126)
-* -pad:                                  Other list operations.
-                                                              (line 179)
-* -partial:                              Function combinators.
-                                                              (line   9)
-* -partition:                            Partitioning.        (line  74)
-* -partition-after-item:                 Partitioning.        (line 177)
-* -partition-after-pred:                 Partitioning.        (line 145)
-* -partition-all:                        Partitioning.        (line  86)
-* -partition-all-in-steps:               Partitioning.        (line 109)
-* -partition-before-item:                Partitioning.        (line 167)
-* -partition-before-pred:                Partitioning.        (line 156)
-* -partition-by:                         Partitioning.        (line 121)
-* -partition-by-header:                  Partitioning.        (line 132)
-* -partition-in-steps:                   Partitioning.        (line  97)
-* -permutations:                         Set operations.      (line  52)
-* -powerset:                             Set operations.      (line  44)
-* -prodfn:                               Function combinators.
-                                                              (line 209)
-* -product:                              Reductions.          (line 181)
-* -reduce:                               Reductions.          (line  46)
-* -reduce-from:                          Reductions.          (line   8)
-* -reduce-r:                             Reductions.          (line  65)
-* -reduce-r-from:                        Reductions.          (line  27)
-* -reductions:                           Reductions.          (line 119)
-* -reductions-from:                      Reductions.          (line  87)
-* -reductions-r:                         Reductions.          (line 135)
-* -reductions-r-from:                    Reductions.          (line 103)
-* -remove:                               Sublist selection.   (line  23)
-* -remove-at:                            List to list.        (line 145)
-* -remove-at-indices:                    List to list.        (line 158)
-* -remove-first:                         Sublist selection.   (line  37)
-* -remove-item:                          Sublist selection.   (line  67)
-* -remove-last:                          Sublist selection.   (line  52)
-* -repeat:                               Other list operations.
-                                                              (line  19)
-* -replace:                              List to list.        (line  67)
-* -replace-at:                           List to list.        (line 120)
-* -replace-first:                        List to list.        (line  81)
-* -replace-last:                         List to list.        (line  95)
-* -rotate:                               Other list operations.
-                                                              (line   8)
-* -rpartial:                             Function combinators.
-                                                              (line  20)
-* -running-product:                      Reductions.          (line 191)
-* -running-sum:                          Reductions.          (line 169)
-* -same-items?:                          Predicates.          (line  72)
-* -second-item:                          Other list operations.
-                                                              (line 286)
-* -select-by-indices:                    Sublist selection.   (line 168)
-* -select-column:                        Sublist selection.   (line 198)
-* -select-columns:                       Sublist selection.   (line 179)
-* -separate:                             Partitioning.        (line  63)
-* -setq:                                 Binding.             (line 274)
-* -slice:                                Sublist selection.   (line  85)
-* -snoc:                                 Other list operations.
-                                                              (line  44)
-* -some:                                 Other list operations.
-                                                              (line 248)
-* -some-->:                              Threading macros.    (line  83)
-* -some->:                               Threading macros.    (line  59)
-* -some->>:                              Threading macros.    (line  71)
-* -sort:                                 Other list operations.
-                                                              (line 350)
-* -splice:                               Maps.                (line  90)
-* -splice-list:                          Maps.                (line 110)
-* -split-at:                             Partitioning.        (line   8)
-* -split-on:                             Partitioning.        (line  28)
-* -split-when:                           Partitioning.        (line  46)
-* -split-with:                           Partitioning.        (line  17)
-* -sum:                                  Reductions.          (line 159)
-* -table:                                Other list operations.
-                                                              (line 190)
-* -table-flat:                           Other list operations.
-                                                              (line 209)
-* -tails:                                Reductions.          (line 213)
-* -take:                                 Sublist selection.   (line 101)
-* -take-last:                            Sublist selection.   (line 112)
-* -take-while:                           Sublist selection.   (line 146)
-* -third-item:                           Other list operations.
-                                                              (line 298)
-* -tree-map:                             Tree operations.     (line  28)
-* -tree-map-nodes:                       Tree operations.     (line  39)
-* -tree-mapreduce:                       Tree operations.     (line  84)
-* -tree-mapreduce-from:                  Tree operations.     (line 103)
-* -tree-reduce:                          Tree operations.     (line  52)
-* -tree-reduce-from:                     Tree operations.     (line  69)
-* -tree-seq:                             Tree operations.     (line   8)
-* -unfold:                               Unfolding.           (line  25)
-* -union:                                Set operations.      (line   8)
-* -unzip:                                Other list operations.
-                                                              (line 146)
-* -update-at:                            List to list.        (line 132)
-* -when-let:                             Binding.             (line   9)
-* -when-let*:                            Binding.             (line  23)
-* -zip:                                  Other list operations.
-                                                              (line  95)
-* -zip-fill:                             Other list operations.
-                                                              (line 138)
-* -zip-lists:                            Other list operations.
-                                                              (line 119)
-* -zip-with:                             Other list operations.
-                                                              (line  79)
-
-
-\1f
-Tag Table:
-Node: Top\7f946
-Node: Installation\7f2425
-Node: Using in a package\7f2958
-Node: Syntax highlighting of dash functions\7f3322
-Node: Functions\7f3705
-Node: Maps\7f4916
-Ref: -map\7f5211
-Ref: -map-when\7f5552
-Ref: -map-first\7f6130
-Ref: -map-last\7f6608
-Ref: -map-indexed\7f7081
-Ref: -annotate\7f7561
-Ref: -splice\7f8051
-Ref: -splice-list\7f8832
-Ref: -mapcat\7f9294
-Ref: -copy\7f9670
-Node: Sublist selection\7f9874
-Ref: -filter\7f10067
-Ref: -remove\7f10519
-Ref: -remove-first\7f10925
-Ref: -remove-last\7f11452
-Ref: -remove-item\7f11973
-Ref: -non-nil\7f12368
-Ref: -slice\7f12527
-Ref: -take\7f13059
-Ref: -take-last\7f13367
-Ref: -drop\7f13690
-Ref: -drop-last\7f13963
-Ref: -take-while\7f14223
-Ref: -drop-while\7f14573
-Ref: -select-by-indices\7f14929
-Ref: -select-columns\7f15443
-Ref: -select-column\7f16149
-Node: List to list\7f16613
-Ref: -keep\7f16805
-Ref: -concat\7f17308
-Ref: -flatten\7f17605
-Ref: -flatten-n\7f18364
-Ref: -replace\7f18751
-Ref: -replace-first\7f19214
-Ref: -replace-last\7f19711
-Ref: -insert-at\7f20201
-Ref: -replace-at\7f20528
-Ref: -update-at\7f20918
-Ref: -remove-at\7f21409
-Ref: -remove-at-indices\7f21897
-Node: Reductions\7f22479
-Ref: -reduce-from\7f22648
-Ref: -reduce-r-from\7f23414
-Ref: -reduce\7f24181
-Ref: -reduce-r\7f24910
-Ref: -reductions-from\7f25781
-Ref: -reductions-r-from\7f26496
-Ref: -reductions\7f27221
-Ref: -reductions-r\7f27846
-Ref: -count\7f28481
-Ref: -sum\7f28705
-Ref: -running-sum\7f28894
-Ref: -product\7f29187
-Ref: -running-product\7f29396
-Ref: -inits\7f29709
-Ref: -tails\7f29957
-Ref: -common-prefix\7f30204
-Ref: -common-suffix\7f30501
-Ref: -min\7f30798
-Ref: -min-by\7f31024
-Ref: -max\7f31547
-Ref: -max-by\7f31772
-Node: Unfolding\7f32300
-Ref: -iterate\7f32539
-Ref: -unfold\7f32984
-Node: Predicates\7f33792
-Ref: -any?\7f33916
-Ref: -all?\7f34236
-Ref: -none?\7f34566
-Ref: -only-some?\7f34868
-Ref: -contains?\7f35353
-Ref: -same-items?\7f35742
-Ref: -is-prefix?\7f36127
-Ref: -is-suffix?\7f36450
-Ref: -is-infix?\7f36773
-Node: Partitioning\7f37127
-Ref: -split-at\7f37315
-Ref: -split-with\7f37600
-Ref: -split-on\7f38003
-Ref: -split-when\7f38679
-Ref: -separate\7f39319
-Ref: -partition\7f39761
-Ref: -partition-all\7f40213
-Ref: -partition-in-steps\7f40641
-Ref: -partition-all-in-steps\7f41138
-Ref: -partition-by\7f41623
-Ref: -partition-by-header\7f42005
-Ref: -partition-after-pred\7f42609
-Ref: -partition-before-pred\7f42953
-Ref: -partition-before-item\7f43304
-Ref: -partition-after-item\7f43615
-Ref: -group-by\7f43921
-Node: Indexing\7f44358
-Ref: -elem-index\7f44560
-Ref: -elem-indices\7f44955
-Ref: -find-index\7f45338
-Ref: -find-last-index\7f45827
-Ref: -find-indices\7f46331
-Ref: -grade-up\7f46739
-Ref: -grade-down\7f47142
-Node: Set operations\7f47552
-Ref: -union\7f47735
-Ref: -difference\7f48177
-Ref: -intersection\7f48594
-Ref: -powerset\7f49031
-Ref: -permutations\7f49244
-Ref: -distinct\7f49544
-Node: Other list operations\7f49922
-Ref: -rotate\7f50147
-Ref: -repeat\7f50517
-Ref: -cons*\7f50780
-Ref: -snoc\7f51167
-Ref: -interpose\7f51580
-Ref: -interleave\7f51878
-Ref: -zip-with\7f52247
-Ref: -zip\7f52964
-Ref: -zip-lists\7f53796
-Ref: -zip-fill\7f54497
-Ref: -unzip\7f54820
-Ref: -cycle\7f55565
-Ref: -pad\7f55938
-Ref: -table\7f56261
-Ref: -table-flat\7f57050
-Ref: -first\7f58058
-Ref: -some\7f58430
-Ref: -last\7f58739
-Ref: -first-item\7f59073
-Ref: -second-item\7f59489
-Ref: -third-item\7f59769
-Ref: -fourth-item\7f60047
-Ref: -fifth-item\7f60313
-Ref: -last-item\7f60575
-Ref: -butlast\7f60867
-Ref: -sort\7f61114
-Ref: -list\7f61603
-Ref: -fix\7f61934
-Node: Tree operations\7f62474
-Ref: -tree-seq\7f62670
-Ref: -tree-map\7f63528
-Ref: -tree-map-nodes\7f63971
-Ref: -tree-reduce\7f64821
-Ref: -tree-reduce-from\7f65703
-Ref: -tree-mapreduce\7f66304
-Ref: -tree-mapreduce-from\7f67164
-Ref: -clone\7f68450
-Node: Threading macros\7f68778
-Ref: ->\7f68923
-Ref: ->>\7f69414
-Ref: -->\7f69919
-Ref: -as->\7f70475
-Ref: -some->\7f70930
-Ref: -some->>\7f71304
-Ref: -some-->\7f71740
-Node: Binding\7f72211
-Ref: -when-let\7f72423
-Ref: -when-let*\7f72908
-Ref: -if-let\7f73431
-Ref: -if-let*\7f73826
-Ref: -let\7f74443
-Ref: -let*\7f80533
-Ref: -lambda\7f81473
-Ref: -setq\7f82270
-Node: Side-effects\7f83086
-Ref: -each\7f83280
-Ref: -each-while\7f83687
-Ref: -each-indexed\7f84047
-Ref: -each-r\7f84565
-Ref: -each-r-while\7f84998
-Ref: -dotimes\7f85373
-Ref: -doto\7f85676
-Ref: --doto\7f86104
-Node: Destructive operations\7f86379
-Ref: !cons\7f86552
-Ref: !cdr\7f86758
-Node: Function combinators\7f86953
-Ref: -partial\7f87227
-Ref: -rpartial\7f87623
-Ref: -juxt\7f88026
-Ref: -compose\7f88458
-Ref: -applify\7f89011
-Ref: -on\7f89442
-Ref: -flip\7f89968
-Ref: -const\7f90280
-Ref: -cut\7f90619
-Ref: -not\7f91105
-Ref: -orfn\7f91415
-Ref: -andfn\7f91849
-Ref: -iteratefn\7f92344
-Ref: -fixfn\7f93047
-Ref: -prodfn\7f94609
-Node: Development\7f95677
-Node: Contribute\7f96026
-Node: Changes\7f96774
-Node: Contributors\7f99772
-Node: Index\7f101391
-\1f
-End Tag Table
-
-\1f
-Local Variables:
-coding: utf-8
-End:
diff --git a/elpa/dash-20200119.2310/dir b/elpa/dash-20200119.2310/dir
deleted file mode 100644 (file)
index 49b1700..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-This is the file .../info/dir, which contains the
-topmost node of the Info hierarchy, called (dir)Top.
-The first time you invoke Info you start off looking at this node.
-\1f
-File: dir,     Node: Top       This is the top of the INFO tree
-
-  This (the Directory node) gives a menu of major topics.
-  Typing "q" exits, "H" lists all Info commands, "d" returns here,
-  "h" gives a primer for first-timers,
-  "mEmacs<Return>" visits the Emacs manual, etc.
-
-  In Emacs, you can click mouse button 2 on a menu item or cross reference
-  to select it.
-
-* Menu:
-
-Emacs
-* Dash: (dash.info).            A modern list library for GNU Emacs
diff --git a/elpa/dash-20210101.1712/dash-autoloads.el b/elpa/dash-20210101.1712/dash-autoloads.el
new file mode 100644 (file)
index 0000000..0b16ab1
--- /dev/null
@@ -0,0 +1,70 @@
+;;; dash-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "dash" "dash.el" (0 0 0 0))
+;;; Generated autoloads from dash.el
+
+(autoload 'dash-fontify-mode "dash" "\
+Toggle fontification of Dash special variables.
+
+If called interactively, enable Dash-Fontify mode if ARG is
+positive, and disable it if ARG is zero or negative.  If called
+from Lisp, also enable the mode if ARG is omitted or nil, and
+toggle it if ARG is `toggle'; disable the mode otherwise.
+
+Dash-Fontify mode is a buffer-local minor mode intended for Emacs
+Lisp buffers.  Enabling it causes the special variables bound in
+anaphoric Dash macros to be fontified.  These anaphoras include
+`it', `it-index', `acc', and `other'.  In older Emacs versions
+which do not dynamically detect macros, Dash-Fontify mode
+additionally fontifies Dash macro calls.
+
+See also `dash-fontify-mode-lighter' and
+`global-dash-fontify-mode'.
+
+\(fn &optional ARG)" t nil)
+
+(put 'global-dash-fontify-mode 'globalized-minor-mode t)
+
+(defvar global-dash-fontify-mode nil "\
+Non-nil if Global Dash-Fontify mode is enabled.
+See the `global-dash-fontify-mode' command
+for a description of this minor mode.
+Setting this variable directly does not take effect;
+either customize it (see the info node `Easy Customization')
+or call the function `global-dash-fontify-mode'.")
+
+(custom-autoload 'global-dash-fontify-mode "dash" nil)
+
+(autoload 'global-dash-fontify-mode "dash" "\
+Toggle Dash-Fontify mode in all buffers.
+With prefix ARG, enable Global Dash-Fontify mode if ARG is positive;
+otherwise, disable it.  If called from Lisp, enable the mode if
+ARG is omitted or nil.
+
+Dash-Fontify mode is enabled in all buffers where
+`dash--turn-on-fontify-mode' would do it.
+See `dash-fontify-mode' for more information on Dash-Fontify mode.
+
+\(fn &optional ARG)" t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "dash" '("!cdr" "!cons" "--" "->" "-a" "-butlast" "-c" "-d" "-e" "-f" "-gr" "-i" "-keep" "-l" "-m" "-non" "-only-some" "-p" "-r" "-s" "-t" "-u" "-value-to-list" "-when-let" "-zip" "dash-")))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("dash-pkg.el") (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; dash-autoloads.el ends here
diff --git a/elpa/dash-20210101.1712/dash-pkg.el b/elpa/dash-20210101.1712/dash-pkg.el
new file mode 100644 (file)
index 0000000..cc822c6
--- /dev/null
@@ -0,0 +1,9 @@
+(define-package "dash" "20210101.1712" "A modern list library for Emacs" 'nil :commit "e8ed3d640797a8b816d1d5e2710a960765ab034b" :authors
+  (("Magnar Sveen" . "magnarsNOSPAMgmail.com"))
+  :maintainer
+  ("Magnar Sveen" . "magnarsNOSPAMgmail.com")
+  :keywords
+  ("extensions" "lisp"))
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/dash-20210101.1712/dash.el b/elpa/dash-20210101.1712/dash.el
new file mode 100644 (file)
index 0000000..3c07f3b
--- /dev/null
@@ -0,0 +1,2928 @@
+;;; dash.el --- A modern list library for Emacs  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
+
+;; Author: Magnar Sveen <magnarsNOSPAMgmail.com>
+;; Version: 2.17.0
+;; Keywords: extensions, lisp
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; A modern list api for Emacs.
+;;
+;; See documentation on https://github.com/magnars/dash.el#functions
+;;
+;; **Please note** The lexical binding in this file is not utilised at the
+;; moment. We will take full advantage of lexical binding in an upcoming 3.0
+;; release of Dash. In the meantime, we've added the pragma to avoid a bug that
+;; you can read more about in https://github.com/magnars/dash.el/issues/130.
+;;
+
+;;; Code:
+
+;; TODO: `gv' was introduced in Emacs 24.3, so remove this and all
+;; calls to `defsetf' when support for earlier versions is dropped.
+(eval-when-compile
+  (unless (fboundp 'gv-define-setter)
+    (require 'cl)))
+
+(defgroup dash ()
+  "Customize group for Dash, a modern list library."
+  :group 'extensions
+  :group 'lisp
+  :prefix "dash-")
+
+(defmacro !cons (car cdr)
+  "Destructive: Set CDR to the cons of CAR and CDR."
+  `(setq ,cdr (cons ,car ,cdr)))
+
+(defmacro !cdr (list)
+  "Destructive: Set LIST to the cdr of LIST."
+  `(setq ,list (cdr ,list)))
+
+(defmacro --each (list &rest body)
+  "Anaphoric form of `-each'."
+  (declare (debug (form body))
+           (indent 1))
+  (let ((l (make-symbol "list")))
+    `(let ((,l ,list)
+           (it-index 0))
+       (while ,l
+         (let ((it (car ,l)))
+           ,@body)
+         (setq it-index (1+ it-index))
+         (!cdr ,l)))))
+
+(defmacro -doto (eval-initial-value &rest forms)
+  "Eval a form, then insert that form as the 2nd argument to other forms.
+The EVAL-INITIAL-VALUE form is evaluated once. Its result is
+passed to FORMS, which are then evaluated sequentially. Returns
+the target form."
+  (declare (indent 1))
+  (let ((retval (make-symbol "value")))
+    `(let ((,retval ,eval-initial-value))
+       ,@(mapcar (lambda (form)
+                   (if (sequencep form)
+                       `(,(-first-item form) ,retval ,@(cdr form))
+                     `(funcall form ,retval)))
+                 forms)
+       ,retval)))
+
+(defmacro --doto (eval-initial-value &rest forms)
+  "Anaphoric form of `-doto'.
+Note: `it' is not required in each form."
+  (declare (indent 1))
+  `(let ((it ,eval-initial-value))
+     ,@forms
+     it))
+
+(defun -each (list fn)
+  "Call FN with every item in LIST. Return nil, used for side-effects only."
+  (declare (indent 1))
+  (--each list (funcall fn it)))
+
+(defalias '--each-indexed '--each)
+
+(defun -each-indexed (list fn)
+  "Call (FN index item) for each item in LIST.
+
+In the anaphoric form `--each-indexed', the index is exposed as symbol `it-index'.
+
+See also: `-map-indexed'."
+  (declare (indent 1))
+  (--each list (funcall fn it-index it)))
+
+(defmacro --each-while (list pred &rest body)
+  "Anaphoric form of `-each-while'."
+  (declare (debug (form form body))
+           (indent 2))
+  (let ((l (make-symbol "list")))
+    `(let ((,l ,list)
+           (it-index 0)
+           it)
+       (ignore it)
+       (while (when ,l
+                (setq it (pop ,l))
+                ,pred)
+         ,@body
+         (setq it-index (1+ it-index))))))
+
+(defun -each-while (list pred fn)
+  "Call FN with every item in LIST while (PRED item) is non-nil.
+Return nil, used for side-effects only."
+  (declare (indent 2))
+  (--each-while list (funcall pred it) (funcall fn it)))
+
+(defmacro --each-r (list &rest body)
+  "Anaphoric form of `-each-r'."
+  (declare (debug (form body))
+           (indent 1))
+  (let ((v (make-symbol "vector")))
+    ;; Implementation note: building vector is considerably faster
+    ;; than building a reversed list (vector takes less memory, so
+    ;; there is less GC), plus length comes naturally.  In-place
+    ;; 'nreverse' would be faster still, but BODY would be able to see
+    ;; that, even if modification was reversed before we return.
+    `(let* ((,v (vconcat ,list))
+            (it-index (length ,v))
+            it)
+       (while (> it-index 0)
+         (setq it-index (1- it-index))
+         (setq it (aref ,v it-index))
+         ,@body))))
+
+(defun -each-r (list fn)
+  "Call FN with every item in LIST in reversed order.
+ Return nil, used for side-effects only."
+  (--each-r list (funcall fn it)))
+
+(defmacro --each-r-while (list pred &rest body)
+  "Anaphoric form of `-each-r-while'."
+  (declare (debug (form form body))
+           (indent 2))
+  (let ((v (make-symbol "vector")))
+    `(let* ((,v (vconcat ,list))
+            (it-index (length ,v))
+            it)
+       (while (> it-index 0)
+         (setq it-index (1- it-index))
+         (setq it (aref ,v it-index))
+         (if (not ,pred)
+             (setq it-index -1)
+           ,@body)))))
+
+(defun -each-r-while (list pred fn)
+  "Call FN with every item in reversed LIST while (PRED item) is non-nil.
+Return nil, used for side-effects only."
+  (--each-r-while list (funcall pred it) (funcall fn it)))
+
+(defmacro --dotimes (num &rest body)
+  "Repeatedly executes BODY (presumably for side-effects) with symbol `it' bound to integers from 0 through NUM-1."
+  (declare (debug (form body))
+           (indent 1))
+  (let ((n (make-symbol "num")))
+    `(let ((,n ,num)
+           (it 0))
+       (while (< it ,n)
+         ,@body
+         (setq it (1+ it))))))
+
+(defun -dotimes (num fn)
+  "Repeatedly calls FN (presumably for side-effects) passing in integers from 0 through NUM-1."
+  (declare (indent 1))
+  (--dotimes num (funcall fn it)))
+
+(defun -map (fn list)
+  "Return a new list consisting of the result of applying FN to the items in LIST."
+  (mapcar fn list))
+
+(defmacro --map (form list)
+  "Anaphoric form of `-map'."
+  (declare (debug (form form)))
+  `(mapcar (lambda (it) ,form) ,list))
+
+(defmacro --reduce-from (form initial-value list)
+  "Anaphoric form of `-reduce-from'."
+  (declare (debug (form form form)))
+  `(let ((acc ,initial-value))
+     (--each ,list (setq acc ,form))
+     acc))
+
+(defun -reduce-from (fn initial-value list)
+  "Return the result of applying FN to INITIAL-VALUE and the
+first item in LIST, then applying FN to that result and the 2nd
+item, etc. If LIST contains no items, return INITIAL-VALUE and
+do not call FN.
+
+In the anaphoric form `--reduce-from', the accumulated value is
+exposed as symbol `acc'.
+
+See also: `-reduce', `-reduce-r'"
+  (--reduce-from (funcall fn acc it) initial-value list))
+
+(defmacro --reduce (form list)
+  "Anaphoric form of `-reduce'."
+  (declare (debug (form form)))
+  (let ((lv (make-symbol "list-value")))
+    `(let ((,lv ,list))
+       (if ,lv
+           (--reduce-from ,form (car ,lv) (cdr ,lv))
+         (let (acc it) ,form)))))
+
+(defun -reduce (fn list)
+  "Return the result of applying FN to the first 2 items in LIST,
+then applying FN to that result and the 3rd item, etc. If LIST
+contains no items, return the result of calling FN with no
+arguments. If LIST contains a single item, return that item
+and do not call FN.
+
+In the anaphoric form `--reduce', the accumulated value is
+exposed as symbol `acc'.
+
+See also: `-reduce-from', `-reduce-r'"
+  (if list
+      (-reduce-from fn (car list) (cdr list))
+    (funcall fn)))
+
+(defmacro --reduce-r-from (form initial-value list)
+  "Anaphoric version of `-reduce-r-from'."
+  (declare (debug (form form form)))
+  `(--reduce-from ,form ,initial-value (reverse ,list)))
+
+(defun -reduce-r-from (fn initial-value list)
+  "Replace conses with FN, nil with INITIAL-VALUE and evaluate
+the resulting expression. If LIST is empty, INITIAL-VALUE is
+returned and FN is not called.
+
+Note: this function works the same as `-reduce-from' but the
+operation associates from right instead of from left.
+
+See also: `-reduce-r', `-reduce'"
+  (--reduce-r-from (funcall fn it acc) initial-value list))
+
+(defmacro --reduce-r (form list)
+  "Anaphoric version of `-reduce-r'."
+  (declare (debug (form form)))
+  `(--reduce ,form (reverse ,list)))
+
+(defun -reduce-r (fn list)
+  "Replace conses with FN and evaluate the resulting expression.
+The final nil is ignored. If LIST contains no items, return the
+result of calling FN with no arguments. If LIST contains a single
+item, return that item and do not call FN.
+
+The first argument of FN is the new item, the second is the
+accumulated value.
+
+Note: this function works the same as `-reduce' but the operation
+associates from right instead of from left.
+
+See also: `-reduce-r-from', `-reduce'"
+  (if list
+      (--reduce-r (funcall fn it acc) list)
+    (funcall fn)))
+
+(defun -reductions-from (fn init list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce-from' for explanation of the arguments.
+
+See also: `-reductions', `-reductions-r', `-reduce-r'"
+  (nreverse (--reduce-from (cons (funcall fn (car acc) it) acc) (list init) list)))
+
+(defun -reductions (fn list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce' for explanation of the arguments.
+
+See also: `-reductions-from', `-reductions-r', `-reduce-r'"
+  (and list (-reductions-from fn (car list) (cdr list))))
+
+(defun -reductions-r-from (fn init list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce-r-from' for explanation of the arguments.
+
+See also: `-reductions-r', `-reductions', `-reduce'"
+  (--reduce-r-from (cons (funcall fn it (car acc)) acc) (list init) list))
+
+(defun -reductions-r (fn list)
+  "Return a list of the intermediate values of the reduction.
+
+See `-reduce-r' for explanation of the arguments.
+
+See also: `-reductions-r-from', `-reductions', `-reduce'"
+  (when list
+    (let ((rev (reverse list)))
+      (--reduce-from (cons (funcall fn it (car acc)) acc)
+                     (list (car rev))
+                     (cdr rev)))))
+
+(defmacro --filter (form list)
+  "Anaphoric form of `-filter'.
+
+See also: `--remove'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each ,list (when ,form (!cons it ,r)))
+       (nreverse ,r))))
+
+(defun -filter (pred list)
+  "Return a new list of the items in LIST for which PRED returns a non-nil value.
+
+Alias: `-select'
+
+See also: `-keep', `-remove'."
+  (--filter (funcall pred it) list))
+
+(defalias '-select '-filter)
+(defalias '--select '--filter)
+
+(defmacro --remove (form list)
+  "Anaphoric form of `-remove'.
+
+See also `--filter'."
+  (declare (debug (form form)))
+  `(--filter (not ,form) ,list))
+
+(defun -remove (pred list)
+  "Return a new list of the items in LIST for which PRED returns nil.
+
+Alias: `-reject'
+
+See also: `-filter'."
+  (--remove (funcall pred it) list))
+
+(defalias '-reject '-remove)
+(defalias '--reject '--remove)
+
+(defun -remove-first (pred list)
+  "Return a new list with the first item matching PRED removed.
+
+Alias: `-reject-first'
+
+See also: `-remove', `-map-first'"
+  (let (front)
+    (while (and list (not (funcall pred (car list))))
+      (push (car list) front)
+      (!cdr list))
+    (if list
+        (-concat (nreverse front) (cdr list))
+      (nreverse front))))
+
+(defmacro --remove-first (form list)
+  "Anaphoric form of `-remove-first'."
+  (declare (debug (form form)))
+  `(-remove-first (lambda (it) ,form) ,list))
+
+(defalias '-reject-first '-remove-first)
+(defalias '--reject-first '--remove-first)
+
+(defun -remove-last (pred list)
+  "Return a new list with the last item matching PRED removed.
+
+Alias: `-reject-last'
+
+See also: `-remove', `-map-last'"
+  (nreverse (-remove-first pred (reverse list))))
+
+(defmacro --remove-last (form list)
+  "Anaphoric form of `-remove-last'."
+  (declare (debug (form form)))
+  `(-remove-last (lambda (it) ,form) ,list))
+
+(defalias '-reject-last '-remove-last)
+(defalias '--reject-last '--remove-last)
+
+(defun -remove-item (item list)
+  "Remove all occurrences of ITEM from LIST.
+
+Comparison is done with `equal'."
+  (declare (pure t) (side-effect-free t))
+  (--remove (equal it item) list))
+
+(defmacro --keep (form list)
+  "Anaphoric form of `-keep'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result"))
+        (m (make-symbol "mapped")))
+    `(let (,r)
+       (--each ,list (let ((,m ,form)) (when ,m (!cons ,m ,r))))
+       (nreverse ,r))))
+
+(defun -keep (fn list)
+  "Return a new list of the non-nil results of applying FN to the items in LIST.
+
+If you want to select the original items satisfying a predicate use `-filter'."
+  (--keep (funcall fn it) list))
+
+(defun -non-nil (list)
+  "Return all non-nil elements of LIST."
+  (declare (pure t) (side-effect-free t))
+  (-remove 'null list))
+
+(defmacro --map-indexed (form list)
+  "Anaphoric form of `-map-indexed'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each ,list
+         (!cons ,form ,r))
+       (nreverse ,r))))
+
+(defun -map-indexed (fn list)
+  "Return a new list consisting of the result of (FN index item) for each item in LIST.
+
+In the anaphoric form `--map-indexed', the index is exposed as symbol `it-index'.
+
+See also: `-each-indexed'."
+  (--map-indexed (funcall fn it-index it) list))
+
+(defmacro --map-when (pred rep list)
+  "Anaphoric form of `-map-when'."
+  (declare (debug (form form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each ,list (!cons (if ,pred ,rep it) ,r))
+       (nreverse ,r))))
+
+(defun -map-when (pred rep list)
+  "Return a new list where the elements in LIST that do not match the PRED function
+are unchanged, and where the elements in LIST that do match the PRED function are mapped
+through the REP function.
+
+Alias: `-replace-where'
+
+See also: `-update-at'"
+  (--map-when (funcall pred it) (funcall rep it) list))
+
+(defalias '-replace-where '-map-when)
+(defalias '--replace-where '--map-when)
+
+(defun -map-first (pred rep list)
+  "Replace first item in LIST satisfying PRED with result of REP called on this item.
+
+See also: `-map-when', `-replace-first'"
+  (let (front)
+    (while (and list (not (funcall pred (car list))))
+      (push (car list) front)
+      (!cdr list))
+    (if list
+        (-concat (nreverse front) (cons (funcall rep (car list)) (cdr list)))
+      (nreverse front))))
+
+(defmacro --map-first (pred rep list)
+  "Anaphoric form of `-map-first'."
+  `(-map-first (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
+
+(defun -map-last (pred rep list)
+  "Replace last item in LIST satisfying PRED with result of REP called on this item.
+
+See also: `-map-when', `-replace-last'"
+  (nreverse (-map-first pred rep (reverse list))))
+
+(defmacro --map-last (pred rep list)
+  "Anaphoric form of `-map-last'."
+  `(-map-last (lambda (it) ,pred) (lambda (it) (ignore it) ,rep) ,list))
+
+(defun -replace (old new list)
+  "Replace all OLD items in LIST with NEW.
+
+Elements are compared using `equal'.
+
+See also: `-replace-at'"
+  (declare (pure t) (side-effect-free t))
+  (--map-when (equal it old) new list))
+
+(defun -replace-first (old new list)
+  "Replace the first occurrence of OLD with NEW in LIST.
+
+Elements are compared using `equal'.
+
+See also: `-map-first'"
+  (declare (pure t) (side-effect-free t))
+  (--map-first (equal old it) new list))
+
+(defun -replace-last (old new list)
+  "Replace the last occurrence of OLD with NEW in LIST.
+
+Elements are compared using `equal'.
+
+See also: `-map-last'"
+  (declare (pure t) (side-effect-free t))
+  (--map-last (equal old it) new list))
+
+(defmacro --mapcat (form list)
+  "Anaphoric form of `-mapcat'."
+  (declare (debug (form form)))
+  `(apply 'append (--map ,form ,list)))
+
+(defun -mapcat (fn list)
+  "Return the concatenation of the result of mapping FN over LIST.
+Thus function FN should return a list."
+  (--mapcat (funcall fn it) list))
+
+(defun -flatten (l)
+  "Take a nested list L and return its contents as a single, flat list.
+
+Note that because `nil' represents a list of zero elements (an
+empty list), any mention of nil in L will disappear after
+flattening.  If you need to preserve nils, consider `-flatten-n'
+or map them to some unique symbol and then map them back.
+
+Conses of two atoms are considered \"terminals\", that is, they
+aren't flattened further.
+
+See also: `-flatten-n'"
+  (declare (pure t) (side-effect-free t))
+  (if (and (listp l) (listp (cdr l)))
+      (-mapcat '-flatten l)
+    (list l)))
+
+(defmacro --iterate (form init n)
+  "Anaphoric version of `-iterate'."
+  (declare (debug (form form form)))
+  `(-iterate (lambda (it) ,form) ,init ,n))
+
+(defun -flatten-n (num list)
+  "Flatten NUM levels of a nested LIST.
+
+See also: `-flatten'"
+  (declare (pure t) (side-effect-free t))
+  (-last-item (--iterate (--mapcat (-list it) it) list (1+ num))))
+
+(defun -concat (&rest lists)
+  "Return a new list with the concatenation of the elements in the supplied LISTS."
+  (declare (pure t) (side-effect-free t))
+  (apply 'append lists))
+
+(defalias '-copy 'copy-sequence
+  "Create a shallow copy of LIST.
+
+\(fn LIST)")
+
+(defun -splice (pred fun list)
+  "Splice lists generated by FUN in place of elements matching PRED in LIST.
+
+FUN takes the element matching PRED as input.
+
+This function can be used as replacement for `,@' in case you
+need to splice several lists at marked positions (for example
+with keywords).
+
+See also: `-splice-list', `-insert-at'"
+  (let (r)
+    (--each list
+      (if (funcall pred it)
+          (let ((new (funcall fun it)))
+            (--each new (!cons it r)))
+        (!cons it r)))
+    (nreverse r)))
+
+(defmacro --splice (pred form list)
+  "Anaphoric form of `-splice'."
+  `(-splice (lambda (it) ,pred) (lambda (it) ,form) ,list))
+
+(defun -splice-list (pred new-list list)
+  "Splice NEW-LIST in place of elements matching PRED in LIST.
+
+See also: `-splice', `-insert-at'"
+  (-splice pred (lambda (_) new-list) list))
+
+(defmacro --splice-list (pred new-list list)
+  "Anaphoric form of `-splice-list'."
+  `(-splice-list (lambda (it) ,pred) ,new-list ,list))
+
+(defun -cons* (&rest args)
+  "Make a new list from the elements of ARGS.
+
+The last 2 members of ARGS are used as the final cons of the
+result so if the final member of ARGS is not a list the result is
+a dotted list."
+  (declare (pure t) (side-effect-free t))
+  (-reduce-r 'cons args))
+
+(defun -snoc (list elem &rest elements)
+  "Append ELEM to the end of the list.
+
+This is like `cons', but operates on the end of list.
+
+If ELEMENTS is non nil, append these to the list as well."
+  (-concat list (list elem) elements))
+
+(defmacro --first (form list)
+  "Anaphoric form of `-first'."
+  (declare (debug (form form)))
+  (let ((n (make-symbol "needle")))
+    `(let (,n)
+       (--each-while ,list (not ,n)
+         (when ,form (setq ,n it)))
+       ,n)))
+
+(defun -first (pred list)
+  "Return the first x in LIST where (PRED x) is non-nil, else nil.
+
+To get the first item in the list no questions asked, use `car'.
+
+Alias: `-find'"
+  (--first (funcall pred it) list))
+
+(defalias '-find '-first)
+(defalias '--find '--first)
+
+(defmacro --some (form list)
+  "Anaphoric form of `-some'."
+  (declare (debug (form form)))
+  (let ((n (make-symbol "needle")))
+    `(let (,n)
+       (--each-while ,list (not ,n)
+         (setq ,n ,form))
+       ,n)))
+
+(defun -some (pred list)
+  "Return (PRED x) for the first LIST item where (PRED x) is non-nil, else nil.
+
+Alias: `-any'"
+  (--some (funcall pred it) list))
+
+(defalias '-any '-some)
+(defalias '--any '--some)
+
+(defmacro --last (form list)
+  "Anaphoric form of `-last'."
+  (declare (debug (form form)))
+  (let ((n (make-symbol "needle")))
+    `(let (,n)
+       (--each ,list
+         (when ,form (setq ,n it)))
+       ,n)))
+
+(defun -last (pred list)
+  "Return the last x in LIST where (PRED x) is non-nil, else nil."
+  (--last (funcall pred it) list))
+
+(defalias '-first-item 'car
+  "Return the first item of LIST, or nil on an empty list.
+
+See also: `-second-item', `-last-item'.
+
+\(fn LIST)")
+
+;; Ensure that calls to `-first-item' are compiled to a single opcode,
+;; just like `car'.
+(put '-first-item 'byte-opcode 'byte-car)
+(put '-first-item 'byte-compile 'byte-compile-one-arg)
+
+(defalias '-second-item 'cadr
+  "Return the second item of LIST, or nil if LIST is too short.
+
+See also: `-third-item'.
+
+\(fn LIST)")
+
+(defalias '-third-item
+  (if (fboundp 'caddr)
+      #'caddr
+    (lambda (list) (car (cddr list))))
+  "Return the third item of LIST, or nil if LIST is too short.
+
+See also: `-fourth-item'.
+
+\(fn LIST)")
+
+(defun -fourth-item (list)
+  "Return the fourth item of LIST, or nil if LIST is too short.
+
+See also: `-fifth-item'."
+  (declare (pure t) (side-effect-free t))
+  (car (cdr (cdr (cdr list)))))
+
+(defun -fifth-item (list)
+  "Return the fifth item of LIST, or nil if LIST is too short.
+
+See also: `-last-item'."
+  (declare (pure t) (side-effect-free t))
+  (car (cdr (cdr (cdr (cdr list))))))
+
+(defun -last-item (list)
+  "Return the last item of LIST, or nil on an empty list."
+  (declare (pure t) (side-effect-free t))
+  (car (last list)))
+
+;; Use `with-no-warnings' to suppress unbound `-last-item' or
+;; undefined `gv--defsetter' warnings arising from both
+;; `gv-define-setter' and `defsetf' in certain Emacs versions.
+(with-no-warnings
+  (if (fboundp 'gv-define-setter)
+      (gv-define-setter -last-item (val x) `(setcar (last ,x) ,val))
+    (defsetf -last-item (x) (val) `(setcar (last ,x) ,val))))
+
+(defun -butlast (list)
+  "Return a list of all items in list except for the last."
+  ;; no alias as we don't want magic optional argument
+  (declare (pure t) (side-effect-free t))
+  (butlast list))
+
+(defmacro --count (pred list)
+  "Anaphoric form of `-count'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let ((,r 0))
+       (--each ,list (when ,pred (setq ,r (1+ ,r))))
+       ,r)))
+
+(defun -count (pred list)
+  "Counts the number of items in LIST where (PRED item) is non-nil."
+  (--count (funcall pred it) list))
+
+(defun ---truthy? (val)
+  (declare (pure t) (side-effect-free t))
+  (not (null val)))
+
+(defmacro --any? (form list)
+  "Anaphoric form of `-any?'."
+  (declare (debug (form form)))
+  `(---truthy? (--some ,form ,list)))
+
+(defun -any? (pred list)
+  "Return t if (PRED x) is non-nil for any x in LIST, else nil.
+
+Alias: `-any-p', `-some?', `-some-p'"
+  (--any? (funcall pred it) list))
+
+(defalias '-some? '-any?)
+(defalias '--some? '--any?)
+(defalias '-any-p '-any?)
+(defalias '--any-p '--any?)
+(defalias '-some-p '-any?)
+(defalias '--some-p '--any?)
+
+(defmacro --all? (form list)
+  "Anaphoric form of `-all?'."
+  (declare (debug (form form)))
+  (let ((a (make-symbol "all")))
+    `(let ((,a t))
+       (--each-while ,list ,a (setq ,a ,form))
+       (---truthy? ,a))))
+
+(defun -all? (pred list)
+  "Return t if (PRED x) is non-nil for all x in LIST, else nil.
+
+Alias: `-all-p', `-every?', `-every-p'"
+  (--all? (funcall pred it) list))
+
+(defalias '-every? '-all?)
+(defalias '--every? '--all?)
+(defalias '-all-p '-all?)
+(defalias '--all-p '--all?)
+(defalias '-every-p '-all?)
+(defalias '--every-p '--all?)
+
+(defmacro --none? (form list)
+  "Anaphoric form of `-none?'."
+  (declare (debug (form form)))
+  `(--all? (not ,form) ,list))
+
+(defun -none? (pred list)
+  "Return t if (PRED x) is nil for all x in LIST, else nil.
+
+Alias: `-none-p'"
+  (--none? (funcall pred it) list))
+
+(defalias '-none-p '-none?)
+(defalias '--none-p '--none?)
+
+(defmacro --only-some? (form list)
+  "Anaphoric form of `-only-some?'."
+  (declare (debug (form form)))
+  (let ((y (make-symbol "yes"))
+        (n (make-symbol "no")))
+    `(let (,y ,n)
+       (--each-while ,list (not (and ,y ,n))
+         (if ,form (setq ,y t) (setq ,n t)))
+       (---truthy? (and ,y ,n)))))
+
+(defun -only-some? (pred list)
+  "Return `t` if at least one item of LIST matches PRED and at least one item of LIST does not match PRED.
+Return `nil` both if all items match the predicate or if none of the items match the predicate.
+
+Alias: `-only-some-p'"
+  (--only-some? (funcall pred it) list))
+
+(defalias '-only-some-p '-only-some?)
+(defalias '--only-some-p '--only-some?)
+
+(defun -slice (list from &optional to step)
+  "Return copy of LIST, starting from index FROM to index TO.
+
+FROM or TO may be negative.  These values are then interpreted
+modulo the length of the list.
+
+If STEP is a number, only each STEPth item in the resulting
+section is returned.  Defaults to 1."
+  (declare (pure t) (side-effect-free t))
+  (let ((length (length list))
+        (new-list nil))
+    ;; to defaults to the end of the list
+    (setq to (or to length))
+    (setq step (or step 1))
+    ;; handle negative indices
+    (when (< from 0)
+      (setq from (mod from length)))
+    (when (< to 0)
+      (setq to (mod to length)))
+
+    ;; iterate through the list, keeping the elements we want
+    (--each-while list (< it-index to)
+      (when (and (>= it-index from)
+                 (= (mod (- from it-index) step) 0))
+        (push it new-list)))
+    (nreverse new-list)))
+
+(defmacro --take-while (form list)
+  "Anaphoric form of `-take-while'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result")))
+    `(let (,r)
+       (--each-while ,list ,form (push it ,r))
+       (nreverse ,r))))
+
+(defun -take-while (pred list)
+  "Take successive items from LIST for which PRED returns non-nil.
+PRED is a function of one argument.  Return a new list of the
+successive elements from the start of LIST for which PRED returns
+non-nil.
+
+See also: `-drop-while'"
+  (--take-while (funcall pred it) list))
+
+(defmacro --drop-while (form list)
+  "Anaphoric form of `-drop-while'."
+  (declare (debug (form form)))
+  (let ((l (make-symbol "list")))
+    `(let ((,l ,list))
+       (--each-while ,l ,form (pop ,l))
+       (copy-sequence ,l))))
+
+(defun -drop-while (pred list)
+  "Drop successive items from LIST for which PRED returns non-nil.
+PRED is a function of one argument.  Return a copy of the tail of
+LIST starting from its first element for which PRED returns nil.
+
+See also: `-take-while'"
+  (--drop-while (funcall pred it) list))
+
+(defun -take (n list)
+  "Return a copy of the first N items in LIST.
+Return a copy of LIST if it contains N items or fewer.
+Return nil if N is zero or less.
+
+See also: `-take-last'"
+  (declare (pure t) (side-effect-free t))
+  (--take-while (< it-index n) list))
+
+(defun -take-last (n list)
+  "Return a copy of the last N items of LIST in order.
+Return a copy of LIST if it contains N items or fewer.
+Return nil if N is zero or less.
+
+See also: `-take'"
+  (declare (pure t) (side-effect-free t))
+  (copy-sequence (last list n)))
+
+(defun -drop (n list)
+  "Return a copy of the tail of LIST without the first N items.
+Return a copy of LIST if N is zero or less.
+Return nil if LIST contains N items or fewer.
+
+See also: `-drop-last'"
+  (copy-sequence (nthcdr n list)))
+
+(defun -drop-last (n list)
+  "Return a copy of LIST without its last N items.
+Return a copy of LIST if N is zero or less.
+Return nil if LIST contains N items or fewer.
+
+See also: `-drop'"
+  (declare (pure t) (side-effect-free t))
+  (nbutlast (copy-sequence list) n))
+
+(defun -split-at (n list)
+  "Return a list of ((-take N LIST) (-drop N LIST)), in no more than one pass through the list."
+  (declare (pure t) (side-effect-free t))
+  (let (result)
+    (--dotimes n
+      (when list
+        (!cons (car list) result)
+        (!cdr list)))
+    (list (nreverse result) list)))
+
+(defun -rotate (n list)
+  "Rotate LIST N places to the right.  With N negative, rotate to the left.
+The time complexity is O(n)."
+  (declare (pure t) (side-effect-free t))
+  (when list
+    (let* ((len (length list))
+           (n-mod-len (mod n len))
+           (new-tail-len (- len n-mod-len)))
+      (append (-drop new-tail-len list) (-take new-tail-len list)))))
+
+(defun -insert-at (n x list)
+  "Return a list with X inserted into LIST at position N.
+
+See also: `-splice', `-splice-list'"
+  (declare (pure t) (side-effect-free t))
+  (let ((split-list (-split-at n list)))
+    (nconc (car split-list) (cons x (cadr split-list)))))
+
+(defun -replace-at (n x list)
+  "Return a list with element at Nth position in LIST replaced with X.
+
+See also: `-replace'"
+  (declare (pure t) (side-effect-free t))
+  (let ((split-list (-split-at n list)))
+    (nconc (car split-list) (cons x (cdr (cadr split-list))))))
+
+(defun -update-at (n func list)
+  "Return a list with element at Nth position in LIST replaced with `(func (nth n list))`.
+
+See also: `-map-when'"
+  (let ((split-list (-split-at n list)))
+    (nconc (car split-list) (cons (funcall func (car (cadr split-list))) (cdr (cadr split-list))))))
+
+(defmacro --update-at (n form list)
+  "Anaphoric version of `-update-at'."
+  (declare (debug (form form form)))
+  `(-update-at ,n (lambda (it) ,form) ,list))
+
+(defun -remove-at (n list)
+  "Return a list with element at Nth position in LIST removed.
+
+See also: `-remove-at-indices', `-remove'"
+  (declare (pure t) (side-effect-free t))
+  (-remove-at-indices (list n) list))
+
+(defun -remove-at-indices (indices list)
+  "Return a list whose elements are elements from LIST without
+elements selected as `(nth i list)` for all i
+from INDICES.
+
+See also: `-remove-at', `-remove'"
+  (declare (pure t) (side-effect-free t))
+  (let* ((indices (-sort '< indices))
+         (diffs (cons (car indices) (-map '1- (-zip-with '- (cdr indices) indices))))
+         r)
+    (--each diffs
+      (let ((split (-split-at it list)))
+        (!cons (car split) r)
+        (setq list (cdr (cadr split)))))
+    (!cons list r)
+    (apply '-concat (nreverse r))))
+
+(defmacro --split-with (pred list)
+  "Anaphoric form of `-split-with'."
+  (declare (debug (form form)))
+  (let ((l (make-symbol "list"))
+        (r (make-symbol "result"))
+        (c (make-symbol "continue")))
+    `(let ((,l ,list)
+           (,r nil)
+           (,c t))
+       (while (and ,l ,c)
+         (let ((it (car ,l)))
+           (if (not ,pred)
+               (setq ,c nil)
+             (!cons it ,r)
+             (!cdr ,l))))
+       (list (nreverse ,r) ,l))))
+
+(defun -split-with (pred list)
+  "Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)), in no more than one pass through the list."
+  (--split-with (funcall pred it) list))
+
+(defmacro -split-on (item list)
+  "Split the LIST each time ITEM is found.
+
+Unlike `-partition-by', the ITEM is discarded from the results.
+Empty lists are also removed from the result.
+
+Comparison is done by `equal'.
+
+See also `-split-when'"
+  (declare (debug (form form)))
+  `(-split-when (lambda (it) (equal it ,item)) ,list))
+
+(defmacro --split-when (form list)
+  "Anaphoric version of `-split-when'."
+  (declare (debug (form form)))
+  `(-split-when (lambda (it) ,form) ,list))
+
+(defun -split-when (fn list)
+  "Split the LIST on each element where FN returns non-nil.
+
+Unlike `-partition-by', the \"matched\" element is discarded from
+the results.  Empty lists are also removed from the result.
+
+This function can be thought of as a generalization of
+`split-string'."
+  (let (r s)
+    (while list
+      (if (not (funcall fn (car list)))
+          (push (car list) s)
+        (when s (push (nreverse s) r))
+        (setq s nil))
+      (!cdr list))
+    (when s (push (nreverse s) r))
+    (nreverse r)))
+
+(defmacro --separate (form list)
+  "Anaphoric form of `-separate'."
+  (declare (debug (form form)))
+  (let ((y (make-symbol "yes"))
+        (n (make-symbol "no")))
+    `(let (,y ,n)
+       (--each ,list (if ,form (!cons it ,y) (!cons it ,n)))
+       (list (nreverse ,y) (nreverse ,n)))))
+
+(defun -separate (pred list)
+  "Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one pass through the list."
+  (--separate (funcall pred it) list))
+
+(defun ---partition-all-in-steps-reversed (n step list)
+  "Private: Used by -partition-all-in-steps and -partition-in-steps."
+  (when (< step 1)
+    (error "Step must be a positive number, or you're looking at some juicy infinite loops."))
+  (let ((result nil))
+    (while list
+      (!cons (-take n list) result)
+      (setq list (-drop step list)))
+    result))
+
+(defun -partition-all-in-steps (n step list)
+  "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
+The last groups may contain less than N items."
+  (declare (pure t) (side-effect-free t))
+  (nreverse (---partition-all-in-steps-reversed n step list)))
+
+(defun -partition-in-steps (n step list)
+  "Return a new list with the items in LIST grouped into N-sized sublists at offsets STEP apart.
+If there are not enough items to make the last group N-sized,
+those items are discarded."
+  (declare (pure t) (side-effect-free t))
+  (let ((result (---partition-all-in-steps-reversed n step list)))
+    (while (and result (< (length (car result)) n))
+      (!cdr result))
+    (nreverse result)))
+
+(defun -partition-all (n list)
+  "Return a new list with the items in LIST grouped into N-sized sublists.
+The last group may contain less than N items."
+  (declare (pure t) (side-effect-free t))
+  (-partition-all-in-steps n n list))
+
+(defun -partition (n list)
+  "Return a new list with the items in LIST grouped into N-sized sublists.
+If there are not enough items to make the last group N-sized,
+those items are discarded."
+  (declare (pure t) (side-effect-free t))
+  (-partition-in-steps n n list))
+
+(defmacro --partition-by (form list)
+  "Anaphoric form of `-partition-by'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result"))
+        (s (make-symbol "sublist"))
+        (v (make-symbol "value"))
+        (n (make-symbol "new-value"))
+        (l (make-symbol "list")))
+    `(let ((,l ,list))
+       (when ,l
+         (let* ((,r nil)
+                (it (car ,l))
+                (,s (list it))
+                (,v ,form)
+                (,l (cdr ,l)))
+           (while ,l
+             (let* ((it (car ,l))
+                    (,n ,form))
+               (unless (equal ,v ,n)
+                 (!cons (nreverse ,s) ,r)
+                 (setq ,s nil)
+                 (setq ,v ,n))
+               (!cons it ,s)
+               (!cdr ,l)))
+           (!cons (nreverse ,s) ,r)
+           (nreverse ,r))))))
+
+(defun -partition-by (fn list)
+  "Apply FN to each item in LIST, splitting it each time FN returns a new value."
+  (--partition-by (funcall fn it) list))
+
+(defmacro --partition-by-header (form list)
+  "Anaphoric form of `-partition-by-header'."
+  (declare (debug (form form)))
+  (let ((r (make-symbol "result"))
+        (s (make-symbol "sublist"))
+        (h (make-symbol "header-value"))
+        (b (make-symbol "seen-body?"))
+        (n (make-symbol "new-value"))
+        (l (make-symbol "list")))
+    `(let ((,l ,list))
+       (when ,l
+         (let* ((,r nil)
+                (it (car ,l))
+                (,s (list it))
+                (,h ,form)
+                (,b nil)
+                (,l (cdr ,l)))
+           (while ,l
+             (let* ((it (car ,l))
+                    (,n ,form))
+               (if (equal ,h ,n)
+                   (when ,b
+                     (!cons (nreverse ,s) ,r)
+                     (setq ,s nil)
+                     (setq ,b nil))
+                 (setq ,b t))
+               (!cons it ,s)
+               (!cdr ,l)))
+           (!cons (nreverse ,s) ,r)
+           (nreverse ,r))))))
+
+(defun -partition-by-header (fn list)
+  "Apply FN to the first item in LIST. That is the header
+value. Apply FN to each item in LIST, splitting it each time FN
+returns the header value, but only after seeing at least one
+other value (the body)."
+  (--partition-by-header (funcall fn it) list))
+
+(defun -partition-after-pred (pred list)
+  "Partition directly after each time PRED is true on an element of LIST."
+  (when list
+    (let ((rest (-partition-after-pred pred
+                                       (cdr list))))
+      (if (funcall pred (car list))
+          ;;split after (car list)
+          (cons (list (car list))
+                rest)
+
+        ;;don't split after (car list)
+        (cons (cons (car list)
+                    (car rest))
+              (cdr rest))))))
+
+(defun -partition-before-pred (pred list)
+  "Partition directly before each time PRED is true on an element of LIST."
+  (nreverse (-map #'reverse
+                  (-partition-after-pred pred (reverse list)))))
+
+(defun -partition-after-item (item list)
+  "Partition directly after each time ITEM appears in LIST."
+  (-partition-after-pred (lambda (ele) (equal ele item))
+                         list))
+
+(defun -partition-before-item (item list)
+  "Partition directly before each time ITEM appears in LIST."
+  (-partition-before-pred (lambda (ele) (equal ele item))
+                          list))
+
+(defmacro --group-by (form list)
+  "Anaphoric form of `-group-by'."
+  (declare (debug t))
+  (let ((n (make-symbol "n"))
+        (k (make-symbol "k"))
+        (grp (make-symbol "grp")))
+    `(nreverse
+      (-map
+       (lambda (,n)
+         (cons (car ,n)
+               (nreverse (cdr ,n))))
+       (--reduce-from
+        (let* ((,k (,@form))
+               (,grp (assoc ,k acc)))
+          (if ,grp
+              (setcdr ,grp (cons it (cdr ,grp)))
+            (push
+             (list ,k it)
+             acc))
+          acc)
+        nil ,list)))))
+
+(defun -group-by (fn list)
+  "Separate LIST into an alist whose keys are FN applied to the
+elements of LIST.  Keys are compared by `equal'."
+  (--group-by (funcall fn it) list))
+
+(defun -interpose (sep list)
+  "Return a new list of all elements in LIST separated by SEP."
+  (declare (pure t) (side-effect-free t))
+  (let (result)
+    (when list
+      (!cons (car list) result)
+      (!cdr list))
+    (while list
+      (setq result (cons (car list) (cons sep result)))
+      (!cdr list))
+    (nreverse result)))
+
+(defun -interleave (&rest lists)
+  "Return a new list of the first item in each list, then the second etc."
+  (declare (pure t) (side-effect-free t))
+  (when lists
+    (let (result)
+      (while (-none? 'null lists)
+        (--each lists (!cons (car it) result))
+        (setq lists (-map 'cdr lists)))
+      (nreverse result))))
+
+(defmacro --zip-with (form list1 list2)
+  "Anaphoric form of `-zip-with'.
+
+The elements in list1 are bound as symbol `it', the elements in list2 as symbol `other'."
+  (declare (debug (form form form)))
+  (let ((r (make-symbol "result"))
+        (l1 (make-symbol "list1"))
+        (l2 (make-symbol "list2")))
+    `(let ((,r nil)
+           (,l1 ,list1)
+           (,l2 ,list2))
+       (while (and ,l1 ,l2)
+         (let ((it (car ,l1))
+               (other (car ,l2)))
+           (!cons ,form ,r)
+           (!cdr ,l1)
+           (!cdr ,l2)))
+       (nreverse ,r))))
+
+(defun -zip-with (fn list1 list2)
+  "Zip the two lists LIST1 and LIST2 using a function FN.  This
+function is applied pairwise taking as first argument element of
+LIST1 and as second argument element of LIST2 at corresponding
+position.
+
+The anaphoric form `--zip-with' binds the elements from LIST1 as symbol `it',
+and the elements from LIST2 as symbol `other'."
+  (--zip-with (funcall fn it other) list1 list2))
+
+(defun -zip-lists (&rest lists)
+  "Zip LISTS together.  Group the head of each list, followed by the
+second elements of each list, and so on. The lengths of the returned
+groupings are equal to the length of the shortest input list.
+
+The return value is always list of lists, which is a difference
+from `-zip-pair' which returns a cons-cell in case two input
+lists are provided.
+
+See also: `-zip'"
+  (declare (pure t) (side-effect-free t))
+  (when lists
+    (let (results)
+      (while (-none? 'null lists)
+        (setq results (cons (mapcar 'car lists) results))
+        (setq lists (mapcar 'cdr lists)))
+      (nreverse results))))
+
+(defun -zip (&rest lists)
+  "Zip LISTS together.  Group the head of each list, followed by the
+second elements of each list, and so on. The lengths of the returned
+groupings are equal to the length of the shortest input list.
+
+If two lists are provided as arguments, return the groupings as a list
+of cons cells. Otherwise, return the groupings as a list of lists.
+
+Use `-zip-lists' if you need the return value to always be a list
+of lists.
+
+Alias: `-zip-pair'
+
+See also: `-zip-lists'"
+  (declare (pure t) (side-effect-free t))
+  (when lists
+    (let (results)
+      (while (-none? 'null lists)
+        (setq results (cons (mapcar 'car lists) results))
+        (setq lists (mapcar 'cdr lists)))
+      (setq results (nreverse results))
+      (if (= (length lists) 2)
+          ;; to support backward compatibility, return
+          ;; a cons cell if two lists were provided
+          (--map (cons (car it) (cadr it)) results)
+        results))))
+
+(defalias '-zip-pair '-zip)
+
+(defun -zip-fill (fill-value &rest lists)
+  "Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
+lengths of the returned groupings are equal to the length of the
+longest input list."
+  (declare (pure t) (side-effect-free t))
+  (apply '-zip (apply '-pad (cons fill-value lists))))
+
+(defun -unzip (lists)
+  "Unzip LISTS.
+
+This works just like `-zip' but takes a list of lists instead of
+a variable number of arguments, such that
+
+  (-unzip (-zip L1 L2 L3 ...))
+
+is identity (given that the lists are the same length).
+
+Note in particular that calling this on a list of two lists will
+return a list of cons-cells such that the above identity works.
+
+See also: `-zip'"
+  (apply '-zip lists))
+
+(defun -cycle (list)
+  "Return an infinite circular copy of LIST.
+The returned list cycles through the elements of LIST and repeats
+from the beginning."
+  (declare (pure t) (side-effect-free t))
+  ;; Also works with sequences that aren't lists.
+  (let ((newlist (append list ())))
+    (nconc newlist newlist)))
+
+(defun -pad (fill-value &rest lists)
+  "Appends FILL-VALUE to the end of each list in LISTS such that they
+will all have the same length."
+  (let* ((annotations (-annotate 'length lists))
+         (n (-max (-map 'car annotations))))
+    (--map (append (cdr it) (-repeat (- n (car it)) fill-value)) annotations)))
+
+(defun -annotate (fn list)
+  "Return a list of cons cells where each cell is FN applied to each
+element of LIST paired with the unmodified element of LIST."
+  (-zip (-map fn list) list))
+
+(defmacro --annotate (form list)
+  "Anaphoric version of `-annotate'."
+  (declare (debug (form form)))
+  `(-annotate (lambda (it) ,form) ,list))
+
+(defun dash--table-carry (lists restore-lists &optional re)
+  "Helper for `-table' and `-table-flat'.
+
+If a list overflows, carry to the right and reset the list."
+  (while (not (or (car lists)
+                  (equal lists '(nil))))
+    (setcar lists (car restore-lists))
+    (pop (cadr lists))
+    (!cdr lists)
+    (!cdr restore-lists)
+    (when re
+      (push (nreverse (car re)) (cadr re))
+      (setcar re nil)
+      (!cdr re))))
+
+(defun -table (fn &rest lists)
+  "Compute outer product of LISTS using function FN.
+
+The function FN should have the same arity as the number of
+supplied lists.
+
+The outer product is computed by applying fn to all possible
+combinations created by taking one element from each list in
+order.  The dimension of the result is (length lists).
+
+See also: `-table-flat'"
+  (let ((restore-lists (copy-sequence lists))
+        (last-list (last lists))
+        (re (make-list (length lists) nil)))
+    (while (car last-list)
+      (let ((item (apply fn (-map 'car lists))))
+        (push item (car re))
+        (setcar lists (cdar lists)) ;; silence byte compiler
+        (dash--table-carry lists restore-lists re)))
+    (nreverse (car (last re)))))
+
+(defun -table-flat (fn &rest lists)
+  "Compute flat outer product of LISTS using function FN.
+
+The function FN should have the same arity as the number of
+supplied lists.
+
+The outer product is computed by applying fn to all possible
+combinations created by taking one element from each list in
+order.  The results are flattened, ignoring the tensor structure
+of the result.  This is equivalent to calling:
+
+  (-flatten-n (1- (length lists)) (apply \\='-table fn lists))
+
+but the implementation here is much more efficient.
+
+See also: `-flatten-n', `-table'"
+  (let ((restore-lists (copy-sequence lists))
+        (last-list (last lists))
+        re)
+    (while (car last-list)
+      (let ((item (apply fn (-map 'car lists))))
+        (push item re)
+        (setcar lists (cdar lists)) ;; silence byte compiler
+        (dash--table-carry lists restore-lists)))
+    (nreverse re)))
+
+(defun -partial (fn &rest args)
+  "Take a function FN and fewer than the normal arguments to FN,
+and return a fn that takes a variable number of additional ARGS.
+When called, the returned function calls FN with ARGS first and
+then additional args."
+  (apply 'apply-partially fn args))
+
+(defun -elem-index (elem list)
+  "Return the index of the first element in the given LIST which
+is equal to the query element ELEM, or nil if there is no
+such element."
+  (declare (pure t) (side-effect-free t))
+  (car (-elem-indices elem list)))
+
+(defun -elem-indices (elem list)
+  "Return the indices of all elements in LIST equal to the query
+element ELEM, in ascending order."
+  (declare (pure t) (side-effect-free t))
+  (-find-indices (-partial 'equal elem) list))
+
+(defun -find-indices (pred list)
+  "Return the indices of all elements in LIST satisfying the
+predicate PRED, in ascending order."
+  (apply 'append (--map-indexed (when (funcall pred it) (list it-index)) list)))
+
+(defmacro --find-indices (form list)
+  "Anaphoric version of `-find-indices'."
+  (declare (debug (form form)))
+  `(-find-indices (lambda (it) ,form) ,list))
+
+(defun -find-index (pred list)
+  "Take a predicate PRED and a LIST and return the index of the
+first element in the list satisfying the predicate, or nil if
+there is no such element.
+
+See also `-first'."
+  (car (-find-indices pred list)))
+
+(defmacro --find-index (form list)
+  "Anaphoric version of `-find-index'."
+  (declare (debug (form form)))
+  `(-find-index (lambda (it) ,form) ,list))
+
+(defun -find-last-index (pred list)
+  "Take a predicate PRED and a LIST and return the index of the
+last element in the list satisfying the predicate, or nil if
+there is no such element.
+
+See also `-last'."
+  (-last-item (-find-indices pred list)))
+
+(defmacro --find-last-index (form list)
+  "Anaphoric version of `-find-last-index'."
+  `(-find-last-index (lambda (it) ,form) ,list))
+
+(defun -select-by-indices (indices list)
+  "Return a list whose elements are elements from LIST selected
+as `(nth i list)` for all i from INDICES."
+  (declare (pure t) (side-effect-free t))
+  (let (r)
+    (--each indices
+      (!cons (nth it list) r))
+    (nreverse r)))
+
+(defun -select-columns (columns table)
+  "Select COLUMNS from TABLE.
+
+TABLE is a list of lists where each element represents one row.
+It is assumed each row has the same length.
+
+Each row is transformed such that only the specified COLUMNS are
+selected.
+
+See also: `-select-column', `-select-by-indices'"
+  (declare (pure t) (side-effect-free t))
+  (--map (-select-by-indices columns it) table))
+
+(defun -select-column (column table)
+  "Select COLUMN from TABLE.
+
+TABLE is a list of lists where each element represents one row.
+It is assumed each row has the same length.
+
+The single selected column is returned as a list.
+
+See also: `-select-columns', `-select-by-indices'"
+  (declare (pure t) (side-effect-free t))
+  (--mapcat (-select-by-indices (list column) it) table))
+
+(defmacro -> (x &optional form &rest more)
+  "Thread the expr through the forms. Insert X as the second item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, insert the first form as the
+second item in second form, etc."
+  (declare (debug (form &rest [&or symbolp (sexp &rest form)])))
+  (cond
+   ((null form) x)
+   ((null more) (if (listp form)
+                    `(,(car form) ,x ,@(cdr form))
+                  (list form x)))
+   (:else `(-> (-> ,x ,form) ,@more))))
+
+(defmacro ->> (x &optional form &rest more)
+  "Thread the expr through the forms. Insert X as the last item
+in the first form, making a list of it if it is not a list
+already. If there are more forms, insert the first form as the
+last item in second form, etc."
+  (declare (debug ->))
+  (cond
+   ((null form) x)
+   ((null more) (if (listp form)
+                    `(,@form ,x)
+                  (list form x)))
+   (:else `(->> (->> ,x ,form) ,@more))))
+
+(defmacro --> (x &rest forms)
+  "Starting with the value of X, thread each expression through FORMS.
+
+Insert X at the position signified by the symbol `it' in the first
+form.  If there are more forms, insert the first form at the position
+signified by `it' in in second form, etc."
+  (declare (debug (form body)))
+  `(-as-> ,x it ,@forms))
+
+(defmacro -as-> (value variable &rest forms)
+  "Starting with VALUE, thread VARIABLE through FORMS.
+
+In the first form, bind VARIABLE to VALUE.  In the second form, bind
+VARIABLE to the result of the first form, and so forth."
+  (declare (debug (form symbolp body)))
+  (if (null forms)
+      `,value
+    `(let ((,variable ,value))
+       (-as-> ,(if (symbolp (car forms))
+                 (list (car forms) variable)
+               (car forms))
+            ,variable
+              ,@(cdr forms)))))
+
+(defmacro -some-> (x &optional form &rest more)
+  "When expr is non-nil, thread it through the first form (via `->'),
+and when that result is non-nil, through the next form, etc."
+  (declare (debug ->)
+           (indent 1))
+  (if (null form) x
+    (let ((result (make-symbol "result")))
+      `(-some-> (-when-let (,result ,x)
+                  (-> ,result ,form))
+                ,@more))))
+
+(defmacro -some->> (x &optional form &rest more)
+  "When expr is non-nil, thread it through the first form (via `->>'),
+and when that result is non-nil, through the next form, etc."
+  (declare (debug ->)
+           (indent 1))
+  (if (null form) x
+    (let ((result (make-symbol "result")))
+      `(-some->> (-when-let (,result ,x)
+                   (->> ,result ,form))
+                 ,@more))))
+
+(defmacro -some--> (x &optional form &rest more)
+  "When expr is non-nil, thread it through the first form (via `-->'),
+and when that result is non-nil, through the next form, etc."
+  (declare (debug ->)
+           (indent 1))
+  (if (null form) x
+    (let ((result (make-symbol "result")))
+      `(-some--> (-when-let (,result ,x)
+                   (--> ,result ,form))
+                 ,@more))))
+
+(defun -grade-up (comparator list)
+  "Grade elements of LIST using COMPARATOR relation, yielding a
+permutation vector such that applying this permutation to LIST
+sorts it in ascending order."
+  ;; ugly hack to "fix" lack of lexical scope
+  (let ((comp `(lambda (it other) (funcall ',comparator (car it) (car other)))))
+    (->> (--map-indexed (cons it it-index) list)
+         (-sort comp)
+         (-map 'cdr))))
+
+(defun -grade-down (comparator list)
+  "Grade elements of LIST using COMPARATOR relation, yielding a
+permutation vector such that applying this permutation to LIST
+sorts it in descending order."
+  ;; ugly hack to "fix" lack of lexical scope
+  (let ((comp `(lambda (it other) (funcall ',comparator (car other) (car it)))))
+    (->> (--map-indexed (cons it it-index) list)
+         (-sort comp)
+         (-map 'cdr))))
+
+(defvar dash--source-counter 0
+  "Monotonic counter for generated symbols.")
+
+(defun dash--match-make-source-symbol ()
+  "Generate a new dash-source symbol.
+
+All returned symbols are guaranteed to be unique."
+  (prog1 (make-symbol (format "--dash-source-%d--" dash--source-counter))
+    (setq dash--source-counter (1+ dash--source-counter))))
+
+(defun dash--match-ignore-place-p (symbol)
+  "Return non-nil if SYMBOL is a symbol and starts with _."
+  (and (symbolp symbol)
+       (eq (aref (symbol-name symbol) 0) ?_)))
+
+(defun dash--match-cons-skip-cdr (skip-cdr source)
+  "Helper function generating idiomatic shifting code."
+  (cond
+   ((= skip-cdr 0)
+    `(pop ,source))
+   (t
+    `(prog1 ,(dash--match-cons-get-car skip-cdr source)
+       (setq ,source ,(dash--match-cons-get-cdr (1+ skip-cdr) source))))))
+
+(defun dash--match-cons-get-car (skip-cdr source)
+  "Helper function generating idiomatic code to get nth car."
+  (cond
+   ((= skip-cdr 0)
+    `(car ,source))
+   ((= skip-cdr 1)
+    `(cadr ,source))
+   (t
+    `(nth ,skip-cdr ,source))))
+
+(defun dash--match-cons-get-cdr (skip-cdr source)
+  "Helper function generating idiomatic code to get nth cdr."
+  (cond
+   ((= skip-cdr 0)
+    source)
+   ((= skip-cdr 1)
+    `(cdr ,source))
+   (t
+    `(nthcdr ,skip-cdr ,source))))
+
+(defun dash--match-cons (match-form source)
+  "Setup a cons matching environment and call the real matcher."
+  (let ((s (dash--match-make-source-symbol))
+        (n 0)
+        (m match-form))
+    (while (and (consp m)
+                (dash--match-ignore-place-p (car m)))
+      (setq n (1+ n)) (!cdr m))
+    (cond
+     ;; when we only have one pattern in the list, we don't have to
+     ;; create a temporary binding (--dash-source--) for the source
+     ;; and just use the input directly
+     ((and (consp m)
+           (not (cdr m)))
+      (dash--match (car m) (dash--match-cons-get-car n source)))
+     ;; handle other special types
+     ((> n 0)
+      (dash--match m (dash--match-cons-get-cdr n source)))
+     ;; this is the only entry-point for dash--match-cons-1, that's
+     ;; why we can't simply use the above branch, it would produce
+     ;; infinite recursion
+     (t
+      (cons (list s source) (dash--match-cons-1 match-form s))))))
+
+(defun dash--get-expand-function (type)
+  "Get expand function name for TYPE."
+  (intern-soft (format "dash-expand:%s" type)))
+
+(defun dash--match-cons-1 (match-form source &optional props)
+  "Match MATCH-FORM against SOURCE.
+
+MATCH-FORM is a proper or improper list.  Each element of
+MATCH-FORM is either a symbol, which gets bound to the respective
+value in source or another match form which gets destructured
+recursively.
+
+If the cdr of last cons cell in the list is `nil', matching stops
+there.
+
+SOURCE is a proper or improper list."
+  (let ((skip-cdr (or (plist-get props :skip-cdr) 0)))
+    (cond
+     ((consp match-form)
+      (cond
+       ((cdr match-form)
+        (cond
+         ((and (symbolp (car match-form))
+               (functionp (dash--get-expand-function (car match-form))))
+          (dash--match-kv (dash--match-kv-normalize-match-form match-form) (dash--match-cons-get-cdr skip-cdr source)))
+         ((dash--match-ignore-place-p (car match-form))
+          (dash--match-cons-1 (cdr match-form) source
+                              (plist-put props :skip-cdr (1+ skip-cdr))))
+         (t
+          (-concat (dash--match (car match-form) (dash--match-cons-skip-cdr skip-cdr source))
+                   (dash--match-cons-1 (cdr match-form) source)))))
+       (t ;; Last matching place, no need for shift
+        (dash--match (car match-form) (dash--match-cons-get-car skip-cdr source)))))
+     ((eq match-form nil)
+      nil)
+     (t ;; Handle improper lists.  Last matching place, no need for shift
+      (dash--match match-form (dash--match-cons-get-cdr skip-cdr source))))))
+
+(defun dash--vector-tail (seq start)
+  "Return the tail of SEQ starting at START."
+  (cond
+   ((vectorp seq)
+    (let* ((re-length (- (length seq) start))
+           (re (make-vector re-length 0)))
+      (--dotimes re-length (aset re it (aref seq (+ it start))))
+      re))
+   ((stringp seq)
+    (substring seq start))))
+
+(defun dash--match-vector (match-form source)
+  "Setup a vector matching environment and call the real matcher."
+  (let ((s (dash--match-make-source-symbol)))
+    (cond
+     ;; don't bind `s' if we only have one sub-pattern
+     ((= (length match-form) 1)
+      (dash--match (aref match-form 0) `(aref ,source 0)))
+     ;; if the source is a symbol, we don't need to re-bind it
+     ((symbolp source)
+      (dash--match-vector-1 match-form source))
+     ;; don't bind `s' if we only have one sub-pattern which is not ignored
+     ((let* ((ignored-places (mapcar 'dash--match-ignore-place-p match-form))
+             (ignored-places-n (length (-remove 'null ignored-places))))
+        (when (= ignored-places-n (1- (length match-form)))
+          (let ((n (-find-index 'null ignored-places)))
+            (dash--match (aref match-form n) `(aref ,source ,n))))))
+     (t
+      (cons (list s source) (dash--match-vector-1 match-form s))))))
+
+(defun dash--match-vector-1 (match-form source)
+  "Match MATCH-FORM against SOURCE.
+
+MATCH-FORM is a vector.  Each element of MATCH-FORM is either a
+symbol, which gets bound to the respective value in source or
+another match form which gets destructured recursively.
+
+If second-from-last place in MATCH-FORM is the symbol &rest, the
+next element of the MATCH-FORM is matched against the tail of
+SOURCE, starting at index of the &rest symbol.  This is
+conceptually the same as the (head . tail) match for improper
+lists, where dot plays the role of &rest.
+
+SOURCE is a vector.
+
+If the MATCH-FORM vector is shorter than SOURCE vector, only
+the (length MATCH-FORM) places are bound, the rest of the SOURCE
+is discarded."
+  (let ((i 0)
+        (l (length match-form))
+        (re))
+    (while (< i l)
+      (let ((m (aref match-form i)))
+        (push (cond
+               ((and (symbolp m)
+                     (eq m '&rest))
+                (prog1 (dash--match
+                        (aref match-form (1+ i))
+                        `(dash--vector-tail ,source ,i))
+                  (setq i l)))
+               ((and (symbolp m)
+                     ;; do not match symbols starting with _
+                     (not (eq (aref (symbol-name m) 0) ?_)))
+                (list (list m `(aref ,source ,i))))
+               ((not (symbolp m))
+                (dash--match m `(aref ,source ,i))))
+              re)
+        (setq i (1+ i))))
+    (-flatten-n 1 (nreverse re))))
+
+(defun dash--match-kv-normalize-match-form (pattern)
+  "Normalize kv PATTERN.
+
+This method normalizes PATTERN to the format expected by
+`dash--match-kv'.  See `-let' for the specification."
+  (let ((normalized (list (car pattern)))
+        (skip nil)
+        (fill-placeholder (make-symbol "--dash-fill-placeholder--")))
+    (-each (apply '-zip (-pad fill-placeholder (cdr pattern) (cddr pattern)))
+      (lambda (pair)
+        (let ((current (car pair))
+              (next (cdr pair)))
+          (if skip
+              (setq skip nil)
+            (if (or (eq fill-placeholder next)
+                    (not (or (and (symbolp next)
+                                  (not (keywordp next))
+                                  (not (eq next t))
+                                  (not (eq next nil)))
+                             (and (consp next)
+                                  (not (eq (car next) 'quote)))
+                             (vectorp next))))
+                (progn
+                  (cond
+                   ((keywordp current)
+                    (push current normalized)
+                    (push (intern (substring (symbol-name current) 1)) normalized))
+                   ((stringp current)
+                    (push current normalized)
+                    (push (intern current) normalized))
+                   ((and (consp current)
+                         (eq (car current) 'quote))
+                    (push current normalized)
+                    (push (cadr current) normalized))
+                   (t (error "-let: found key `%s' in kv destructuring but its pattern `%s' is invalid and can not be derived from the key" current next)))
+                  (setq skip nil))
+              (push current normalized)
+              (push next normalized)
+              (setq skip t))))))
+    (nreverse normalized)))
+
+(defun dash--match-kv (match-form source)
+  "Setup a kv matching environment and call the real matcher.
+
+kv can be any key-value store, such as plist, alist or hash-table."
+  (let ((s (dash--match-make-source-symbol)))
+    (cond
+     ;; don't bind `s' if we only have one sub-pattern (&type key val)
+     ((= (length match-form) 3)
+      (dash--match-kv-1 (cdr match-form) source (car match-form)))
+     ;; if the source is a symbol, we don't need to re-bind it
+     ((symbolp source)
+      (dash--match-kv-1 (cdr match-form) source (car match-form)))
+     (t
+      (cons (list s source) (dash--match-kv-1 (cdr match-form) s (car match-form)))))))
+
+(defun dash-expand:&hash (key source)
+  "Generate extracting KEY from SOURCE for &hash destructuring."
+  `(gethash ,key ,source))
+
+(defun dash-expand:&plist (key source)
+  "Generate extracting KEY from SOURCE for &plist destructuring."
+  `(plist-get ,source ,key))
+
+(defun dash-expand:&alist (key source)
+  "Generate extracting KEY from SOURCE for &alist destructuring."
+  `(cdr (assoc ,key ,source)))
+
+(defun dash-expand:&hash? (key source)
+  "Generate extracting KEY from SOURCE for &hash? destructuring.
+Similar to &hash but check whether the map is not nil."
+  (let ((src (make-symbol "src")))
+    `(let ((,src ,source))
+       (when ,src (gethash ,key ,src)))))
+
+(defalias 'dash-expand:&keys 'dash-expand:&plist)
+
+(defun dash--match-kv-1 (match-form source type)
+  "Match MATCH-FORM against SOURCE of type TYPE.
+
+MATCH-FORM is a proper list of the form (key1 place1 ... keyN
+placeN).  Each placeK is either a symbol, which gets bound to the
+value of keyK retrieved from the key-value store, or another
+match form which gets destructured recursively.
+
+SOURCE is a key-value store of type TYPE, which can be a plist,
+an alist or a hash table.
+
+TYPE is a token specifying the type of the key-value store.
+Valid values are &plist, &alist and &hash."
+  (-flatten-n 1 (-map
+                 (lambda (kv)
+                   (let* ((k (car kv))
+                          (v (cadr kv))
+                          (getter
+                           (funcall (dash--get-expand-function type) k source)))
+                     (cond
+                      ((symbolp v)
+                       (list (list v getter)))
+                      (t (dash--match v getter)))))
+                 (-partition 2 match-form))))
+
+(defun dash--match-symbol (match-form source)
+  "Bind a symbol.
+
+This works just like `let', there is no destructuring."
+  (list (list match-form source)))
+
+(defun dash--match (match-form source)
+  "Match MATCH-FORM against SOURCE.
+
+This function tests the MATCH-FORM and dispatches to specific
+matchers based on the type of the expression.
+
+Key-value stores are disambiguated by placing a token &plist,
+&alist or &hash as a first item in the MATCH-FORM."
+  (cond
+   ((symbolp match-form)
+    (dash--match-symbol match-form source))
+   ((consp match-form)
+    (cond
+     ;; Handle the "x &as" bindings first.
+     ((and (consp (cdr match-form))
+           (symbolp (car match-form))
+           (eq '&as (cadr match-form)))
+      (let ((s (car match-form)))
+        (cons (list s source)
+              (dash--match (cddr match-form) s))))
+     ((functionp (dash--get-expand-function (car match-form)))
+      (dash--match-kv (dash--match-kv-normalize-match-form match-form) source))
+     (t (dash--match-cons match-form source))))
+   ((vectorp match-form)
+    ;; We support the &as binding in vectors too
+    (cond
+     ((and (> (length match-form) 2)
+           (symbolp (aref match-form 0))
+           (eq '&as (aref match-form 1)))
+      (let ((s (aref match-form 0)))
+        (cons (list s source)
+              (dash--match (dash--vector-tail match-form 2) s))))
+     (t (dash--match-vector match-form source))))))
+
+(defun dash--normalize-let-varlist (varlist)
+  "Normalize VARLIST so that every binding is a list.
+
+`let' allows specifying a binding which is not a list but simply
+the place which is then automatically bound to nil, such that all
+three of the following are identical and evaluate to nil.
+
+  (let (a) a)
+  (let ((a)) a)
+  (let ((a nil)) a)
+
+This function normalizes all of these to the last form."
+  (--map (if (consp it) it (list it nil)) varlist))
+
+(defmacro -let* (varlist &rest body)
+  "Bind variables according to VARLIST then eval BODY.
+
+VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
+PATTERN is matched against the SOURCE structurally.  SOURCE is
+only evaluated once for each PATTERN.
+
+Each SOURCE can refer to the symbols already bound by this
+VARLIST.  This is useful if you want to destructure SOURCE
+recursively but also want to name the intermediate structures.
+
+See `-let' for the list of all possible patterns."
+  (declare (debug ((&rest [&or (sexp form) sexp]) body))
+           (indent 1))
+  (let* ((varlist (dash--normalize-let-varlist varlist))
+         (bindings (--mapcat (dash--match (car it) (cadr it)) varlist)))
+    `(let* ,bindings
+       ,@body)))
+
+(defmacro -let (varlist &rest body)
+  "Bind variables according to VARLIST then eval BODY.
+
+VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
+PATTERN is matched against the SOURCE \"structurally\".  SOURCE
+is only evaluated once for each PATTERN.  Each PATTERN is matched
+recursively, and can therefore contain sub-patterns which are
+matched against corresponding sub-expressions of SOURCE.
+
+All the SOURCEs are evalled before any symbols are
+bound (i.e. \"in parallel\").
+
+If VARLIST only contains one (PATTERN SOURCE) element, you can
+optionally specify it using a vector and discarding the
+outer-most parens.  Thus
+
+  (-let ((PATTERN SOURCE)) ..)
+
+becomes
+
+  (-let [PATTERN SOURCE] ..).
+
+`-let' uses a convention of not binding places (symbols) starting
+with _ whenever it's possible.  You can use this to skip over
+entries you don't care about.  However, this is not *always*
+possible (as a result of implementation) and these symbols might
+get bound to undefined values.
+
+Following is the overview of supported patterns.  Remember that
+patterns can be matched recursively, so every a, b, aK in the
+following can be a matching construct and not necessarily a
+symbol/variable.
+
+Symbol:
+
+  a - bind the SOURCE to A.  This is just like regular `let'.
+
+Conses and lists:
+
+  (a) - bind `car' of cons/list to A
+
+  (a . b) - bind car of cons to A and `cdr' to B
+
+  (a b) - bind car of list to A and `cadr' to B
+
+  (a1 a2 a3  ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3 ...
+
+  (a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to REST.
+
+Vectors:
+
+  [a] - bind 0th element of a non-list sequence to A (works with
+        vectors, strings, bit arrays...)
+
+  [a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st to
+                   A1, 2nd to A2, ...
+                   If the PATTERN is shorter than SOURCE, the values at
+                   places not in PATTERN are ignored.
+                   If the PATTERN is longer than SOURCE, an `error' is
+                   thrown.
+
+  [a1 a2 a3 ... &rest rest] - as above, but bind the rest of
+                              the sequence to REST.  This is
+                              conceptually the same as improper list
+                              matching (a1 a2 ... aN . rest)
+
+Key/value stores:
+
+  (&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+                                 SOURCE plist to aK.  If the
+                                 value is not found, aK is nil.
+                                 Uses `plist-get' to fetch values.
+
+  (&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
+                                 SOURCE alist to aK.  If the
+                                 value is not found, aK is nil.
+                                 Uses `assoc' to fetch values.
+
+  (&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
+                                SOURCE hash table to aK.  If the
+                                value is not found, aK is nil.
+                                Uses `gethash' to fetch values.
+
+Further, special keyword &keys supports \"inline\" matching of
+plist-like key-value pairs, similarly to &keys keyword of
+`cl-defun'.
+
+  (a1 a2 ... aN &keys key1 b1 ... keyN bK)
+
+This binds N values from the list to a1 ... aN, then interprets
+the cdr as a plist (see key/value matching above).
+
+A shorthand notation for kv-destructuring exists which allows the
+patterns be optionally left out and derived from the key name in
+the following fashion:
+
+- a key :foo is converted into `foo' pattern,
+- a key 'bar is converted into `bar' pattern,
+- a key \"baz\" is converted into `baz' pattern.
+
+That is, the entire value under the key is bound to the derived
+variable without any further destructuring.
+
+This is possible only when the form following the key is not a
+valid pattern (i.e. not a symbol, a cons cell or a vector).
+Otherwise the matching proceeds as usual and in case of an
+invalid spec fails with an error.
+
+Thus the patterns are normalized as follows:
+
+   ;; derive all the missing patterns
+   (&plist :foo 'bar \"baz\") => (&plist :foo foo 'bar bar \"baz\" baz)
+
+   ;; we can specify some but not others
+   (&plist :foo 'bar explicit-bar) => (&plist :foo foo 'bar explicit-bar)
+
+   ;; nothing happens, we store :foo in x
+   (&plist :foo x) => (&plist :foo x)
+
+   ;; nothing happens, we match recursively
+   (&plist :foo (a b c)) => (&plist :foo (a b c))
+
+You can name the source using the syntax SYMBOL &as PATTERN.
+This syntax works with lists (proper or improper), vectors and
+all types of maps.
+
+  (list &as a b c) (list 1 2 3)
+
+binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
+
+Similarly:
+
+  (bounds &as beg . end) (cons 1 2)
+
+binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
+
+  (items &as first . rest) (list 1 2 3)
+
+binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
+
+  [vect &as _ b c] [1 2 3]
+
+binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as usual).
+
+  (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
+
+binds B to 2 and PLIST to (:a 1 :b 2 :c 3).  Same for &alist and &hash.
+
+This is especially useful when we want to capture the result of a
+computation and destructure at the same time.  Consider the
+form (function-returning-complex-structure) returning a list of
+two vectors with two items each.  We want to capture this entire
+result and pass it to another computation, but at the same time
+we want to get the second item from each vector.  We can achieve
+it with pattern
+
+  (result &as [_ a] [_ b]) (function-returning-complex-structure)
+
+Note: Clojure programmers may know this feature as the \":as
+binding\".  The difference is that we put the &as at the front
+because we need to support improper list binding."
+  (declare (debug ([&or (&rest [&or (sexp form) sexp])
+                        (vector [&rest [sexp form]])]
+                   body))
+           (indent 1))
+  (if (vectorp varlist)
+      `(let* ,(dash--match (aref varlist 0) (aref varlist 1))
+         ,@body)
+    (let* ((varlist (dash--normalize-let-varlist varlist))
+           (inputs (--map-indexed (list (make-symbol (format "input%d" it-index)) (cadr it)) varlist))
+           (new-varlist (--map (list (caar it) (cadr it)) (-zip varlist inputs))))
+      `(let ,inputs
+         (-let* ,new-varlist ,@body)))))
+
+(defmacro -lambda (match-form &rest body)
+  "Return a lambda which destructures its input as MATCH-FORM and executes BODY.
+
+Note that you have to enclose the MATCH-FORM in a pair of parens,
+such that:
+
+  (-lambda (x) body)
+  (-lambda (x y ...) body)
+
+has the usual semantics of `lambda'.  Furthermore, these get
+translated into normal lambda, so there is no performance
+penalty.
+
+See `-let' for the description of destructuring mechanism."
+  (declare (doc-string 2) (indent defun)
+           (debug (&define sexp
+                           [&optional stringp]
+                           [&optional ("interactive" interactive)]
+                           def-body)))
+  (cond
+   ((not (consp match-form))
+    (signal 'wrong-type-argument "match-form must be a list"))
+   ;; no destructuring, so just return regular lambda to make things faster
+   ((-all? 'symbolp match-form)
+    `(lambda ,match-form ,@body))
+   (t
+    (let* ((inputs (--map-indexed (list it (make-symbol (format "input%d" it-index))) match-form)))
+      ;; TODO: because inputs to the lambda are evaluated only once,
+      ;; -let* need not to create the extra bindings to ensure that.
+      ;; We should find a way to optimize that.  Not critical however.
+      `(lambda ,(--map (cadr it) inputs)
+         (-let* ,inputs ,@body))))))
+
+(defmacro -setq (&rest forms)
+  "Bind each MATCH-FORM to the value of its VAL.
+
+MATCH-FORM destructuring is done according to the rules of `-let'.
+
+This macro allows you to bind multiple variables by destructuring
+the value, so for example:
+
+  (-setq (a b) x
+         (&plist :c c) plist)
+
+expands roughly speaking to the following code
+
+  (setq a (car x)
+        b (cadr x)
+        c (plist-get plist :c))
+
+Care is taken to only evaluate each VAL once so that in case of
+multiple assignments it does not cause unexpected side effects.
+
+\(fn [MATCH-FORM VAL]...)"
+  (declare (debug (&rest sexp form))
+           (indent 1))
+  (when (= (mod (length forms) 2) 1)
+    (error "Odd number of arguments"))
+  (let* ((forms-and-sources
+          ;; First get all the necessary mappings with all the
+          ;; intermediate bindings.
+          (-map (lambda (x) (dash--match (car x) (cadr x)))
+                (-partition 2 forms)))
+         ;; To preserve the logic of dynamic scoping we must ensure
+         ;; that we `setq' the variables outside of the `let*' form
+         ;; which holds the destructured intermediate values.  For
+         ;; this we generate for each variable a placeholder which is
+         ;; bound to (lexically) the result of the destructuring.
+         ;; Then outside of the helper `let*' form we bind all the
+         ;; original variables to their respective placeholders.
+         ;; TODO: There is a lot of room for possible optimization,
+         ;; for start playing with `special-variable-p' to eliminate
+         ;; unnecessary re-binding.
+         (variables-to-placeholders
+          (-mapcat
+           (lambda (bindings)
+             (-map
+              (lambda (binding)
+                (let ((var (car binding)))
+                  (list var (make-symbol (concat "--dash-binding-" (symbol-name var) "--")))))
+              (--filter (not (string-prefix-p "--" (symbol-name (car it)))) bindings)))
+           forms-and-sources)))
+    `(let ,(-map 'cadr variables-to-placeholders)
+       (let* ,(-flatten-n 1 forms-and-sources)
+         (setq ,@(-flatten (-map 'reverse variables-to-placeholders))))
+       (setq ,@(-flatten variables-to-placeholders)))))
+
+(defmacro -if-let* (vars-vals then &rest else)
+  "If all VALS evaluate to true, bind them to their corresponding
+VARS and do THEN, otherwise do ELSE. VARS-VALS should be a list
+of (VAR VAL) pairs.
+
+Note: binding is done according to `-let*'.  VALS are evaluated
+sequentially, and evaluation stops after the first nil VAL is
+encountered."
+  (declare (debug ((&rest (sexp form)) form body))
+           (indent 2))
+  (->> vars-vals
+       (--mapcat (dash--match (car it) (cadr it)))
+       (--reduce-r-from
+        (let ((var (car it))
+              (val (cadr it)))
+          `(let ((,var ,val))
+             (if ,var ,acc ,@else)))
+        then)))
+
+(defmacro -if-let (var-val then &rest else)
+  "If VAL evaluates to non-nil, bind it to VAR and do THEN,
+otherwise do ELSE.
+
+Note: binding is done according to `-let'.
+
+\(fn (VAR VAL) THEN &rest ELSE)"
+  (declare (debug ((sexp form) form body))
+           (indent 2))
+  `(-if-let* (,var-val) ,then ,@else))
+
+(defmacro --if-let (val then &rest else)
+  "If VAL evaluates to non-nil, bind it to symbol `it' and do THEN,
+otherwise do ELSE."
+  (declare (debug (form form body))
+           (indent 2))
+  `(-if-let (it ,val) ,then ,@else))
+
+(defmacro -when-let* (vars-vals &rest body)
+  "If all VALS evaluate to true, bind them to their corresponding
+VARS and execute body. VARS-VALS should be a list of (VAR VAL)
+pairs.
+
+Note: binding is done according to `-let*'.  VALS are evaluated
+sequentially, and evaluation stops after the first nil VAL is
+encountered."
+  (declare (debug ((&rest (sexp form)) body))
+           (indent 1))
+  `(-if-let* ,vars-vals (progn ,@body)))
+
+(defmacro -when-let (var-val &rest body)
+  "If VAL evaluates to non-nil, bind it to VAR and execute body.
+
+Note: binding is done according to `-let'.
+
+\(fn (VAR VAL) &rest BODY)"
+  (declare (debug ((sexp form) body))
+           (indent 1))
+  `(-if-let ,var-val (progn ,@body)))
+
+(defmacro --when-let (val &rest body)
+  "If VAL evaluates to non-nil, bind it to symbol `it' and
+execute body."
+  (declare (debug (form body))
+           (indent 1))
+  `(--if-let ,val (progn ,@body)))
+
+(defvar -compare-fn nil
+  "Tests for equality use this function or `equal' if this is nil.
+It should only be set using dynamic scope with a let, like:
+
+  (let ((-compare-fn #\\='=)) (-union numbers1 numbers2 numbers3)")
+
+(defun -distinct (list)
+  "Return a new list with all duplicates removed.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil.
+
+Alias: `-uniq'"
+  ;; Implementation note: The speedup gained from hash table lookup
+  ;; starts to outweigh its overhead for lists of length greater than
+  ;; 32.  See discussion in PR #305.
+  (let* ((len (length list))
+         (lut (and (> len 32)
+                   ;; Check that `-compare-fn' is a valid hash-table
+                   ;; lookup function or `nil'.
+                   (memq -compare-fn '(nil equal eq eql))
+                   (make-hash-table :test (or -compare-fn #'equal)
+                                    :size len))))
+    (if lut
+        (--filter (unless (gethash it lut)
+                    (puthash it t lut))
+                  list)
+      (--each list (unless (-contains? lut it) (!cons it lut)))
+      (nreverse lut))))
+
+(defalias '-uniq '-distinct)
+
+(defun -union (list list2)
+  "Return a new list containing the elements of LIST and elements of LIST2 that are not in LIST.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+  ;; We fall back to iteration implementation if the comparison
+  ;; function isn't one of `eq', `eql' or `equal'.
+  (let* ((result (reverse list))
+         ;; TODO: get rid of this dynamic variable, pass it as an
+         ;; argument instead.
+         (-compare-fn (if (bound-and-true-p -compare-fn)
+                          -compare-fn
+                        'equal)))
+    (if (memq -compare-fn '(eq eql equal))
+        (let ((ht (make-hash-table :test -compare-fn)))
+          (--each list (puthash it t ht))
+          (--each list2 (unless (gethash it ht) (!cons it result))))
+      (--each list2 (unless (-contains? result it) (!cons it result))))
+    (nreverse result)))
+
+(defun -intersection (list list2)
+  "Return a new list containing only the elements that are members of both LIST and LIST2.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+  (--filter (-contains? list2 it) list))
+
+(defun -difference (list list2)
+  "Return a new list with only the members of LIST that are not in LIST2.
+The test for equality is done with `equal',
+or with `-compare-fn' if that's non-nil."
+  (--filter (not (-contains? list2 it)) list))
+
+(defun -powerset (list)
+  "Return the power set of LIST."
+  (if (null list) '(())
+    (let ((last (-powerset (cdr list))))
+      (append (mapcar (lambda (x) (cons (car list) x)) last)
+              last))))
+
+(defun -permutations (list)
+  "Return the permutations of LIST."
+  (if (null list) '(())
+    (apply #'append
+           (mapcar (lambda (x)
+                     (mapcar (lambda (perm) (cons x perm))
+                             (-permutations (remove x list))))
+                   list))))
+
+(defun -inits (list)
+  "Return all prefixes of LIST."
+  (let ((res (list list)))
+    (setq list (reverse list))
+    (while list
+      (push (reverse (!cdr list)) res))
+    res))
+
+(defun -tails (list)
+  "Return all suffixes of LIST"
+  (-reductions-r-from 'cons nil list))
+
+(defun -common-prefix (&rest lists)
+  "Return the longest common prefix of LISTS."
+  (declare (pure t) (side-effect-free t))
+  (--reduce (--take-while (and acc (equal (pop acc) it)) it)
+            lists))
+
+(defun -common-suffix (&rest lists)
+  "Return the longest common suffix of LISTS."
+  (nreverse (apply #'-common-prefix (mapcar #'reverse lists))))
+
+(defun -contains? (list element)
+  "Return non-nil if LIST contains ELEMENT.
+
+The test for equality is done with `equal', or with `-compare-fn'
+if that's non-nil.
+
+Alias: `-contains-p'"
+  (not
+   (null
+    (cond
+     ((null -compare-fn)    (member element list))
+     ((eq -compare-fn 'eq)  (memq element list))
+     ((eq -compare-fn 'eql) (memql element list))
+     (t
+      (let ((lst list))
+        (while (and lst
+                    (not (funcall -compare-fn element (car lst))))
+          (setq lst (cdr lst)))
+        lst))))))
+
+(defalias '-contains-p '-contains?)
+
+(defun -same-items? (list list2)
+  "Return true if LIST and LIST2 has the same items.
+
+The order of the elements in the lists does not matter.
+
+Alias: `-same-items-p'"
+  (let ((length-a (length list))
+        (length-b (length list2)))
+    (and
+     (= length-a length-b)
+     (= length-a (length (-intersection list list2))))))
+
+(defalias '-same-items-p '-same-items?)
+
+(defun -is-prefix? (prefix list)
+  "Return non-nil if PREFIX is prefix of LIST.
+
+Alias: `-is-prefix-p'"
+  (declare (pure t) (side-effect-free t))
+  (--each-while list (equal (car prefix) it)
+    (!cdr prefix))
+  (not prefix))
+
+(defun -is-suffix? (suffix list)
+  "Return non-nil if SUFFIX is suffix of LIST.
+
+Alias: `-is-suffix-p'"
+  (declare (pure t) (side-effect-free t))
+  (-is-prefix? (reverse suffix) (reverse list)))
+
+(defun -is-infix? (infix list)
+  "Return non-nil if INFIX is infix of LIST.
+
+This operation runs in O(n^2) time
+
+Alias: `-is-infix-p'"
+  (declare (pure t) (side-effect-free t))
+  (let (done)
+    (while (and (not done) list)
+      (setq done (-is-prefix? infix list))
+      (!cdr list))
+    done))
+
+(defalias '-is-prefix-p '-is-prefix?)
+(defalias '-is-suffix-p '-is-suffix?)
+(defalias '-is-infix-p '-is-infix?)
+
+(defun -sort (comparator list)
+  "Sort LIST, stably, comparing elements using COMPARATOR.
+Return the sorted list.  LIST is NOT modified by side effects.
+COMPARATOR is called with two elements of LIST, and should return non-nil
+if the first element should sort before the second."
+  (sort (copy-sequence list) comparator))
+
+(defmacro --sort (form list)
+  "Anaphoric form of `-sort'."
+  (declare (debug (form form)))
+  `(-sort (lambda (it other) ,form) ,list))
+
+(defun -list (&rest args)
+  "Return a list with ARGS.
+
+If first item of ARGS is already a list, simply return ARGS.  If
+not, return a list with ARGS as elements."
+  (declare (pure t) (side-effect-free t))
+  (let ((arg (car args)))
+    (if (listp arg) arg args)))
+
+(defun -repeat (n x)
+  "Return a list with X repeated N times.
+Return nil if N is less than 1."
+  (declare (pure t) (side-effect-free t))
+  (let (ret)
+    (--dotimes n (!cons x ret))
+    ret))
+
+(defun -sum (list)
+  "Return the sum of LIST."
+  (declare (pure t) (side-effect-free t))
+  (apply '+ list))
+
+(defun -running-sum (list)
+  "Return a list with running sums of items in LIST.
+
+LIST must be non-empty."
+  (declare (pure t) (side-effect-free t))
+  (unless (consp list)
+    (error "LIST must be non-empty"))
+  (-reductions '+ list))
+
+(defun -product (list)
+  "Return the product of LIST."
+  (declare (pure t) (side-effect-free t))
+  (apply '* list))
+
+(defun -running-product (list)
+  "Return a list with running products of items in LIST.
+
+LIST must be non-empty."
+  (declare (pure t) (side-effect-free t))
+  (unless (consp list)
+    (error "LIST must be non-empty"))
+  (-reductions '* list))
+
+(defun -max (list)
+  "Return the largest value from LIST of numbers or markers."
+  (declare (pure t) (side-effect-free t))
+  (apply 'max list))
+
+(defun -min (list)
+  "Return the smallest value from LIST of numbers or markers."
+  (declare (pure t) (side-effect-free t))
+  (apply 'min list))
+
+(defun -max-by (comparator list)
+  "Take a comparison function COMPARATOR and a LIST and return
+the greatest element of the list by the comparison function.
+
+See also combinator `-on' which can transform the values before
+comparing them."
+  (--reduce (if (funcall comparator it acc) it acc) list))
+
+(defun -min-by (comparator list)
+  "Take a comparison function COMPARATOR and a LIST and return
+the least element of the list by the comparison function.
+
+See also combinator `-on' which can transform the values before
+comparing them."
+  (--reduce (if (funcall comparator it acc) acc it) list))
+
+(defmacro --max-by (form list)
+  "Anaphoric version of `-max-by'.
+
+The items for the comparator form are exposed as \"it\" and \"other\"."
+  (declare (debug (form form)))
+  `(-max-by (lambda (it other) ,form) ,list))
+
+(defmacro --min-by (form list)
+  "Anaphoric version of `-min-by'.
+
+The items for the comparator form are exposed as \"it\" and \"other\"."
+  (declare (debug (form form)))
+  `(-min-by (lambda (it other) ,form) ,list))
+
+(defun -iterate (fun init n)
+  "Return a list of iterated applications of FUN to INIT.
+
+This means a list of form:
+
+  (init (fun init) (fun (fun init)) ...)
+
+N is the length of the returned list."
+  (if (= n 0) nil
+    (let ((r (list init)))
+      (--dotimes (1- n)
+        (push (funcall fun (car r)) r))
+      (nreverse r))))
+
+(defun -fix (fn list)
+  "Compute the (least) fixpoint of FN with initial input LIST.
+
+FN is called at least once, results are compared with `equal'."
+  (let ((re (funcall fn list)))
+    (while (not (equal list re))
+      (setq list re)
+      (setq re (funcall fn re)))
+    re))
+
+(defmacro --fix (form list)
+  "Anaphoric form of `-fix'."
+  `(-fix (lambda (it) ,form) ,list))
+
+(defun -unfold (fun seed)
+  "Build a list from SEED using FUN.
+
+This is \"dual\" operation to `-reduce-r': while -reduce-r
+consumes a list to produce a single value, `-unfold' takes a
+seed value and builds a (potentially infinite!) list.
+
+FUN should return `nil' to stop the generating process, or a
+cons (A . B), where A will be prepended to the result and B is
+the new seed."
+  (let ((last (funcall fun seed)) r)
+    (while last
+      (push (car last) r)
+      (setq last (funcall fun (cdr last))))
+    (nreverse r)))
+
+(defmacro --unfold (form seed)
+  "Anaphoric version of `-unfold'."
+  (declare (debug (form form)))
+  `(-unfold (lambda (it) ,form) ,seed))
+
+(defun -cons-pair? (con)
+  "Return non-nil if CON is true cons pair.
+That is (A . B) where B is not a list.
+
+Alias: `-cons-pair-p'"
+  (declare (pure t) (side-effect-free t))
+  (and (listp con)
+       (not (listp (cdr con)))))
+
+(defalias '-cons-pair-p '-cons-pair?)
+
+(defun -cons-to-list (con)
+  "Convert a cons pair to a list with `car' and `cdr' of the pair respectively."
+  (declare (pure t) (side-effect-free t))
+  (list (car con) (cdr con)))
+
+(defun -value-to-list (val)
+  "Convert a value to a list.
+
+If the value is a cons pair, make a list with two elements, `car'
+and `cdr' of the pair respectively.
+
+If the value is anything else, wrap it in a list."
+  (declare (pure t) (side-effect-free t))
+  (cond
+   ((-cons-pair? val) (-cons-to-list val))
+   (t (list val))))
+
+(defun -tree-mapreduce-from (fn folder init-value tree)
+  "Apply FN to each element of TREE, and make a list of the results.
+If elements of TREE are lists themselves, apply FN recursively to
+elements of these nested lists.
+
+Then reduce the resulting lists using FOLDER and initial value
+INIT-VALUE. See `-reduce-r-from'.
+
+This is the same as calling `-tree-reduce-from' after `-tree-map'
+but is twice as fast as it only traverse the structure once."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) (funcall fn tree))
+   ((listp tree)
+    (-reduce-r-from folder init-value (mapcar (lambda (x) (-tree-mapreduce-from fn folder init-value x)) tree)))
+   (t (funcall fn tree))))
+
+(defmacro --tree-mapreduce-from (form folder init-value tree)
+  "Anaphoric form of `-tree-mapreduce-from'."
+  (declare (debug (form form form form)))
+  `(-tree-mapreduce-from (lambda (it) ,form) (lambda (it acc) ,folder) ,init-value ,tree))
+
+(defun -tree-mapreduce (fn folder tree)
+  "Apply FN to each element of TREE, and make a list of the results.
+If elements of TREE are lists themselves, apply FN recursively to
+elements of these nested lists.
+
+Then reduce the resulting lists using FOLDER and initial value
+INIT-VALUE. See `-reduce-r-from'.
+
+This is the same as calling `-tree-reduce' after `-tree-map'
+but is twice as fast as it only traverse the structure once."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) (funcall fn tree))
+   ((listp tree)
+    (-reduce-r folder (mapcar (lambda (x) (-tree-mapreduce fn folder x)) tree)))
+   (t (funcall fn tree))))
+
+(defmacro --tree-mapreduce (form folder tree)
+  "Anaphoric form of `-tree-mapreduce'."
+  (declare (debug (form form form)))
+  `(-tree-mapreduce (lambda (it) ,form) (lambda (it acc) ,folder) ,tree))
+
+(defun -tree-map (fn tree)
+  "Apply FN to each element of TREE while preserving the tree structure."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) (funcall fn tree))
+   ((listp tree)
+    (mapcar (lambda (x) (-tree-map fn x)) tree))
+   (t (funcall fn tree))))
+
+(defmacro --tree-map (form tree)
+  "Anaphoric form of `-tree-map'."
+  (declare (debug (form form)))
+  `(-tree-map (lambda (it) ,form) ,tree))
+
+(defun -tree-reduce-from (fn init-value tree)
+  "Use FN to reduce elements of list TREE.
+If elements of TREE are lists themselves, apply the reduction recursively.
+
+FN is first applied to INIT-VALUE and first element of the list,
+then on this result and second element from the list etc.
+
+The initial value is ignored on cons pairs as they always contain
+two elements."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) tree)
+   ((listp tree)
+    (-reduce-r-from fn init-value (mapcar (lambda (x) (-tree-reduce-from fn init-value x)) tree)))
+   (t tree)))
+
+(defmacro --tree-reduce-from (form init-value tree)
+  "Anaphoric form of `-tree-reduce-from'."
+  (declare (debug (form form form)))
+  `(-tree-reduce-from (lambda (it acc) ,form) ,init-value ,tree))
+
+(defun -tree-reduce (fn tree)
+  "Use FN to reduce elements of list TREE.
+If elements of TREE are lists themselves, apply the reduction recursively.
+
+FN is first applied to first element of the list and second
+element, then on this result and third element from the list etc.
+
+See `-reduce-r' for how exactly are lists of zero or one element handled."
+  (cond
+   ((not tree) nil)
+   ((-cons-pair? tree) tree)
+   ((listp tree)
+    (-reduce-r fn (mapcar (lambda (x) (-tree-reduce fn x)) tree)))
+   (t tree)))
+
+(defmacro --tree-reduce (form tree)
+  "Anaphoric form of `-tree-reduce'."
+  (declare (debug (form form)))
+  `(-tree-reduce (lambda (it acc) ,form) ,tree))
+
+(defun -tree-map-nodes (pred fun tree)
+  "Call FUN on each node of TREE that satisfies PRED.
+
+If PRED returns nil, continue descending down this node.  If PRED
+returns non-nil, apply FUN to this node and do not descend
+further."
+  (if (funcall pred tree)
+      (funcall fun tree)
+    (if (and (listp tree)
+             (not (-cons-pair? tree)))
+        (-map (lambda (x) (-tree-map-nodes pred fun x)) tree)
+      tree)))
+
+(defmacro --tree-map-nodes (pred form tree)
+  "Anaphoric form of `-tree-map-nodes'."
+  `(-tree-map-nodes (lambda (it) ,pred) (lambda (it) ,form) ,tree))
+
+(defun -tree-seq (branch children tree)
+  "Return a sequence of the nodes in TREE, in depth-first search order.
+
+BRANCH is a predicate of one argument that returns non-nil if the
+passed argument is a branch, that is, a node that can have children.
+
+CHILDREN is a function of one argument that returns the children
+of the passed branch node.
+
+Non-branch nodes are simply copied."
+  (cons tree
+        (when (funcall branch tree)
+          (-mapcat (lambda (x) (-tree-seq branch children x))
+                   (funcall children tree)))))
+
+(defmacro --tree-seq (branch children tree)
+  "Anaphoric form of `-tree-seq'."
+  `(-tree-seq (lambda (it) ,branch) (lambda (it) ,children) ,tree))
+
+(defun -clone (list)
+  "Create a deep copy of LIST.
+The new list has the same elements and structure but all cons are
+replaced with new ones.  This is useful when you need to clone a
+structure such as plist or alist."
+  (declare (pure t) (side-effect-free t))
+  (-tree-map 'identity list))
+
+;;; Font lock
+
+(defvar dash--keywords
+  `(;; TODO: Do not fontify the following automatic variables
+    ;; globally; detect and limit to their local anaphoric scope.
+    (,(concat "\\_<" (regexp-opt '("acc" "it" "it-index" "other")) "\\_>")
+     0 font-lock-variable-name-face)
+    ;; Elisp macro fontification was static prior to Emacs 25.
+    ,@(when (< emacs-major-version 25)
+        (let ((macs '("!cdr"
+                      "!cons"
+                      "-->"
+                      "--all?"
+                      "--annotate"
+                      "--any?"
+                      "--count"
+                      "--dotimes"
+                      "--doto"
+                      "--drop-while"
+                      "--each"
+                      "--each-r"
+                      "--each-r-while"
+                      "--each-while"
+                      "--filter"
+                      "--find-index"
+                      "--find-indices"
+                      "--find-last-index"
+                      "--first"
+                      "--fix"
+                      "--group-by"
+                      "--if-let"
+                      "--iterate"
+                      "--keep"
+                      "--last"
+                      "--map"
+                      "--map-first"
+                      "--map-indexed"
+                      "--map-last"
+                      "--map-when"
+                      "--mapcat"
+                      "--max-by"
+                      "--min-by"
+                      "--none?"
+                      "--only-some?"
+                      "--partition-by"
+                      "--partition-by-header"
+                      "--reduce"
+                      "--reduce-from"
+                      "--reduce-r"
+                      "--reduce-r-from"
+                      "--remove"
+                      "--remove-first"
+                      "--remove-last"
+                      "--separate"
+                      "--some"
+                      "--sort"
+                      "--splice"
+                      "--splice-list"
+                      "--split-when"
+                      "--split-with"
+                      "--take-while"
+                      "--tree-map"
+                      "--tree-map-nodes"
+                      "--tree-mapreduce"
+                      "--tree-mapreduce-from"
+                      "--tree-reduce"
+                      "--tree-reduce-from"
+                      "--tree-seq"
+                      "--unfold"
+                      "--update-at"
+                      "--when-let"
+                      "--zip-with"
+                      "->"
+                      "->>"
+                      "-as->"
+                      "-doto"
+                      "-if-let"
+                      "-if-let*"
+                      "-lambda"
+                      "-let"
+                      "-let*"
+                      "-setq"
+                      "-some-->"
+                      "-some->"
+                      "-some->>"
+                      "-split-on"
+                      "-when-let"
+                      "-when-let*")))
+          `((,(concat "(" (regexp-opt macs 'symbols)) . 1)))))
+  "Font lock keywords for `dash-fontify-mode'.")
+
+(defcustom dash-fontify-mode-lighter nil
+  "Mode line lighter for `dash-fontify-mode'.
+Either a string to display in the mode line when
+`dash-fontify-mode' is on, or nil to display
+nothing (the default)."
+  :package-version '(dash . "2.18.0")
+  :group 'dash
+  :type '(choice (string :tag "Lighter" :value " Dash")
+                 (const :tag "Nothing" nil)))
+
+;;;###autoload
+(define-minor-mode dash-fontify-mode
+  "Toggle fontification of Dash special variables.
+
+Dash-Fontify mode is a buffer-local minor mode intended for Emacs
+Lisp buffers.  Enabling it causes the special variables bound in
+anaphoric Dash macros to be fontified.  These anaphoras include
+`it', `it-index', `acc', and `other'.  In older Emacs versions
+which do not dynamically detect macros, Dash-Fontify mode
+additionally fontifies Dash macro calls.
+
+See also `dash-fontify-mode-lighter' and
+`global-dash-fontify-mode'."
+  :group 'dash :lighter dash-fontify-mode-lighter
+  (if dash-fontify-mode
+      (font-lock-add-keywords nil dash--keywords t)
+    (font-lock-remove-keywords nil dash--keywords))
+  (cond ((fboundp 'font-lock-flush) ;; Added in Emacs 25.
+         (font-lock-flush))
+        ;; `font-lock-fontify-buffer' unconditionally enables
+        ;; `font-lock-mode' and is marked `interactive-only' in later
+        ;; Emacs versions which have `font-lock-flush', so we guard
+        ;; and pacify as needed, respectively.
+        (font-lock-mode
+         (with-no-warnings
+           (font-lock-fontify-buffer)))))
+
+(defun dash--turn-on-fontify-mode ()
+  "Enable `dash-fontify-mode' if in an Emacs Lisp buffer."
+  (when (derived-mode-p #'emacs-lisp-mode)
+    (dash-fontify-mode)))
+
+;;;###autoload
+(define-globalized-minor-mode global-dash-fontify-mode
+  dash-fontify-mode dash--turn-on-fontify-mode
+  :group 'dash)
+
+(defcustom dash-enable-fontlock nil
+  "If non-nil, fontify Dash macro calls and special variables."
+  :group 'dash
+  :set (lambda (sym val)
+         (set-default sym val)
+         (global-dash-fontify-mode (if val 1 0)))
+  :type 'boolean)
+
+(make-obsolete-variable
+ 'dash-enable-fontlock #'global-dash-fontify-mode "2.18.0")
+
+(define-obsolete-function-alias
+  'dash-enable-font-lock #'global-dash-fontify-mode "2.18.0")
+
+(provide 'dash)
+;;; dash.el ends here
diff --git a/elpa/dash-20210101.1712/dash.info b/elpa/dash-20210101.1712/dash.info
new file mode 100644 (file)
index 0000000..ab669ce
--- /dev/null
@@ -0,0 +1,3436 @@
+This is dash.info, produced by makeinfo version 6.5 from dash.texi.
+
+This manual is for â€˜dash.el’ version 2.12.1.
+
+   Copyright Â© 2012-2015 Magnar Sveen
+
+     This program is free software: you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation, either version 3 of the
+     License, or (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see
+     <https://www.gnu.org/licenses/>.
+INFO-DIR-SECTION Emacs
+START-INFO-DIR-ENTRY
+* Dash: (dash.info). A modern list library for GNU Emacs
+END-INFO-DIR-ENTRY
+
+\1f
+File: dash.info,  Node: Top,  Next: Installation,  Up: (dir)
+
+dash
+****
+
+This manual is for â€˜dash.el’ version 2.12.1.
+
+   Copyright Â© 2012-2015 Magnar Sveen
+
+     This program is free software: you can redistribute it and/or
+     modify it under the terms of the GNU General Public License as
+     published by the Free Software Foundation, either version 3 of the
+     License, or (at your option) any later version.
+
+     This program is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+     General Public License for more details.
+
+     You should have received a copy of the GNU General Public License
+     along with this program.  If not, see
+     <https://www.gnu.org/licenses/>.
+
+* Menu:
+
+* Installation::
+* Functions::
+* Development::
+* Index::
+
+— The Detailed Node Listing â€”
+
+Installation
+
+* Using in a package::
+* Fontification of special variables::
+
+Functions
+
+* Maps::
+* Sublist selection::
+* List to list::
+* Reductions::
+* Unfolding::
+* Predicates::
+* Partitioning::
+* Indexing::
+* Set operations::
+* Other list operations::
+* Tree operations::
+* Threading macros::
+* Binding::
+* Side-effects::
+* Destructive operations::
+* Function combinators::
+
+Development
+
+* Contribute::          How to contribute
+* Changes::             List of significant changes by version
+* Contributors::        List of contributors
+
+\1f
+File: dash.info,  Node: Installation,  Next: Functions,  Prev: Top,  Up: Top
+
+1 Installation
+**************
+
+It’s available on GNU ELPA (https://elpa.gnu.org/) and MELPA
+(https://melpa.org/); use â€˜M-x package-install’:
+
+‘M-x package-install <RET> dash’
+     Install the dash library.
+
+‘M-x package-install <RET> dash-functional’
+     Optional, if you want the function combinators.
+
+   Alternatively, you can just dump dash.el or dash-functional.el in
+your load path somewhere.
+
+* Menu:
+
+* Using in a package::
+* Fontification of special variables::
+
+\1f
+File: dash.info,  Node: Using in a package,  Next: Fontification of special variables,  Up: Installation
+
+1.1 Using in a package
+======================
+
+Add this to the big comment block at the top:
+
+     ;; Package-Requires: ((dash "2.12.1"))
+
+To get function combinators:
+
+     ;; Package-Requires: ((dash "2.12.1") (dash-functional "1.2.0") (emacs "24"))
+
+\1f
+File: dash.info,  Node: Fontification of special variables,  Prev: Using in a package,  Up: Installation
+
+1.2 Fontification of special variables
+======================================
+
+Font lock of special Dash variables (‘it’, â€˜acc’, etc.) in Emacs Lisp
+buffers can optionally be enabled with the autoloaded minor mode
+‘dash-fontify-mode’.  In older Emacs versions which do not dynamically
+detect macros, the minor mode also fontifies Dash macro calls.
+
+   To automatically enable the minor mode in all Emacs Lisp buffers,
+just call its autoloaded global counterpart â€˜global-dash-fontify-mode’,
+either interactively or from your â€˜user-init-file’:
+
+     (global-dash-fontify-mode)
+
+\1f
+File: dash.info,  Node: Functions,  Next: Development,  Prev: Installation,  Up: Top
+
+2 Functions
+***********
+
+This chapter contains reference documentation for the dash application
+programming interface (API). All functions and constructs in the library
+are prefixed with a dash (-).
+
+   There are also anaphoric versions of functions where that makes
+sense, prefixed with two dashes instead of one.
+
+   For instance, while â€˜-map’ takes a function to map over the list, one
+can also use the anaphoric form with double dashes - which will then be
+executed with â€˜it’ exposed as the list item.  Here’s an example:
+
+     (-map (lambda (n) (* n n)) '(1 2 3 4)) ;; normal version
+
+     (--map (* it it) '(1 2 3 4)) ;; anaphoric version
+
+Of course, the original can also be written like
+
+     (defun square (n) (* n n))
+
+     (-map 'square '(1 2 3 4))
+
+which demonstrates the usefulness of both versions.
+
+* Menu:
+
+* Maps::
+* Sublist selection::
+* List to list::
+* Reductions::
+* Unfolding::
+* Predicates::
+* Partitioning::
+* Indexing::
+* Set operations::
+* Other list operations::
+* Tree operations::
+* Threading macros::
+* Binding::
+* Side-effects::
+* Destructive operations::
+* Function combinators::
+
+\1f
+File: dash.info,  Node: Maps,  Next: Sublist selection,  Up: Functions
+
+2.1 Maps
+========
+
+Functions in this category take a transforming function, which is then
+applied sequentially to each or selected elements of the input list.
+The results are collected in order and returned as new list.
+
+ -- Function: -map (fn list)
+     Return a new list consisting of the result of applying FN to the
+     items in LIST.
+
+          (-map (lambda (num) (* num num)) '(1 2 3 4))
+              â‡’ '(1 4 9 16)
+          (-map 'square '(1 2 3 4))
+              â‡’ '(1 4 9 16)
+          (--map (* it it) '(1 2 3 4))
+              â‡’ '(1 4 9 16)
+
+ -- Function: -map-when (pred rep list)
+     Return a new list where the elements in LIST that do not match the
+     PRED function are unchanged, and where the elements in LIST that do
+     match the PRED function are mapped through the REP function.
+
+     Alias: â€˜-replace-where’
+
+     See also: â€˜-update-at’ (*note -update-at::)
+
+          (-map-when 'even? 'square '(1 2 3 4))
+              â‡’ '(1 4 3 16)
+          (--map-when (> it 2) (* it it) '(1 2 3 4))
+              â‡’ '(1 2 9 16)
+          (--map-when (= it 2) 17 '(1 2 3 4))
+              â‡’ '(1 17 3 4)
+
+ -- Function: -map-first (pred rep list)
+     Replace first item in LIST satisfying PRED with result of REP
+     called on this item.
+
+     See also: â€˜-map-when’ (*note -map-when::), â€˜-replace-first’ (*note
+     -replace-first::)
+
+          (-map-first 'even? 'square '(1 2 3 4))
+              â‡’ '(1 4 3 4)
+          (--map-first (> it 2) (* it it) '(1 2 3 4))
+              â‡’ '(1 2 9 4)
+          (--map-first (= it 2) 17 '(1 2 3 2))
+              â‡’ '(1 17 3 2)
+
+ -- Function: -map-last (pred rep list)
+     Replace last item in LIST satisfying PRED with result of REP called
+     on this item.
+
+     See also: â€˜-map-when’ (*note -map-when::), â€˜-replace-last’ (*note
+     -replace-last::)
+
+          (-map-last 'even? 'square '(1 2 3 4))
+              â‡’ '(1 2 3 16)
+          (--map-last (> it 2) (* it it) '(1 2 3 4))
+              â‡’ '(1 2 3 16)
+          (--map-last (= it 2) 17 '(1 2 3 2))
+              â‡’ '(1 2 3 17)
+
+ -- Function: -map-indexed (fn list)
+     Return a new list consisting of the result of (FN index item) for
+     each item in LIST.
+
+     In the anaphoric form â€˜--map-indexed’, the index is exposed as
+     symbol â€˜it-index’.
+
+     See also: â€˜-each-indexed’ (*note -each-indexed::).
+
+          (-map-indexed (lambda (index item) (- item index)) '(1 2 3 4))
+              â‡’ '(1 1 1 1)
+          (--map-indexed (- it it-index) '(1 2 3 4))
+              â‡’ '(1 1 1 1)
+
+ -- Function: -annotate (fn list)
+     Return a list of cons cells where each cell is FN applied to each
+     element of LIST paired with the unmodified element of LIST.
+
+          (-annotate '1+ '(1 2 3))
+              â‡’ '((2 . 1) (3 . 2) (4 . 3))
+          (-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world")))
+              â‡’ '((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
+          (--annotate (< 1 it) '(0 1 2 3))
+              â‡’ '((nil . 0) (nil . 1) (t . 2) (t . 3))
+
+ -- Function: -splice (pred fun list)
+     Splice lists generated by FUN in place of elements matching PRED in
+     LIST.
+
+     FUN takes the element matching PRED as input.
+
+     This function can be used as replacement for â€˜,@’ in case you need
+     to splice several lists at marked positions (for example with
+     keywords).
+
+     See also: â€˜-splice-list’ (*note -splice-list::), â€˜-insert-at’
+     (*note -insert-at::)
+
+          (-splice 'even? (lambda (x) (list x x)) '(1 2 3 4))
+              â‡’ '(1 2 2 3 4 4)
+          (--splice 't (list it it) '(1 2 3 4))
+              â‡’ '(1 1 2 2 3 3 4 4)
+          (--splice (equal it :magic) '((list of) (magical) (code)) '((foo) (bar) :magic (baz)))
+              â‡’ '((foo) (bar) (list of) (magical) (code) (baz))
+
+ -- Function: -splice-list (pred new-list list)
+     Splice NEW-LIST in place of elements matching PRED in LIST.
+
+     See also: â€˜-splice’ (*note -splice::), â€˜-insert-at’ (*note
+     -insert-at::)
+
+          (-splice-list 'keywordp '(a b c) '(1 :foo 2))
+              â‡’ '(1 a b c 2)
+          (-splice-list 'keywordp nil '(1 :foo 2))
+              â‡’ '(1 2)
+          (--splice-list (keywordp it) '(a b c) '(1 :foo 2))
+              â‡’ '(1 a b c 2)
+
+ -- Function: -mapcat (fn list)
+     Return the concatenation of the result of mapping FN over LIST.
+     Thus function FN should return a list.
+
+          (-mapcat 'list '(1 2 3))
+              â‡’ '(1 2 3)
+          (-mapcat (lambda (item) (list 0 item)) '(1 2 3))
+              â‡’ '(0 1 0 2 0 3)
+          (--mapcat (list 0 it) '(1 2 3))
+              â‡’ '(0 1 0 2 0 3)
+
+ -- Function: -copy (arg)
+     Create a shallow copy of LIST.
+
+     (fn LIST)
+
+          (-copy '(1 2 3))
+              â‡’ '(1 2 3)
+          (let ((a '(1 2 3))) (eq a (-copy a)))
+              â‡’ nil
+
+\1f
+File: dash.info,  Node: Sublist selection,  Next: List to list,  Prev: Maps,  Up: Functions
+
+2.2 Sublist selection
+=====================
+
+Functions returning a sublist of the original list.
+
+ -- Function: -filter (pred list)
+     Return a new list of the items in LIST for which PRED returns a
+     non-nil value.
+
+     Alias: â€˜-select’
+
+     See also: â€˜-keep’ (*note -keep::), â€˜-remove’ (*note -remove::).
+
+          (-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
+              â‡’ '(2 4)
+          (-filter 'even? '(1 2 3 4))
+              â‡’ '(2 4)
+          (--filter (= 0 (% it 2)) '(1 2 3 4))
+              â‡’ '(2 4)
+
+ -- Function: -remove (pred list)
+     Return a new list of the items in LIST for which PRED returns nil.
+
+     Alias: â€˜-reject’
+
+     See also: â€˜-filter’ (*note -filter::).
+
+          (-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
+              â‡’ '(1 3)
+          (-remove 'even? '(1 2 3 4))
+              â‡’ '(1 3)
+          (--remove (= 0 (% it 2)) '(1 2 3 4))
+              â‡’ '(1 3)
+
+ -- Function: -remove-first (pred list)
+     Return a new list with the first item matching PRED removed.
+
+     Alias: â€˜-reject-first’
+
+     See also: â€˜-remove’ (*note -remove::), â€˜-map-first’ (*note
+     -map-first::)
+
+          (-remove-first 'even? '(1 3 5 4 7 8 10))
+              â‡’ '(1 3 5 7 8 10)
+          (-remove-first 'stringp '(1 2 "first" "second" "third"))
+              â‡’ '(1 2 "second" "third")
+          (--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10))
+              â‡’ '(1 2 3 5 6 7 8 9 10)
+
+ -- Function: -remove-last (pred list)
+     Return a new list with the last item matching PRED removed.
+
+     Alias: â€˜-reject-last’
+
+     See also: â€˜-remove’ (*note -remove::), â€˜-map-last’ (*note
+     -map-last::)
+
+          (-remove-last 'even? '(1 3 5 4 7 8 10 11))
+              â‡’ '(1 3 5 4 7 8 11)
+          (-remove-last 'stringp '(1 2 "last" "second" "third"))
+              â‡’ '(1 2 "last" "second")
+          (--remove-last (> it 3) '(1 2 3 4 5 6 7 8 9 10))
+              â‡’ '(1 2 3 4 5 6 7 8 9)
+
+ -- Function: -remove-item (item list)
+     Remove all occurrences of ITEM from LIST.
+
+     Comparison is done with â€˜equal’.
+
+          (-remove-item 3 '(1 2 3 2 3 4 5 3))
+              â‡’ '(1 2 2 4 5)
+          (-remove-item 'foo '(foo bar baz foo))
+              â‡’ '(bar baz)
+          (-remove-item "bob" '("alice" "bob" "eve" "bob" "dave"))
+              â‡’ '("alice" "eve" "dave")
+
+ -- Function: -non-nil (list)
+     Return all non-nil elements of LIST.
+
+          (-non-nil '(1 nil 2 nil nil 3 4 nil 5 nil))
+              â‡’ '(1 2 3 4 5)
+
+ -- Function: -slice (list from &optional to step)
+     Return copy of LIST, starting from index FROM to index TO.
+
+     FROM or TO may be negative.  These values are then interpreted
+     modulo the length of the list.
+
+     If STEP is a number, only each STEPth item in the resulting section
+     is returned.  Defaults to 1.
+
+          (-slice '(1 2 3 4 5) 1)
+              â‡’ '(2 3 4 5)
+          (-slice '(1 2 3 4 5) 0 3)
+              â‡’ '(1 2 3)
+          (-slice '(1 2 3 4 5 6 7 8 9) 1 -1 2)
+              â‡’ '(2 4 6 8)
+
+ -- Function: -take (n list)
+     Return a copy of the first N items in LIST.  Return a copy of LIST
+     if it contains N items or fewer.  Return nil if N is zero or less.
+
+     See also: â€˜-take-last’ (*note -take-last::)
+
+          (-take 3 '(1 2 3 4 5))
+              â‡’ '(1 2 3)
+          (-take 17 '(1 2 3 4 5))
+              â‡’ '(1 2 3 4 5)
+          (-take 0 '(1 2 3 4 5))
+              â‡’ nil
+
+ -- Function: -take-last (n list)
+     Return a copy of the last N items of LIST in order.  Return a copy
+     of LIST if it contains N items or fewer.  Return nil if N is zero
+     or less.
+
+     See also: â€˜-take’ (*note -take::)
+
+          (-take-last 3 '(1 2 3 4 5))
+              â‡’ '(3 4 5)
+          (-take-last 17 '(1 2 3 4 5))
+              â‡’ '(1 2 3 4 5)
+          (-take-last 1 '(1 2 3 4 5))
+              â‡’ '(5)
+
+ -- Function: -drop (n list)
+     Return a copy of the tail of LIST without the first N items.
+     Return a copy of LIST if N is zero or less.  Return nil if LIST
+     contains N items or fewer.
+
+     See also: â€˜-drop-last’ (*note -drop-last::)
+
+          (-drop 3 '(1 2 3 4 5))
+              â‡’ '(4 5)
+          (-drop 17 '(1 2 3 4 5))
+              â‡’ nil
+          (-drop 0 '(1 2 3 4 5))
+              â‡’ '(1 2 3 4 5)
+
+ -- Function: -drop-last (n list)
+     Return a copy of LIST without its last N items.  Return a copy of
+     LIST if N is zero or less.  Return nil if LIST contains N items or
+     fewer.
+
+     See also: â€˜-drop’ (*note -drop::)
+
+          (-drop-last 3 '(1 2 3 4 5))
+              â‡’ '(1 2)
+          (-drop-last 17 '(1 2 3 4 5))
+              â‡’ nil
+          (-drop-last 0 '(1 2 3 4 5))
+              â‡’ '(1 2 3 4 5)
+
+ -- Function: -take-while (pred list)
+     Take successive items from LIST for which PRED returns non-nil.
+     PRED is a function of one argument.  Return a new list of the
+     successive elements from the start of LIST for which PRED returns
+     non-nil.
+
+     See also: â€˜-drop-while’ (*note -drop-while::)
+
+          (-take-while 'even? '(1 2 3 4))
+              â‡’ nil
+          (-take-while 'even? '(2 4 5 6))
+              â‡’ '(2 4)
+          (--take-while (< it 4) '(1 2 3 4 3 2 1))
+              â‡’ '(1 2 3)
+
+ -- Function: -drop-while (pred list)
+     Drop successive items from LIST for which PRED returns non-nil.
+     PRED is a function of one argument.  Return a copy of the tail of
+     LIST starting from its first element for which PRED returns nil.
+
+     See also: â€˜-take-while’ (*note -take-while::)
+
+          (-drop-while 'even? '(1 2 3 4))
+              â‡’ '(1 2 3 4)
+          (-drop-while 'even? '(2 4 5 6))
+              â‡’ '(5 6)
+          (--drop-while (< it 4) '(1 2 3 4 3 2 1))
+              â‡’ '(4 3 2 1)
+
+ -- Function: -select-by-indices (indices list)
+     Return a list whose elements are elements from LIST selected as
+     â€˜(nth i list)‘ for all i from INDICES.
+
+          (-select-by-indices '(4 10 2 3 6) '("v" "e" "l" "o" "c" "i" "r" "a" "p" "t" "o" "r"))
+              â‡’ '("c" "o" "l" "o" "r")
+          (-select-by-indices '(2 1 0) '("a" "b" "c"))
+              â‡’ '("c" "b" "a")
+          (-select-by-indices '(0 1 2 0 1 3 3 1) '("f" "a" "r" "l"))
+              â‡’ '("f" "a" "r" "f" "a" "l" "l" "a")
+
+ -- Function: -select-columns (columns table)
+     Select COLUMNS from TABLE.
+
+     TABLE is a list of lists where each element represents one row.  It
+     is assumed each row has the same length.
+
+     Each row is transformed such that only the specified COLUMNS are
+     selected.
+
+     See also: â€˜-select-column’ (*note -select-column::),
+     â€˜-select-by-indices’ (*note -select-by-indices::)
+
+          (-select-columns '(0 2) '((1 2 3) (a b c) (:a :b :c)))
+              â‡’ '((1 3) (a c) (:a :c))
+          (-select-columns '(1) '((1 2 3) (a b c) (:a :b :c)))
+              â‡’ '((2) (b) (:b))
+          (-select-columns nil '((1 2 3) (a b c) (:a :b :c)))
+              â‡’ '(nil nil nil)
+
+ -- Function: -select-column (column table)
+     Select COLUMN from TABLE.
+
+     TABLE is a list of lists where each element represents one row.  It
+     is assumed each row has the same length.
+
+     The single selected column is returned as a list.
+
+     See also: â€˜-select-columns’ (*note -select-columns::),
+     â€˜-select-by-indices’ (*note -select-by-indices::)
+
+          (-select-column 1 '((1 2 3) (a b c) (:a :b :c)))
+              â‡’ '(2 b :b)
+
+\1f
+File: dash.info,  Node: List to list,  Next: Reductions,  Prev: Sublist selection,  Up: Functions
+
+2.3 List to list
+================
+
+Functions returning a modified copy of the input list.
+
+ -- Function: -keep (fn list)
+     Return a new list of the non-nil results of applying FN to the
+     items in LIST.
+
+     If you want to select the original items satisfying a predicate use
+     â€˜-filter’ (*note -filter::).
+
+          (-keep 'cdr '((1 2 3) (4 5) (6)))
+              â‡’ '((2 3) (5))
+          (-keep (lambda (num) (when (> num 3) (* 10 num))) '(1 2 3 4 5 6))
+              â‡’ '(40 50 60)
+          (--keep (when (> it 3) (* 10 it)) '(1 2 3 4 5 6))
+              â‡’ '(40 50 60)
+
+ -- Function: -concat (&rest lists)
+     Return a new list with the concatenation of the elements in the
+     supplied LISTS.
+
+          (-concat '(1))
+              â‡’ '(1)
+          (-concat '(1) '(2))
+              â‡’ '(1 2)
+          (-concat '(1) '(2 3) '(4))
+              â‡’ '(1 2 3 4)
+
+ -- Function: -flatten (l)
+     Take a nested list L and return its contents as a single, flat
+     list.
+
+     Note that because â€˜nil’ represents a list of zero elements (an
+     empty list), any mention of nil in L will disappear after
+     flattening.  If you need to preserve nils, consider â€˜-flatten-n’
+     (*note -flatten-n::) or map them to some unique symbol and then map
+     them back.
+
+     Conses of two atoms are considered "terminals", that is, they
+     aren’t flattened further.
+
+     See also: â€˜-flatten-n’ (*note -flatten-n::)
+
+          (-flatten '((1)))
+              â‡’ '(1)
+          (-flatten '((1 (2 3) (((4 (5)))))))
+              â‡’ '(1 2 3 4 5)
+          (-flatten '(1 2 (3 . 4)))
+              â‡’ '(1 2 (3 . 4))
+
+ -- Function: -flatten-n (num list)
+     Flatten NUM levels of a nested LIST.
+
+     See also: â€˜-flatten’ (*note -flatten::)
+
+          (-flatten-n 1 '((1 2) ((3 4) ((5 6)))))
+              â‡’ '(1 2 (3 4) ((5 6)))
+          (-flatten-n 2 '((1 2) ((3 4) ((5 6)))))
+              â‡’ '(1 2 3 4 (5 6))
+          (-flatten-n 3 '((1 2) ((3 4) ((5 6)))))
+              â‡’ '(1 2 3 4 5 6)
+
+ -- Function: -replace (old new list)
+     Replace all OLD items in LIST with NEW.
+
+     Elements are compared using â€˜equal’.
+
+     See also: â€˜-replace-at’ (*note -replace-at::)
+
+          (-replace 1 "1" '(1 2 3 4 3 2 1))
+              â‡’ '("1" 2 3 4 3 2 "1")
+          (-replace "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+              â‡’ '("a" "nice" "bar" "sentence" "about" "bar")
+          (-replace 1 2 nil)
+              â‡’ nil
+
+ -- Function: -replace-first (old new list)
+     Replace the first occurrence of OLD with NEW in LIST.
+
+     Elements are compared using â€˜equal’.
+
+     See also: â€˜-map-first’ (*note -map-first::)
+
+          (-replace-first 1 "1" '(1 2 3 4 3 2 1))
+              â‡’ '("1" 2 3 4 3 2 1)
+          (-replace-first "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+              â‡’ '("a" "nice" "bar" "sentence" "about" "foo")
+          (-replace-first 1 2 nil)
+              â‡’ nil
+
+ -- Function: -replace-last (old new list)
+     Replace the last occurrence of OLD with NEW in LIST.
+
+     Elements are compared using â€˜equal’.
+
+     See also: â€˜-map-last’ (*note -map-last::)
+
+          (-replace-last 1 "1" '(1 2 3 4 3 2 1))
+              â‡’ '(1 2 3 4 3 2 "1")
+          (-replace-last "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
+              â‡’ '("a" "nice" "foo" "sentence" "about" "bar")
+          (-replace-last 1 2 nil)
+              â‡’ nil
+
+ -- Function: -insert-at (n x list)
+     Return a list with X inserted into LIST at position N.
+
+     See also: â€˜-splice’ (*note -splice::), â€˜-splice-list’ (*note
+     -splice-list::)
+
+          (-insert-at 1 'x '(a b c))
+              â‡’ '(a x b c)
+          (-insert-at 12 'x '(a b c))
+              â‡’ '(a b c x)
+
+ -- Function: -replace-at (n x list)
+     Return a list with element at Nth position in LIST replaced with X.
+
+     See also: â€˜-replace’ (*note -replace::)
+
+          (-replace-at 0 9 '(0 1 2 3 4 5))
+              â‡’ '(9 1 2 3 4 5)
+          (-replace-at 1 9 '(0 1 2 3 4 5))
+              â‡’ '(0 9 2 3 4 5)
+          (-replace-at 4 9 '(0 1 2 3 4 5))
+              â‡’ '(0 1 2 3 9 5)
+
+ -- Function: -update-at (n func list)
+     Return a list with element at Nth position in LIST replaced with
+     â€˜(func (nth n list))‘.
+
+     See also: â€˜-map-when’ (*note -map-when::)
+
+          (-update-at 0 (lambda (x) (+ x 9)) '(0 1 2 3 4 5))
+              â‡’ '(9 1 2 3 4 5)
+          (-update-at 1 (lambda (x) (+ x 8)) '(0 1 2 3 4 5))
+              â‡’ '(0 9 2 3 4 5)
+          (--update-at 2 (length it) '("foo" "bar" "baz" "quux"))
+              â‡’ '("foo" "bar" 3 "quux")
+
+ -- Function: -remove-at (n list)
+     Return a list with element at Nth position in LIST removed.
+
+     See also: â€˜-remove-at-indices’ (*note -remove-at-indices::),
+     â€˜-remove’ (*note -remove::)
+
+          (-remove-at 0 '("0" "1" "2" "3" "4" "5"))
+              â‡’ '("1" "2" "3" "4" "5")
+          (-remove-at 1 '("0" "1" "2" "3" "4" "5"))
+              â‡’ '("0" "2" "3" "4" "5")
+          (-remove-at 2 '("0" "1" "2" "3" "4" "5"))
+              â‡’ '("0" "1" "3" "4" "5")
+
+ -- Function: -remove-at-indices (indices list)
+     Return a list whose elements are elements from LIST without
+     elements selected as â€˜(nth i list)‘ for all i from INDICES.
+
+     See also: â€˜-remove-at’ (*note -remove-at::), â€˜-remove’ (*note
+     -remove::)
+
+          (-remove-at-indices '(0) '("0" "1" "2" "3" "4" "5"))
+              â‡’ '("1" "2" "3" "4" "5")
+          (-remove-at-indices '(0 2 4) '("0" "1" "2" "3" "4" "5"))
+              â‡’ '("1" "3" "5")
+          (-remove-at-indices '(0 5) '("0" "1" "2" "3" "4" "5"))
+              â‡’ '("1" "2" "3" "4")
+
+\1f
+File: dash.info,  Node: Reductions,  Next: Unfolding,  Prev: List to list,  Up: Functions
+
+2.4 Reductions
+==============
+
+Functions reducing lists into single value.
+
+ -- Function: -reduce-from (fn initial-value list)
+     Return the result of applying FN to INITIAL-VALUE and the first
+     item in LIST, then applying FN to that result and the 2nd item,
+     etc.  If LIST contains no items, return INITIAL-VALUE and do not
+     call FN.
+
+     In the anaphoric form â€˜--reduce-from’, the accumulated value is
+     exposed as symbol â€˜acc’.
+
+     See also: â€˜-reduce’ (*note -reduce::), â€˜-reduce-r’ (*note
+     -reduce-r::)
+
+          (-reduce-from '- 10 '(1 2 3))
+              â‡’ 4
+          (-reduce-from (lambda (memo item) (format "(%s - %d)" memo item)) "10" '(1 2 3))
+              â‡’ "(((10 - 1) - 2) - 3)"
+          (--reduce-from (concat acc " " it) "START" '("a" "b" "c"))
+              â‡’ "START a b c"
+
+ -- Function: -reduce-r-from (fn initial-value list)
+     Replace conses with FN, nil with INITIAL-VALUE and evaluate the
+     resulting expression.  If LIST is empty, INITIAL-VALUE is returned
+     and FN is not called.
+
+     Note: this function works the same as â€˜-reduce-from’ (*note
+     -reduce-from::) but the operation associates from right instead of
+     from left.
+
+     See also: â€˜-reduce-r’ (*note -reduce-r::), â€˜-reduce’ (*note
+     -reduce::)
+
+          (-reduce-r-from '- 10 '(1 2 3))
+              â‡’ -8
+          (-reduce-r-from (lambda (item memo) (format "(%d - %s)" item memo)) "10" '(1 2 3))
+              â‡’ "(1 - (2 - (3 - 10)))"
+          (--reduce-r-from (concat it " " acc) "END" '("a" "b" "c"))
+              â‡’ "a b c END"
+
+ -- Function: -reduce (fn list)
+     Return the result of applying FN to the first 2 items in LIST, then
+     applying FN to that result and the 3rd item, etc.  If LIST contains
+     no items, return the result of calling FN with no arguments.  If
+     LIST contains a single item, return that item and do not call FN.
+
+     In the anaphoric form â€˜--reduce’, the accumulated value is exposed
+     as symbol â€˜acc’.
+
+     See also: â€˜-reduce-from’ (*note -reduce-from::), â€˜-reduce-r’ (*note
+     -reduce-r::)
+
+          (-reduce '- '(1 2 3 4))
+              â‡’ -8
+          (-reduce 'list '(1 2 3 4))
+              â‡’ '(((1 2) 3) 4)
+          (--reduce (format "%s-%d" acc it) '(1 2 3))
+              â‡’ "1-2-3"
+
+ -- Function: -reduce-r (fn list)
+     Replace conses with FN and evaluate the resulting expression.  The
+     final nil is ignored.  If LIST contains no items, return the result
+     of calling FN with no arguments.  If LIST contains a single item,
+     return that item and do not call FN.
+
+     The first argument of FN is the new item, the second is the
+     accumulated value.
+
+     Note: this function works the same as â€˜-reduce’ (*note -reduce::)
+     but the operation associates from right instead of from left.
+
+     See also: â€˜-reduce-r-from’ (*note -reduce-r-from::), â€˜-reduce’
+     (*note -reduce::)
+
+          (-reduce-r '- '(1 2 3 4))
+              â‡’ -2
+          (-reduce-r (lambda (item memo) (format "%s-%d" memo item)) '(1 2 3))
+              â‡’ "3-2-1"
+          (--reduce-r (format "%s-%d" acc it) '(1 2 3))
+              â‡’ "3-2-1"
+
+ -- Function: -reductions-from (fn init list)
+     Return a list of the intermediate values of the reduction.
+
+     See â€˜-reduce-from’ (*note -reduce-from::) for explanation of the
+     arguments.
+
+     See also: â€˜-reductions’ (*note -reductions::), â€˜-reductions-r’
+     (*note -reductions-r::), â€˜-reduce-r’ (*note -reduce-r::)
+
+          (-reductions-from (lambda (a i) (format "(%s FN %d)" a i)) "INIT" '(1 2 3 4))
+              â‡’ '("INIT" "(INIT FN 1)" "((INIT FN 1) FN 2)" "(((INIT FN 1) FN 2) FN 3)" "((((INIT FN 1) FN 2) FN 3) FN 4)")
+          (-reductions-from 'max 0 '(2 1 4 3))
+              â‡’ '(0 2 2 4 4)
+          (-reductions-from '* 1 '(1 2 3 4))
+              â‡’ '(1 1 2 6 24)
+
+ -- Function: -reductions-r-from (fn init list)
+     Return a list of the intermediate values of the reduction.
+
+     See â€˜-reduce-r-from’ (*note -reduce-r-from::) for explanation of
+     the arguments.
+
+     See also: â€˜-reductions-r’ (*note -reductions-r::), â€˜-reductions’
+     (*note -reductions::), â€˜-reduce’ (*note -reduce::)
+
+          (-reductions-r-from (lambda (i a) (format "(%d FN %s)" i a)) "INIT" '(1 2 3 4))
+              â‡’ '("(1 FN (2 FN (3 FN (4 FN INIT))))" "(2 FN (3 FN (4 FN INIT)))" "(3 FN (4 FN INIT))" "(4 FN INIT)" "INIT")
+          (-reductions-r-from 'max 0 '(2 1 4 3))
+              â‡’ '(4 4 4 3 0)
+          (-reductions-r-from '* 1 '(1 2 3 4))
+              â‡’ '(24 24 12 4 1)
+
+ -- Function: -reductions (fn list)
+     Return a list of the intermediate values of the reduction.
+
+     See â€˜-reduce’ (*note -reduce::) for explanation of the arguments.
+
+     See also: â€˜-reductions-from’ (*note -reductions-from::),
+     â€˜-reductions-r’ (*note -reductions-r::), â€˜-reduce-r’ (*note
+     -reduce-r::)
+
+          (-reductions (lambda (a i) (format "(%s FN %d)" a i)) '(1 2 3 4))
+              â‡’ '(1 "(1 FN 2)" "((1 FN 2) FN 3)" "(((1 FN 2) FN 3) FN 4)")
+          (-reductions '+ '(1 2 3 4))
+              â‡’ '(1 3 6 10)
+          (-reductions '* '(1 2 3 4))
+              â‡’ '(1 2 6 24)
+
+ -- Function: -reductions-r (fn list)
+     Return a list of the intermediate values of the reduction.
+
+     See â€˜-reduce-r’ (*note -reduce-r::) for explanation of the
+     arguments.
+
+     See also: â€˜-reductions-r-from’ (*note -reductions-r-from::),
+     â€˜-reductions’ (*note -reductions::), â€˜-reduce’ (*note -reduce::)
+
+          (-reductions-r (lambda (i a) (format "(%d FN %s)" i a)) '(1 2 3 4))
+              â‡’ '("(1 FN (2 FN (3 FN 4)))" "(2 FN (3 FN 4))" "(3 FN 4)" 4)
+          (-reductions-r '+ '(1 2 3 4))
+              â‡’ '(10 9 7 4)
+          (-reductions-r '* '(1 2 3 4))
+              â‡’ '(24 24 12 4)
+
+ -- Function: -count (pred list)
+     Counts the number of items in LIST where (PRED item) is non-nil.
+
+          (-count 'even? '(1 2 3 4 5))
+              â‡’ 2
+          (--count (< it 4) '(1 2 3 4))
+              â‡’ 3
+
+ -- Function: -sum (list)
+     Return the sum of LIST.
+
+          (-sum '())
+              â‡’ 0
+          (-sum '(1))
+              â‡’ 1
+          (-sum '(1 2 3 4))
+              â‡’ 10
+
+ -- Function: -running-sum (list)
+     Return a list with running sums of items in LIST.
+
+     LIST must be non-empty.
+
+          (-running-sum '(1 2 3 4))
+              â‡’ '(1 3 6 10)
+          (-running-sum '(1))
+              â‡’ '(1)
+          (-running-sum '())
+              â‡’ error
+
+ -- Function: -product (list)
+     Return the product of LIST.
+
+          (-product '())
+              â‡’ 1
+          (-product '(1))
+              â‡’ 1
+          (-product '(1 2 3 4))
+              â‡’ 24
+
+ -- Function: -running-product (list)
+     Return a list with running products of items in LIST.
+
+     LIST must be non-empty.
+
+          (-running-product '(1 2 3 4))
+              â‡’ '(1 2 6 24)
+          (-running-product '(1))
+              â‡’ '(1)
+          (-running-product '())
+              â‡’ error
+
+ -- Function: -inits (list)
+     Return all prefixes of LIST.
+
+          (-inits '(1 2 3 4))
+              â‡’ '(nil (1) (1 2) (1 2 3) (1 2 3 4))
+          (-inits nil)
+              â‡’ '(nil)
+          (-inits '(1))
+              â‡’ '(nil (1))
+
+ -- Function: -tails (list)
+     Return all suffixes of LIST
+
+          (-tails '(1 2 3 4))
+              â‡’ '((1 2 3 4) (2 3 4) (3 4) (4) nil)
+          (-tails nil)
+              â‡’ '(nil)
+          (-tails '(1))
+              â‡’ '((1) nil)
+
+ -- Function: -common-prefix (&rest lists)
+     Return the longest common prefix of LISTS.
+
+          (-common-prefix '(1))
+              â‡’ '(1)
+          (-common-prefix '(1 2) '(3 4) '(1 2))
+              â‡’ nil
+          (-common-prefix '(1 2) '(1 2 3) '(1 2 3 4))
+              â‡’ '(1 2)
+
+ -- Function: -common-suffix (&rest lists)
+     Return the longest common suffix of LISTS.
+
+          (-common-suffix '(1))
+              â‡’ '(1)
+          (-common-suffix '(1 2) '(3 4) '(1 2))
+              â‡’ nil
+          (-common-suffix '(1 2 3 4) '(2 3 4) '(3 4))
+              â‡’ '(3 4)
+
+ -- Function: -min (list)
+     Return the smallest value from LIST of numbers or markers.
+
+          (-min '(0))
+              â‡’ 0
+          (-min '(3 2 1))
+              â‡’ 1
+          (-min '(1 2 3))
+              â‡’ 1
+
+ -- Function: -min-by (comparator list)
+     Take a comparison function COMPARATOR and a LIST and return the
+     least element of the list by the comparison function.
+
+     See also combinator â€˜-on’ (*note -on::) which can transform the
+     values before comparing them.
+
+          (-min-by '> '(4 3 6 1))
+              â‡’ 1
+          (--min-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
+              â‡’ '(1 2 3)
+          (--min-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
+              â‡’ '(2)
+
+ -- Function: -max (list)
+     Return the largest value from LIST of numbers or markers.
+
+          (-max '(0))
+              â‡’ 0
+          (-max '(3 2 1))
+              â‡’ 3
+          (-max '(1 2 3))
+              â‡’ 3
+
+ -- Function: -max-by (comparator list)
+     Take a comparison function COMPARATOR and a LIST and return the
+     greatest element of the list by the comparison function.
+
+     See also combinator â€˜-on’ (*note -on::) which can transform the
+     values before comparing them.
+
+          (-max-by '> '(4 3 6 1))
+              â‡’ 6
+          (--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
+              â‡’ '(3 2)
+          (--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
+              â‡’ '(1 2 3)
+
+\1f
+File: dash.info,  Node: Unfolding,  Next: Predicates,  Prev: Reductions,  Up: Functions
+
+2.5 Unfolding
+=============
+
+Operations dual to reductions, building lists from seed value rather
+than consuming a list to produce a single value.
+
+ -- Function: -iterate (fun init n)
+     Return a list of iterated applications of FUN to INIT.
+
+     This means a list of form:
+
+     (init (fun init) (fun (fun init)) ...)
+
+     N is the length of the returned list.
+
+          (-iterate '1+ 1 10)
+              â‡’ '(1 2 3 4 5 6 7 8 9 10)
+          (-iterate (lambda (x) (+ x x)) 2 5)
+              â‡’ '(2 4 8 16 32)
+          (--iterate (* it it) 2 5)
+              â‡’ '(2 4 16 256 65536)
+
+ -- Function: -unfold (fun seed)
+     Build a list from SEED using FUN.
+
+     This is "dual" operation to â€˜-reduce-r’ (*note -reduce-r::): while
+     -reduce-r consumes a list to produce a single value, â€˜-unfold’
+     (*note -unfold::) takes a seed value and builds a (potentially
+     infinite!)  list.
+
+     FUN should return â€˜nil’ to stop the generating process, or a cons
+     (A .  B), where A will be prepended to the result and B is the new
+     seed.
+
+          (-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10)
+              â‡’ '(10 9 8 7 6 5 4 3 2 1)
+          (--unfold (when it (cons it (cdr it))) '(1 2 3 4))
+              â‡’ '((1 2 3 4) (2 3 4) (3 4) (4))
+          (--unfold (when it (cons it (butlast it))) '(1 2 3 4))
+              â‡’ '((1 2 3 4) (1 2 3) (1 2) (1))
+
+\1f
+File: dash.info,  Node: Predicates,  Next: Partitioning,  Prev: Unfolding,  Up: Functions
+
+2.6 Predicates
+==============
+
+ -- Function: -any? (pred list)
+     Return t if (PRED x) is non-nil for any x in LIST, else nil.
+
+     Alias: â€˜-any-p’, â€˜-some?’, â€˜-some-p’
+
+          (-any? 'even? '(1 2 3))
+              â‡’ t
+          (-any? 'even? '(1 3 5))
+              â‡’ nil
+          (-any? 'null '(1 3 5))
+              â‡’ nil
+
+ -- Function: -all? (pred list)
+     Return t if (PRED x) is non-nil for all x in LIST, else nil.
+
+     Alias: â€˜-all-p’, â€˜-every?’, â€˜-every-p’
+
+          (-all? 'even? '(1 2 3))
+              â‡’ nil
+          (-all? 'even? '(2 4 6))
+              â‡’ t
+          (--all? (= 0 (% it 2)) '(2 4 6))
+              â‡’ t
+
+ -- Function: -none? (pred list)
+     Return t if (PRED x) is nil for all x in LIST, else nil.
+
+     Alias: â€˜-none-p’
+
+          (-none? 'even? '(1 2 3))
+              â‡’ nil
+          (-none? 'even? '(1 3 5))
+              â‡’ t
+          (--none? (= 0 (% it 2)) '(1 2 3))
+              â‡’ nil
+
+ -- Function: -only-some? (pred list)
+     Return â€˜t‘ if at least one item of LIST matches PRED and at least
+     one item of LIST does not match PRED.  Return â€˜nil‘ both if all
+     items match the predicate or if none of the items match the
+     predicate.
+
+     Alias: â€˜-only-some-p’
+
+          (-only-some? 'even? '(1 2 3))
+              â‡’ t
+          (-only-some? 'even? '(1 3 5))
+              â‡’ nil
+          (-only-some? 'even? '(2 4 6))
+              â‡’ nil
+
+ -- Function: -contains? (list element)
+     Return non-nil if LIST contains ELEMENT.
+
+     The test for equality is done with â€˜equal’, or with â€˜-compare-fn’
+     if that’s non-nil.
+
+     Alias: â€˜-contains-p’
+
+          (-contains? '(1 2 3) 1)
+              â‡’ t
+          (-contains? '(1 2 3) 2)
+              â‡’ t
+          (-contains? '(1 2 3) 4)
+              â‡’ nil
+
+ -- Function: -same-items? (list list2)
+     Return true if LIST and LIST2 has the same items.
+
+     The order of the elements in the lists does not matter.
+
+     Alias: â€˜-same-items-p’
+
+          (-same-items? '(1 2 3) '(1 2 3))
+              â‡’ t
+          (-same-items? '(1 2 3) '(3 2 1))
+              â‡’ t
+          (-same-items? '(1 2 3) '(1 2 3 4))
+              â‡’ nil
+
+ -- Function: -is-prefix? (prefix list)
+     Return non-nil if PREFIX is prefix of LIST.
+
+     Alias: â€˜-is-prefix-p’
+
+          (-is-prefix? '(1 2 3) '(1 2 3 4 5))
+              â‡’ t
+          (-is-prefix? '(1 2 3 4 5) '(1 2 3))
+              â‡’ nil
+          (-is-prefix? '(1 3) '(1 2 3 4 5))
+              â‡’ nil
+
+ -- Function: -is-suffix? (suffix list)
+     Return non-nil if SUFFIX is suffix of LIST.
+
+     Alias: â€˜-is-suffix-p’
+
+          (-is-suffix? '(3 4 5) '(1 2 3 4 5))
+              â‡’ t
+          (-is-suffix? '(1 2 3 4 5) '(3 4 5))
+              â‡’ nil
+          (-is-suffix? '(3 5) '(1 2 3 4 5))
+              â‡’ nil
+
+ -- Function: -is-infix? (infix list)
+     Return non-nil if INFIX is infix of LIST.
+
+     This operation runs in O(n^2) time
+
+     Alias: â€˜-is-infix-p’
+
+          (-is-infix? '(1 2 3) '(1 2 3 4 5))
+              â‡’ t
+          (-is-infix? '(2 3 4) '(1 2 3 4 5))
+              â‡’ t
+          (-is-infix? '(3 4 5) '(1 2 3 4 5))
+              â‡’ t
+
+\1f
+File: dash.info,  Node: Partitioning,  Next: Indexing,  Prev: Predicates,  Up: Functions
+
+2.7 Partitioning
+================
+
+Functions partitioning the input list into a list of lists.
+
+ -- Function: -split-at (n list)
+     Return a list of ((-take N LIST) (-drop N LIST)), in no more than
+     one pass through the list.
+
+          (-split-at 3 '(1 2 3 4 5))
+              â‡’ '((1 2 3) (4 5))
+          (-split-at 17 '(1 2 3 4 5))
+              â‡’ '((1 2 3 4 5) nil)
+
+ -- Function: -split-with (pred list)
+     Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)),
+     in no more than one pass through the list.
+
+          (-split-with 'even? '(1 2 3 4))
+              â‡’ '(nil (1 2 3 4))
+          (-split-with 'even? '(2 4 5 6))
+              â‡’ '((2 4) (5 6))
+          (--split-with (< it 4) '(1 2 3 4 3 2 1))
+              â‡’ '((1 2 3) (4 3 2 1))
+
+ -- Macro: -split-on (item list)
+     Split the LIST each time ITEM is found.
+
+     Unlike â€˜-partition-by’ (*note -partition-by::), the ITEM is
+     discarded from the results.  Empty lists are also removed from the
+     result.
+
+     Comparison is done by â€˜equal’.
+
+     See also â€˜-split-when’ (*note -split-when::)
+
+          (-split-on '| '(Nil | Leaf a | Node [Tree a]))
+              â‡’ '((Nil) (Leaf a) (Node [Tree a]))
+          (-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e"))
+              â‡’ '(("a" "b") ("c") ("d" "e"))
+          (-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e"))
+              â‡’ '(("a" "b") ("d" "e"))
+
+ -- Function: -split-when (fn list)
+     Split the LIST on each element where FN returns non-nil.
+
+     Unlike â€˜-partition-by’ (*note -partition-by::), the "matched"
+     element is discarded from the results.  Empty lists are also
+     removed from the result.
+
+     This function can be thought of as a generalization of
+     â€˜split-string’.
+
+          (-split-when 'even? '(1 2 3 4 5 6))
+              â‡’ '((1) (3) (5))
+          (-split-when 'even? '(1 2 3 4 6 8 9))
+              â‡’ '((1) (3) (9))
+          (--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args))
+              â‡’ '((a b) (c d) (args))
+
+ -- Function: -separate (pred list)
+     Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one
+     pass through the list.
+
+          (-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7))
+              â‡’ '((2 4 6) (1 3 5 7))
+          (--separate (< it 5) '(3 7 5 9 3 2 1 4 6))
+              â‡’ '((3 3 2 1 4) (7 5 9 6))
+          (-separate 'cdr '((1 2) (1) (1 2 3) (4)))
+              â‡’ '(((1 2) (1 2 3)) ((1) (4)))
+
+ -- Function: -partition (n list)
+     Return a new list with the items in LIST grouped into N-sized
+     sublists.  If there are not enough items to make the last group
+     N-sized, those items are discarded.
+
+          (-partition 2 '(1 2 3 4 5 6))
+              â‡’ '((1 2) (3 4) (5 6))
+          (-partition 2 '(1 2 3 4 5 6 7))
+              â‡’ '((1 2) (3 4) (5 6))
+          (-partition 3 '(1 2 3 4 5 6 7))
+              â‡’ '((1 2 3) (4 5 6))
+
+ -- Function: -partition-all (n list)
+     Return a new list with the items in LIST grouped into N-sized
+     sublists.  The last group may contain less than N items.
+
+          (-partition-all 2 '(1 2 3 4 5 6))
+              â‡’ '((1 2) (3 4) (5 6))
+          (-partition-all 2 '(1 2 3 4 5 6 7))
+              â‡’ '((1 2) (3 4) (5 6) (7))
+          (-partition-all 3 '(1 2 3 4 5 6 7))
+              â‡’ '((1 2 3) (4 5 6) (7))
+
+ -- Function: -partition-in-steps (n step list)
+     Return a new list with the items in LIST grouped into N-sized
+     sublists at offsets STEP apart.  If there are not enough items to
+     make the last group N-sized, those items are discarded.
+
+          (-partition-in-steps 2 1 '(1 2 3 4))
+              â‡’ '((1 2) (2 3) (3 4))
+          (-partition-in-steps 3 2 '(1 2 3 4))
+              â‡’ '((1 2 3))
+          (-partition-in-steps 3 2 '(1 2 3 4 5))
+              â‡’ '((1 2 3) (3 4 5))
+
+ -- Function: -partition-all-in-steps (n step list)
+     Return a new list with the items in LIST grouped into N-sized
+     sublists at offsets STEP apart.  The last groups may contain less
+     than N items.
+
+          (-partition-all-in-steps 2 1 '(1 2 3 4))
+              â‡’ '((1 2) (2 3) (3 4) (4))
+          (-partition-all-in-steps 3 2 '(1 2 3 4))
+              â‡’ '((1 2 3) (3 4))
+          (-partition-all-in-steps 3 2 '(1 2 3 4 5))
+              â‡’ '((1 2 3) (3 4 5) (5))
+
+ -- Function: -partition-by (fn list)
+     Apply FN to each item in LIST, splitting it each time FN returns a
+     new value.
+
+          (-partition-by 'even? '())
+              â‡’ '()
+          (-partition-by 'even? '(1 1 2 2 2 3 4 6 8))
+              â‡’ '((1 1) (2 2 2) (3) (4 6 8))
+          (--partition-by (< it 3) '(1 2 3 4 3 2 1))
+              â‡’ '((1 2) (3 4 3) (2 1))
+
+ -- Function: -partition-by-header (fn list)
+     Apply FN to the first item in LIST.  That is the header value.
+     Apply FN to each item in LIST, splitting it each time FN returns
+     the header value, but only after seeing at least one other value
+     (the body).
+
+          (--partition-by-header (= it 1) '(1 2 3 1 2 1 2 3 4))
+              â‡’ '((1 2 3) (1 2) (1 2 3 4))
+          (--partition-by-header (> it 0) '(1 2 0 1 0 1 2 3 0))
+              â‡’ '((1 2 0) (1 0) (1 2 3 0))
+          (-partition-by-header 'even? '(2 1 1 1 4 1 3 5 6 6 1))
+              â‡’ '((2 1 1 1) (4 1 3 5) (6 6 1))
+
+ -- Function: -partition-after-pred (pred list)
+     Partition directly after each time PRED is true on an element of
+     LIST.
+
+          (-partition-after-pred #'odd? '())
+              â‡’ '()
+          (-partition-after-pred #'odd? '(1))
+              â‡’ '((1))
+          (-partition-after-pred #'odd? '(0 1))
+              â‡’ '((0 1))
+
+ -- Function: -partition-before-pred (pred list)
+     Partition directly before each time PRED is true on an element of
+     LIST.
+
+          (-partition-before-pred #'odd? '())
+              â‡’ '()
+          (-partition-before-pred #'odd? '(1))
+              â‡’ '((1))
+          (-partition-before-pred #'odd? '(0 1))
+              â‡’ '((0) (1))
+
+ -- Function: -partition-before-item (item list)
+     Partition directly before each time ITEM appears in LIST.
+
+          (-partition-before-item 3 '())
+              â‡’ '()
+          (-partition-before-item 3 '(1))
+              â‡’ '((1))
+          (-partition-before-item 3 '(3))
+              â‡’ '((3))
+
+ -- Function: -partition-after-item (item list)
+     Partition directly after each time ITEM appears in LIST.
+
+          (-partition-after-item 3 '())
+              â‡’ '()
+          (-partition-after-item 3 '(1))
+              â‡’ '((1))
+          (-partition-after-item 3 '(3))
+              â‡’ '((3))
+
+ -- Function: -group-by (fn list)
+     Separate LIST into an alist whose keys are FN applied to the
+     elements of LIST.  Keys are compared by â€˜equal’.
+
+          (-group-by 'even? '())
+              â‡’ '()
+          (-group-by 'even? '(1 1 2 2 2 3 4 6 8))
+              â‡’ '((nil 1 1 3) (t 2 2 2 4 6 8))
+          (--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e"))
+              â‡’ '(("a" "a/b" "a/e") ("c" "c/d"))
+
+\1f
+File: dash.info,  Node: Indexing,  Next: Set operations,  Prev: Partitioning,  Up: Functions
+
+2.8 Indexing
+============
+
+Return indices of elements based on predicates, sort elements by indices
+etc.
+
+ -- Function: -elem-index (elem list)
+     Return the index of the first element in the given LIST which is
+     equal to the query element ELEM, or nil if there is no such
+     element.
+
+          (-elem-index 2 '(6 7 8 2 3 4))
+              â‡’ 3
+          (-elem-index "bar" '("foo" "bar" "baz"))
+              â‡’ 1
+          (-elem-index '(1 2) '((3) (5 6) (1 2) nil))
+              â‡’ 2
+
+ -- Function: -elem-indices (elem list)
+     Return the indices of all elements in LIST equal to the query
+     element ELEM, in ascending order.
+
+          (-elem-indices 2 '(6 7 8 2 3 4 2 1))
+              â‡’ '(3 6)
+          (-elem-indices "bar" '("foo" "bar" "baz"))
+              â‡’ '(1)
+          (-elem-indices '(1 2) '((3) (1 2) (5 6) (1 2) nil))
+              â‡’ '(1 3)
+
+ -- Function: -find-index (pred list)
+     Take a predicate PRED and a LIST and return the index of the first
+     element in the list satisfying the predicate, or nil if there is no
+     such element.
+
+     See also â€˜-first’ (*note -first::).
+
+          (-find-index 'even? '(2 4 1 6 3 3 5 8))
+              â‡’ 0
+          (--find-index (< 5 it) '(2 4 1 6 3 3 5 8))
+              â‡’ 3
+          (-find-index (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
+              â‡’ 1
+
+ -- Function: -find-last-index (pred list)
+     Take a predicate PRED and a LIST and return the index of the last
+     element in the list satisfying the predicate, or nil if there is no
+     such element.
+
+     See also â€˜-last’ (*note -last::).
+
+          (-find-last-index 'even? '(2 4 1 6 3 3 5 8))
+              â‡’ 7
+          (--find-last-index (< 5 it) '(2 7 1 6 3 8 5 2))
+              â‡’ 5
+          (-find-last-index (-partial 'string-lessp "baz") '("q" "foo" "baz"))
+              â‡’ 1
+
+ -- Function: -find-indices (pred list)
+     Return the indices of all elements in LIST satisfying the predicate
+     PRED, in ascending order.
+
+          (-find-indices 'even? '(2 4 1 6 3 3 5 8))
+              â‡’ '(0 1 3 7)
+          (--find-indices (< 5 it) '(2 4 1 6 3 3 5 8))
+              â‡’ '(3 7)
+          (-find-indices (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
+              â‡’ '(1)
+
+ -- Function: -grade-up (comparator list)
+     Grade elements of LIST using COMPARATOR relation, yielding a
+     permutation vector such that applying this permutation to LIST
+     sorts it in ascending order.
+
+          (-grade-up '< '(3 1 4 2 1 3 3))
+              â‡’ '(1 4 3 0 5 6 2)
+          (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-up '< l) l))
+              â‡’ '(1 1 2 3 3 3 4)
+
+ -- Function: -grade-down (comparator list)
+     Grade elements of LIST using COMPARATOR relation, yielding a
+     permutation vector such that applying this permutation to LIST
+     sorts it in descending order.
+
+          (-grade-down '< '(3 1 4 2 1 3 3))
+              â‡’ '(2 0 5 6 3 1 4)
+          (let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-down '< l) l))
+              â‡’ '(4 3 3 3 2 1 1)
+
+\1f
+File: dash.info,  Node: Set operations,  Next: Other list operations,  Prev: Indexing,  Up: Functions
+
+2.9 Set operations
+==================
+
+Operations pretending lists are sets.
+
+ -- Function: -union (list list2)
+     Return a new list containing the elements of LIST and elements of
+     LIST2 that are not in LIST.  The test for equality is done with
+     â€˜equal’, or with â€˜-compare-fn’ if that’s non-nil.
+
+          (-union '(1 2 3) '(3 4 5))
+              â‡’ '(1 2 3 4 5)
+          (-union '(1 2 3 4) '())
+              â‡’ '(1 2 3 4)
+          (-union '(1 1 2 2) '(3 2 1))
+              â‡’ '(1 1 2 2 3)
+
+ -- Function: -difference (list list2)
+     Return a new list with only the members of LIST that are not in
+     LIST2.  The test for equality is done with â€˜equal’, or with
+     â€˜-compare-fn’ if that’s non-nil.
+
+          (-difference '() '())
+              â‡’ '()
+          (-difference '(1 2 3) '(4 5 6))
+              â‡’ '(1 2 3)
+          (-difference '(1 2 3 4) '(3 4 5 6))
+              â‡’ '(1 2)
+
+ -- Function: -intersection (list list2)
+     Return a new list containing only the elements that are members of
+     both LIST and LIST2.  The test for equality is done with â€˜equal’,
+     or with â€˜-compare-fn’ if that’s non-nil.
+
+          (-intersection '() '())
+              â‡’ '()
+          (-intersection '(1 2 3) '(4 5 6))
+              â‡’ '()
+          (-intersection '(1 2 3 4) '(3 4 5 6))
+              â‡’ '(3 4)
+
+ -- Function: -powerset (list)
+     Return the power set of LIST.
+
+          (-powerset '())
+              â‡’ '(nil)
+          (-powerset '(x y z))
+              â‡’ '((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
+
+ -- Function: -permutations (list)
+     Return the permutations of LIST.
+
+          (-permutations '())
+              â‡’ '(nil)
+          (-permutations '(1 2))
+              â‡’ '((1 2) (2 1))
+          (-permutations '(a b c))
+              â‡’ '((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
+
+ -- Function: -distinct (list)
+     Return a new list with all duplicates removed.  The test for
+     equality is done with â€˜equal’, or with â€˜-compare-fn’ if that’s
+     non-nil.
+
+     Alias: â€˜-uniq’
+
+          (-distinct '())
+              â‡’ '()
+          (-distinct '(1 2 2 4))
+              â‡’ '(1 2 4)
+          (-distinct '(t t t))
+              â‡’ '(t)
+
+\1f
+File: dash.info,  Node: Other list operations,  Next: Tree operations,  Prev: Set operations,  Up: Functions
+
+2.10 Other list operations
+==========================
+
+Other list functions not fit to be classified elsewhere.
+
+ -- Function: -rotate (n list)
+     Rotate LIST N places to the right.  With N negative, rotate to the
+     left.  The time complexity is O(n).
+
+          (-rotate 3 '(1 2 3 4 5 6 7))
+              â‡’ '(5 6 7 1 2 3 4)
+          (-rotate -3 '(1 2 3 4 5 6 7))
+              â‡’ '(4 5 6 7 1 2 3)
+          (-rotate 16 '(1 2 3 4 5 6 7))
+              â‡’ '(6 7 1 2 3 4 5)
+
+ -- Function: -repeat (n x)
+     Return a list with X repeated N times.  Return nil if N is less
+     than 1.
+
+          (-repeat 3 :a)
+              â‡’ '(:a :a :a)
+          (-repeat 1 :a)
+              â‡’ '(:a)
+          (-repeat 0 :a)
+              â‡’ nil
+
+ -- Function: -cons* (&rest args)
+     Make a new list from the elements of ARGS.
+
+     The last 2 members of ARGS are used as the final cons of the result
+     so if the final member of ARGS is not a list the result is a dotted
+     list.
+
+          (-cons* 1 2)
+              â‡’ '(1 . 2)
+          (-cons* 1 2 3)
+              â‡’ '(1 2 . 3)
+          (-cons* 1)
+              â‡’ 1
+
+ -- Function: -snoc (list elem &rest elements)
+     Append ELEM to the end of the list.
+
+     This is like â€˜cons’, but operates on the end of list.
+
+     If ELEMENTS is non nil, append these to the list as well.
+
+          (-snoc '(1 2 3) 4)
+              â‡’ '(1 2 3 4)
+          (-snoc '(1 2 3) 4 5 6)
+              â‡’ '(1 2 3 4 5 6)
+          (-snoc '(1 2 3) '(4 5 6))
+              â‡’ '(1 2 3 (4 5 6))
+
+ -- Function: -interpose (sep list)
+     Return a new list of all elements in LIST separated by SEP.
+
+          (-interpose "-" '())
+              â‡’ '()
+          (-interpose "-" '("a"))
+              â‡’ '("a")
+          (-interpose "-" '("a" "b" "c"))
+              â‡’ '("a" "-" "b" "-" "c")
+
+ -- Function: -interleave (&rest lists)
+     Return a new list of the first item in each list, then the second
+     etc.
+
+          (-interleave '(1 2) '("a" "b"))
+              â‡’ '(1 "a" 2 "b")
+          (-interleave '(1 2) '("a" "b") '("A" "B"))
+              â‡’ '(1 "a" "A" 2 "b" "B")
+          (-interleave '(1 2 3) '("a" "b"))
+              â‡’ '(1 "a" 2 "b")
+
+ -- Function: -zip-with (fn list1 list2)
+     Zip the two lists LIST1 and LIST2 using a function FN.  This
+     function is applied pairwise taking as first argument element of
+     LIST1 and as second argument element of LIST2 at corresponding
+     position.
+
+     The anaphoric form â€˜--zip-with’ binds the elements from LIST1 as
+     symbol â€˜it’, and the elements from LIST2 as symbol â€˜other’.
+
+          (-zip-with '+ '(1 2 3) '(4 5 6))
+              â‡’ '(5 7 9)
+          (-zip-with 'cons '(1 2 3) '(4 5 6))
+              â‡’ '((1 . 4) (2 . 5) (3 . 6))
+          (--zip-with (concat it " and " other) '("Batman" "Jekyll") '("Robin" "Hyde"))
+              â‡’ '("Batman and Robin" "Jekyll and Hyde")
+
+ -- Function: -zip (&rest lists)
+     Zip LISTS together.  Group the head of each list, followed by the
+     second elements of each list, and so on.  The lengths of the
+     returned groupings are equal to the length of the shortest input
+     list.
+
+     If two lists are provided as arguments, return the groupings as a
+     list of cons cells.  Otherwise, return the groupings as a list of
+     lists.
+
+     Use â€˜-zip-lists’ (*note -zip-lists::) if you need the return value
+     to always be a list of lists.
+
+     Alias: â€˜-zip-pair’
+
+     See also: â€˜-zip-lists’ (*note -zip-lists::)
+
+          (-zip '(1 2 3) '(4 5 6))
+              â‡’ '((1 . 4) (2 . 5) (3 . 6))
+          (-zip '(1 2 3) '(4 5 6 7))
+              â‡’ '((1 . 4) (2 . 5) (3 . 6))
+          (-zip '(1 2) '(3 4 5) '(6))
+              â‡’ '((1 3 6))
+
+ -- Function: -zip-lists (&rest lists)
+     Zip LISTS together.  Group the head of each list, followed by the
+     second elements of each list, and so on.  The lengths of the
+     returned groupings are equal to the length of the shortest input
+     list.
+
+     The return value is always list of lists, which is a difference
+     from â€˜-zip-pair’ which returns a cons-cell in case two input lists
+     are provided.
+
+     See also: â€˜-zip’ (*note -zip::)
+
+          (-zip-lists '(1 2 3) '(4 5 6))
+              â‡’ '((1 4) (2 5) (3 6))
+          (-zip-lists '(1 2 3) '(4 5 6 7))
+              â‡’ '((1 4) (2 5) (3 6))
+          (-zip-lists '(1 2) '(3 4 5) '(6))
+              â‡’ '((1 3 6))
+
+ -- Function: -zip-fill (fill-value &rest lists)
+     Zip LISTS, with FILL-VALUE padded onto the shorter lists.  The
+     lengths of the returned groupings are equal to the length of the
+     longest input list.
+
+          (-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9))
+              â‡’ '((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
+
+ -- Function: -unzip (lists)
+     Unzip LISTS.
+
+     This works just like â€˜-zip’ (*note -zip::) but takes a list of
+     lists instead of a variable number of arguments, such that
+
+     (-unzip (-zip L1 L2 L3 ...))
+
+     is identity (given that the lists are the same length).
+
+     Note in particular that calling this on a list of two lists will
+     return a list of cons-cells such that the above identity works.
+
+     See also: â€˜-zip’ (*note -zip::)
+
+          (-unzip (-zip '(1 2 3) '(a b c) '("e" "f" "g")))
+              â‡’ '((1 2 3) (a b c) ("e" "f" "g"))
+          (-unzip '((1 2) (3 4) (5 6) (7 8) (9 10)))
+              â‡’ '((1 3 5 7 9) (2 4 6 8 10))
+          (-unzip '((1 2) (3 4)))
+              â‡’ '((1 . 3) (2 . 4))
+
+ -- Function: -cycle (list)
+     Return an infinite circular copy of LIST.  The returned list cycles
+     through the elements of LIST and repeats from the beginning.
+
+          (-take 5 (-cycle '(1 2 3)))
+              â‡’ '(1 2 3 1 2)
+          (-take 7 (-cycle '(1 "and" 3)))
+              â‡’ '(1 "and" 3 1 "and" 3 1)
+          (-zip (-cycle '(1 2 3)) '(1 2))
+              â‡’ '((1 . 1) (2 . 2))
+
+ -- Function: -pad (fill-value &rest lists)
+     Appends FILL-VALUE to the end of each list in LISTS such that they
+     will all have the same length.
+
+          (-pad 0 '())
+              â‡’ '(nil)
+          (-pad 0 '(1))
+              â‡’ '((1))
+          (-pad 0 '(1 2 3) '(4 5))
+              â‡’ '((1 2 3) (4 5 0))
+
+ -- Function: -table (fn &rest lists)
+     Compute outer product of LISTS using function FN.
+
+     The function FN should have the same arity as the number of
+     supplied lists.
+
+     The outer product is computed by applying fn to all possible
+     combinations created by taking one element from each list in order.
+     The dimension of the result is (length lists).
+
+     See also: â€˜-table-flat’ (*note -table-flat::)
+
+          (-table '* '(1 2 3) '(1 2 3))
+              â‡’ '((1 2 3) (2 4 6) (3 6 9))
+          (-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
+              â‡’ '((7 15) (10 22))
+          (apply '-table 'list (-repeat 3 '(1 2)))
+              â‡’ '((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))
+
+ -- Function: -table-flat (fn &rest lists)
+     Compute flat outer product of LISTS using function FN.
+
+     The function FN should have the same arity as the number of
+     supplied lists.
+
+     The outer product is computed by applying fn to all possible
+     combinations created by taking one element from each list in order.
+     The results are flattened, ignoring the tensor structure of the
+     result.  This is equivalent to calling:
+
+     (-flatten-n (1- (length lists)) (apply â€™-table fn lists))
+
+     but the implementation here is much more efficient.
+
+     See also: â€˜-flatten-n’ (*note -flatten-n::), â€˜-table’ (*note
+     -table::)
+
+          (-table-flat 'list '(1 2 3) '(a b c))
+              â‡’ '((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
+          (-table-flat '* '(1 2 3) '(1 2 3))
+              â‡’ '(1 2 3 2 4 6 3 6 9)
+          (apply '-table-flat 'list (-repeat 3 '(1 2)))
+              â‡’ '((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))
+
+ -- Function: -first (pred list)
+     Return the first x in LIST where (PRED x) is non-nil, else nil.
+
+     To get the first item in the list no questions asked, use â€˜car’.
+
+     Alias: â€˜-find’
+
+          (-first 'even? '(1 2 3))
+              â‡’ 2
+          (-first 'even? '(1 3 5))
+              â‡’ nil
+          (-first 'null '(1 3 5))
+              â‡’ nil
+
+ -- Function: -some (pred list)
+     Return (PRED x) for the first LIST item where (PRED x) is non-nil,
+     else nil.
+
+     Alias: â€˜-any’
+
+          (-some 'even? '(1 2 3))
+              â‡’ t
+          (-some 'null '(1 2 3))
+              â‡’ nil
+          (-some 'null '(1 2 nil))
+              â‡’ t
+
+ -- Function: -last (pred list)
+     Return the last x in LIST where (PRED x) is non-nil, else nil.
+
+          (-last 'even? '(1 2 3 4 5 6 3 3 3))
+              â‡’ 6
+          (-last 'even? '(1 3 7 5 9))
+              â‡’ nil
+          (--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
+              â‡’ "short"
+
+ -- Function: -first-item (list)
+     Return the first item of LIST, or nil on an empty list.
+
+     See also: â€˜-second-item’ (*note -second-item::), â€˜-last-item’
+     (*note -last-item::).
+
+     (fn LIST)
+
+          (-first-item '(1 2 3))
+              â‡’ 1
+          (-first-item nil)
+              â‡’ nil
+          (let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
+              â‡’ '(5 2 3)
+
+ -- Function: -second-item (arg1)
+     Return the second item of LIST, or nil if LIST is too short.
+
+     See also: â€˜-third-item’ (*note -third-item::).
+
+     (fn LIST)
+
+          (-second-item '(1 2 3))
+              â‡’ 2
+          (-second-item nil)
+              â‡’ nil
+
+ -- Function: -third-item (arg1)
+     Return the third item of LIST, or nil if LIST is too short.
+
+     See also: â€˜-fourth-item’ (*note -fourth-item::).
+
+     (fn LIST)
+
+          (-third-item '(1 2 3))
+              â‡’ 3
+          (-third-item nil)
+              â‡’ nil
+
+ -- Function: -fourth-item (list)
+     Return the fourth item of LIST, or nil if LIST is too short.
+
+     See also: â€˜-fifth-item’ (*note -fifth-item::).
+
+          (-fourth-item '(1 2 3 4))
+              â‡’ 4
+          (-fourth-item nil)
+              â‡’ nil
+
+ -- Function: -fifth-item (list)
+     Return the fifth item of LIST, or nil if LIST is too short.
+
+     See also: â€˜-last-item’ (*note -last-item::).
+
+          (-fifth-item '(1 2 3 4 5))
+              â‡’ 5
+          (-fifth-item nil)
+              â‡’ nil
+
+ -- Function: -last-item (list)
+     Return the last item of LIST, or nil on an empty list.
+
+          (-last-item '(1 2 3))
+              â‡’ 3
+          (-last-item nil)
+              â‡’ nil
+          (let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
+              â‡’ '(1 2 5)
+
+ -- Function: -butlast (list)
+     Return a list of all items in list except for the last.
+
+          (-butlast '(1 2 3))
+              â‡’ '(1 2)
+          (-butlast '(1 2))
+              â‡’ '(1)
+          (-butlast '(1))
+              â‡’ nil
+
+ -- Function: -sort (comparator list)
+     Sort LIST, stably, comparing elements using COMPARATOR.  Return the
+     sorted list.  LIST is NOT modified by side effects.  COMPARATOR is
+     called with two elements of LIST, and should return non-nil if the
+     first element should sort before the second.
+
+          (-sort '< '(3 1 2))
+              â‡’ '(1 2 3)
+          (-sort '> '(3 1 2))
+              â‡’ '(3 2 1)
+          (--sort (< it other) '(3 1 2))
+              â‡’ '(1 2 3)
+
+ -- Function: -list (&rest args)
+     Return a list with ARGS.
+
+     If first item of ARGS is already a list, simply return ARGS.  If
+     not, return a list with ARGS as elements.
+
+          (-list 1)
+              â‡’ '(1)
+          (-list 1 2 3)
+              â‡’ '(1 2 3)
+          (-list '(1 2 3))
+              â‡’ '(1 2 3)
+
+ -- Function: -fix (fn list)
+     Compute the (least) fixpoint of FN with initial input LIST.
+
+     FN is called at least once, results are compared with â€˜equal’.
+
+          (-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3 4 5 6)))
+              â‡’ '((1) (2) (3) (4) (5) (6))
+          (let ((data '(("starwars" "scifi") ("jedi" "starwars" "warrior")))) (--fix (-uniq (--mapcat (cons it (cdr (assoc it data))) it)) '("jedi" "book")))
+              â‡’ '("jedi" "starwars" "warrior" "scifi" "book")
+
+\1f
+File: dash.info,  Node: Tree operations,  Next: Threading macros,  Prev: Other list operations,  Up: Functions
+
+2.11 Tree operations
+====================
+
+Functions pretending lists are trees.
+
+ -- Function: -tree-seq (branch children tree)
+     Return a sequence of the nodes in TREE, in depth-first search
+     order.
+
+     BRANCH is a predicate of one argument that returns non-nil if the
+     passed argument is a branch, that is, a node that can have
+     children.
+
+     CHILDREN is a function of one argument that returns the children of
+     the passed branch node.
+
+     Non-branch nodes are simply copied.
+
+          (-tree-seq 'listp 'identity '(1 (2 3) 4 (5 (6 7))))
+              â‡’ '((1 (2 3) 4 (5 (6 7))) 1 (2 3) 2 3 4 (5 (6 7)) 5 (6 7) 6 7)
+          (-tree-seq 'listp 'reverse '(1 (2 3) 4 (5 (6 7))))
+              â‡’ '((1 (2 3) 4 (5 (6 7))) (5 (6 7)) (6 7) 7 6 5 4 (2 3) 3 2 1)
+          (--tree-seq (vectorp it) (append it nil) [1 [2 3] 4 [5 [6 7]]])
+              â‡’ '([1 [2 3] 4 [5 [6 7]]] 1 [2 3] 2 3 4 [5 [6 7]] 5 [6 7] 6 7)
+
+ -- Function: -tree-map (fn tree)
+     Apply FN to each element of TREE while preserving the tree
+     structure.
+
+          (-tree-map '1+ '(1 (2 3) (4 (5 6) 7)))
+              â‡’ '(2 (3 4) (5 (6 7) 8))
+          (-tree-map '(lambda (x) (cons x (expt 2 x))) '(1 (2 3) 4))
+              â‡’ '((1 . 2) ((2 . 4) (3 . 8)) (4 . 16))
+          (--tree-map (length it) '("<body>" ("<p>" "text" "</p>") "</body>"))
+              â‡’ '(6 (3 4 4) 7)
+
+ -- Function: -tree-map-nodes (pred fun tree)
+     Call FUN on each node of TREE that satisfies PRED.
+
+     If PRED returns nil, continue descending down this node.  If PRED
+     returns non-nil, apply FUN to this node and do not descend further.
+
+          (-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6 7] 8)))
+              â‡’ '(1 5 4 (5 13 8))
+          (-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar) :baz 8)))
+              â‡’ '(1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
+          (--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode 'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c d))))
+              â‡’ '(with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
+
+ -- Function: -tree-reduce (fn tree)
+     Use FN to reduce elements of list TREE.  If elements of TREE are
+     lists themselves, apply the reduction recursively.
+
+     FN is first applied to first element of the list and second
+     element, then on this result and third element from the list etc.
+
+     See â€˜-reduce-r’ (*note -reduce-r::) for how exactly are lists of
+     zero or one element handled.
+
+          (-tree-reduce '+ '(1 (2 3) (4 5)))
+              â‡’ 15
+          (-tree-reduce 'concat '("strings" (" on" " various") ((" levels"))))
+              â‡’ "strings on various levels"
+          (--tree-reduce (cond ((stringp it) (concat it " " acc)) (t (let ((sn (symbol-name it))) (concat "<" sn ">" acc "</" sn ">")))) '(body (p "some words") (div "more" (b "bold") "words")))
+              â‡’ "<body><p>some words</p> <div>more <b>bold</b> words</div></body>"
+
+ -- Function: -tree-reduce-from (fn init-value tree)
+     Use FN to reduce elements of list TREE.  If elements of TREE are
+     lists themselves, apply the reduction recursively.
+
+     FN is first applied to INIT-VALUE and first element of the list,
+     then on this result and second element from the list etc.
+
+     The initial value is ignored on cons pairs as they always contain
+     two elements.
+
+          (-tree-reduce-from '+ 1 '(1 (1 1) ((1))))
+              â‡’ 8
+          (--tree-reduce-from (-concat acc (list it)) nil '(1 (2 3 (4 5)) (6 7)))
+              â‡’ '((7 6) ((5 4) 3 2) 1)
+
+ -- Function: -tree-mapreduce (fn folder tree)
+     Apply FN to each element of TREE, and make a list of the results.
+     If elements of TREE are lists themselves, apply FN recursively to
+     elements of these nested lists.
+
+     Then reduce the resulting lists using FOLDER and initial value
+     INIT-VALUE.  See â€˜-reduce-r-from’ (*note -reduce-r-from::).
+
+     This is the same as calling â€˜-tree-reduce’ (*note -tree-reduce::)
+     after â€˜-tree-map’ (*note -tree-map::) but is twice as fast as it
+     only traverse the structure once.
+
+          (-tree-mapreduce 'list 'append '(1 (2 (3 4) (5 6)) (7 (8 9))))
+              â‡’ '(1 2 3 4 5 6 7 8 9)
+          (--tree-mapreduce 1 (+ it acc) '(1 (2 (4 9) (2 1)) (7 (4 3))))
+              â‡’ 9
+          (--tree-mapreduce 0 (max acc (1+ it)) '(1 (2 (4 9) (2 1)) (7 (4 3))))
+              â‡’ 3
+
+ -- Function: -tree-mapreduce-from (fn folder init-value tree)
+     Apply FN to each element of TREE, and make a list of the results.
+     If elements of TREE are lists themselves, apply FN recursively to
+     elements of these nested lists.
+
+     Then reduce the resulting lists using FOLDER and initial value
+     INIT-VALUE.  See â€˜-reduce-r-from’ (*note -reduce-r-from::).
+
+     This is the same as calling â€˜-tree-reduce-from’ (*note
+     -tree-reduce-from::) after â€˜-tree-map’ (*note -tree-map::) but is
+     twice as fast as it only traverse the structure once.
+
+          (-tree-mapreduce-from 'identity '* 1 '(1 (2 (3 4) (5 6)) (7 (8 9))))
+              â‡’ 362880
+          (--tree-mapreduce-from (+ it it) (cons it acc) nil '(1 (2 (4 9) (2 1)) (7 (4 3))))
+              â‡’ '(2 (4 (8 18) (4 2)) (14 (8 6)))
+          (concat "{" (--tree-mapreduce-from (cond ((-cons-pair? it) (concat (symbol-name (car it)) " -> " (symbol-name (cdr it)))) (t (concat (symbol-name it) " : {"))) (concat it (unless (or (equal acc "}") (equal (substring it (1- (length it))) "{")) ", ") acc) "}" '((elips-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
+              â‡’ "{elips-mode : {foo : {bar -> booze{, baz -> qux{, c-mode : {foo -> bla, bum -> bam}}"
+
+ -- Function: -clone (list)
+     Create a deep copy of LIST.  The new list has the same elements and
+     structure but all cons are replaced with new ones.  This is useful
+     when you need to clone a structure such as plist or alist.
+
+          (let* ((a '(1 2 3)) (b (-clone a))) (nreverse a) b)
+              â‡’ '(1 2 3)
+
+\1f
+File: dash.info,  Node: Threading macros,  Next: Binding,  Prev: Tree operations,  Up: Functions
+
+2.12 Threading macros
+=====================
+
+ -- Macro: -> (x &optional form &rest more)
+     Thread the expr through the forms.  Insert X as the second item in
+     the first form, making a list of it if it is not a list already.
+     If there are more forms, insert the first form as the second item
+     in second form, etc.
+
+          (-> '(2 3 5))
+              â‡’ '(2 3 5)
+          (-> '(2 3 5) (append '(8 13)))
+              â‡’ '(2 3 5 8 13)
+          (-> '(2 3 5) (append '(8 13)) (-slice 1 -1))
+              â‡’ '(3 5 8)
+
+ -- Macro: ->> (x &optional form &rest more)
+     Thread the expr through the forms.  Insert X as the last item in
+     the first form, making a list of it if it is not a list already.
+     If there are more forms, insert the first form as the last item in
+     second form, etc.
+
+          (->> '(1 2 3) (-map 'square))
+              â‡’ '(1 4 9)
+          (->> '(1 2 3) (-map 'square) (-remove 'even?))
+              â‡’ '(1 9)
+          (->> '(1 2 3) (-map 'square) (-reduce '+))
+              â‡’ 14
+
+ -- Macro: --> (x &rest forms)
+     Starting with the value of X, thread each expression through FORMS.
+
+     Insert X at the position signified by the symbol â€˜it’ in the first
+     form.  If there are more forms, insert the first form at the
+     position signified by â€˜it’ in in second form, etc.
+
+          (--> "def" (concat "abc" it "ghi"))
+              â‡’ "abcdefghi"
+          (--> "def" (concat "abc" it "ghi") (upcase it))
+              â‡’ "ABCDEFGHI"
+          (--> "def" (concat "abc" it "ghi") upcase)
+              â‡’ "ABCDEFGHI"
+
+ -- Macro: -as-> (value variable &rest forms)
+     Starting with VALUE, thread VARIABLE through FORMS.
+
+     In the first form, bind VARIABLE to VALUE.  In the second form,
+     bind VARIABLE to the result of the first form, and so forth.
+
+          (-as-> 3 my-var (1+ my-var) (list my-var) (mapcar (lambda (ele) (* 2 ele)) my-var))
+              â‡’ '(8)
+          (-as-> 3 my-var 1+)
+              â‡’ 4
+          (-as-> 3 my-var)
+              â‡’ 3
+
+ -- Macro: -some-> (x &optional form &rest more)
+     When expr is non-nil, thread it through the first form (via â€˜->’
+     (*note ->::)), and when that result is non-nil, through the next
+     form, etc.
+
+          (-some-> '(2 3 5))
+              â‡’ '(2 3 5)
+          (-some-> 5 square)
+              â‡’ 25
+          (-some-> 5 even? square)
+              â‡’ nil
+
+ -- Macro: -some->> (x &optional form &rest more)
+     When expr is non-nil, thread it through the first form (via â€˜->>’
+     (*note ->>::)), and when that result is non-nil, through the next
+     form, etc.
+
+          (-some->> '(1 2 3) (-map 'square))
+              â‡’ '(1 4 9)
+          (-some->> '(1 3 5) (-last 'even?) (+ 100))
+              â‡’ nil
+          (-some->> '(2 4 6) (-last 'even?) (+ 100))
+              â‡’ 106
+
+ -- Macro: -some--> (x &optional form &rest more)
+     When expr is non-nil, thread it through the first form (via â€˜-->’
+     (*note -->::)), and when that result is non-nil, through the next
+     form, etc.
+
+          (-some--> "def" (concat "abc" it "ghi"))
+              â‡’ "abcdefghi"
+          (-some--> nil (concat "abc" it "ghi"))
+              â‡’ nil
+          (-some--> '(1 3 5) (-filter 'even? it) (append it it) (-map 'square it))
+              â‡’ nil
+
+\1f
+File: dash.info,  Node: Binding,  Next: Side-effects,  Prev: Threading macros,  Up: Functions
+
+2.13 Binding
+============
+
+Convenient versions of â€˜let‘ and â€˜let*‘ constructs combined with flow
+control.
+
+ -- Macro: -when-let (var-val &rest body)
+     If VAL evaluates to non-nil, bind it to VAR and execute body.
+
+     Note: binding is done according to â€˜-let’ (*note -let::).
+
+     (fn (VAR VAL) &rest BODY)
+
+          (-when-let (match-index (string-match "d" "abcd")) (+ match-index 2))
+              â‡’ 5
+          (-when-let ((&plist :foo foo) (list :foo "foo")) foo)
+              â‡’ "foo"
+          (-when-let ((&plist :foo foo) (list :bar "bar")) foo)
+              â‡’ nil
+
+ -- Macro: -when-let* (vars-vals &rest body)
+     If all VALS evaluate to true, bind them to their corresponding VARS
+     and execute body.  VARS-VALS should be a list of (VAR VAL) pairs.
+
+     Note: binding is done according to â€˜-let*’ (*note -let*::).  VALS
+     are evaluated sequentially, and evaluation stops after the first
+     nil VAL is encountered.
+
+          (-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z))
+              â‡’ 15
+          (-when-let* ((x 5) (y nil) (z 7)) (+ x y z))
+              â‡’ nil
+
+ -- Macro: -if-let (var-val then &rest else)
+     If VAL evaluates to non-nil, bind it to VAR and do THEN, otherwise
+     do ELSE.
+
+     Note: binding is done according to â€˜-let’ (*note -let::).
+
+     (fn (VAR VAL) THEN &rest ELSE)
+
+          (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7)
+              â‡’ 7
+          (--if-let (even? 4) it nil)
+              â‡’ t
+
+ -- Macro: -if-let* (vars-vals then &rest else)
+     If all VALS evaluate to true, bind them to their corresponding VARS
+     and do THEN, otherwise do ELSE.  VARS-VALS should be a list of (VAR
+     VAL) pairs.
+
+     Note: binding is done according to â€˜-let*’ (*note -let*::).  VALS
+     are evaluated sequentially, and evaluation stops after the first
+     nil VAL is encountered.
+
+          (-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo")
+              â‡’ 15
+          (-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo")
+              â‡’ "foo"
+          (-if-let* (((_ _ x) '(nil nil 7))) x)
+              â‡’ 7
+
+ -- Macro: -let (varlist &rest body)
+     Bind variables according to VARLIST then eval BODY.
+
+     VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
+     PATTERN is matched against the SOURCE "structurally".  SOURCE is
+     only evaluated once for each PATTERN.  Each PATTERN is matched
+     recursively, and can therefore contain sub-patterns which are
+     matched against corresponding sub-expressions of SOURCE.
+
+     All the SOURCEs are evalled before any symbols are bound (i.e.  "in
+     parallel").
+
+     If VARLIST only contains one (PATTERN SOURCE) element, you can
+     optionally specify it using a vector and discarding the outer-most
+     parens.  Thus
+
+     (-let ((PATTERN SOURCE)) ..)
+
+     becomes
+
+     (-let [PATTERN SOURCE] ..).
+
+     â€˜-let’ (*note -let::) uses a convention of not binding places
+     (symbols) starting with _ whenever it’s possible.  You can use this
+     to skip over entries you don’t care about.  However, this is not
+     *always* possible (as a result of implementation) and these symbols
+     might get bound to undefined values.
+
+     Following is the overview of supported patterns.  Remember that
+     patterns can be matched recursively, so every a, b, aK in the
+     following can be a matching construct and not necessarily a
+     symbol/variable.
+
+     Symbol:
+
+     a - bind the SOURCE to A.  This is just like regular â€˜let’.
+
+     Conses and lists:
+
+     (a) - bind â€˜car’ of cons/list to A
+
+     (a .  b) - bind car of cons to A and â€˜cdr’ to B
+
+     (a b) - bind car of list to A and â€˜cadr’ to B
+
+     (a1 a2 a3 ...)  - bind 0th car of list to A1, 1st to A2, 2nd to A3
+     ...
+
+     (a1 a2 a3 ...  aN .  rest) - as above, but bind the Nth cdr to
+     REST.
+
+     Vectors:
+
+     [a] - bind 0th element of a non-list sequence to A (works with
+     vectors, strings, bit arrays...)
+
+     [a1 a2 a3 ...]  - bind 0th element of non-list sequence to A0, 1st
+     to A1, 2nd to A2, ...  If the PATTERN is shorter than SOURCE, the
+     values at places not in PATTERN are ignored.  If the PATTERN is
+     longer than SOURCE, an â€˜error’ is thrown.
+
+     [a1 a2 a3 ...  &rest rest] - as above, but bind the rest of the
+     sequence to REST.  This is conceptually the same as improper list
+     matching (a1 a2 ...  aN .  rest)
+
+     Key/value stores:
+
+     (&plist key0 a0 ...  keyN aN) - bind value mapped by keyK in the
+     SOURCE plist to aK. If the value is not found, aK is nil.  Uses
+     â€˜plist-get’ to fetch values.
+
+     (&alist key0 a0 ...  keyN aN) - bind value mapped by keyK in the
+     SOURCE alist to aK. If the value is not found, aK is nil.  Uses
+     â€˜assoc’ to fetch values.
+
+     (&hash key0 a0 ...  keyN aN) - bind value mapped by keyK in the
+     SOURCE hash table to aK. If the value is not found, aK is nil.
+     Uses â€˜gethash’ to fetch values.
+
+     Further, special keyword &keys supports "inline" matching of
+     plist-like key-value pairs, similarly to &keys keyword of
+     â€˜cl-defun’.
+
+     (a1 a2 ...  aN &keys key1 b1 ...  keyN bK)
+
+     This binds N values from the list to a1 ...  aN, then interprets
+     the cdr as a plist (see key/value matching above).
+
+     A shorthand notation for kv-destructuring exists which allows the
+     patterns be optionally left out and derived from the key name in
+     the following fashion:
+
+     - a key :foo is converted into â€˜foo’ pattern, - a key â€™bar is
+     converted into â€˜bar’ pattern, - a key "baz" is converted into â€˜baz’
+     pattern.
+
+     That is, the entire value under the key is bound to the derived
+     variable without any further destructuring.
+
+     This is possible only when the form following the key is not a
+     valid pattern (i.e.  not a symbol, a cons cell or a vector).
+     Otherwise the matching proceeds as usual and in case of an invalid
+     spec fails with an error.
+
+     Thus the patterns are normalized as follows:
+
+     ;; derive all the missing patterns (&plist :foo â€™bar "baz") =>
+     (&plist :foo foo â€™bar bar "baz" baz)
+
+     ;; we can specify some but not others (&plist :foo â€™bar
+     explicit-bar) => (&plist :foo foo â€™bar explicit-bar)
+
+     ;; nothing happens, we store :foo in x (&plist :foo x) => (&plist
+     :foo x)
+
+     ;; nothing happens, we match recursively (&plist :foo (a b c)) =>
+     (&plist :foo (a b c))
+
+     You can name the source using the syntax SYMBOL &as PATTERN.  This
+     syntax works with lists (proper or improper), vectors and all types
+     of maps.
+
+     (list &as a b c) (list 1 2 3)
+
+     binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
+
+     Similarly:
+
+     (bounds &as beg .  end) (cons 1 2)
+
+     binds BEG to 1, END to 2 and BOUNDS to (1 .  2).
+
+     (items &as first .  rest) (list 1 2 3)
+
+     binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
+
+     [vect &as _ b c] [1 2 3]
+
+     binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as
+     usual).
+
+     (plist &as &plist :b b) (list :a 1 :b 2 :c 3)
+
+     binds B to 2 and PLIST to (:a 1 :b 2 :c 3).  Same for &alist and
+     &hash.
+
+     This is especially useful when we want to capture the result of a
+     computation and destructure at the same time.  Consider the form
+     (function-returning-complex-structure) returning a list of two
+     vectors with two items each.  We want to capture this entire result
+     and pass it to another computation, but at the same time we want to
+     get the second item from each vector.  We can achieve it with
+     pattern
+
+     (result &as [_ a] [_ b]) (function-returning-complex-structure)
+
+     Note: Clojure programmers may know this feature as the ":as
+     binding".  The difference is that we put the &as at the front
+     because we need to support improper list binding.
+
+          (-let (([a (b c) d] [1 (2 3) 4])) (list a b c d))
+              â‡’ '(1 2 3 4)
+          (-let [(a b c . d) (list 1 2 3 4 5 6)] (list a b c d))
+              â‡’ '(1 2 3 (4 5 6))
+          (-let [(&plist :foo foo :bar bar) (list :baz 3 :foo 1 :qux 4 :bar 2)] (list foo bar))
+              â‡’ '(1 2)
+
+ -- Macro: -let* (varlist &rest body)
+     Bind variables according to VARLIST then eval BODY.
+
+     VARLIST is a list of lists of the form (PATTERN SOURCE).  Each
+     PATTERN is matched against the SOURCE structurally.  SOURCE is only
+     evaluated once for each PATTERN.
+
+     Each SOURCE can refer to the symbols already bound by this VARLIST.
+     This is useful if you want to destructure SOURCE recursively but
+     also want to name the intermediate structures.
+
+     See â€˜-let’ (*note -let::) for the list of all possible patterns.
+
+          (-let* (((a . b) (cons 1 2)) ((c . d) (cons 3 4))) (list a b c d))
+              â‡’ '(1 2 3 4)
+          (-let* (((a . b) (cons 1 (cons 2 3))) ((c . d) b)) (list a b c d))
+              â‡’ '(1 (2 . 3) 2 3)
+          (-let* (((&alist "foo" foo "bar" bar) (list (cons "foo" 1) (cons "bar" (list 'a 'b 'c)))) ((a b c) bar)) (list foo a b c bar))
+              â‡’ '(1 a b c (a b c))
+
+ -- Macro: -lambda (match-form &rest body)
+     Return a lambda which destructures its input as MATCH-FORM and
+     executes BODY.
+
+     Note that you have to enclose the MATCH-FORM in a pair of parens,
+     such that:
+
+     (-lambda (x) body) (-lambda (x y ...)  body)
+
+     has the usual semantics of â€˜lambda’.  Furthermore, these get
+     translated into normal lambda, so there is no performance penalty.
+
+     See â€˜-let’ (*note -let::) for the description of destructuring
+     mechanism.
+
+          (-map (-lambda ((x y)) (+ x y)) '((1 2) (3 4) (5 6)))
+              â‡’ '(3 7 11)
+          (-map (-lambda ([x y]) (+ x y)) '([1 2] [3 4] [5 6]))
+              â‡’ '(3 7 11)
+          (funcall (-lambda ((_ . a) (_ . b)) (-concat a b)) '(1 2 3) '(4 5 6))
+              â‡’ '(2 3 5 6)
+
+ -- Macro: -setq (&rest forms)
+     Bind each MATCH-FORM to the value of its VAL.
+
+     MATCH-FORM destructuring is done according to the rules of â€˜-let’
+     (*note -let::).
+
+     This macro allows you to bind multiple variables by destructuring
+     the value, so for example:
+
+     (-setq (a b) x (&plist :c c) plist)
+
+     expands roughly speaking to the following code
+
+     (setq a (car x) b (cadr x) c (plist-get plist :c))
+
+     Care is taken to only evaluate each VAL once so that in case of
+     multiple assignments it does not cause unexpected side effects.
+
+     (fn [MATCH-FORM VAL]...)
+
+          (progn (-setq a 1) a)
+              â‡’ 1
+          (progn (-setq (a b) (list 1 2)) (list a b))
+              â‡’ '(1 2)
+          (progn (-setq (&plist :c c) (list :c "c")) c)
+              â‡’ "c"
+
+\1f
+File: dash.info,  Node: Side-effects,  Next: Destructive operations,  Prev: Binding,  Up: Functions
+
+2.14 Side-effects
+=================
+
+Functions iterating over lists for side-effect only.
+
+ -- Function: -each (list fn)
+     Call FN with every item in LIST.  Return nil, used for side-effects
+     only.
+
+          (let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))))
+              â‡’ nil
+          (let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
+              â‡’ '(3 2 1)
+          (let (s) (--each '(1 2 3) (setq s (cons it s))) s)
+              â‡’ '(3 2 1)
+
+ -- Function: -each-while (list pred fn)
+     Call FN with every item in LIST while (PRED item) is non-nil.
+     Return nil, used for side-effects only.
+
+          (let (s) (-each-while '(2 4 5 6) 'even? (lambda (item) (push item s))) s)
+              â‡’ '(4 2)
+          (let (s) (--each-while '(1 2 3 4) (< it 3) (push it s)) s)
+              â‡’ '(2 1)
+          (let ((s 0)) (--each-while '(1 3 4 5) (odd? it) (setq s (+ s it))) s)
+              â‡’ 4
+
+ -- Function: -each-indexed (list fn)
+     Call (FN index item) for each item in LIST.
+
+     In the anaphoric form â€˜--each-indexed’, the index is exposed as
+     symbol â€˜it-index’.
+
+     See also: â€˜-map-indexed’ (*note -map-indexed::).
+
+          (let (s) (-each-indexed '(a b c) (lambda (index item) (setq s (cons (list item index) s)))) s)
+              â‡’ '((c 2) (b 1) (a 0))
+          (let (s) (--each-indexed '(a b c) (setq s (cons (list it it-index) s))) s)
+              â‡’ '((c 2) (b 1) (a 0))
+
+ -- Function: -each-r (list fn)
+     Call FN with every item in LIST in reversed order.  Return nil,
+     used for side-effects only.
+
+          (let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))))
+              â‡’ nil
+          (let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
+              â‡’ '(1 2 3)
+          (let (s) (--each-r '(1 2 3) (setq s (cons it s))) s)
+              â‡’ '(1 2 3)
+
+ -- Function: -each-r-while (list pred fn)
+     Call FN with every item in reversed LIST while (PRED item) is
+     non-nil.  Return nil, used for side-effects only.
+
+          (let (s) (-each-r-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
+              â‡’ '(6)
+          (let (s) (--each-r-while '(1 2 3 4) (>= it 3) (!cons it s)) s)
+              â‡’ '(3 4)
+
+ -- Function: -dotimes (num fn)
+     Repeatedly calls FN (presumably for side-effects) passing in
+     integers from 0 through NUM-1.
+
+          (let (s) (-dotimes 3 (lambda (n) (!cons n s))) s)
+              â‡’ '(2 1 0)
+          (let (s) (--dotimes 5 (!cons it s)) s)
+              â‡’ '(4 3 2 1 0)
+
+ -- Macro: -doto (eval-initial-value &rest forms)
+     Eval a form, then insert that form as the 2nd argument to other
+     forms.  The EVAL-INITIAL-VALUE form is evaluated once.  Its result
+     is passed to FORMS, which are then evaluated sequentially.  Returns
+     the target form.
+
+          (-doto '(1 2 3) (!cdr) (!cdr))
+              â‡’ '(3)
+          (-doto '(1 . 2) (setcar 3) (setcdr 4))
+              â‡’ '(3 . 4)
+
+ -- Macro: --doto (eval-initial-value &rest forms)
+     Anaphoric form of â€˜-doto’ (*note -doto::).  Note: â€˜it’ is not
+     required in each form.
+
+          (gethash "key" (--doto (make-hash-table :test 'equal) (puthash "key" "value" it)))
+              â‡’ "value"
+
+\1f
+File: dash.info,  Node: Destructive operations,  Next: Function combinators,  Prev: Side-effects,  Up: Functions
+
+2.15 Destructive operations
+===========================
+
+ -- Macro: !cons (car cdr)
+     Destructive: Set CDR to the cons of CAR and CDR.
+
+          (let (l) (!cons 5 l) l)
+              â‡’ '(5)
+          (let ((l '(3))) (!cons 5 l) l)
+              â‡’ '(5 3)
+
+ -- Macro: !cdr (list)
+     Destructive: Set LIST to the cdr of LIST.
+
+          (let ((l '(3))) (!cdr l) l)
+              â‡’ '()
+          (let ((l '(3 5))) (!cdr l) l)
+              â‡’ '(5)
+
+\1f
+File: dash.info,  Node: Function combinators,  Prev: Destructive operations,  Up: Functions
+
+2.16 Function combinators
+=========================
+
+These combinators require Emacs 24 for its lexical scope.  So they are
+offered in a separate package: â€˜dash-functional‘.
+
+ -- Function: -partial (fn &rest args)
+     Take a function FN and fewer than the normal arguments to FN, and
+     return a fn that takes a variable number of additional ARGS.  When
+     called, the returned function calls FN with ARGS first and then
+     additional args.
+
+          (funcall (-partial '- 5) 3)
+              â‡’ 2
+          (funcall (-partial '+ 5 2) 3)
+              â‡’ 10
+
+ -- Function: -rpartial (fn &rest args)
+     Takes a function FN and fewer than the normal arguments to FN, and
+     returns a fn that takes a variable number of additional ARGS.  When
+     called, the returned function calls FN with the additional args
+     first and then ARGS.
+
+          (funcall (-rpartial '- 5) 8)
+              â‡’ 3
+          (funcall (-rpartial '- 5 2) 10)
+              â‡’ 3
+
+ -- Function: -juxt (&rest fns)
+     Takes a list of functions and returns a fn that is the
+     juxtaposition of those fns.  The returned fn takes a variable
+     number of args, and returns a list containing the result of
+     applying each fn to the args (left-to-right).
+
+          (funcall (-juxt '+ '-) 3 5)
+              â‡’ '(8 -2)
+          (-map (-juxt 'identity 'square) '(1 2 3))
+              â‡’ '((1 1) (2 4) (3 9))
+
+ -- Function: -compose (&rest fns)
+     Takes a list of functions and returns a fn that is the composition
+     of those fns.  The returned fn takes a variable number of
+     arguments, and returns the result of applying each fn to the result
+     of applying the previous fn to the arguments (right-to-left).
+
+          (funcall (-compose 'square '+) 2 3)
+              â‡’ (square (+ 2 3))
+          (funcall (-compose 'identity 'square) 3)
+              â‡’ (square 3)
+          (funcall (-compose 'square 'identity) 3)
+              â‡’ (square 3)
+
+ -- Function: -applify (fn)
+     Changes an n-arity function FN to a 1-arity function that expects a
+     list with n items as arguments
+
+          (-map (-applify '+) '((1 1 1) (1 2 3) (5 5 5)))
+              â‡’ '(3 6 15)
+          (-map (-applify (lambda (a b c) `(,a (,b (,c))))) '((1 1 1) (1 2 3) (5 5 5)))
+              â‡’ '((1 (1 (1))) (1 (2 (3))) (5 (5 (5))))
+          (funcall (-applify '<) '(3 6))
+              â‡’ t
+
+ -- Function: -on (operator transformer)
+     Return a function of two arguments that first applies TRANSFORMER
+     to each of them and then applies OPERATOR on the results (in the
+     same order).
+
+     In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
+
+          (-sort (-on '< 'length) '((1 2 3) (1) (1 2)))
+              â‡’ '((1) (1 2) (1 2 3))
+          (-min-by (-on '> 'length) '((1 2 3) (4) (1 2)))
+              â‡’ '(4)
+          (-min-by (-on 'string-lessp 'number-to-string) '(2 100 22))
+              â‡’ 22
+
+ -- Function: -flip (func)
+     Swap the order of arguments for binary function FUNC.
+
+     In types: (a -> b -> c) -> b -> a -> c
+
+          (funcall (-flip '<) 2 1)
+              â‡’ t
+          (funcall (-flip '-) 3 8)
+              â‡’ 5
+          (-sort (-flip '<) '(4 3 6 1))
+              â‡’ '(6 4 3 1)
+
+ -- Function: -const (c)
+     Return a function that returns C ignoring any additional arguments.
+
+     In types: a -> b -> a
+
+          (funcall (-const 2) 1 3 "foo")
+              â‡’ 2
+          (-map (-const 1) '("a" "b" "c" "d"))
+              â‡’ '(1 1 1 1)
+          (-sum (-map (-const 1) '("a" "b" "c" "d")))
+              â‡’ 4
+
+ -- Macro: -cut (&rest params)
+     Take n-ary function and n arguments and specialize some of them.
+     Arguments denoted by <> will be left unspecialized.
+
+     See SRFI-26 for detailed description.
+
+          (funcall (-cut list 1 <> 3 <> 5) 2 4)
+              â‡’ '(1 2 3 4 5)
+          (-map (-cut funcall <> 5) '(1+ 1- (lambda (x) (/ 1.0 x))))
+              â‡’ '(6 4 0.2)
+          (-map (-cut <> 1 2 3) (list 'list 'vector 'string))
+              â‡’ '((1 2 3) [1 2 3] "\ 1\ 2\ 3")
+
+ -- Function: -not (pred)
+     Take a unary predicate PRED and return a unary predicate that
+     returns t if PRED returns nil and nil if PRED returns non-nil.
+
+          (funcall (-not 'even?) 5)
+              â‡’ t
+          (-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8))
+              â‡’ '(1 2 3 4)
+
+ -- Function: -orfn (&rest preds)
+     Take list of unary predicates PREDS and return a unary predicate
+     with argument x that returns non-nil if at least one of the PREDS
+     returns non-nil on x.
+
+     In types: [a -> Bool] -> a -> Bool
+
+          (-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10))
+              â‡’ '(1 2 3 4 6 8 10)
+          (funcall (-orfn 'stringp 'even?) "foo")
+              â‡’ t
+
+ -- Function: -andfn (&rest preds)
+     Take list of unary predicates PREDS and return a unary predicate
+     with argument x that returns non-nil if all of the PREDS returns
+     non-nil on x.
+
+     In types: [a -> Bool] -> a -> Bool
+
+          (funcall (-andfn (-cut < <> 10) 'even?) 6)
+              â‡’ t
+          (funcall (-andfn (-cut < <> 10) 'even?) 12)
+              â‡’ nil
+          (-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
+              â‡’ '(1 3 5)
+
+ -- Function: -iteratefn (fn n)
+     Return a function FN composed N times with itself.
+
+     FN is a unary function.  If you need to use a function of higher
+     arity, use â€˜-applify’ (*note -applify::) first to turn it into a
+     unary function.
+
+     With n = 0, this acts as identity function.
+
+     In types: (a -> a) -> Int -> a -> a.
+
+     This function satisfies the following law:
+
+     (funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init
+     (1+ n))).
+
+          (funcall (-iteratefn (lambda (x) (* x x)) 3) 2)
+              â‡’ 256
+          (funcall (-iteratefn '1+ 3) 1)
+              â‡’ 4
+          (funcall (-iteratefn 'cdr 3) '(1 2 3 4 5))
+              â‡’ '(4 5)
+
+ -- Function: -fixfn (fn &optional equal-test halt-test)
+     Return a function that computes the (least) fixpoint of FN.
+
+     FN must be a unary function.  The returned lambda takes a single
+     argument, X, the initial value for the fixpoint iteration.  The
+     iteration halts when either of the following conditions is
+     satisfied:
+
+     1.  Iteration converges to the fixpoint, with equality being tested
+     using EQUAL-TEST.  If EQUAL-TEST is not specified, â€˜equal’ is used.
+     For functions over the floating point numbers, it may be necessary
+     to provide an appropriate approximate comparison test.
+
+     2.  HALT-TEST returns a non-nil value.  HALT-TEST defaults to a
+     simple counter that returns t after â€˜-fixfn-max-iterations’, to
+     guard against infinite iteration.  Otherwise, HALT-TEST must be a
+     function that accepts a single argument, the current value of X,
+     and returns non-nil as long as iteration should continue.  In this
+     way, a more sophisticated convergence test may be supplied by the
+     caller.
+
+     The return value of the lambda is either the fixpoint or, if
+     iteration halted before converging, a cons with car â€˜halted’ and
+     cdr the final output from HALT-TEST.
+
+     In types: (a -> a) -> a -> a.
+
+          (funcall (-fixfn 'cos 'approx-equal) 0.7)
+              â‡’ 0.7390851332151607
+          (funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
+              â‡’ 1.8555845286409378
+          (funcall (-fixfn 'sin 'approx-equal) 0.1)
+              â‡’ '(halted . t)
+
+ -- Function: -prodfn (&rest fns)
+     Take a list of n functions and return a function that takes a list
+     of length n, applying i-th function to i-th element of the input
+     list.  Returns a list of length n.
+
+     In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
+
+     This function satisfies the following laws:
+
+     (-compose (-prodfn f g ...)  (-prodfn f’ g’ ...))  = (-prodfn
+     (-compose f f’) (-compose g g’) ...)  (-prodfn f g ...)  = (-juxt
+     (-compose f (-partial â€™nth 0)) (-compose g (-partial â€™nth 1)) ...)
+     (-compose (-prodfn f g ...)  (-juxt f’ g’ ...))  = (-juxt (-compose
+     f f’) (-compose g g’) ...)  (-compose (-partial â€™nth n) (-prod f1
+     f2 ...))  = (-compose fn (-partial â€™nth n))
+
+          (funcall (-prodfn '1+ '1- 'number-to-string) '(1 2 3))
+              â‡’ '(2 1 "3")
+          (-map (-prodfn '1+ '1-) '((1 2) (3 4) (5 6) (7 8)))
+              â‡’ '((2 1) (4 3) (6 5) (8 7))
+          (apply '+ (funcall (-prodfn 'length 'string-to-number) '((1 2 3) "15")))
+              â‡’ 18
+
+\1f
+File: dash.info,  Node: Development,  Next: Index,  Prev: Functions,  Up: Top
+
+3 Development
+*************
+
+The dash repository is hosted on GitHub:
+<https://github.com/magnars/dash.el>
+
+* Menu:
+
+* Contribute::          How to contribute
+* Changes::             List of significant changes by version
+* Contributors::        List of contributors
+
+\1f
+File: dash.info,  Node: Contribute,  Next: Changes,  Up: Development
+
+3.1 Contribute
+==============
+
+Yes, please do.  Pure functions in the list manipulation realm only,
+please.  There’s a suite of tests in dev/examples.el, so remember to add
+tests for your function, or it might get broken later.
+
+   Run the tests with â€˜./run-tests.sh’.  Create the docs with
+‘./create-docs.sh’.  I highly recommend that you install these as a
+pre-commit hook, so that the tests are always running and the docs are
+always in sync:
+
+cp pre-commit.sh .git/hooks/pre-commit
+
+   Oh, and don’t edit â€˜README.md’ directly, it is auto-generated.
+Change â€˜readme-template.md’ or â€˜examples-to-docs.el’ instead.  The same
+goes for the info manual.
+
+\1f
+File: dash.info,  Node: Changes,  Next: Contributors,  Prev: Contribute,  Up: Development
+
+3.2 Changes
+===========
+
+Changes in 2.10:
+
+   â€¢ Add â€˜-let’ destructuring to â€˜-if-let’ and â€˜-when-let’ (Fredrik
+     Bergroth)
+
+Changes in 2.9:
+
+   â€¢ Add â€˜-let’, â€˜-let*’ and â€˜-lambda’ with destructuring
+   â€¢ Add â€˜-tree-seq’ and â€˜-tree-map-nodes’
+   â€¢ Add â€˜-non-nil’
+   â€¢ Add â€˜-fix’
+   â€¢ Add â€˜-fixfn’ (dash-functional 1.2)
+   â€¢ Add â€˜-copy’ (Wilfred Hughes)
+
+Changes in 2.8:
+
+   â€¢ Add â€˜-butlast’
+
+Changes in 2.7:
+
+   â€¢ â€˜-zip’ now supports more than two lists (Steve Lamb)
+   â€¢ Add â€˜-cycle’, â€˜-pad’, â€˜-annotate’, â€˜-zip-fill’ (Steve Lamb)
+   â€¢ Add â€˜-table’, â€˜-table-flat’ (finite cartesian product)
+   â€¢ Add â€˜-flatten-n’
+   â€¢ â€˜-slice’ now supports "step" argument
+   â€¢ Add functional combinators â€˜-iteratefn’, â€˜-prodfn’
+   â€¢ Add â€˜-replace’, â€˜-splice’, â€˜-splice-list’ which generalize
+     â€˜-replace-at’ and â€˜-insert-at’
+   â€¢ Add â€˜-compose’, â€˜-iteratefn’ and â€˜-prodfn’ (dash-functional 1.1)
+
+Changes in 2.6:
+
+   â€¢ Add â€˜-is-prefix-p’, â€˜-is-suffix-p’, â€˜-is-infix-p’ (Matus Goljer)
+   â€¢ Add â€˜-iterate’, â€˜-unfold’ (Matus Goljer)
+   â€¢ Add â€˜-split-on’, â€˜-split-when’ (Matus Goljer)
+   â€¢ Add â€˜-find-last-index’ (Matus Goljer)
+   â€¢ Add â€˜-list’ (Johan Andersson)
+
+Changes in 2.5:
+
+   â€¢ Add â€˜-same-items?’ (Johan Andersson)
+   â€¢ A few bugfixes
+
+Changes in 2.4:
+
+   â€¢ Add â€˜-snoc’ (Matus Goljer)
+   â€¢ Add â€˜-replace-at’, â€˜-update-at’, â€˜-remove-at’, and
+     â€˜-remove-at-indices’ (Matus Goljer)
+
+Changes in 2.3:
+
+   â€¢ Add tree operations (Matus Goljer)
+   â€¢ Make font-lock optional
+
+Changes in 2.2:
+
+   â€¢ Add â€˜-compose’ (Christina Whyte)
+
+Changes in 2.1:
+
+   â€¢ Add indexing operations (Matus Goljer)
+
+Changes in 2.0:
+
+   â€¢ Split out â€˜dash-functional.el’ (Matus Goljer)
+   â€¢ Add â€˜-andfn’, â€˜-orfn’, â€˜-not’, â€˜-cut’, â€˜-const’, â€˜-flip’ and â€˜-on’.
+     (Matus Goljer)
+   â€¢ Fix â€˜-min’, â€˜-max’, â€˜-min-by’ and â€˜-max-by’ (Matus Goljer)
+
+Changes in 1.8:
+
+   â€¢ Add â€˜-first-item’ and â€˜-last-item’ (Wilfred Hughes)
+
+Changes in 1.7:
+
+   â€¢ Add â€˜-rotate’ (Matus Goljer)
+
+Changes in 1.6:
+
+   â€¢ Add â€˜-min’, â€˜-max’, â€˜-min-by’ and â€˜-max-by’ (Johan Andersson)
+
+Changes in 1.5:
+
+   â€¢ Add â€˜-sum’ and â€˜-product’ (Johan Andersson)
+
+Changes in 1.4:
+
+   â€¢ Add â€˜-sort’
+   â€¢ Add â€˜-reduce-r’ (Matus Goljer)
+   â€¢ Add â€˜-reduce-r-from’ (Matus Goljer)
+
+Changes in 1.3:
+
+   â€¢ Add â€˜-partition-in-steps’
+   â€¢ Add â€˜-partition-all-in-steps’
+
+Changes in 1.2:
+
+   â€¢ Add â€˜-last’ (Matus Goljer)
+   â€¢ Add â€˜-insert-at’ (Emanuel Evans)
+   â€¢ Add â€˜-when-let’ and â€˜-if-let’ (Emanuel Evans)
+   â€¢ Add â€˜-when-let*’ and â€˜-if-let*’ (Emanuel Evans)
+   â€¢ Some bugfixes
+
+\1f
+File: dash.info,  Node: Contributors,  Prev: Changes,  Up: Development
+
+3.3 Contributors
+================
+
+   â€¢ Matus Goljer (https://github.com/Fuco1) contributed lots of
+     features and functions.
+   â€¢ Takafumi Arakaki (https://github.com/tkf) contributed â€˜-group-by’.
+   â€¢ tali713 (https://github.com/tali713) is the author of â€˜-applify’.
+   â€¢ Víctor M. Valenzuela (https://github.com/vemv) contributed
+     â€˜-repeat’.
+   â€¢ Nic Ferrier (https://github.com/nicferrier) contributed â€˜-cons*’.
+   â€¢ Wilfred Hughes (https://github.com/Wilfred) contributed â€˜-slice’,
+     â€˜-first-item’ and â€˜-last-item’.
+   â€¢ Emanuel Evans (https://github.com/shosti) contributed â€˜-if-let’,
+     â€˜-when-let’ and â€˜-insert-at’.
+   â€¢ Johan Andersson (https://github.com/rejeep) contributed â€˜-sum’,
+     â€˜-product’ and â€˜-same-items?’
+   â€¢ Christina Whyte (https://github.com/kurisuwhyte) contributed
+     â€˜-compose’
+   â€¢ Steve Lamb (https://github.com/steventlamb) contributed â€˜-cycle’,
+     â€˜-pad’, â€˜-annotate’, â€˜-zip-fill’ and an n-ary version of â€˜-zip’.
+   â€¢ Fredrik Bergroth (https://github.com/fbergroth) made the â€˜-if-let’
+     family use â€˜-let’ destructuring and improved script for generating
+     documentation.
+   â€¢ Mark Oteiza (https://github.com/holomorph) contributed the script
+     to create an info manual.
+   â€¢ Vasilij Schneidermann (https://github.com/wasamasa) contributed
+     â€˜-some’.
+   â€¢ William West (https://github.com/occidens) made â€˜-fixfn’ more
+     robust at handling floats.
+
+   Thanks!
+
+\1f
+File: dash.info,  Node: Index,  Prev: Development,  Up: Top
+
+Index
+*****
+
+\0\b[index\0\b]
+* Menu:
+
+* !cdr:                                  Destructive operations.
+                                                              (line  14)
+* !cons:                                 Destructive operations.
+                                                              (line   6)
+* -->:                                   Threading macros.    (line  32)
+* --doto:                                Side-effects.        (line  83)
+* ->:                                    Threading macros.    (line   6)
+* ->>:                                   Threading macros.    (line  19)
+* -all?:                                 Predicates.          (line  18)
+* -andfn:                                Function combinators.
+                                                              (line 138)
+* -annotate:                             Maps.                (line  79)
+* -any?:                                 Predicates.          (line   6)
+* -applify:                              Function combinators.
+                                                              (line  55)
+* -as->:                                 Threading macros.    (line  46)
+* -butlast:                              Other list operations.
+                                                              (line 340)
+* -clone:                                Tree operations.     (line 122)
+* -common-prefix:                        Reductions.          (line 223)
+* -common-suffix:                        Reductions.          (line 233)
+* -compose:                              Function combinators.
+                                                              (line  42)
+* -concat:                               List to list.        (line  22)
+* -cons*:                                Other list operations.
+                                                              (line  30)
+* -const:                                Function combinators.
+                                                              (line  92)
+* -contains?:                            Predicates.          (line  57)
+* -copy:                                 Maps.                (line 134)
+* -count:                                Reductions.          (line 151)
+* -cut:                                  Function combinators.
+                                                              (line 104)
+* -cycle:                                Other list operations.
+                                                              (line 168)
+* -difference:                           Set operations.      (line  20)
+* -distinct:                             Set operations.      (line  62)
+* -dotimes:                              Side-effects.        (line  63)
+* -doto:                                 Side-effects.        (line  72)
+* -drop:                                 Sublist selection.   (line 128)
+* -drop-last:                            Sublist selection.   (line 142)
+* -drop-while:                           Sublist selection.   (line 171)
+* -each:                                 Side-effects.        (line   8)
+* -each-indexed:                         Side-effects.        (line  30)
+* -each-r:                               Side-effects.        (line  43)
+* -each-r-while:                         Side-effects.        (line  54)
+* -each-while:                           Side-effects.        (line  19)
+* -elem-index:                           Indexing.            (line   9)
+* -elem-indices:                         Indexing.            (line  21)
+* -fifth-item:                           Other list operations.
+                                                              (line 320)
+* -filter:                               Sublist selection.   (line   8)
+* -find-index:                           Indexing.            (line  32)
+* -find-indices:                         Indexing.            (line  60)
+* -find-last-index:                      Indexing.            (line  46)
+* -first:                                Other list operations.
+                                                              (line 234)
+* -first-item:                           Other list operations.
+                                                              (line 271)
+* -fix:                                  Other list operations.
+                                                              (line 376)
+* -fixfn:                                Function combinators.
+                                                              (line 175)
+* -flatten:                              List to list.        (line  33)
+* -flatten-n:                            List to list.        (line  55)
+* -flip:                                 Function combinators.
+                                                              (line  80)
+* -fourth-item:                          Other list operations.
+                                                              (line 310)
+* -grade-down:                           Indexing.            (line  81)
+* -grade-up:                             Indexing.            (line  71)
+* -group-by:                             Partitioning.        (line 187)
+* -if-let:                               Binding.             (line  36)
+* -if-let*:                              Binding.             (line  49)
+* -inits:                                Reductions.          (line 203)
+* -insert-at:                            List to list.        (line 109)
+* -interleave:                           Other list operations.
+                                                              (line  68)
+* -interpose:                            Other list operations.
+                                                              (line  58)
+* -intersection:                         Set operations.      (line  32)
+* -is-infix?:                            Predicates.          (line 110)
+* -is-prefix?:                           Predicates.          (line  86)
+* -is-suffix?:                           Predicates.          (line  98)
+* -iterate:                              Unfolding.           (line   9)
+* -iteratefn:                            Function combinators.
+                                                              (line 152)
+* -juxt:                                 Function combinators.
+                                                              (line  31)
+* -keep:                                 List to list.        (line   8)
+* -lambda:                               Binding.             (line 252)
+* -last:                                 Other list operations.
+                                                              (line 261)
+* -last-item:                            Other list operations.
+                                                              (line 330)
+* -let:                                  Binding.             (line  65)
+* -let*:                                 Binding.             (line 232)
+* -list:                                 Other list operations.
+                                                              (line 363)
+* -map:                                  Maps.                (line  10)
+* -map-first:                            Maps.                (line  37)
+* -map-indexed:                          Maps.                (line  65)
+* -map-last:                             Maps.                (line  51)
+* -map-when:                             Maps.                (line  21)
+* -mapcat:                               Maps.                (line 123)
+* -max:                                  Reductions.          (line 267)
+* -max-by:                               Reductions.          (line 277)
+* -min:                                  Reductions.          (line 243)
+* -min-by:                               Reductions.          (line 253)
+* -non-nil:                              Sublist selection.   (line  79)
+* -none?:                                Predicates.          (line  30)
+* -not:                                  Function combinators.
+                                                              (line 117)
+* -on:                                   Function combinators.
+                                                              (line  66)
+* -only-some?:                           Predicates.          (line  42)
+* -orfn:                                 Function combinators.
+                                                              (line 126)
+* -pad:                                  Other list operations.
+                                                              (line 179)
+* -partial:                              Function combinators.
+                                                              (line   9)
+* -partition:                            Partitioning.        (line  74)
+* -partition-after-item:                 Partitioning.        (line 177)
+* -partition-after-pred:                 Partitioning.        (line 145)
+* -partition-all:                        Partitioning.        (line  86)
+* -partition-all-in-steps:               Partitioning.        (line 109)
+* -partition-before-item:                Partitioning.        (line 167)
+* -partition-before-pred:                Partitioning.        (line 156)
+* -partition-by:                         Partitioning.        (line 121)
+* -partition-by-header:                  Partitioning.        (line 132)
+* -partition-in-steps:                   Partitioning.        (line  97)
+* -permutations:                         Set operations.      (line  52)
+* -powerset:                             Set operations.      (line  44)
+* -prodfn:                               Function combinators.
+                                                              (line 209)
+* -product:                              Reductions.          (line 181)
+* -reduce:                               Reductions.          (line  46)
+* -reduce-from:                          Reductions.          (line   8)
+* -reduce-r:                             Reductions.          (line  65)
+* -reduce-r-from:                        Reductions.          (line  27)
+* -reductions:                           Reductions.          (line 119)
+* -reductions-from:                      Reductions.          (line  87)
+* -reductions-r:                         Reductions.          (line 135)
+* -reductions-r-from:                    Reductions.          (line 103)
+* -remove:                               Sublist selection.   (line  23)
+* -remove-at:                            List to list.        (line 145)
+* -remove-at-indices:                    List to list.        (line 158)
+* -remove-first:                         Sublist selection.   (line  37)
+* -remove-item:                          Sublist selection.   (line  67)
+* -remove-last:                          Sublist selection.   (line  52)
+* -repeat:                               Other list operations.
+                                                              (line  19)
+* -replace:                              List to list.        (line  67)
+* -replace-at:                           List to list.        (line 120)
+* -replace-first:                        List to list.        (line  81)
+* -replace-last:                         List to list.        (line  95)
+* -rotate:                               Other list operations.
+                                                              (line   8)
+* -rpartial:                             Function combinators.
+                                                              (line  20)
+* -running-product:                      Reductions.          (line 191)
+* -running-sum:                          Reductions.          (line 169)
+* -same-items?:                          Predicates.          (line  72)
+* -second-item:                          Other list operations.
+                                                              (line 286)
+* -select-by-indices:                    Sublist selection.   (line 185)
+* -select-column:                        Sublist selection.   (line 215)
+* -select-columns:                       Sublist selection.   (line 196)
+* -separate:                             Partitioning.        (line  63)
+* -setq:                                 Binding.             (line 274)
+* -slice:                                Sublist selection.   (line  85)
+* -snoc:                                 Other list operations.
+                                                              (line  44)
+* -some:                                 Other list operations.
+                                                              (line 248)
+* -some-->:                              Threading macros.    (line  83)
+* -some->:                               Threading macros.    (line  59)
+* -some->>:                              Threading macros.    (line  71)
+* -sort:                                 Other list operations.
+                                                              (line 350)
+* -splice:                               Maps.                (line  90)
+* -splice-list:                          Maps.                (line 110)
+* -split-at:                             Partitioning.        (line   8)
+* -split-on:                             Partitioning.        (line  28)
+* -split-when:                           Partitioning.        (line  46)
+* -split-with:                           Partitioning.        (line  17)
+* -sum:                                  Reductions.          (line 159)
+* -table:                                Other list operations.
+                                                              (line 190)
+* -table-flat:                           Other list operations.
+                                                              (line 209)
+* -tails:                                Reductions.          (line 213)
+* -take:                                 Sublist selection.   (line 101)
+* -take-last:                            Sublist selection.   (line 114)
+* -take-while:                           Sublist selection.   (line 156)
+* -third-item:                           Other list operations.
+                                                              (line 298)
+* -tree-map:                             Tree operations.     (line  28)
+* -tree-map-nodes:                       Tree operations.     (line  39)
+* -tree-mapreduce:                       Tree operations.     (line  84)
+* -tree-mapreduce-from:                  Tree operations.     (line 103)
+* -tree-reduce:                          Tree operations.     (line  52)
+* -tree-reduce-from:                     Tree operations.     (line  69)
+* -tree-seq:                             Tree operations.     (line   8)
+* -unfold:                               Unfolding.           (line  25)
+* -union:                                Set operations.      (line   8)
+* -unzip:                                Other list operations.
+                                                              (line 146)
+* -update-at:                            List to list.        (line 132)
+* -when-let:                             Binding.             (line   9)
+* -when-let*:                            Binding.             (line  23)
+* -zip:                                  Other list operations.
+                                                              (line  95)
+* -zip-fill:                             Other list operations.
+                                                              (line 138)
+* -zip-lists:                            Other list operations.
+                                                              (line 119)
+* -zip-with:                             Other list operations.
+                                                              (line  79)
+
+
+\1f
+Tag Table:
+Node: Top\7f947
+Node: Installation\7f2424
+Node: Using in a package\7f2991
+Node: Fontification of special variables\7f3352
+Node: Functions\7f4056
+Node: Maps\7f5267
+Ref: -map\7f5562
+Ref: -map-when\7f5903
+Ref: -map-first\7f6481
+Ref: -map-last\7f6959
+Ref: -map-indexed\7f7432
+Ref: -annotate\7f7912
+Ref: -splice\7f8402
+Ref: -splice-list\7f9183
+Ref: -mapcat\7f9645
+Ref: -copy\7f10021
+Node: Sublist selection\7f10225
+Ref: -filter\7f10418
+Ref: -remove\7f10870
+Ref: -remove-first\7f11276
+Ref: -remove-last\7f11803
+Ref: -remove-item\7f12324
+Ref: -non-nil\7f12719
+Ref: -slice\7f12878
+Ref: -take\7f13410
+Ref: -take-last\7f13819
+Ref: -drop\7f14252
+Ref: -drop-last\7f14682
+Ref: -take-while\7f15110
+Ref: -drop-while\7f15636
+Ref: -select-by-indices\7f16160
+Ref: -select-columns\7f16674
+Ref: -select-column\7f17380
+Node: List to list\7f17844
+Ref: -keep\7f18036
+Ref: -concat\7f18539
+Ref: -flatten\7f18836
+Ref: -flatten-n\7f19595
+Ref: -replace\7f19982
+Ref: -replace-first\7f20445
+Ref: -replace-last\7f20942
+Ref: -insert-at\7f21432
+Ref: -replace-at\7f21759
+Ref: -update-at\7f22149
+Ref: -remove-at\7f22640
+Ref: -remove-at-indices\7f23128
+Node: Reductions\7f23710
+Ref: -reduce-from\7f23879
+Ref: -reduce-r-from\7f24645
+Ref: -reduce\7f25412
+Ref: -reduce-r\7f26141
+Ref: -reductions-from\7f27012
+Ref: -reductions-r-from\7f27727
+Ref: -reductions\7f28452
+Ref: -reductions-r\7f29077
+Ref: -count\7f29712
+Ref: -sum\7f29936
+Ref: -running-sum\7f30125
+Ref: -product\7f30418
+Ref: -running-product\7f30627
+Ref: -inits\7f30940
+Ref: -tails\7f31188
+Ref: -common-prefix\7f31435
+Ref: -common-suffix\7f31732
+Ref: -min\7f32029
+Ref: -min-by\7f32255
+Ref: -max\7f32778
+Ref: -max-by\7f33003
+Node: Unfolding\7f33531
+Ref: -iterate\7f33770
+Ref: -unfold\7f34215
+Node: Predicates\7f35023
+Ref: -any?\7f35147
+Ref: -all?\7f35467
+Ref: -none?\7f35797
+Ref: -only-some?\7f36099
+Ref: -contains?\7f36584
+Ref: -same-items?\7f36973
+Ref: -is-prefix?\7f37358
+Ref: -is-suffix?\7f37681
+Ref: -is-infix?\7f38004
+Node: Partitioning\7f38358
+Ref: -split-at\7f38546
+Ref: -split-with\7f38831
+Ref: -split-on\7f39234
+Ref: -split-when\7f39910
+Ref: -separate\7f40550
+Ref: -partition\7f40992
+Ref: -partition-all\7f41444
+Ref: -partition-in-steps\7f41872
+Ref: -partition-all-in-steps\7f42369
+Ref: -partition-by\7f42854
+Ref: -partition-by-header\7f43236
+Ref: -partition-after-pred\7f43840
+Ref: -partition-before-pred\7f44184
+Ref: -partition-before-item\7f44535
+Ref: -partition-after-item\7f44846
+Ref: -group-by\7f45152
+Node: Indexing\7f45589
+Ref: -elem-index\7f45791
+Ref: -elem-indices\7f46186
+Ref: -find-index\7f46569
+Ref: -find-last-index\7f47058
+Ref: -find-indices\7f47562
+Ref: -grade-up\7f47970
+Ref: -grade-down\7f48373
+Node: Set operations\7f48783
+Ref: -union\7f48966
+Ref: -difference\7f49408
+Ref: -intersection\7f49825
+Ref: -powerset\7f50262
+Ref: -permutations\7f50475
+Ref: -distinct\7f50775
+Node: Other list operations\7f51153
+Ref: -rotate\7f51378
+Ref: -repeat\7f51748
+Ref: -cons*\7f52011
+Ref: -snoc\7f52398
+Ref: -interpose\7f52811
+Ref: -interleave\7f53109
+Ref: -zip-with\7f53478
+Ref: -zip\7f54195
+Ref: -zip-lists\7f55027
+Ref: -zip-fill\7f55728
+Ref: -unzip\7f56051
+Ref: -cycle\7f56796
+Ref: -pad\7f57198
+Ref: -table\7f57521
+Ref: -table-flat\7f58310
+Ref: -first\7f59318
+Ref: -some\7f59690
+Ref: -last\7f59999
+Ref: -first-item\7f60333
+Ref: -second-item\7f60749
+Ref: -third-item\7f61029
+Ref: -fourth-item\7f61307
+Ref: -fifth-item\7f61573
+Ref: -last-item\7f61835
+Ref: -butlast\7f62127
+Ref: -sort\7f62374
+Ref: -list\7f62863
+Ref: -fix\7f63194
+Node: Tree operations\7f63734
+Ref: -tree-seq\7f63930
+Ref: -tree-map\7f64788
+Ref: -tree-map-nodes\7f65231
+Ref: -tree-reduce\7f66081
+Ref: -tree-reduce-from\7f66963
+Ref: -tree-mapreduce\7f67564
+Ref: -tree-mapreduce-from\7f68424
+Ref: -clone\7f69710
+Node: Threading macros\7f70038
+Ref: ->\7f70183
+Ref: ->>\7f70674
+Ref: -->\7f71179
+Ref: -as->\7f71735
+Ref: -some->\7f72190
+Ref: -some->>\7f72564
+Ref: -some-->\7f73000
+Node: Binding\7f73471
+Ref: -when-let\7f73683
+Ref: -when-let*\7f74168
+Ref: -if-let\7f74691
+Ref: -if-let*\7f75086
+Ref: -let\7f75703
+Ref: -let*\7f81793
+Ref: -lambda\7f82733
+Ref: -setq\7f83530
+Node: Side-effects\7f84346
+Ref: -each\7f84540
+Ref: -each-while\7f84947
+Ref: -each-indexed\7f85405
+Ref: -each-r\7f85923
+Ref: -each-r-while\7f86356
+Ref: -dotimes\7f86731
+Ref: -doto\7f87034
+Ref: --doto\7f87462
+Node: Destructive operations\7f87737
+Ref: !cons\7f87910
+Ref: !cdr\7f88116
+Node: Function combinators\7f88311
+Ref: -partial\7f88585
+Ref: -rpartial\7f88979
+Ref: -juxt\7f89382
+Ref: -compose\7f89814
+Ref: -applify\7f90367
+Ref: -on\7f90798
+Ref: -flip\7f91324
+Ref: -const\7f91636
+Ref: -cut\7f91975
+Ref: -not\7f92461
+Ref: -orfn\7f92771
+Ref: -andfn\7f93205
+Ref: -iteratefn\7f93700
+Ref: -fixfn\7f94403
+Ref: -prodfn\7f95966
+Node: Development\7f97034
+Node: Contribute\7f97383
+Node: Changes\7f98131
+Node: Contributors\7f101129
+Node: Index\7f102748
+\1f
+End Tag Table
+
+\1f
+Local Variables:
+coding: utf-8
+End:
diff --git a/elpa/dash-20210101.1712/dir b/elpa/dash-20210101.1712/dir
new file mode 100644 (file)
index 0000000..49b1700
--- /dev/null
@@ -0,0 +1,18 @@
+This is the file .../info/dir, which contains the
+topmost node of the Info hierarchy, called (dir)Top.
+The first time you invoke Info you start off looking at this node.
+\1f
+File: dir,     Node: Top       This is the top of the INFO tree
+
+  This (the Directory node) gives a menu of major topics.
+  Typing "q" exits, "H" lists all Info commands, "d" returns here,
+  "h" gives a primer for first-timers,
+  "mEmacs<Return>" visits the Emacs manual, etc.
+
+  In Emacs, you can click mouse button 2 on a menu item or cross reference
+  to select it.
+
+* Menu:
+
+Emacs
+* Dash: (dash.info).            A modern list library for GNU Emacs