]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
update a
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Mon, 17 Jan 2022 10:50:01 +0000 (11:50 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Mon, 17 Jan 2022 10:50:01 +0000 (11:50 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
elpa/a-20180907.953/a-autoloads.el [deleted file]
elpa/a-20180907.953/a-pkg.el [deleted file]
elpa/a-20180907.953/a.el [deleted file]
elpa/a-20210929.1510/a-autoloads.el [new file with mode: 0644]
elpa/a-20210929.1510/a-pkg.el [new file with mode: 0644]
elpa/a-20210929.1510/a.el [new file with mode: 0644]

diff --git a/elpa/a-20180907.953/a-autoloads.el b/elpa/a-20180907.953/a-autoloads.el
deleted file mode 100644 (file)
index c9ec568..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-;;; a-autoloads.el --- automatically extracted autoloads
-;;
-;;; Code:
-
-(add-to-list 'load-path (directory-file-name
-                         (or (file-name-directory #$) (car load-path))))
-
-\f
-;;;### (autoloads nil "a" "a.el" (0 0 0 0))
-;;; Generated autoloads from a.el
-
-(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "a" '("a-")))
-
-;;;***
-\f
-;; Local Variables:
-;; version-control: never
-;; no-byte-compile: t
-;; no-update-autoloads: t
-;; coding: utf-8
-;; End:
-;;; a-autoloads.el ends here
diff --git a/elpa/a-20180907.953/a-pkg.el b/elpa/a-20180907.953/a-pkg.el
deleted file mode 100644 (file)
index f07f864..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-;;; -*- no-byte-compile: t -*-
-(define-package "a" "20180907.953" "Associative data structure functions" '((emacs "25")) :commit "18966975db7110d0aac726be95b593e2fc3d44ed" :keywords '("lisp") :authors '(("Arne Brasseur" . "arneNOSPAMarnebrasseur.net")) :maintainer '("Arne Brasseur" . "arneNOSPAMarnebrasseur.net") :url "https://github.com/plexus/a.el")
diff --git a/elpa/a-20180907.953/a.el b/elpa/a-20180907.953/a.el
deleted file mode 100644 (file)
index b699160..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-;;; a.el --- Associative data structure functions   -*- lexical-binding: t; -*-
-
-;; Copyright (C) 2017  Arne Brasseur
-
-;; Author: Arne Brasseur <arneNOSPAMarnebrasseur.net>
-;; URL: https://github.com/plexus/a.el
-;; Package-Version: 20180907.953
-;; Keywords: lisp
-;; Version: 0.1.1
-;; Package-Requires: ((emacs "25"))
-
-;; This file is not part of GNU Emacs.
-
-;; This file 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, or (at your option)
-;; any later version.
-
-;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-
-;; Library for dealing with associative data structures: alists, hash-maps, and
-;; vectors (for vectors, the indices are treated as keys).
-;;
-;; This library is largely inspired by Clojure, it has many of the functions
-;; found in clojure.core, prefixed with `a-'. All functions treat their
-;; arguments as immutable, so e.g. `a-assoc' will clone the hash-table or alist
-;; it is given. Keep this in mind when writing performance sensitive code.
-
-;;; Code:
-
-(eval-when-compile (require 'subr-x)) ;; for things like hash-table-keys
-
-(require 'cl-lib)
-(require 'seq)
-
-(defun a-associative-p (obj)
-  (or (not obj)
-      (hash-table-p obj)
-      (and (consp obj) (consp (car obj)))))
-
-(defalias 'a-associative? 'a-associative-p)
-
-(defun a-get (map key &optional not-found)
-  "Return the value MAP mapped to KEY, NOT-FOUND or nil if key not present."
-  (cond
-   ;; own implementation instead of alist-get so keys are checked with equal
-   ;; instead of eq
-   ((listp map)
-    (a--alist-get map key not-found))
-
-   ((vectorp map)
-    (if (a-has-key? map key)
-        (aref map key)
-      not-found))
-
-   ((hash-table-p map)
-    (gethash key map not-found))
-   (t (user-error "Not associative: %S" map))))
-
-(defun a--alist-get (map key &optional not-found)
-  "Like alist-get, but uses equal instead of eq to look up in map MAP key KEY.
-Returns NOT-FOUND if the key is not present, or `nil' if
-NOT-FOUND is not specified."
-  (cl-block nil
-    (seq-doseq (pair map)
-      (when (equal (car pair) key)
-        (cl-return (cdr pair))))
-    not-found))
-
-(defun a-get-in (m ks &optional not-found)
-  "Look up a value in a nested associative structure.
-
-Given a data structure M, and a sequence of keys KS, find the
-value found by using each key in turn to do a lookup in the next
-\"layer\". Return `nil' if the key is not present, or the NOT-FOUND
-value if supplied."
-  (let ((result m))
-    (cl-block nil
-      (seq-doseq (k ks)
-        (if (a-has-key? result k)
-            (setq result (a-get result k))
-          (cl-return not-found)))
-      result)))
-
-(defmacro a-get* (&rest keys)
-  "Look up a value in a nested associative structure.
-
-Like a-get-in, but takes the key sequence KEYS directly as vararg
-arguments, rather than as a single sequence."
-  (cl-labels ((rec (keys)
-                   `(a-get ,(if (and (consp (cdr keys))
-                                     (cddr keys))
-                                (rec (cdr keys))
-                              (cadr keys))
-                           ,(car keys))))
-    (rec (nreverse keys))))
-
-(defun a-has-key (coll k)
-  "Check if the given associative collection COLL has a certain key K."
-  (cond
-   ((listp coll)         (not (eq (a--alist-get coll k :not-found) :not-found)))
-   ((vectorp coll)       (and (integerp k) (< -1 k (length coll))))
-   ((hash-table-p coll)  (not (eq (gethash k coll :not-found) :not-found)))
-   (t (user-error "Not associative: %S" coll))))
-
-(defalias 'a-has-key? 'a-has-key)
-
-(defun a-assoc-1 (coll k v)
-  "Like `a-assoc', (in COLL assoc K with V) but only takes a single k-v pair.
-Internal helper function."
-  (cond
-   ((listp coll)
-    (if (a-has-key? coll k)
-        (mapcar (lambda (entry)
-                  (if (equal (car entry) k)
-                      (cons k v)
-                    entry))
-                coll)
-      (cons (cons k v) coll)))
-
-   ((vectorp coll)
-    (if (and (integerp k) (> k 0))
-        (if (< k (length coll))
-            (let ((copy (copy-sequence coll)))
-              (aset copy k v)
-              copy)
-          (vconcat coll (make-list (- k (length coll)) nil) (list v)))))
-
-   ((hash-table-p coll)
-    (let ((copy (copy-hash-table coll)))
-      (puthash k v copy)
-      copy))))
-
-(defun a-assoc (coll &rest kvs)
-  "Return an updated collection COLL, associating values with keys KVS."
-  (when (not (cl-evenp (a-count kvs)))
-    (user-error "a-assoc requires an even number of arguments!"))
-  (seq-reduce (lambda (coll kv)
-                  (seq-let [k v] kv
-                    (a-assoc-1 coll k v)))
-              (seq-partition kvs 2)
-              coll))
-
-(defun a-keys (coll)
-  "Return the keys in the collection COLL."
-  (cond
-   ((listp coll)
-    (mapcar #'car coll))
-
-   ((hash-table-p coll)
-    (hash-table-keys coll))))
-
-(defun a-vals (coll)
-  "Return the values in the collection COLL."
-  (cond
-   ((listp coll)
-    (mapcar #'cdr coll))
-
-   ((hash-table-p coll)
-    (hash-table-values coll))))
-
-(defun a-reduce-kv (fn from coll)
-  "Reduce with FN starting from FROM the collection COLL.
-Reduce an associative collection COLL, starting with an initial
-value of FROM. The reducing function FN receives the intermediate
-value, key, and value."
-  (seq-reduce (lambda (acc key)
-                  (funcall fn acc key (a-get coll key)))
-              (a-keys coll)
-              from))
-
-(defun a-count (coll)
-  "Count the number of key-value pairs in COLL.
-Like length, but can also return the length of hash tables."
-  (cond
-   ((seqp coll)
-    (length coll))
-
-   ((hash-table-p coll)
-    (hash-table-count coll))))
-
-(defun a-equal (a b)
-  "Compare collections A, B for value equality.
-
-Associative collections (hash tables and a-lists) are considered
-equal if they contain equal key-value pairs, regardless of order.
-
-Sequences (lists or vectors) are considered equal if they contain
-the same elements in the same order.
-
-Collection elements are compared using `a-equal'. In other words,
-the equality check is recursive, resulting in a \"deep\" equality
-check.
-
-Anything that isn't associative or a sequence is compared with
-`equal'."
-  (cond
-   ((and (a-associative? a) (a-associative? b))
-    (or (equal a b)
-        (when (eq (a-count a) (a-count b))
-          (cl-block nil
-            (seq-doseq (k (a-keys a))
-              (when (not (a-equal (a-get a k) (a-get b k)))
-                (cl-return nil)))
-            t))))
-   ((and (sequencep a) (sequencep b))
-    (and (eq (length a) (length b))
-         (or (and (seq-empty-p a) (seq-empty-p b))
-             (and (a-equal (elt a 0) (elt b 0))
-                  (a-equal (seq-drop a 1) (seq-drop b 1))))))
-   (t
-    (equal a b))))
-
-(defalias 'a-equal? 'a-equal)
-
-(defun a-merge (&rest colls)
-  "Merge multiple associative collections.
-Return the type of the first collection COLLS."
-  (seq-reduce (lambda (this that)
-                (a-reduce-kv (lambda (coll k v)
-                               (a-assoc coll k v))
-                             this
-                             that))
-              (cdr colls)
-              (car colls)))
-
-(defun a-merge-with (f &rest colls)
-  "Merge multiple associative collections.
-Return the type of the first collection COLLS. If a key exists in
-both, then combine the associated values by calling f on them."
-  (seq-reduce (lambda (this that)
-                (a-reduce-kv (lambda (coll k v)
-                               (a-assoc coll k (if (a-has-key coll k)
-                                                   (funcall f v (a-get coll k))
-                                                 v)))
-                             this
-                             that))
-              (cdr colls)
-              (car colls)))
-
-(defun a-alist (&rest kvs)
-  "Create an association list from the given keys and values KVS.
-Arguments are simply provided in sequence, rather than as lists or cons cells.
-For example: (a-alist :foo 123 :bar 456)"
-  (mapcar (lambda (kv) (cons (car kv) (cadr kv))) (seq-partition kvs 2)))
-
-(defalias 'a-list 'a-alist)
-
-(defun a-hash-table (&rest kvs)
-  "Create a hash table from the given keys and values KVS.
-Arguments are simply provided in sequence, rather than as lists
-or cons cells. As \"test\" for the hash table, equal is used. The
-hash table is created without extra storage space, so with a size
-equal to amount of key-value pairs, since it is assumed to be
-treated as immutable.
-For example: (a-hash-table :foo 123 :bar 456)"
-  (let* ((kv-pairs (seq-partition kvs 2))
-         (hash-map (make-hash-table :test 'equal :size (length kv-pairs))))
-    (seq-do (lambda (pair)
-              (puthash (car pair) (cadr pair) hash-map))
-            kv-pairs)
-    hash-map))
-
-(defun a-assoc-in (coll keys value)
-  "In collection COLL, at location KEYS, associate value VALUE.
-Associates a value in a nested associative collection COLL, where
-KEYS is a sequence of keys and VALUE is the new value and returns
-a new nested structure. If any levels do not exist, association
-lists will be created."
-  (cl-case (length keys)
-    (0 coll)
-    (1 (a-assoc-1 coll (elt keys 0) value))
-    (t (a-assoc-1 coll
-                  (elt keys 0)
-                  (a-assoc-in (a-get coll (elt keys 0))
-                              (seq-drop keys 1)
-                              value)))))
-
-(defun a-dissoc--list (list keys)
-  "Return updated LIST with KEYS removed.
-Internal helper. Use `a-dissoc' instead."
-  (a-reduce-kv (lambda (res k v)
-                 (if (member k keys)
-                     res
-                   (cons (cons k v) res)))
-               nil
-               list))
-
-(defun a-dissoc--hash-table (table keys)
-  "Return updated TABLE with KEYS removed.
-Internal helper. Use `a-dissoc' instead."
-  (let ((new-table (make-hash-table :size (hash-table-count table)
-                                    :test (hash-table-test table)))
-        (rest-keys (seq-remove (lambda (k)
-                                 (member k keys))
-                               (a-keys table))))
-    (seq-doseq (k rest-keys)
-      (puthash k (gethash k table) new-table))
-    new-table))
-
-(defun a-dissoc (coll &rest keys)
-  "Return an updated version of collection COLL with the KEY removed."
-  (cond
-   ((listp coll) (a-dissoc--list coll keys))
-   ((hash-table-p coll) (a-dissoc--hash-table coll keys))))
-
-(defun a-update (coll key fn &rest args)
-  "In collection COLL, at location KEY, apply FN with extra args ARGS.
-'Updates' a value in an associative collection COLL, where KEY is
-a key and FN is a function that will take the old value and any
-supplied args and return the new value, and returns a new
-structure. If the key does not exist, nil is passed as the old
-value."
-  (a-assoc-1 coll
-             key
-             (apply #'funcall fn (a-get coll key) args)))
-
-(defun a-update-in (coll keys fn &rest args)
-  "In collection COLL, at location KEYS, apply FN with extra args ARGS.
-'Updates' a value in a nested associative collection COLL, where
-KEYS is a sequence of keys and FN is a function that will take
-the old value and any supplied ARGS and return the new value, and
-returns a new nested structure. If any levels do not exist,
-association lists will be created."
-  (cl-case (length keys)
-    (0 coll)
-    (1 (apply #'a-update coll (elt keys 0) fn args))
-    (t (a-assoc-1 coll
-                  (elt keys 0)
-                  (apply #'a-update-in
-                         (a-get coll (elt keys 0))
-                         (seq-drop keys 1)
-                         fn
-                         args)))))
-
-(provide 'a)
-;;; a.el ends here
diff --git a/elpa/a-20210929.1510/a-autoloads.el b/elpa/a-20210929.1510/a-autoloads.el
new file mode 100644 (file)
index 0000000..c9ec568
--- /dev/null
@@ -0,0 +1,22 @@
+;;; a-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+                         (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "a" "a.el" (0 0 0 0))
+;;; Generated autoloads from a.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "a" '("a-")))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; a-autoloads.el ends here
diff --git a/elpa/a-20210929.1510/a-pkg.el b/elpa/a-20210929.1510/a-pkg.el
new file mode 100644 (file)
index 0000000..279b129
--- /dev/null
@@ -0,0 +1,2 @@
+;;; Generated package description from a.el  -*- no-byte-compile: t -*-
+(define-package "a" "20210929.1510" "Associative data structure functions" '((emacs "25")) :commit "9ad2d18252b729174fe22ed0b2b7670c88f60c31" :authors '(("Arne Brasseur" . "arneNOSPAMarnebrasseur.net")) :maintainer '("Arne Brasseur" . "arneNOSPAMarnebrasseur.net") :keywords '("lisp") :url "https://github.com/plexus/a.el")
diff --git a/elpa/a-20210929.1510/a.el b/elpa/a-20210929.1510/a.el
new file mode 100644 (file)
index 0000000..305b4b9
--- /dev/null
@@ -0,0 +1,357 @@
+;;; a.el --- Associative data structure functions   -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2017-2021  Arne Brasseur
+
+;; Author: Arne Brasseur <arneNOSPAMarnebrasseur.net>
+;; URL: https://github.com/plexus/a.el
+;; Package-Version: 20210929.1510
+;; Package-Commit: 9ad2d18252b729174fe22ed0b2b7670c88f60c31
+;; Keywords: lisp
+;; Version: 1.0.0
+;; Package-Requires: ((emacs "25"))
+
+;; This file is not part of GNU Emacs.
+
+;; This file 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, or (at your option)
+;; any later version.
+
+;; This file 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 GNU Emacs; see the file COPYING.  If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; Library for dealing with associative data structures: alists, hash-maps, and
+;; vectors (for vectors, the indices are treated as keys).
+;;
+;; This library is largely inspired by Clojure, it has many of the functions
+;; found in clojure.core, prefixed with `a-'. All functions treat their
+;; arguments as immutable, so e.g. `a-assoc' will clone the hash-table or alist
+;; it is given. Keep this in mind when writing performance sensitive code.
+
+;;; Code:
+
+(eval-when-compile (require 'subr-x)) ;; for things like hash-table-keys
+
+(require 'cl-lib)
+(require 'seq)
+
+(defun a-associative-p (obj)
+  (or (not obj)
+      (hash-table-p obj)
+      (and (consp obj)
+           (consp (car obj)))))
+
+(defalias 'a-associative? 'a-associative-p)
+
+(defun a-get (map key &optional not-found)
+  "Return the value MAP mapped to KEY, NOT-FOUND or nil if key not present."
+  (cond
+   ;; own implementation instead of alist-get so keys are checked with equal
+   ;; instead of eq
+   ((listp map)
+    (a--alist-get map key not-found))
+
+   ((vectorp map)
+    (if (a-has-key? map key)
+        (aref map key)
+      not-found))
+
+   ((hash-table-p map)
+    (gethash key map not-found))
+   (t (user-error "Not associative: %S" map))))
+
+(defun a--alist-get (map key &optional not-found)
+  "Like alist-get, but uses equal instead of eq to look up in map MAP key KEY.
+Returns NOT-FOUND if the key is not present, or `nil' if
+NOT-FOUND is not specified."
+  (cl-block nil
+    (seq-doseq (pair map)
+      (when (equal (car pair) key)
+        (cl-return (cdr pair))))
+    not-found))
+
+(defun a-get-in (m ks &optional not-found)
+  "Look up a value in a nested associative structure.
+
+Given a data structure M, and a sequence of keys KS, find the
+value found by using each key in turn to do a lookup in the next
+\"layer\". Return `nil' if the key is not present, or the NOT-FOUND
+value if supplied."
+  (let ((result m))
+    (cl-block nil
+      (seq-doseq (k ks)
+        (if (a-has-key? result k)
+            (setq result (a-get result k))
+          (cl-return not-found)))
+      result)))
+
+(defmacro a-get* (&rest keys)
+  "Look up a value in a nested associative structure.
+
+Like a-get-in, but takes the key sequence KEYS directly as vararg
+arguments, rather than as a single sequence."
+  (cl-labels ((rec (keys)
+                   `(a-get ,(if (and (consp (cdr keys))
+                                     (cddr keys))
+                                (rec (cdr keys))
+                              (cadr keys))
+                           ,(car keys))))
+    (rec (nreverse keys))))
+
+(defun a-has-key (coll k)
+  "Check if the given associative collection COLL has a certain key K."
+  (cond
+   ((listp coll)         (not (eq (a--alist-get coll k :not-found) :not-found)))
+   ((vectorp coll)       (and (integerp k) (< -1 k (length coll))))
+   ((hash-table-p coll)  (not (eq (gethash k coll :not-found) :not-found)))
+   (t (user-error "Not associative: %S" coll))))
+
+(defalias 'a-has-key? 'a-has-key)
+
+(defun a-assoc-1 (coll k v)
+  "Like `a-assoc', (in COLL assoc K with V) but only takes a single k-v pair.
+Internal helper function."
+  (cond
+   ((listp coll)
+    (if (a-has-key? coll k)
+        (mapcar (lambda (entry)
+                  (if (equal (car entry) k)
+                      (cons k v)
+                    entry))
+                coll)
+      (cons (cons k v) coll)))
+
+   ((vectorp coll)
+    (if (and (integerp k) (>= k 0))
+        (if (< k (length coll))
+            (let ((copy (copy-sequence coll)))
+              (aset copy k v)
+              copy)
+          (vconcat coll (make-list (- k (length coll)) nil) (list v)))))
+
+   ((hash-table-p coll)
+    (let ((copy (copy-hash-table coll)))
+      (puthash k v copy)
+      copy))))
+
+(defun a-assoc (coll &rest kvs)
+  "Return an updated collection COLL, associating values with keys KVS."
+  (when (not (cl-evenp (a-count kvs)))
+    (user-error "a-assoc requires an even number of arguments!"))
+  (seq-reduce (lambda (coll kv)
+                  (seq-let [k v] kv
+                    (a-assoc-1 coll k v)))
+              (seq-partition kvs 2)
+              coll))
+
+(defun a-keys (coll)
+  "Return the keys in the collection COLL."
+  (cond
+   ((listp coll)
+    (mapcar #'car coll))
+
+   ((hash-table-p coll)
+    (hash-table-keys coll))))
+
+(defun a-vals (coll)
+  "Return the values in the collection COLL."
+  (cond
+   ((listp coll)
+    (mapcar #'cdr coll))
+
+   ((hash-table-p coll)
+    (hash-table-values coll))))
+
+(defun a-reduce-kv (fn from coll)
+  "Reduce with FN starting from FROM the collection COLL.
+Reduce an associative collection COLL, starting with an initial
+value of FROM. The reducing function FN receives the intermediate
+value, key, and value."
+  (seq-reduce (lambda (acc key)
+                  (funcall fn acc key (a-get coll key)))
+              (a-keys coll)
+              from))
+
+(defun a-count (coll)
+  "Count the number of key-value pairs in COLL.
+Like length, but can also return the length of hash tables."
+  (cond
+   ((seqp coll)
+    (length coll))
+
+   ((hash-table-p coll)
+    (hash-table-count coll))))
+
+(defun a-equal (a b)
+  "Compare collections A, B for value equality.
+
+Associative collections (hash tables and a-lists) are considered
+equal if they contain equal key-value pairs, regardless of order.
+
+Sequences (lists or vectors) are considered equal if they contain
+the same elements in the same order.
+
+Collection elements are compared using `a-equal'. In other words,
+the equality check is recursive, resulting in a \"deep\" equality
+check.
+
+Anything that isn't associative or a sequence is compared with
+`equal'."
+  (cond
+   ((and (a-associative? a) (a-associative? b))
+    (or (equal a b)
+        (when (eq (a-count a) (a-count b))
+          (cl-block nil
+            (seq-doseq (k (a-keys a))
+              (when (not (and
+                          (a-has-key b k)
+                          (a-equal (a-get a k) (a-get b k))))
+                (cl-return nil)))
+            (seq-doseq (k (a-keys b))
+              (when (not (and
+                          (a-has-key a k)
+                          (a-equal (a-get a k) (a-get b k))))
+                (cl-return nil)))
+            t))))
+   ((and (sequencep a) (sequencep b))
+    (and (eq (length a) (length b))
+         (or (and (seq-empty-p a) (seq-empty-p b))
+             (and (a-equal (elt a 0) (elt b 0))
+                  (a-equal (seq-drop a 1) (seq-drop b 1))))))
+   (t
+    (equal a b))))
+
+(defalias 'a-equal? 'a-equal)
+
+(defun a-merge (&rest colls)
+  "Merge multiple associative collections.
+Return the type of the first collection COLLS."
+  (seq-reduce (lambda (this that)
+                (a-reduce-kv (lambda (coll k v)
+                               (a-assoc coll k v))
+                             this
+                             that))
+              (cdr colls)
+              (car colls)))
+
+(defun a-merge-with (f &rest colls)
+  "Merge multiple associative collections.
+Return the type of the first collection COLLS. If a key exists in
+both, then combine the associated values by calling f on them."
+  (seq-reduce (lambda (this that)
+                (a-reduce-kv (lambda (coll k v)
+                               (a-assoc coll k (if (a-has-key coll k)
+                                                   (funcall f v (a-get coll k))
+                                                 v)))
+                             this
+                             that))
+              (cdr colls)
+              (car colls)))
+
+(defun a-alist (&rest kvs)
+  "Create an association list from the given keys and values KVS.
+Arguments are simply provided in sequence, rather than as lists or cons cells.
+For example: (a-alist :foo 123 :bar 456)"
+  (mapcar (lambda (kv) (cons (car kv) (cadr kv))) (seq-partition kvs 2)))
+
+(defalias 'a-list 'a-alist)
+
+(defun a-hash-table (&rest kvs)
+  "Create a hash table from the given keys and values KVS.
+Arguments are simply provided in sequence, rather than as lists
+or cons cells. As \"test\" for the hash table, equal is used. The
+hash table is created without extra storage space, so with a size
+equal to amount of key-value pairs, since it is assumed to be
+treated as immutable.
+For example: (a-hash-table :foo 123 :bar 456)"
+  (let* ((kv-pairs (seq-partition kvs 2))
+         (hash-map (make-hash-table :test 'equal :size (length kv-pairs))))
+    (seq-do (lambda (pair)
+              (puthash (car pair) (cadr pair) hash-map))
+            kv-pairs)
+    hash-map))
+
+(defun a-assoc-in (coll keys value)
+  "In collection COLL, at location KEYS, associate value VALUE.
+Associates a value in a nested associative collection COLL, where
+KEYS is a sequence of keys and VALUE is the new value and returns
+a new nested structure. If any levels do not exist, association
+lists will be created."
+  (cl-case (length keys)
+    (0 coll)
+    (1 (a-assoc-1 coll (elt keys 0) value))
+    (t (a-assoc-1 coll
+                  (elt keys 0)
+                  (a-assoc-in (a-get coll (elt keys 0))
+                              (seq-drop keys 1)
+                              value)))))
+
+(defun a-dissoc--list (list keys)
+  "Return updated LIST with KEYS removed.
+Internal helper. Use `a-dissoc' instead."
+  (a-reduce-kv (lambda (res k v)
+                 (if (member k keys)
+                     res
+                   (cons (cons k v) res)))
+               nil
+               list))
+
+(defun a-dissoc--hash-table (table keys)
+  "Return updated TABLE with KEYS removed.
+Internal helper. Use `a-dissoc' instead."
+  (let ((new-table (make-hash-table :size (hash-table-count table)
+                                    :test (hash-table-test table)))
+        (rest-keys (seq-remove (lambda (k)
+                                 (member k keys))
+                               (a-keys table))))
+    (seq-doseq (k rest-keys)
+      (puthash k (gethash k table) new-table))
+    new-table))
+
+(defun a-dissoc (coll &rest keys)
+  "Return an updated version of collection COLL with the KEY removed."
+  (cond
+   ((listp coll) (a-dissoc--list coll keys))
+   ((hash-table-p coll) (a-dissoc--hash-table coll keys))))
+
+(defun a-update (coll key fn &rest args)
+  "In collection COLL, at location KEY, apply FN with extra args ARGS.
+'Updates' a value in an associative collection COLL, where KEY is
+a key and FN is a function that will take the old value and any
+supplied args and return the new value, and returns a new
+structure. If the key does not exist, nil is passed as the old
+value."
+  (a-assoc-1 coll
+             key
+             (apply #'funcall fn (a-get coll key) args)))
+
+(defun a-update-in (coll keys fn &rest args)
+  "In collection COLL, at location KEYS, apply FN with extra args ARGS.
+'Updates' a value in a nested associative collection COLL, where
+KEYS is a sequence of keys and FN is a function that will take
+the old value and any supplied ARGS and return the new value, and
+returns a new nested structure. If any levels do not exist,
+association lists will be created."
+  (cl-case (length keys)
+    (0 coll)
+    (1 (apply #'a-update coll (elt keys 0) fn args))
+    (t (a-assoc-1 coll
+                  (elt keys 0)
+                  (apply #'a-update-in
+                         (a-get coll (elt keys 0))
+                         (seq-drop keys 1)
+                         fn
+                         args)))))
+
+(provide 'a)
+
+;;; a.el ends here