!reduce macro

master
Magnar Sveen 14 years ago
parent b24d056081
commit ed2e44722b
  1. 28
      bang.el
  2. 14
      tests.el

@ -27,11 +27,6 @@
(eval-when-compile (require 'cl))
(defvar !compare-fn nil
"Tests for equality use this function or `equal' if this is nil.
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 '()))
@ -47,11 +42,27 @@ It should only be set using dynamic scope with a let, like:
`(mapcar #',form-or-fn ,list)
`(mapcar #'(lambda (it) ,form-or-fn) ,list)))
(defmacro !reduce-from (form-or-fn initial-value list)
`(let ((!--list ,list)
(!--acc ,initial-value))
(while !--list
(let ((it (car !--list))
(acc !--acc))
(setq !--acc ,(if (functionp form-or-fn) (list form-or-fn 'acc 'it) (list 'progn form-or-fn)))
(setq !--list (cdr !--list))))
!--acc))
(defmacro !reduce (form-or-fn list)
(if (eval list)
`(!reduce-from ,form-or-fn ,(car (eval list)) ',(cdr (eval list)))
(if (functionp form-or-fn)
(list form-or-fn)
`(let (acc it) ,form-or-fn))))
(defun !concat (list)
(apply 'concatenate 'list list))
(defalias '!select 'remove-if-not)
(defalias '!select '!filter)
(defalias '!reject 'remove-if)
(defalias '!partial 'apply-partially)
@ -92,5 +103,10 @@ or with `!compare-fn' if that's non-nil."
(setq lst (cdr lst)))
lst))))
(defvar !compare-fn nil
"Tests for equality use this function or `equal' if this is nil.
It should only be set using dynamic scope with a let, like:
(let ((!compare-fn =)) (!union numbers1 numbers2 numbers3)")
(provide 'bang)
;;; bang.el ends here

@ -16,6 +16,20 @@
(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 reduce ()
"`!reduce' takes a list and applies the function over them to create one result"
(should (equal (!reduce + '()) 0))
(should (equal (!reduce + '(1)) 1))
(should (equal (!reduce + '(1 2)) 3))
(should (equal (!reduce-from + 7 '()) 7))
(should (equal (!reduce-from + 7 '(1)) 8))
(should (equal (!reduce-from + 7 '(1 2)) 10))
(should (equal (!reduce (lambda (memo item) (format "%s-%s" memo item)) '(1 2 3)) "1-2-3"))
(should (equal (!reduce (format "%s-%s" acc it) '(1 2 3)) "1-2-3"))
(should (equal (!reduce (format "%s-%s" acc it) '()) "nil-nil"))
)
(ert-deftest difference ()
"`!difference' returns a new list of only elements in list1 that are not in list2."
(should (equal (!difference '() '()) '()))

Loading…
Cancel
Save