Feature #6758
openObject#sequence
Description
=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.
本件に関しては、ここに至る若干の経緯がありますので、併せて説明します。
-
I introduced this method as ((Object#repeat)) on my Japanese blog.
-
私のブログにおいて、本メソッドを((Object#repeat))として紹介する記事を公開。
((URL:http://melborne.github.com/2012/07/12/object-repeat-take-care-of-sequence/))
-
Matz tweeted to the article.
"um.. the feature is attractive, but the name is.."
-
記事に対してMatzがつぶやく。
「うーん、昨日としては魅力的だけど、名前がなあ。」
((URL:https://twitter.com/yukihiro_matz/status/223790181113806848))
-
I updated the article to propose ((Object#repeat_apply)) or ((Object#repeat_call)).
-
Object#repeat_apply, Object#repeat_callを提案するべく記事を更新。
-
Matz tweeted to the article.
@merborne (kyo endo) more clear. but combining two verbs is wrong. I understand naming is difficult.
-
記事に対してMatzがつぶやく。
@merborne (kyo endo) なるほど「repeat_apply」か「repeat_call」ですか。repeat単体よりは誤解を受けにくいとは思いますが、repeatって動詞とapply/callって動詞の組み合わせは感心しませんね。名前って難しい。
((URL:https://twitter.com/yukihiro_matz/status/224105896110866432))
-
Matz tweeted to the article.
@merborne (kyo endo) I suggest some clue lies around a word "series"..
-
記事に対してMatzがつぶやく。
@merborne (kyo endo) 「級数/series」あたりに名前のヒントがありそうな。
((URL:https://twitter.com/yukihiro_matz/status/224106160591081472))
-
I tweeted to Matz.
-
私もつぶやく
@yukihiro_matz you are right..
repeated_apply
repeated_call
?..@yukihiro_matz たしかに.. repeated_apply repeated_callかな..
((URL:https://twitter.com/merborne/status/224108387653259264))
> @yukihiro_matz clue! `series_by` ?
> @yukihiro_matz ヒント! series_by ?
((URL:https://twitter.com/merborne/status/224108809948377088))
> @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というのはどうでしょうか。
((URL:https://twitter.com/merborne/status/224324670764220416))
the conversation closed..
会話終了..
- Ideas from other Rubyists
Some Japanese Rubyists tweeted or commented me on the name. Candidates are..
- 他の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」あたりに名前のヒントがありそうな。
((URL:https://twitter.com/makotokuwata/status/225806204390227968))
Thank you for your consideration.
以上、ご検討のほどよろしくお願い致します。
=end