From: "zverok (Victor Shepelev) via ruby-core" <ruby-core@...> Date: 2023-01-22T15:23:18+00:00 Subject: [ruby-core:111969] [Ruby master Feature#19324] Enumerator.product => Enumerable#product Issue #19324 has been updated by zverok (Victor Shepelev). > I believe quite many people are in favor of `Array.product` and/or `Array.zip`. I wish the implementation/existence of `Enumerator.product` will work as a pressure towards implementing these methods as well. I can empathize with that, but there are two important things to consider: 1. Even if standalone `product` is a thing, `Enumerable#product` still needs to be defined: as my examples show, "first argument is special" is frequent; and inability to just convert `ary.product(others)` to `ary.lazy.product(others)` is irritating 2. **If** there would be a course to have a few "standalone methods", I believe it should be discussed as soon as possible to settle on an acceptable approaches. We have a small window of opportunity (while `Enumerator.product` is just introduced and can be considered not creating a lot of backward compatibility issues) to settle on the proper design. In particular, questions to consider: * Would standalone methods really be a thing (even if in distant future), or would it always be just one sore exception? * If it would be a thing, what would be the proper place for it? Because, actually **even** for standalone method I don't believe `Enumerator` is the most appropriate. If it would be in Array, it probably make sense to have a pair of `Array#zip` and `Array.zip`; probably the same is true for abstract enumerables: `Enumerable#product` and `Enumerable.product`. * Other currently existing `Enumerator` class methods (`.new` and `.produce`) are focused on "creating **a new enumerator** (from some arguments/algorithms)", while `Enumerator.product` is focused on "apply this operation **to enumerables**" (producing... whatever it will produce, the user isn't focused on "enumerator" concept here) ---------------------------------------- Feature #19324: Enumerator.product => Enumerable#product https://bugs.ruby-lang.org/issues/19324#change-101400 * Author: zverok (Victor Shepelev) * Status: Open * Priority: Normal ---------------------------------------- I know it might be too late after introducing a feature and releasing a version, but I find `Enumerator.product` quite confusing, and can't find any justification in #18685. **Problem 1: It is `Array#product` but `Enumerator.product`** ```ruby [1, 2].product([4, 5]) # => [[1, 4], [1, 5], [2, 4], [2, 5]] # Usually, when we add methods to Enumerable/Enumerator which # already array had before, it is symmetric, say... [1, nil, 2, 3].compact #=> [1, 2, 3] [1, nil, 2, 3].lazy.compact.first(2) #=> [1, 2] # But not in this case: [1, 2].lazy.product([4, 5]).first(2) # undefined method `product' for #<Enumerator::Lazy: [1, 2]> (NoMethodError) # Because you "just" need to change it to: Enumerator.product([1, 2].lazy, [4, 5]).first(2) # => [[1, 4], [1, 5]] ``` No other method was "promoted" from Array this way And in general, I believe core methods tend to belong to the first object in the expression and not be free module methods, Elixir style. **Problem 2: It is one letter different from `Enumerator.produce`** I understand I might be biased here (as a person who proposed `produce`), and that method is not as popular (yet?) as I hoped, but still, two methods that do completely different things and differ by one letter, both being somewhat vague verbs (so it is easy to confuse them unless you did a lot of math and "product" is firmly set for set product in your head). I believe that EITHER of two problems would be concerning enough, but the combination of them seems to be a strong enough argument to make the change?.. (Maybe with graceful deprecation of module method in one next version, but, considering the Ruby 3.2 is just released, maybe vice versa, fix the problem in the next minor release?..) -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/