For similar reasons for creating
Enumerable#sum a companion method
Enumerable#product is also very useful. Taking the product of
numbers in arrays is a common operation in many numerical algorithms,
especially in number theory and cryptography, and its optimization in
Ruby will make it more conducive to math heavy algorithms and tasks.
> [2,3,5,7].reduce(:*) => 210
can be optimized to this
> [2,3,5,7].product => 210
It should also allow an initial value
> [2,3,5,7].product(2) => 420 > [2,3,5,7].product(0.5) => 105
Crystal already has this
#2 [ruby-core:85089] Updated by jzakiya (Jabari Zakiya) 4 months ago
I looked here https://ruby-doc.org/core-2.5.0/Enumerable.html and didn't see
that method, so I didn't know it existed. But
multiply would also work.
Where in the docs is
product then causes a conflict with the Crystal definition/use.
#5 [ruby-core:85109] Updated by shevegen (Robert A. Heiler) 4 months ago
which is a little longer, but I think is more accurately
descriptive and intuitive.
We are back to the ancient problem - giving things good names. :-)
The only name from the above that I like is .sum - the others
do not tell me much at all. ;-)
I am not sure what .combinations would do - then again I also
never fully understood the name .reduce() either. People
often associate different actions with the same (but also
#6 [ruby-core:85123] Updated by jzakiya (Jabari Zakiya) 4 months ago
That's interesting because I never intuitively understood the use
inject, especially for numerical purposes, and always now use
reduce, which was (I believe) created by Haskell (the person and
programming language), and has long been a concept in functional
programming. To me it says that an array of numbers (items) will be
reduced|collapsed into a single value based on the given operation.
Also, after reading your comment and thinking about it, there is a way
to reclaim the
product method name and recast it for this new (better) use.
A better name for the current
Array#combine, which has
the same number of characters, so it can replace the word inplace in code
without the need to possibly reformat it.
[1,2,3].product [5,6,7] which seems like a vector|matrix operation can be renamed as [1,2,3].combine [5,6,7] or even [1,2,3].combine_with [5,6,7}
I think this is much clearer indication of its intent and purpose.
Here's a proposed path to reclaim and recast
product as proposed.
Array#combine(_with) as an alias to the current
Replace its use in the Ruby core and stdlib code.
Make announcement to deprecate use of
Array#product to give people time to change.
Enumerable#multiply to act as proposed
Eliminate use of
Enumerable#product as alias of
Since everyone knows Ruby 3 is going to be a breaking some old code change, if
people are weaned off old code use then this change really won't create problems.
On one hand you are creating a new capability in
while keeping, but renaming, a current capability. Plus, I can't think that alot of
code|people currently use
Array#product, so I doubt it affects a lot of code|people.
(Is this ever used in Rails, etc?)
Python went through this going from 2 to 3, famously with the
Basically what I'm illustrating, if there is a will there is a way to make this change,
without a lot of disruption and pain.
#7 [ruby-core:85165] Updated by nate00 (Nate Sullivan) 4 months ago
Enumerable#product is named after the Cartesian product (also called just "product" in set theory). For example, see the discussion in issue 7444. Renaming it to
combine might cause people to think it's related to mathematical combinations, but as far as I can tell, it isn't related.
#8 [ruby-core:85195] Updated by jzakiya (Jabari Zakiya) 4 months ago
According to the thread you provided the initial suggested name was
which was shortened to the current
Array#product. Its proposed intent was to provide
combination groups of set-like items, and not as an arithmetic operation.
As was stated previously, naming things is Hard!, especially when you can't anticipate all
the unintended consequences.
I think Crystal has gotten it correct for this, having both
Enumerable#sum methods. I suspect the overwhelming majority of programmers|users
coming to Ruby would expects the following behavior too.
[2,3,5,7].sum => 17 # the result of adding all the array elements [2,3,5,7].product => 210 # the result of multiplying all the array elements
#9 [ruby-core:85317] Updated by joanbm (Joan Blackmoore) 4 months ago
EDIT: The original request was updated and my comment is related to the meaning of previous one. I don't agree with adding method of identical name but distinct semantic, ie. existing
Array#product as a Cartesian product of elements and
Enumerable#product as a product of their multiplication. It would only bring inconsistency and confusion, esp. conflicting while
I'd also vote YES for this feature request, move
It is especially missing when working with (lazy) infinite sequences and problems leading to cartesian product of elements. Now it has to be implemented by nesting blocks of
Enumerable#flat_map, which is cumbersome and inelegant when, ironically, there is method already available but for Array (sub)class(es) only.
p.s. Please stay on topic, discussion about chosen method name is pointless because it is already there. Backward compatibility should be kept as possible and its name is also justified although opinions may differ.