From: "merborne (kyo endo)" Date: 2012-07-21T08:54:51+09:00 Subject: [ruby-core:46583] [ruby-trunk - Feature #6758] Object#sequence Issue #6758 has been updated by merborne (kyo endo). trans (Thomas Sawyer) wrote: > Nice, but why Object method and not Kernel method? Thank you. If you mean Kernel public method, no difference. If you mean Kernel private method that is, function style, I prefer having a receiver. Two reason. Passing block argument from a receiver object is more natural for me than from argument of the method. Also I prefer placing this method into method chain. ---------------------------------------- Feature #6758: Object#sequence https://bugs.ruby-lang.org/issues/6758#change-28244 Author: merborne (kyo endo) Status: Open Priority: Normal Assignee: Category: Target version: =begin == Object#sequence Let me propose a new method ((*Object#sequence*)). ������������������������((*Object#sequence*))��������������������� class Object def sequence(init=true, &blk) x = self Enumerator.new do |y| y << x if init loop { y << (x = yield x) } end end end ((*sequence*)) generate a sequence by applying a block recursively to the receiver object. The result is wrapped with a Enumerator object, thus it is set under lazy evaluation. ((*sequence*))������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������Enumerator��������������������������������������������������������������������������������� == Usage; ��������������������������� 1.sequence { |x| x + 2 }.take(10) # => [1, 3, 5, 7, 9, 11, 13, 15, 17, 19] 3.sequence { |x| x * 2 }.take(10) # => [3, 6, 12, 24, 48, 96, 192, 384, 768, 1536] [0, 1].sequence { |a, b| [b, a + b] }.take(10).map(&:first) # => [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] [0, 1, 1].sequence { |a, b, c| [b, c, a + b + c] }.take(10).map(&:first) # => [0, 1, 1, 2, 4, 7, 13, 24, 44, 81] # square root 5 a = 5 eps = 0.0001 1.0.sequence { |x| (x + a/x) / 2.0 } .each_cons(2) .detect { |a, b| (a - b).abs < eps }[1] # => 2.236067977499978 # Excel label 'A'.sequence { |x| x.succ }.take(30) # => ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "AA", "AB", "AC", "AD"] # random boolean(avoid true-true sequence) true.sequence { |prev| prev ? false : [true, false].sample }.take(20) # => [true, false, true, false, true, false, true, false, true, false, true, false, true, false, true, false, false, false, true, false] == Some background == ��������������� Let me explain some background of this request. ��������������������������������������������������������������������������������������������������������� 1. I introduced this method as ((*Object#repeat*)) on my Japanese blog. 1. ������������������������������������������������((*Object#repeat*))��������������������������������������� (()) 2. Matz tweeted to the article. > "um.. the feature is attractive, but the name is.." 2. ������������������Matz������������������ > ��������������������������������������������������������������������������� (()) 3. I updated the article to propose ((*Object#repeat_apply*)) or ((*Object#repeat_call*)). 3. Object#repeat_apply, Object#repeat_call��������������������������������������� 4. Matz tweeted to the article. > @merborne more clear. but combining two verbs is wrong. I understand naming is difficult. 4. ������������������Matz������������������ > @merborne ���������������repeat_apply���������repeat_call���������������repeat���������������������������������������������������������������repeat���������������apply/call��������������������������������������������������������������������������������� (()) 5. Matz tweeted to the article. > @merborne I suggest some clue lies around a word "series".. 5. ������������������Matz������������������ > @merborne ���������/series������������������������������������������������������ (()) 6. I tweeted to Matz. 6. ������������������ > @yukihiro_matz you are right.. `repeated_apply` `repeated_call`?.. > @yukihiro_matz ������������.. repeated_apply repeated_call������.. (()) > @yukihiro_matz clue! `series_by` ? > @yukihiro_matz ���������! series_by ? (()) > @yukihiro_matz `repeated` is adjective..^^; but I don't like `repeatedly_apply`. I thought once `series_by` is good, but it would be better a method is named based on its behavior, not on its function, I think. How about `repeat_by`? > @yukihiro_matz repeated������������������������^^; ���������repeatedly_apply���������������������������������series_by������������������������������������������������������������������������������������������������������������������������repeat_by��������������������������������������� (()) the conversation closed.. ������������.. 7. Ideas from other Rubyists Some Japanese Rubyists tweeted or commented me on the name. Candidates are.. 7. ������Rubyist��������� ���������������������������Rubyist������������������������������������������������������������������������������ iterate recur recurrence recur_with unfold sequence seq Haskell and Scala have the same functionality with a name of ((*iterate*)). ���������Haskell���Scala���������������������������((*iterate*))������������������������������������������������������ Also, @makotokuwata-san tweeted that ((*Kernel#seq*))(function style) or ((*Enumerator.seq()*))(a Class method) is better. ���������@makotokuwata���������Kernel#seq������������������������������Enumerator.seq()��������������������������������������������������������������������������������������� > @yukihiro_matz @merborne ������������������������������������������������������������"sequence"���"seq"���1������������Kernel#seq(initial,&blk)���������������������������RT ���������/series������������������������������������������������������ (()) Thank you for your consideration. ��������������������������������������������������������������� =end -- http://bugs.ruby-lang.org/