From: "alexeymuranov (Alexey Muranov)" Date: 2012-07-25T16:07:28+09:00 Subject: [ruby-core:46751] [ruby-trunk - Feature #6758] Object#sequence Issue #6758 has been updated by alexeymuranov (Alexey Muranov). merborne (kyo endo) wrote: > alexeymuranov (Alexey Muranov) wrote: > > fibonacci = 0.recurrence(1) { |a, b| a + b } > > I disagree this. because I can't image fibonacci sequence from this code. and two block variables, which are both used as init data comes from different sources(one from a receiver, one from an argument). It's not natural for me. > > with the original, you can easily get a sequence, of which a sequence of diffrences becomes a sequence of numbers with common difference as follows; > > [1, 1].sequence { |a, b| [a+2, a+b] }.take(20).map(&:last) # => [1, 2, 5, 10, 17, 26, 37, 50, 65, 82, 101, 122, 145, 170, 197, 226, 257, 290, 325, 362] > > # a sequence of diffrences of above sequence becomes [1, 3, 5, 7, 9 ..] Ok, i agree. I have also thought of the following "standard" way to build Fibonacci sequence with `#sequence`: fibonacci10 = [0, 1].sequence { |x| x = x.dup; x << (x[0] + x[1]); x.shift; x }.take(10).map(&:first) Of course it would be better with lazy `take` and `map` and without `dup`. ---------------------------------------- Feature #6758: Object#sequence https://bugs.ruby-lang.org/issues/6758#change-28420 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/