This message was deleted.
# stdlib
s
This message was deleted.
m
I know it's called
scan
in Scala, Haskell and other functional languages. So Python seems to be the odd one out actually :P
s
The name
scan
is also used in many Java libraries for this operator.
f
z
I think of it like this: - “scan” means you’re processing every item with the accumulator and emitting the accumulator every time. It doesn’t care what type the accumulator is, so the accumulator must be “initialized” by passing it as an argument. - “reduce” means the accumulator type is derived from the element type, so it doesn’t need to be passed in. So
reduce
is to
fold
what
scanReduce
is to
scan
. Given that, it would make sense to me to rename
reduce
to
foldReduce
, but
reduce
is already an established name and so it’s too late to rename it (and already implies
fold
in other languages as well anyway).
🙂 1
f
They are still
@ExperimentalStdlibApi
and can be renamed. I recommend you to create a bug report at https://youtrack.jetbrains.com/issues/KT and with a PR https://github.com/JetBrains/kotlin where you change the name directly to what you think is best. I cannot tell how likely it is that you will be heard, so don't get your hopes up, but this will give you most leverage.
scan
and
scanReduce
(the others are BC constant forever).
i
The idea of
scan...
naming is following: for each aggregation function, e.g.
fold
,
reduce
,
sum
,
max
etc, we can get its scanning variant by adding the prefix "scan":
scanReduce
,
scanSum
,
scanMax
. The only exception is made for
fold
, which seems to be so common that
scanFold
cuts down to just
scan
. https://youtrack.jetbrains.com/issue/KT-7657#focus=streamItem-27-3520154.0-0
👍 4
s
fold
and
reduce
are not the same,as
foldl
requires an empty value. So I’ve always seen
reduce
as
foldl1
from Haskell, and I think Kotlin has a better name for it than Haskell in that regard.
You also indicate this “Instead there should be one name with overloads for initial values.”
Is there any academical paper that discusses this? I’d be interessted in reading more on this.
f
The previous Wikipedia article I posted and https://en.wikipedia.org/wiki/Fold_(higher-order_function) should provide you with pointers. Fun fact @Astronaut4449 Wikipedia has accumulate listed as a fold alias. 😉
Just to be clear, I have no opinion here but consider it an important topic. That's why I'm in this thread. 😉
s
Ah great it has a good set of references as well. Thanks @Fleshgrinder 👍
p
I just wanted to say, naming is hard. I personally hate all the names mentioned in this thread except for
scan
which sounds cool. 😎
c
Oh there is already a thread for this. Scan is used by Rx which is available in a variety of programming languages. http://reactivex.io/documentation/operators/scan.html
I don’t know if Kotlin is blindly following other languages… Personally I would agree with the decision to use scan if it was just on the basis of Rx. You have RxSwift, RxScala, RxRb, RxPy, RxPHP, RxNET, RxKotlin, RxJS, JxJava, and RxGroovy all using that naming convention.
Yeah, I could see
accumulate
making sense, although I wonder if that would be confusing with
reduce
as well. Reduce has an accumulator function, but I guess accumulate is a more primitive reduce so could also make sense.
Reduce doesn’t output a running result, and by default reduce accumulates values. I think both of those options would just be confusing.
r
Would it make sense to have a
scanFold
function for consistency, and then just have
scan
be an alias for ease of use? (Like
firstOrNull
and
find
)
l
I personally like
runningFold
and
runningReduce
or
rollingFold
and
rollingReduce
I was suggested on Reddit (https://old.reddit.com/r/Kotlin/comments/ftnvzd/stop_scan_and_scanreduce_before_its_too_late/)
c
@Astronaut4449 do you have a link on youtrack or kotlang’s discuss?
🤷🏻‍♂️ not sure, but it’d be useful to track. Scan was originally brought up on discuss I think https://discuss.kotlinlang.org/t/does-kotlin-have-something-similar-to-rxjava-scan/275
😂 1
i
Update on this: we'll introduce `runningFold`/`runningReduce` and remove
scanReduce
.
scan
will remain as a synonym for
runningFold
https://youtrack.jetbrains.com/issue/KT-38060#focus=streamItem-27-4087852.0-0
🙌🏻 8
j
Hey! Kinda related to this. Is there a way to perform a 
reduce
 / 
scanReduce
 and get the final result as a 
Flow
 (if that even makes sense)?
Since
scanReduce
does return flow but emits all intermediate values, and
reduce
emits final value but not wrapped in a Flow
z
Convert to a flow first (
asFlow()
) then perform the reduce on the flow. Flow has
scan
and
reduce
operators, no
scanReduce
, but you could file a feature request or just write your own version.
m
There is
scanReduce
on
Flow
as well. Although I guess it will be deprecated soon and replaced by
runningReduce
: https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/scan-reduce.html
j
Thank you guys!
z
Derp, sorry - need coffee and to stop reading kdocs on my phone 🤦‍♂️
j
Flow has 
scan
Yes, but it emits the intermediate results
and 
reduce
and
reduce
consumes the flow to give you the value. I think what is missing is something such as (http://reactivex.io/documentation/operators/reduce.html)
Copy code
public suspend inline fun <T, R> Flow<T>.fold(
    crossinline operation: suspend (acc: R, value: T) -> R
): Flow<R>
instead of
Copy code
public suspend fun <S, T : S> Flow<T>.reduce(operation: suspend (accumulator: S, value: T) -> S): S