Add !some and !every?

master
Magnar Sveen 14 years ago
parent 24262a133e
commit f59b480a49
  1. 22
      README.md
  2. 28
      bang.el
  3. 10
      examples.el

@ -23,6 +23,8 @@ This is so much a work in progress that you should definitely not be using it ye
* [!intersection](#intersection-list-list2) `(list list2)` * [!intersection](#intersection-list-list2) `(list list2)`
* [!distinct](#distinct-list) `(list)` * [!distinct](#distinct-list) `(list)`
* [!contains?](#contains-list-element) `(list element)` * [!contains?](#contains-list-element) `(list element)`
* [!some](#some-fn-list) `(fn list)`
* [!every?](#every-fn-list) `(fn list)`
There are also anaphoric versions of these functions where that makes sense, There are also anaphoric versions of these functions where that makes sense,
prefixed with two bangs instead of one. prefixed with two bangs instead of one.
@ -205,6 +207,26 @@ or with `!compare-fn` if that's non-nil.
(!contains? '(1 2 3) 4) ;; => nil (!contains? '(1 2 3) 4) ;; => nil
``` ```
### !some `(fn list)`
Returns the first non-nil value of (`fn` x) for any x in `list`, else nil.
```cl
(!some 'even? '(1 2 3)) ;; => t
(!some 'even? '(1 3 5)) ;; => nil
(!!some (= 0 (% it 2)) '(1 2 3)) ;; => t
```
### !every? `(fn list)`
Returns t if (`fn` x) is non-nil for every x in `list`, else nil.
```cl
(!every? 'even? '(1 2 3)) ;; => nil
(!every? 'even? '(2 4 6)) ;; => t
(!!every? (= 0 (% it 2)) '(2 4 6)) ;; => t
```
## Development ## Development

@ -168,6 +168,34 @@ or with `!compare-fn' if that's non-nil."
(setq lst (cdr lst))) (setq lst (cdr lst)))
lst)))))) lst))))))
(defmacro !!some (form list)
"Anaphoric form of `!some'."
`(let ((!--list ,list)
(!--any nil))
(while (and !--list (not !--any))
(let ((it (car !--list)))
(setq !--any ,form))
(setq !--list (cdr !--list)))
!--any))
(defun !some (fn list)
"Returns the first non-nil value of (FN x) for any x in LIST, else nil."
(!!some (funcall fn it) list))
(defmacro !!every? (form list)
"Anaphoric form of `!every?'."
`(let ((!--list ,list)
(!--all t))
(while (and !--all !--list)
(let ((it (car !--list)))
(setq !--all ,form))
(setq !--list (cdr !--list)))
(not (null !--all))))
(defun !every? (fn list)
"Returns t if (FN x) is non-nil for every x in LIST, else nil."
(!!every? (funcall fn it) list))
(defvar !compare-fn nil (defvar !compare-fn nil
"Tests for equality use this function or `equal' if this is 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: It should only be set using dynamic scope with a let, like:

@ -80,3 +80,13 @@
(!contains? '(1 2 3) 4) => nil (!contains? '(1 2 3) 4) => nil
(!contains? '() 1) => nil (!contains? '() 1) => nil
(!contains? '() '()) => nil) (!contains? '() '()) => nil)
(defexamples !some
(!some 'even? '(1 2 3)) => t
(!some 'even? '(1 3 5)) => nil
(!!some (= 0 (% it 2)) '(1 2 3)) => t)
(defexamples !every?
(!every? 'even? '(1 2 3)) => nil
(!every? 'even? '(2 4 6)) => t
(!!every? (= 0 (% it 2)) '(2 4 6)) => t)

Loading…
Cancel
Save