diff --git a/bang.el b/bang.el index 9f67ed0..46689e4 100644 --- a/bang.el +++ b/bang.el @@ -32,11 +32,25 @@ It should only be set using dynamic scope with a let, like: (let ((!compare-fn =)) (!union numbers1 numbers2 numbers3)") +(defmacro !filter (form-or-fn list) + `(let ((!--list ,list) + (!--result '())) + (while !--list + (let ((it (car !--list))) + (when ,(if (functionp form-or-fn) (list form-or-fn 'it) (list 'progn form-or-fn)) + (setq !--result (cons it !--result)))) + (setq !--list (cdr !--list))) + (nreverse !--result))) + +(defmacro !map (form-or-fn list) + (if (functionp form-or-fn) + `(mapcar #',form-or-fn ,list) + `(mapcar #'(lambda (it) ,form-or-fn) ,list))) + + (defun !concat (list) (apply 'concatenate 'list list)) -(defalias '!map 'mapcar) - (defalias '!select 'remove-if-not) (defalias '!reject 'remove-if) @@ -45,16 +59,6 @@ It should only be set using dynamic scope with a let, like: (defun !mapcat (fn list) (!concat (!map fn list))) -(defmacro !filter (form-or-fn list) - `(let ((!--list ,list) - (!--result '())) - (while !--list - (let ((it (car !--list))) - (when ,(if (functionp form-or-fn) (list form-or-fn 'it) (list 'progn form-or-fn)) - (setq !--result (cons it !--result)))) - (setq !--list (cdr !--list))) - (nreverse !--result))) - (defun !uniq (list) "Return a new list with all duplicates removed. The test for equality is done with `equal', diff --git a/tests.el b/tests.el index 5f1a9dc..9600cb6 100644 --- a/tests.el +++ b/tests.el @@ -2,6 +2,7 @@ (require 'bang) (defun even? (num) (= 0 (% num 2))) +(defun square (num) (* num num)) (ert-deftest filter () "`!filter' returns a new list of only those elements where the predicate was non-nil." @@ -9,6 +10,12 @@ (should (equal (!filter (= 0 (% it 2)) '(1 2 3 4)) '(2 4))) (should (equal (!filter even? '(1 2 3 4)) '(2 4)))) +(ert-deftest map () + "`!map' returns a new list with the results of calling the function on each element." + (should (equal (!map (lambda (num) (* num num)) '(1 2 3 4)) '(1 4 9 16))) + (should (equal (!map (* it it) '(1 2 3 4)) '(1 4 9 16))) + (should (equal (!map square '(1 2 3 4)) '(1 4 9 16)))) + (ert-deftest difference () "`!difference' returns a new list of only elements in list1 that are not in list2." (should (equal (!difference '() '()) '()))