Re: Opinion on take-while for stateful transducers

2015-05-12 Thread Andy-
Thanks for the reply. I do like this. I think it's actually more elegant. 
Definitely going into my toolbox. One thing I dislike is that I still have 
to re-implement the logic of the already existing (performant  tested) 
transducers.
Also, I could also add a 4th parameter: 'terminate-early?' but that's then 
already 4 parameters to remember... I'll have to see what way is best once 
I implement more transducers with your or my (hacky) method.

Cheers

On Monday, May 11, 2015 at 1:34:31 PM UTC-4, miner wrote:

 Not an expert, but I’ll throw out an alternative approach that might work 
 for you.  I think it’s simpler to use a transducer that calls functions 
 rather than trying to transform an existing transducer to do the cutoff. 

 (defn take-while-accumulating [accf init pred2] 
(fn [rf] 
  (let [vstate (volatile! init)] 
(fn 
  ([] (rf)) 
  ([result] (rf result)) 
  ([result input] 
   (if (pred2 @vstate input) 
 (do (vswap! vstate accf input) 
 (rf result input)) 
 (reduced result))) 

 accf is like a reducing function: takes two args, state and input, and 
 returns new state of the “accumulation”.  init is the initial state of the 
 accumulation.  pred2 is a predicate taking two args, the accumulation state 
 and the new input.  The process stops when pred2 returns false. 

 ;; distinct 
 (into [] (take-while-accumulating conj #{} (complement contains?)) '(1 2 3 
 4 2 5 6)) 
 ;;= [1 2 3 4] 

 ;; dedupe 
 (into [] (take-while-accumulating (fn [r x] x) ::void not=) '(1 2 1 3 4 4 
 5 6)) 
 ;;= [1 2 1 3 4] 

 ;; monotonically increasing 
 (into [] (take-while-accumulating max 0 =) '(1 2 3 4 4 1 5 6)) 
 [1 2 3 4 4] 


 Steve Miner 
 steve...@gmail.com javascript: 


   

 On May 9, 2015, at 6:28 PM, Andy- andre...@gmail.com javascript: 
 wrote: 

  (defn take-while-xf 

  Takes a transducer and returns a transducer that will immediately 
 finish (ie 
call (reduced)) when the transducer did not call the reducing function 
 and 
just returned the result. Only really useful with stateful 
 transducers. 
Otherwise you'd use take-while. 
  
  [xf] 
  



-- 
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.


Re: Opinion on take-while for stateful transducers

2015-05-11 Thread Steve Miner
Not an expert, but I’ll throw out an alternative approach that might work for 
you.  I think it’s simpler to use a transducer that calls functions rather than 
trying to transform an existing transducer to do the cutoff.

(defn take-while-accumulating [accf init pred2]
   (fn [rf]
 (let [vstate (volatile! init)]
   (fn
 ([] (rf))
 ([result] (rf result))
 ([result input]
  (if (pred2 @vstate input)
(do (vswap! vstate accf input)
(rf result input))
(reduced result)))

accf is like a reducing function: takes two args, state and input, and returns 
new state of the “accumulation”.  init is the initial state of the 
accumulation.  pred2 is a predicate taking two args, the accumulation state and 
the new input.  The process stops when pred2 returns false.

;; distinct
(into [] (take-while-accumulating conj #{} (complement contains?)) '(1 2 3 4 2 
5 6))
;;= [1 2 3 4]

;; dedupe
(into [] (take-while-accumulating (fn [r x] x) ::void not=) '(1 2 1 3 4 4 5 6))
;;= [1 2 1 3 4]

;; monotonically increasing
(into [] (take-while-accumulating max 0 =) '(1 2 3 4 4 1 5 6))
[1 2 3 4 4]


Steve Miner
stevemi...@gmail.com


  

On May 9, 2015, at 6:28 PM, Andy- andre.r...@gmail.com wrote:

 (defn take-while-xf
  
 Takes a transducer and returns a transducer that will immediately finish (ie
   call (reduced)) when the transducer did not call the reducing function and
   just returned the result. Only really useful with stateful transducers.
   Otherwise you'd use take-while.
 
 [xf]
 

-- 
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.