Re: ? stateful-map ?

2022-12-09 Thread Steve Miner
See also https://github.com/cgrand/xforms for a transducer version of 
reductions.  The argument f must have a nullary arity.  (You could probably 
create your own variant if you want an explicit init value.)  I think something 
like this should work:

(require '[net.cgrand.xforms :as x])

(defn xscan-left
  ([f coll] (sequence (xscan-left f) coll))
  ([f] (comp (x/reductions f) (drop 1

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/28761DAD-5FB9-4561-ACD1-BCDE3D64BEEB%40gmail.com.


Re: ? stateful-map ?

2022-11-28 Thread Jules
Very nearly a direct hit :-)

'reductions' definitely gives me what I want when dealing with eager and 
lazy sequences ... but... it seems to have escaped the transducer makeover 
:-(

core> (reductions + 0 [1 2 3 4 5])
(0 1 3 6 10 15)
core> (take 6 (reductions + (range)))
(0 1 3 6 10 15)
core> (reductions + 0)
Error printing return value (IllegalArgumentException) at 
clojure.lang.RT/seqFrom (RT.java:557).
Don't know how to create ISeq from: java.lang.Long
core> (reductions +)
Execution error (ArityException) at theremin.core/eval351732 
(form-init6069347464735150015.clj:60).
Wrong number of args (1) passed to: clojure.core/reductions
core> 

at least I now know what to call what I am looking for.

Thanks for your help - much appreciated,


Jules

On Sunday, 27 November 2022 at 23:47:22 UTC sritc...@gmail.com wrote:

> Pretty sure what you’re looking for is either 
> https://clojuredocs.org/clojure.core/reductions or something close. This 
> idea is called a “scanLeft” in some functional languages, so that should 
> give you another search term to use. Good luck!
>
> On Sun, Nov 27, 2022, at 12:00 PM, Jules wrote:
>
> Guys,
>
> I've found myself needing a function that I am sure cannot be an original 
> but I'm not aware of it existing anywhere...
>
> It is a cross between 'map', 'reduce' and 'iterate'...
>
> Given a function 'f' and a sequence 's' it would return you  a sequence of 
> :
> ```
> [(f s[0]) (f (f s[0]) s[1]) (f (f (f s[0]) s[1]) s[2]) ...]
> ```
>
> or, more concretely, e.g.:
> ```
> util-test> (stateful-map + [0 1 2 3 4 5])
> [0 1 3 6 10 15]
> util-test> 
> ```
>
> I have a couple of approaches to it - one using reduce:
>
> ```
> (defn stateful-map-1 [f [h & t]]
>   (reduce
>(fn [acc v]
>  (conj acc (f (last acc) v)))
>[h]
>t))
> ```
>
> and another, mapping using a stateful function:
>
> ```
> (let [secret (Object.)]
>   (defn stateful-mapper [f]
> (let [state (volatile! secret)] (fn [v] (vswap! state (fn [old new] 
> (if (= secret old) (f new) (f old new))) v)
>
> (defn stateful-map-2 [f s]
>   (mapv (stateful-mapper f) s))
> ```
>
> The former feels more idiomatic whereas the latter (although uglier) is 
> more efficient and has the added benefit of being able to be used for 
> general map-ing which is important as I want to use this approach to 
> transduce a clojure.async.channel.
>
> It could, of course, be expressed directly as a transducer but it feels 
> like something simpler that should only be lifted to a transducer as and 
> when needed (see test below) ...
>
> Here is my working testsuite:
>
> ```
> (deftest stateful-map-test
>   (testing "reduction"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (stateful-map-1 + [0 1 2 3 4 5]
>   (testing "mapping stateful function"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (stateful-map-2 + [0 1 2 3 4 5]
>   (testing "transduction"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (sequence (map (stateful-mapper +)) [0 1 2 3 4 5])
> ```
>
> Am I missing a standard way of doing this in Clojure ? Or is a stateful 
> function the best answer ?
>
> Interested in your thoughts,
>
>
> Jules
>
>
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/clojure/f1ada73f-8249-431a-9f4d-580aea12bdefn%40googlegroups.com
>  
> 
> .
>
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/4c2bf7c2-2703-4d4a-9cc0-00cc830d2705n%40googlegroups.com.


Re: ? stateful-map ?

2022-11-27 Thread Sam Ritchie
Pretty sure what you’re looking for is either 
https://clojuredocs.org/clojure.core/reductions or something close. This idea 
is called a “scanLeft” in some functional languages, so that should give you 
another search term to use. Good luck!

On Sun, Nov 27, 2022, at 12:00 PM, Jules wrote:
> Guys,
> 
> I've found myself needing a function that I am sure cannot be an original but 
> I'm not aware of it existing anywhere...
> 
> It is a cross between 'map', 'reduce' and 'iterate'...
> 
> Given a function 'f' and a sequence 's' it would return you  a sequence of :
> ```
> [(f s[0]) (f (f s[0]) s[1]) (f (f (f s[0]) s[1]) s[2]) ...]
> ```
> 
> or, more concretely, e.g.:
> ```
> util-test> (stateful-map + [0 1 2 3 4 5])
> [0 1 3 6 10 15]
> util-test> 
> ```
> 
> I have a couple of approaches to it - one using reduce:
> 
> ```
> (defn stateful-map-1 [f [h & t]]
>   (reduce
>(fn [acc v]
>  (conj acc (f (last acc) v)))
>[h]
>t))
> ```
> 
> and another, mapping using a stateful function:
> 
> ```
> (let [secret (Object.)]
>   (defn stateful-mapper [f]
> (let [state (volatile! secret)] (fn [v] (vswap! state (fn [old new] (if 
> (= secret old) (f new) (f old new))) v)
> 
> (defn stateful-map-2 [f s]
>   (mapv (stateful-mapper f) s))
> ```
> 
> The former feels more idiomatic whereas the latter (although uglier) is more 
> efficient and has the added benefit of being able to be used for general 
> map-ing which is important as I want to use this approach to transduce a 
> clojure.async.channel.
> 
> It could, of course, be expressed directly as a transducer but it feels like 
> something simpler that should only be lifted to a transducer as and when 
> needed (see test below) ...
> 
> Here is my working testsuite:
> 
> ```
> (deftest stateful-map-test
>   (testing "reduction"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (stateful-map-1 + [0 1 2 3 4 5]
>   (testing "mapping stateful function"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (stateful-map-2 + [0 1 2 3 4 5]
>   (testing "transduction"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (sequence (map (stateful-mapper +)) [0 1 2 3 4 5])
> ```
> 
> Am I missing a standard way of doing this in Clojure ? Or is a stateful 
> function the best answer ?
> 
> Interested in your thoughts,
> 
> 
> Jules
> 
> 
> 
> -- 
> 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.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/clojure/f1ada73f-8249-431a-9f4d-580aea12bdefn%40googlegroups.com
>  
> .

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/798d8cc2-b3b0-4036-b3a2-5cbf43751c98%40app.fastmail.com.


Re: ? stateful-map ?

2022-11-27 Thread Jules
I thought I should have a look at clojure.core.reducers in case there was 
an answer there - but this all still looks eager whereas I need something 
like a lazy reduction which applies a given function to its accumulator and 
each input to give it's new accumulator, which is output on each step...

Jules


On Sunday, 27 November 2022 at 19:00:48 UTC Jules wrote:

> Guys,
>
> I've found myself needing a function that I am sure cannot be an original 
> but I'm not aware of it existing anywhere...
>
> It is a cross between 'map', 'reduce' and 'iterate'...
>
> Given a function 'f' and a sequence 's' it would return you  a sequence of 
> :
> ```
> [(f s[0]) (f (f s[0]) s[1]) (f (f (f s[0]) s[1]) s[2]) ...]
> ```
>
> or, more concretely, e.g.:
> ```
> util-test> (stateful-map + [0 1 2 3 4 5])
> [0 1 3 6 10 15]
> util-test> 
> ```
>
> I have a couple of approaches to it - one using reduce:
>
> ```
> (defn stateful-map-1 [f [h & t]]
>   (reduce
>(fn [acc v]
>  (conj acc (f (last acc) v)))
>[h]
>t))
> ```
>
> and another, mapping using a stateful function:
>
> ```
> (let [secret (Object.)]
>   (defn stateful-mapper [f]
> (let [state (volatile! secret)] (fn [v] (vswap! state (fn [old new] 
> (if (= secret old) (f new) (f old new))) v)
>
> (defn stateful-map-2 [f s]
>   (mapv (stateful-mapper f) s))
> ```
>
> The former feels more idiomatic whereas the latter (although uglier) is 
> more efficient and has the added benefit of being able to be used for 
> general map-ing which is important as I want to use this approach to 
> transduce a clojure.async.channel.
>
> It could, of course, be expressed directly as a transducer but it feels 
> like something simpler that should only be lifted to a transducer as and 
> when needed (see test below) ...
>
> Here is my working testsuite:
>
> ```
> (deftest stateful-map-test
>   (testing "reduction"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (stateful-map-1 + [0 1 2 3 4 5]
>   (testing "mapping stateful function"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (stateful-map-2 + [0 1 2 3 4 5]
>   (testing "transduction"
> (is
>  (=
>   [0 1 3 6 10 15]
>   (sequence (map (stateful-mapper +)) [0 1 2 3 4 5])
> ```
>
> Am I missing a standard way of doing this in Clojure ? Or is a stateful 
> function the best answer ?
>
> Interested in your thoughts,
>
>
> Jules
>
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/fd2a6541-6d54-427c-a603-f451cd4728f3n%40googlegroups.com.