Share your thoughts in the 2024 State of Clojure Survey!

Welcome! Please see the About page for a little more info on how this works.

+2 votes
in Transducers by

Reductions does not currently provide a transducer when called with a 1-arity.

Proposed:

  • A reductions transducer with explicit initialization values: reductions-with
  • Do to arity conflicts, this is a separate function, not combined with reductions

A second patch proposes a variant which allows explicit initialization values: reductions-with

(assert (= (sequence (reductions-with + 0) [1 2 3 4 5]) [1 3 6 10 15])))

Patch: 0003-add-reductions-with.patch

Prescreened by: Alex Miller

16 Answers

0 votes
by

Comment made by: steveminer@gmail.com

The suggested patch gets the "init" value for the reductions by calling the function with no args. I would like a "reductions" transducer that took an explicit "init" rather than relying on a nullary (f).

If I remember correctly, Rich has expressed some regrets about supporting reduce without an init (ala Common Lisp). My understanding is that an explicit init is preferred for new Clojure code.

Unfortunately, an explicit init arg for the transducer would conflict with the standard "no-init" reductions (link: f coll). In my own code, I've used the name "accumulations" for this transducer. Another possible name might be "reductions-with".

0 votes
by

Comment made by: pyr

Hi Steve,

I'd much prefer for init values to be explicit as well, unfortunately, short of testing the 2nd argument in the 2-arity variant - which would probably be even more confusing, there's no way to do that with plain "reductions".

I like the idea of providing a "reductions-with" variant that forced the init value and I'm happy to augment the patch with that if needed.

0 votes
by

Comment made by: pyr

@Steve Miner I added a variant with reductions-with.

0 votes
by

Comment made by: pyr

Is there anything I can help to move this forward?
@alexmiller any comments on the code itself?

0 votes
by

Comment made by: alexmiller

Haven't had a chance to look at it yet, sorry.

0 votes
by

Comment made by: pyr

@alexmiller, if the upshot is getting clojure.spec, I'll take this taking a bit of time to review :-)

0 votes
by

Comment made by: steveminer@gmail.com

For testing, I suggest you compare the output from the transducer version to the output from a simliar call to the sequence reductions. For example,

`

(is (= (reductions + 3 (range 20)) (sequence (reductions-with + 3) (range 20)))

`

I would like to see that equality hold. The 0002 patch doesn't handle the init the same way the current Clojure reductions does.

0 votes
by

Comment made by: pyr

@alexmiller I'm tempting one more nudge to at least get an idea on the patch and the reductions-with variant since 1.9 seems to be getting closer to a release.

0 votes
by

Comment made by: alexmiller

Sorry, don't know that I'll get to it soon or that it will be considered for 1.9. I also don't know that it won't, just ... don't know.

0 votes
by

Comment made by: pyr

@alexmiller, Thanks for the prompt reply. I'm trying to make sure i'll be around when feedback comes to be able to act quickly on it. Cheers!

0 votes
by

Comment made by: pyr

@alexmiller, any additonal insight into wether this has a chance of going in or if I can adapt/perfect the code in any way?

0 votes
by

Comment made by: alexmiller

I will try to prescreen it when I get a chance.

0 votes
by

Comment made by: alexmiller

I think I prefer the reductions-with approach rather than overloading into reductions.

You have two derefs @state - this is not wrong given the assumptions we are making here, but I think it would be stylistically preferred to see a single deref of state in a let.

0 votes
by

Comment made by: pyr

Hi @alexmiller, It does make more sense to only have reductions-with, with a consistent behavior.
I've added a third patch which implements it according to your recommendations, avoiding the double deref.

0 votes
by

Comment made by: sickill

FYI, I've used reductions-with from the 3rd patch by Pierre-Yves in my ClojureScript project and it worked out of the box without any adjustments.

...