anaphoric: fix first & last when conditions fail

* hy/contrib/anaphoric.hy: `ap-first` and `ap-last` now handle cases
  when failure happens for the predicate. Thanks to @tutorto for
  reporting this bug
This commit is contained in:
Abhishek L 2014-05-15 23:41:24 +05:30
parent b5a058a3bc
commit c2982a9ae3
2 changed files with 14 additions and 10 deletions

View File

@ -84,18 +84,20 @@
(defmacro ap-first [predfn lst] (defmacro ap-first [predfn lst]
"Yield the first element that passes `predfn`" "Yield the first element that passes `predfn`"
`(let [[n (gensym)]] (with-gensyms [n]
(ap-each ~lst (when ~predfn (setv n it) (break))) `(let [[~n None]]
n)) (ap-each ~lst (when ~predfn (setv ~n it) (break)))
~n)))
(defmacro ap-last [predfn lst] (defmacro ap-last [predfn lst]
"Yield the last element that passes `predfn`" "Yield the last element that passes `predfn`"
`(let [[n (gensym)]] (with-gensyms [n]
(ap-each ~lst (none? n) `(let [[~n None]]
(ap-each ~lst (none? ~n)
(when ~predfn (when ~predfn
(setv n it))) (setv ~n it)))
n)) ~n)))
(defmacro ap-reduce [form lst &optional [initial-value None]] (defmacro ap-reduce [form lst &optional [initial-value None]]

View File

@ -87,12 +87,14 @@
(defn test-ap-first [] (defn test-ap-first []
"NATIVE: testing anaphoric first" "NATIVE: testing anaphoric first"
(assert-equal (ap-first (> it 5) (range 10)) 6) (assert-equal (ap-first (> it 5) (range 10)) 6)
(assert-equal (ap-first (even? it) [1 2 3 4]) 2)) (assert-equal (ap-first (even? it) [1 2 3 4]) 2)
(assert-equal (ap-first (> it 10) (range 10)) None))
(defn test-ap-last [] (defn test-ap-last []
"NATIVE: testing anaphoric last" "NATIVE: testing anaphoric last"
(assert-equal (ap-last (> it 5) (range 10)) 9) (assert-equal (ap-last (> it 5) (range 10)) 9)
(assert-equal (ap-last (even? it) [1 2 3 4]) 4)) (assert-equal (ap-last (even? it) [1 2 3 4]) 4)
(assert-equal (ap-last (> it 10) (range 10)) None))
(defn test-ap-reduce [] (defn test-ap-reduce []
"NATIVE: testing anaphoric reduce" "NATIVE: testing anaphoric reduce"