Why is there no first?
Bost opened this issue · comments
Bost commented
I wonder what's the reason behind not having:
(defn first
"Reducing function that returns the first value."
([] nil)
([x] x)
([x _] x))
? as a "complement" of last
.
Edit:
Huh, interestingly enough it won't work at all:
(defn dbg-first
([] nil)
([x] x)
([x y]
(println ";; x" x "y" y)
x))
(transduce (comp
(filter odd?)
(map inc))
dbg-first [42]
[1 2 3 4])
;; x [42] y 2
;; x [42] y 4
;; => [42]
I'm getting convinced this issue can be closed. Happy Xmas! :)
Krisztián Szabó commented
You are lookings for rfs/some
:
(defn some
"Reducing function that returns the first logical true value."
([] nil)
([x] x)
([_ x] (when x (reduced x))))
Bost commented
Thanks for pointing out the rfs/some
. However there's something about it:
(require
'[net.cgrand.xforms :as x]
'[net.cgrand.xforms.rfs :as rfs])
(into {} (x/by-key identity rfs/last) [1 2 3 4]) ;; => {1 1, 2 2, 3 3, 4 4}
(into {} (x/by-key identity x/last) [1 2 3 4]) ;; => {1 1, 2 2, 3 3, 4 4}
(into {} (x/by-key identity rfs/some) [1 2 3 4]) ;; => {1 1, 2 2, 3 3, 4 4}
;; (into {} (x/by-key identity x/some) [1 2 3 4]) ;; throws 'Wrong number of args (1) passed to: net.cgrand.xforms/some'
Also:
(reduce rfs/last [1 2 3 4]) ;; => 4
(reduce rfs/some [1 2 3 4]) ;; => returns 2; I'd expect 1
(x/some identity [1 2 3 4]) ;; => 1
(x/last identity [1 2 3 4]) ;; throws 'Wrong number of args (2) passed to: net.cgrand.xforms/reduce/fn--35656'
And here I'd expect same types:
(type (rfs/last identity [1 2 3 4])) ;; => clojure.lang.PersistentVector
(type (rfs/some identity [1 2 3 4])) ;; => clojure.lang.Reduced
Christophe Grand commented
(reduce rfs/some [1 2 3 4]) ;; => returns 2; I'd expect 1
rtfs/*
are meant to be used with transduce
not reduce
(whose no-init arity semantics are not great imo):
(transduce identity rfs/some [1 2 3 4]) ;; => returns 1
x/last
is a transducer not a transducing context. However x/some
is a transducing context
=> (into [] x/last [1 2 3 4])
[4]
=> (x/some x/last [1 2 3 4])
4