refactor(wpcarro/emacs): Remove list.el's dep on dash.el 🎉

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
This commit is contained in:
William Carroll 2022-08-05 11:41:32 -07:00 committed by clbot
parent 42e7254ad0
commit b880fc4a14
3 changed files with 64 additions and 46 deletions

View file

@ -8,9 +8,6 @@ let
version = "1.0.0";
src = ./list.el;
packageRequires =
(with emacsPackages; [
dash
]) ++
(with depot.users.wpcarro.emacs.pkgs; [
maybe
set

View file

@ -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
;; 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)))
;; 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-filter (p xs)
"Return a subset of XS where predicate P returned t."
(list--assert-instance xs)
(seq-filter p xs))
(defun list-map (f xs)
"Call `F' on each element of `XS'."
(-map f xs))
(list--assert-instance xs)
(seq-map f xs))
(defun list-reduce (acc f xs)
"Return over `XS' calling `F' on an element in `XS'and `ACC'."
(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

View file

@ -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)))))