diff options
Diffstat (limited to 'emacs/.emacs.d/wpc/list.el')
-rw-r--r-- | emacs/.emacs.d/wpc/list.el | 106 |
1 files changed, 55 insertions, 51 deletions
diff --git a/emacs/.emacs.d/wpc/list.el b/emacs/.emacs.d/wpc/list.el index bf4dc1ca178d..00ff2affcc8a 100644 --- a/emacs/.emacs.d/wpc/list.el +++ b/emacs/.emacs.d/wpc/list.el @@ -1,8 +1,12 @@ -;;; list.el --- Functions for working with lists. -*- lexical-binding: t -*- +;;; list.el --- Functions for working with lists -*- lexical-binding: t -*- + ;; Author: William Carroll <wpcarro@gmail.com> +;; Version: 0.0.1 +;; URL: https://git.wpcarro.dev/wpcarro/briefcase +;; Package-Requires: ((emacs "24")) ;;; Commentary: -;; Since I prefer having the `list/' namespace, I wrote this module to wrap many +;; Since I prefer having the `list-' namespace, I wrote this module to wrap many ;; of the functions that are defined in the the global namespace in ELisp. I ;; sometimes forget the names of these functions, so it's nice for them to be ;; organized like this. @@ -58,56 +62,56 @@ ;; Constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defconst list/tests? t +(defconst list-tests? t "When t, run the test suite.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Library ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun list/new () +(defun list-new () "Return a new, empty list." '()) -(defun list/concat (&rest lists) +(defun list-concat (&rest lists) "Joins `LISTS' into on list." (apply #'-concat lists)) -(defun list/join (joint xs) +(defun list-join (joint xs) "Join a list of strings, XS, with JOINT." - (if (list/empty? xs) + (if (list-empty? xs) "" - (list/reduce (list/first xs) + (list-reduce (list-first xs) (lambda (x acc) (string-concat acc joint x)) - (list/tail xs)))) + (list-tail xs)))) -(defun list/length (xs) +(defun list-length (xs) "Return the number of elements in `XS'." (length xs)) -(defun list/get (i xs) +(defun list-get (i xs) "Return the value in `XS' at `I', or nil." (nth i xs)) -(defun list/head (xs) +(defun list-head (xs) "Return the head of `XS'." (car xs)) ;; TODO: Learn how to write proper function aliases. -(defun list/first (xs) - "Alias for `list/head' for `XS'." - (list/head xs)) +(defun list-first (xs) + "Alias for `list-head' for `XS'." + (list-head xs)) -(defun list/tail (xs) +(defun list-tail (xs) "Return the tail of `XS'." (cdr xs)) -(defun list/reverse (xs) +(defun list-reverse (xs) "Reverses `XS'." (reverse xs)) -(defun list/cons (x xs) +(defun list-cons (x xs) "Add `X' to the head of `XS'." (cons x xs)) @@ -120,56 +124,56 @@ ;; (funcall f b a))) ;; TODO: Make this function work. -(defun list/reduce (acc f xs) +(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)) -;; TODO: Support this. It seems like `alist/set' is not working as I expected it +;; TODO: Support this. It seems like `alist-set' is not working as I expected it ;; to. Perhaps we should add some tests to confirm the expected behavior. -;; (cl-defun list/index (f xs &key (transform (lambda (x) x))) +;; (cl-defun list-index (f xs &key (transform (lambda (x) x))) ;; "Return a mapping of F applied to each x in XS to TRANSFORM applied to x. ;; The TRANSFORM function defaults to the identity function." ;; (->> xs -;; (list/reduce (alist/new) +;; (list-reduce (alist-new) ;; (lambda (x acc) ;; (let ((k (funcall f x)) ;; (v (funcall transform x))) -;; (if (alist/has-key? k acc) +;; (if (alist-has-key? k acc) ;; (setf (alist-get k acc) (list v)) ;; (setf (alist-get k acc) (list v)))))))) ;; (prelude-assert ;; (equal '(("John" . ("Cleese" "Malkovich")) ;; ("Thomas" . ("Aquinas"))) -;; (list/index (lambda (x) (plist-get x :first-name)) +;; (list-index (lambda (x) (plist-get x :first-name)) ;; '((:first-name "John" :last-name "Cleese") ;; (:first-name "John" :last-name "Malkovich") ;; (:first-name "Thomas" :last-name "Aquinas")) ;; :transform (lambda (x) (plist-get x :last-name))))) -(defun list/map (f xs) +(defun list-map (f xs) "Call `F' on each element of `XS'." (-map f xs)) -(defun list/map-indexed (f xs) +(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) +(defun list-filter (p xs) "Return a subset of XS where predicate P returned t." - (list/reverse - (list/reduce + (list-reverse + (list-reduce '() (lambda (x acc) (if (funcall p x) - (list/cons x acc) + (list-cons x acc) acc)) xs))) -(defun list/reject (p xs) +(defun list-reject (p xs) "Return a subset of XS where predicate of P return nil." - (list/filter (lambda (x) (not (funcall p x))) xs)) + (list-filter (lambda (x) (not (funcall p x))) xs)) -(defun list/find (p xs) +(defun list-find (p xs) "Return the first x in XS that passes P or nil." (-find p xs)) @@ -177,64 +181,64 @@ ;; Predicates ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun list/instance? (xs) +(defun list-instance? (xs) "Return t if `XS' is a list. Be leery of using this with things like alists. Many data structures in Elisp are implemented using linked lists." (listp xs)) -(defun list/empty? (xs) +(defun list-empty? (xs) "Return t if XS are empty." - (= 0 (list/length xs))) + (= 0 (list-length xs))) -(defun list/all? (p xs) +(defun list-all? (p xs) "Return t if all `XS' pass the predicate, `P'." (-all? p xs)) -(defun list/any? (p xs) +(defun list-any? (p xs) "Return t if any `XS' pass the predicate, `P'." (-any? p xs)) -(defun list/contains? (x xs) +(defun list-contains? (x xs) "Return t if X is in XS using `equal'." (-contains? xs x)) -(defun list/xs-distinct-by? (f xs) +(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))) + (->> xs (-map f) set-from-list set-count))) ;; TODO: Support dedupe. ;; TODO: Should we call this unique? Or distinct? ;; TODO: Add tests. -(defun list/dedupe-adjacent (xs) +(defun list-dedupe-adjacent (xs) "Return XS without adjacent duplicates." - (prelude-assert (not (list/empty? xs))) - (list/reduce (list (list/first xs)) + (prelude-assert (not (list-empty? xs))) + (list-reduce (list (list-first xs)) (lambda (x acc) - (if (equal x (list/first acc)) + (if (equal x (list-first acc)) acc - (list/cons x acc))) + (list-cons x acc))) xs)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Tests ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; (when list/tests? +;; (when list-tests? ;; (prelude-assert ;; (= 0 -;; (list/length '()))) +;; (list-length '()))) ;; (prelude-assert ;; (= 5 -;; (list/length '(1 2 3 4 5)))) +;; (list-length '(1 2 3 4 5)))) ;; (prelude-assert ;; (= 16 -;; (list/reduce 1 (lambda (x acc) (+ x acc)) '(1 2 3 4 5)))) +;; (list-reduce 1 (lambda (x acc) (+ x acc)) '(1 2 3 4 5)))) ;; (prelude-assert ;; (equal '(2 4 6 8 10) -;; (list/map (lambda (x) (* x 2)) '(1 2 3 4 5))))) +;; (list-map (lambda (x) (* x 2)) '(1 2 3 4 5))))) (provide 'list) ;;; list.el ends here |