about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2022-08-05T18·41-0700
committerclbot <clbot@tvl.fyi>2022-08-05T18·44+0000
commitb880fc4a14e8f49a0deeb9ff5c0562771d9a70e3 (patch)
tree404e0bb2617a3b7a4ef692dfb73d0a5de721539d
parent42e7254ad0d3c0589646f132f7a04dcd5bfb3523 (diff)
refactor(wpcarro/emacs): Remove list.el's dep on dash.el 🎉 r/4384
Still pruning the dependency tree. Thank you, seq.el, from DWIMing.

Change-Id: I797f08abe44853b9d297a99d5ba9e9bde3dcfeec
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6040
Reviewed-by: wpcarro <wpcarro@gmail.com>
Autosubmit: wpcarro <wpcarro@gmail.com>
Tested-by: BuildkiteCI
-rw-r--r--users/wpcarro/emacs/pkgs/list/default.nix3
-rw-r--r--users/wpcarro/emacs/pkgs/list/list.el92
-rw-r--r--users/wpcarro/emacs/pkgs/list/tests.el13
3 files changed, 63 insertions, 45 deletions
diff --git a/users/wpcarro/emacs/pkgs/list/default.nix b/users/wpcarro/emacs/pkgs/list/default.nix
index cc94df87dc..1be0b901eb 100644
--- a/users/wpcarro/emacs/pkgs/list/default.nix
+++ b/users/wpcarro/emacs/pkgs/list/default.nix
@@ -8,9 +8,6 @@ let
         version = "1.0.0";
         src = ./list.el;
         packageRequires =
