about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilliam Carroll <wpcarro@gmail.com>2022-08-05T19·34-0700
committerclbot <clbot@tvl.fyi>2022-08-05T19·38+0000
commite5503751c4a3279055c4714a91c39affabb8c461 (patch)
tree15ef9ae0766895a6cee2af435c4b1603ca72976c
parentb880fc4a14e8f49a0deeb9ff5c0562771d9a70e3 (diff)
feat(wpcarro/emacs): Add fns to list.el r/4385
new functions:
- duplicate
- last
- delete
- wrap

also:
- drop support for `list-head` (in favor of `list-first`)
- add optional arg to first

Change-Id: If3c48d4749a3bc5a853995996fa02a65a4076a10
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6041
Reviewed-by: wpcarro <wpcarro@gmail.com>
Autosubmit: wpcarro <wpcarro@gmail.com>
Tested-by: BuildkiteCI
-rw-r--r--users/wpcarro/emacs/.emacs.d/wpc/irc.el2
-rw-r--r--users/wpcarro/emacs/.emacs.d/wpc/stack.el2
-rw-r--r--users/wpcarro/emacs/pkgs/list/list.el40
-rw-r--r--users/wpcarro/emacs/pkgs/list/tests.el36
4 files changed, 70 insertions, 10 deletions
diff --git a/users/wpcarro/emacs/.emacs.d/wpc/irc.el b/users/wpcarro/emacs/.emacs.d/wpc/irc.el
index 70d26f7f08..4ae50b4b1b 100644
--- a/users/wpcarro/emacs/.emacs.d/wpc/irc.el
+++ b/users/wpcarro/emacs/.emacs.d/wpc/irc.el
@@ -106,7 +106,7 @@
   (let ((buffers (erc-buffer-list)))
     (if (list-empty? buffers)
         (error "[irc.el] No ERC buffers available")
-      (switch-to-buffer (list-head (erc-buffer-list))))))
+      (switch-to-buffer (list-first (erc-buffer-list))))))
 
 (defun irc-connect-to-freenode ()
   "Connect to Freenode IRC."
diff --git a/users/wpcarro/emacs/.emacs.d/wpc/stack.el b/users/wpcarro/emacs/.emacs.d/wpc/stack.el
index 3d1e3e4a16..e81cec6a45 100644
--- a/users/wpcarro/emacs/.emacs.d/wpc/stack.el
+++ b/users/wpcarro/emacs/.emacs.d/wpc/stack.el
@@ -46,7 +46,7 @@
   "Look at the top element of `XS' without popping it off."
   (->> xs
        stack-xs
-       list-head))
+       list-first))
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Update
diff --git a/users/wpcarro/emacs/pkgs/list/list.el b/users/wpcarro/emacs/pkgs/list/list.el
index 2aa226609d..a395eba267 100644
--- a/users/wpcarro/emacs/pkgs/list/list.el
+++ b/users/wpcarro/emacs/pkgs/list/list.el
@@ -68,6 +68,10 @@
   "Joins `LISTS' into on list."
   (apply #'-concat lists))
 
+(defun list-duplicate (n x)
+  "Duplicates the given element, X, N times in a list."
+  (list-map (lambda (_) x) (number-sequence 1 n)))
+
 (defun list-join (joint xs)
   "Join a list of strings, XS, with JOINT."
   (if (list-empty? xs)
@@ -85,14 +89,17 @@
   "Return the value in `XS' at `I', or nil."
   (nth i xs))
 
-(defun list-head (xs)
-  "Return the head of `XS'."
-  (car xs))
-
-;; TODO: Learn how to write proper function aliases.
-(defun list-first (xs)
+(defun list-first (xs &optional default)
   "Alias for `list-head' for `XS'."
-  (list-head xs))
+  (if (list-empty? xs)
+      default
+    (car xs)))
+
+(defun list-last (xs &optional default)
+  "Returns the last element in XS or DEFAULT if empty."
+  (if (list-empty? xs)
+      default
+    (nth (- (length xs) 1) xs)))
 
 (defun list-tail (xs)
   "Return the tail of `XS'."
@@ -106,6 +113,17 @@
   "Add `X' to the head of `XS'."
   (cons x xs))
 
+(defun list-delete (x xs)
+  "Deletes the given element, X, from XS.
+Returns a new list without X. If X occurs more than once, only the first
+  occurrence is removed."
+  (let ((deleted? nil))
+    (list-reject (lambda (y)
+                   (if deleted? nil
+                     (when (equal x y)
+                       (setq deleted? t) t)))
+                 xs)))
+
 (defun list-filter (p xs)
   "Return a subset of XS where predicate P returned t."
   (list--assert-instance xs)
@@ -202,13 +220,19 @@ Be leery of using this with things like alists.  Many data structures in Elisp
 (defun list-contains? (x xs)
   "Return t if X is in XS using `equal'."
   (list--assert-instance xs)
-  (maybe-some? (seq-contains xs x)))
+  (maybe-some? (seq-contains-p 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)
      (set-count (set-from-list (list-map f xs)))))
 
+(defun list-wrap (xs)
+  "Wraps XS in a list if it is not a list already."
+  (if (list-instance? xs)
+      xs
+    (list xs)))
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Helpers
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/users/wpcarro/emacs/pkgs/list/tests.el b/users/wpcarro/emacs/pkgs/list/tests.el
index e2fb5788d6..4ee03c6b97 100644
--- a/users/wpcarro/emacs/pkgs/list/tests.el
+++ b/users/wpcarro/emacs/pkgs/list/tests.el
@@ -65,3 +65,39 @@
   (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)))))
+
+(ert-deftest list-duplicate ()
+  (should (equal '() (list-duplicate 0 "hello")))
+  (should (equal '("hi") (list-duplicate 1 "hi")))
+  (should (equal '("bye" "bye") (list-duplicate 2 "bye")))
+  (should (equal '((1 2) (1 2) (1 2)) (list-duplicate 3 '(1 2)))))
+
+(ert-deftest list-first ()
+  (should (null (list-first '())))
+  (should (equal 1 (list-first '() 1)))
+  (should (equal 1 (list-first '(1))))
+  (should (equal 1 (list-first '(1) 2)))
+  (should (equal 1 (list-first '(1 2 3)))))
+
+(ert-deftest list-last ()
+  (should (null (list-last '())))
+  (should (equal 1 (list-last '() 1)))
+  (should (equal 1 (list-last '(1))))
+  (should (equal 1 (list-last '(1) 2)))
+  (should (equal 3 (list-last '(1 2 3)))))
+
+(ert-deftest list-wrap ()
+  (should (equal '("hello") (list-wrap "hello")))
+  (should (equal '(1 2 3) (list-wrap '(1 2 3))))
+  (should (equal '() (list-wrap nil))))
+
+(ert-deftest list-delete ()
+  (should (equal '(b c) (list-delete 'a '(a b c))))
+  (should (equal '(a b c) (list-delete 'd '(a b c))))
+  (should (equal '(a b c) (list-delete 'b '(a b b c))))
+  (should (equal '() (list-delete 'b '()))))
+
+;; TODO(wpcarro): Supoprt this.
+;; (ert-deftest list-zip ()
+;;   (should (equal '((1 3 5) (2 4 6)) (list-zip '(1 2) '(3 4) '(5 6))))
+;;   (should (equal '((1 3 5)) (list-zip '(1 2) '(3) '(5 6)))))