From: Ruby-Lang@... Date: 2019-08-11T21:34:46+00:00 Subject: [ruby-core:94292] [Ruby master Feature#14399] Add Enumerable#product Issue #14399 has been updated by jwmittag (J��rg W Mittag). jzakiya (Jabari Zakiya) wrote: > That's interesting because I never intuitively understood the use > of `inject` This is bastardized from Smalltalk. In Smalltalk, method names consist of multiple words and the arguments are written in between the words. In Smalltalk, the method is called `inject:into:` and is called like `aCollection inject: aValue into: aBlock`, i.e. you inject an accumulator into a block that is executed for each element. This a) makes sense, and b) fits with the "in-joke" of naming all of Smalltalk's collection operations using names that rhyme (`inject:into:`, `collect:`, `reject:`, `select:`, `detect:`). Ruby is heavily based on Smalltalk, so it is generally expected that newcomers to Ruby will be familiar with Smalltalk's collection operations, therefore the slightly unusual names. However, the meaning of "injecting an accumulator into a block" gets lost because in Ruby, we cannot write it that way, and so we lose the "into" from the name. > [I] always now use > `reduce`, which [���] has long been a concept in functional > programming. Note however, that at least in some programming languages, `reduce` is a *restricted* version of a `fold` which has a restricted type signature and only works on non-empty collections. In particular, in Scala, `reduce` is equivalent to Ruby's `inject` with only a block argument, and `fold` is equivalent to Ruby's `inject` with an explicit start argument. (In ECMAScript OTOH, `reduce` is the general version.) > `reduce` [���] was (I believe) created by Haskell (the person and > programming language) Actually, Haskell calls the general version `fold` and the restricted version `fold1` (because it requires at least one element, and will take element number 1 as the accumulator). > To me it says that an array of numbers (items) will be > reduced|collapsed into a single value based on the given operation. This idea of "reducing to a single value" is unfortunately somewhat misleading. A lot of people I talk to think that `fold` can only be used for summing, because they don't understand that a) the "single value" can be a different type from the element type and b) the "single value" can be arbitrarily complex, e.g. an array, a tree, an instruction sequence, etc. In fact, `fold` is a *general method of iteration*, it can do *everything* that a loop can do. A compiler is simply a fold over the AST, for example. (The restricted version, i.e. what Haskell calls `fold1` and Scala calls `reduce` OTOH is *not* general.) Or, in short: naming is hard :-D ---------------------------------------- Feature #14399: Add Enumerable#product https://bugs.ruby-lang.org/issues/14399#change-80622 * Author: jzakiya (Jabari Zakiya) * Status: Open * Priority: Normal * Assignee: * Target version: ---------------------------------------- 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. This ``` > [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 `method`. -- https://bugs.ruby-lang.org/ Unsubscribe: