To add to Ivh's answer, the source code isn't too hard to follow here. Cursive 
makes this really easy because you can follow the source right into 
clojure.lang.RT, but you don't need to go that far to see how `reduced?` is 
used.

You can see that all implementations of `reduce` in clojure.core.protocols call 
`reduced?` to see if they should stop reducing. So, this is a convention that a 
reducing or transducing process needs to follow. If you ever need to write a 
function that takes a transducer, and which applies that transducer without 
simply calling `transduce` or friends, you'll also need to uphold that 
contract. More here <https://clojure.org/reference/transducers>.

I thought I had found a nice application for `reduced?` outside this context, 
but alas it was not to be. I wanted to detect whether a `reduce` had terminated 
due to a condition being met or because it had exhausted the input collection, 
assuming that `reduced?` was checking for some metadata glued onto the value.

(reduced? (reduce #(if (= %2 5) (reduced %2) (+ %1 %2)) (range 1 10)))
=> false

The reason is that `reduced` wraps the value in a Reduced, which implements 
IDeref, and one must dereference it to obtain the wrapped value. The reducing / 
transducing processes not only must check for `reduced?` but they are also 
obliged to deref any such value that returns true for that check.

(reduced 5)
=> #object[clojure.lang.Reduced 0x471e4b70 {:status :ready, :val 5}]
(deref *1)
=> 5

So you really will never make use of `reduced?` unless you're *inside* an 
implementation of a reducing / transducing process. As Ivh already stated, 
extremely narrow-use :)


> On Apr 25, 2017, at 12:34 PM, John Gabriele <jmg3...@gmail.com 
> <mailto:jmg3...@gmail.com>> wrote:
> 
> Just recently stumbled upon `reduced` and `reduced?`. It seems rather 
> magical... how does the outer `reduce` (or `reductions`) know to stop? That 
> is, how does the function which is being called (`reduced`) affect the 
> function that's calling it (below, `reductions`)? :
> 
> ~~~clojure
> (defn main
>   []
>   (let [res (reductions (fn [accum x]
>                           (if (< accum 100)
>                             (+ accum x)
>                             (reduced [x accum])))
>                         (range))]
>     (prn res)
>     (prn (reduced? res)) ;=> false
>     (prn (reduced? (last res))))) ;=> false --- why isn't this `true`?
> ~~~
> 
> Also, what's the use of `reduced?`, and on what in the above snippet would I 
> call it to return true?
> 
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com 
> <mailto:clojure@googlegroups.com>
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com 
> <mailto:clojure+unsubscr...@googlegroups.com>
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en 
> <http://groups.google.com/group/clojure?hl=en>
> --- 
> You received this message because you are subscribed to the Google Groups 
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com 
> <mailto:clojure+unsubscr...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout 
> <https://groups.google.com/d/optout>.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to