Is there a function like `Iterable.sum()` that mul...
# announcements
b
Is there a function like
Iterable.sum()
that multiplies instead? I know I can use reduce to get the same effect, just looking for a cleaner way to code this.
m
I think since there is an ambiguity on what it means to .product() an empty iterable, there is no standard implementation. In Java at least, you start of, for sum, with a 'starting value' e.g. of 0. Then you apply each element on that with an operator (+) and the element. so a sum of an empty list is 0. This is intuitive. However, for product logic, you would need to start with 1 and apply the operator (*) and the element. So the product of an empty list is 1. This is counterintuitive. Your best bet would be to make an extension function and just use that. Then it's still clean everywhere you use it.
💯 3
s
Also, unlike sum it seems a
product
would fairly quickly overflow
b
I’m using
BigInteger
so I should be fine 😉
👍 1
k
I feel that the product of an empty list == 1 actually very logical. If you have a reduce with a monoid operator, you'd expect to get the neutral element
It's the same reason why
max()
in python returns negative infinity
b
Based on the common definition for an empty product https://en.wikipedia.org/wiki/Empty_product it should also be 1.
m
@Kroppeb I wholehearthly disagree and I guess that's why it's not implemented in the first place. At least the max function shouldn't return anything in the case of an empty list, especially considering, in the world of mathematics, there is no singular infinity. You can have infinities of several magnitudes. I guess I would have a nullable int for both of those implementations. Letting the programmer decide what to do in case of no list. @Burkhard I agree that by mathematical convention, a product list should be 1, but there is always semantics to worry about. If you agree with the empty list == 1 than you can just implement that yourself. Others would maybe return a null.
k
Returning an nullable int adds quite a bit of overhead though
m
yes, exactly, going back to why there is no implementation to begin with, since some would find this troublesome to work with
programming is a wonderful mix between social languages and mathematics fortunately 🙂
k
Also you'd expect
(1..n).product()
to return
n!
and
0! = 1
,
1..0 = emptyList()
b
That just goes back to the mathmatical definitsions of those functions for edge cases like 0 or empy set though.
k
Or if you have a list * add an element and take the product or * take the product and multiply by that number, you'd get the same result
so list = [3,5,6] , element = 2 [3,5,6,2].product() = 180 [3,5,6].product() * 2 = 90 * 2 = 180 list = [], element = 5 [5].product() = 5 [].product() * 5 = 1 * 5 = 5
The same is true for concatenating 2 lists.
m
Again; that is indeed the mathematical definition of taking the product of an empty list. Again; apparantly not every programmer likes this implementation, or doesn't use it enough to warrant a
default
implementation So make it as you wish 🙂
b
I don’t think you will find any programmer that will argue for any other result when they actually use the function. It’s fine to argue it here but without any real use cases this is pretty much pointless. That said I don’t think it’s necessary to add this to the stdlib. It’s super easy to implement and it is rarely used.
m
I've seen several people that like to return a null, even in the case of sum, since they prefer to write logic like this:
Copy code
val result = someList.someReductionFunction()

when(result){
    null -> doThingForEmptyList()
    else -> doThingWithResult(result)
}
they could also check for the size of the list before reduction, so I don't really agree with this implementation for all works, but I've seen plenty of programmers being stubborn at least 😆