-          (with emacsPackages; [
-            dash
-          ]) ++
           (with depot.users.wpcarro.emacs.pkgs; [
             maybe
             set
diff --git a/users/wpcarro/emacs/pkgs/list/list.el b/users/wpcarro/emacs/pkgs/list/list.el
index a1822e77ff..2aa226609d 100644
--- a/users/wpcarro/emacs/pkgs/list/list.el
+++ b/users/wpcarro/emacs/pkgs/list/list.el
@@ -52,9 +52,9 @@
 ;; Dependencies
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(require 'dash)
 (require 'maybe)
 (require 'set)
+(require 'set)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Library
@@ -106,37 +106,31 @@
   "Add `X' to the head of `XS'."
   (cons x xs))
 
-;; map, filter, reduce
+(defun list-filter (p xs)
+  "Return a subset of XS where predicate P returned t."
+  (list--assert-instance xs)
+  (seq-filter p xs))
 
-;; TODO: Create function adapters like swap.
-;; (defun adapter/swap (f)
-;;   "Return a new function that wraps `F' and swaps the arguments."
-;;   (lambda (a b)
-;;     (funcall f b a)))
+(defun list-map (f xs)
+  "Call `F' on each element of `XS'."
+  (list--assert-instance xs)
+  (seq-map f xs))
 
-;; TODO: Make this function work.
 (defun list-reduce (acc f xs)
   "Return over `XS' calling `F' on an element in `XS'and `ACC'."
-  (-reduce-from (lambda (acc x) (funcall f x acc)) acc xs))
-
-(defun list-map (f xs)
-  "Call `F' on each element of `XS'."
-  (-map f xs))
+  (list--assert-instance xs)
+  (seq-reduce (lambda (acc x) (funcall f x acc)) xs acc))
 
 (defun list-map-indexed (f xs)
   "Call `F' on each element of `XS' along with its index."
-  (-map-indexed (lambda (i x) (funcall f x i)) xs))
-
-(defun list-filter (p xs)
-  "Return a subset of XS where predicate P returned t."
   (list-reverse
-   (list-reduce
-    '()
-    (lambda (x acc)
-      (if (funcall p x)
-          (list-cons x acc)
-        acc))
-    xs)))
+   (cdr
+    (list-reduce '(0 . nil)
+                 (lambda (x acc)
+                   (let ((i (car acc))
+                         (result (cdr acc)))
+                     `(,(+ 1 i) . ,(cons (funcall f x i) result))))
+                 xs))))
 
 (defun list-reject (p xs)
   "Return a subset of XS where predicate of P return nil."
@@ -144,7 +138,8 @@
 
 (defun list-find (p xs)
   "Return the first x in XS that passes P or nil."
-  (-find p xs))
+  (list--assert-instance xs)
+  (seq-find p xs))
 
 ;; TODO: Support dedupe.
 ;; TODO: Should we call this unique? Or distinct?
@@ -164,19 +159,17 @@
   "Chunk XS into lists of size N."
   (if (> n (length xs))
       (list xs)
-    (->> xs
-         (list-reduce '(:curr () :result ())
-                      (lambda (x acc)
-                        (let ((curr (plist-get acc :curr))
-                              (result (plist-get acc :result)))
-                          (if (= (- n 1) (length curr))
-                              `(:curr () :result ,(list-cons (list-reverse (list-cons x curr)) result))
-                            `(:curr ,(list-cons x curr) :result ,result)))))
-         (funcall (lambda (xs)
-                    (let ((curr (plist-get xs :curr))
-                          (result (plist-get xs :result)))
-                      (if curr (list-cons curr result)) result)))
-         list-reverse)))
+    (let* ((xs (list-reduce '(:curr () :result ())
+                            (lambda (x acc)
+                              (let ((curr (plist-get acc :curr))
+                                    (result (plist-get acc :result)))
+                                (if (= (- n 1) (length curr))
+                                    `(:curr () :result ,(list-cons (list-reverse (list-cons x curr)) result))
+                                  `(:curr ,(list-cons x curr) :result
+                                          ,result)))) xs))
+           (curr (plist-get xs :curr))
+           (result (plist-get xs :result)))
+      (list-reverse (if curr (list-cons curr result) result)))))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Predicates
@@ -194,20 +187,35 @@ Be leery of using this with things like alists.  Many data structures in Elisp
 
 (defun list-all? (p xs)
   "Return t if all `XS' pass the predicate, `P'."
-  (-all? p xs))
+  (if (list-empty? xs)
+      t
+    (and (maybe-some? (funcall p (car xs)))
+         (list-all? p (cdr xs)))))
 
 (defun list-any? (p xs)
   "Return t if any `XS' pass the predicate, `P'."
-  (-any? p xs))
+  (if (list-empty? xs)
+      nil
+    (or (maybe-some? (funcall p (car xs)))
+        (list-any? p (cdr xs)))))
 
 (defun list-contains? (x xs)
   "Return t if X is in XS using `equal'."
-  (maybe-some? (-contains? xs x)))
+  (list--assert-instance xs)
+  (maybe-some? (seq-contains xs x)))
 
 (defun list-xs-distinct-by? (f xs)
   "Return t if all elements in XS are distinct after applying F to each."
   (= (length xs)
-     (->> xs (-map f) set-from-list set-count)))
+     (set-count (set-from-list (list-map f xs)))))
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Helpers
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+(defun list--assert-instance (xs)
+  (unless (list-instance? xs)
+    (error (format "Assertion failed: argument is not a list: %s" xs))))
 
 (provide 'list)
 ;;; list.el ends here
diff --git a/users/wpcarro/emacs/pkgs/list/tests.el b/users/wpcarro/emacs/pkgs/list/tests.el
index a6096a1d6e..e2fb5788d6 100644
--- a/users/wpcarro/emacs/pkgs/list/tests.el
+++ b/users/wpcarro/emacs/pkgs/list/tests.el
@@ -52,3 +52,16 @@
                  (list-chunk 3 '(1 2 3 4 5 6))))
   (should (equal '((1 2) (3 4) (5 6))
                  (list-chunk 2 '(1 2 3 4 5 6)))))
+
+(ert-deftest list-find ()
+  (should (equal 2 (list-find (lambda (x) (= 2 x)) '(1 2 3 4)))))
+
+(ert-deftest list-all? ()
+  (should (equal t (list-all? (lambda (x) (= 2 x)) nil)))
+  (should (null (list-all? (lambda (x) (= 2 x)) '(1 2 3))))
+  (should (equal t (list-all? (lambda (x) (= 2 x)) '(2 2 2 2)))))
+
+(ert-deftest list-any? ()
+  (should (null (list-any? (lambda (x) (= 2 x)) nil)))
+  (should (equal t (list-any? (lambda (x) (= 2 x)) '(1 2 3))))
+  (should (null (list-any? (lambda (x) (= 4 x)) '(1 2 3)))))