Feature #5512

Integer#/ の改訂

Added by tadayoshi funaba over 2 years ago. Updated about 1 year ago.

[ruby-dev:44707]
Status:Assigned
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:core
Target version:Next Major

Description

Integer#/ を Integer#quo の別名として定義しなおす事を提案します。

現在の Integer#/ はオペランドが整数である場合値が整数になります。整数を
与えた場合の結果だけを見て、あるいは整数ではない場合の結果だけを見て自
分の望み通りの結果を得たと思い込んでしまうかもしれません。

これついての対処として、Integer#div、または Integer#quo を利用するよう
啓蒙するなどいくつかの提案がありうるでしょうが、本質的な解決法は、やは
り仕様を変更するしかないと思われます。

これはプログラミングにおける総称性の確保の邪魔になり、Numeric#/ を利用
はバグの温床になり得えます。

History

#1 Updated by Yukihiro Matsumoto over 2 years ago

まつもと ゆきひろです

In message "Re: [ruby-trunk - Feature #5512][Open] Integer#/ の改訂"
on Sun, 30 Oct 2011 17:19:45 +0900, tadayoshi funaba redmine@ruby-lang.org writes:

|Integer#/ を Integer#quo の別名として定義しなおす事を提案します。

長期的には賛成しますが、2.0にはあまり過去との非互換性を入れ
たくないので、その次(3.0?)にしようと思います。

#2 Updated by Kenta Murata over 2 years ago

(2011.11.01 03:45 ), Yukihiro Matsumoto wrote:

まつもと ゆきひろです

In message "Re: [ruby-trunk - Feature #5512][Open] Integer#/ の改訂"
on Sun, 30 Oct 2011 17:19:45 +0900, tadayoshi funaba redmine@ruby-lang.org writes:

|Integer#/ を Integer#quo の別名として定義しなおす事を提案します。

長期的には賛成しますが、2.0にはあまり過去との非互換性を入れ
たくないので、その次(3.0?)にしようと思います。

2.0 がリリースされたら trunk で実装できると解釈して良いですか?
それとも、2.0 のリリース後にもう一度考えますか?

--
Kenta Murata muraken@gmail.com
1D69 ADDE 081C 9CC2 2E54 98C1 CEFE 8AFB 6081 B062

#3 Updated by Yusuke Endoh over 2 years ago

遠藤です。

2011年11月1日3:45 Yukihiro Matsumoto matz@ruby-lang.org:

In message "Re: [ruby-trunk - Feature #5512][Open] Integer#/ の改訂"
on Sun, 30 Oct 2011 17:19:45 +0900, tadayoshi funaba redmine@ruby-lang.org writes:

|Integer#/ を Integer#quo の別名として定義しなおす事を提案します。

長期的には賛成しますが、2.0にはあまり過去との非互換性を入れ
たくないので、その次(3.0?)にしようと思います。

本気で変える予定があるのなら、特大の非互換になりますので、今のうちに
切り捨てたい場合の推奨代替策を決めて ( (x/y).round ですかね?) 、
2.0 から啓蒙しておいたほうがいいと思います。(つまり推奨形式になって
いない場合に warning を出す)

個人的には、Integer#// とか別の演算子を導入して、Integer#/ は変えない
方が嬉しいです。切り捨てを期待したコードをすごく書いてきた。。。

--
Yusuke Endoh mame@tsg.ne.jp

#4 Updated by tadayoshi funaba over 2 years ago

本気で変える予定があるのなら、特大の非互換になりますので、今のうちに
切り捨てたい場合の推奨代替策を決めて ( (x/y).round ですかね?) 、
2.0 から啓蒙しておいたほうがいいと思います。(つまり推奨形式になって
いない場合に warning を出す)

それは賛成です。これまでの事を考えるとあまり期待できないですが。
python2 でやったような事ですが、ruby だと div をつかえってくらいでしょ
う。

個人的には、Integer#// とか別の演算子を導入して、Integer#/ は変えない
方が嬉しいです。切り捨てを期待したコードをすごく書いてきた。。。

smalltalk では、// が切捨て \ がそれの対になる余りなっていますが、
ruby では // は正規表現に被るのでダメだと言われました。どっちにしても
Integer#/ を変える事に意味があるので、それだったら、div と quo をつかい
ましょうで終りですね。後はつかいやすいように div メソッドではなく、div
演算子を用意するくらいか。

#5 Updated by Yukihiro Matsumoto over 2 years ago

まつもと ゆきひろです

In message "Re: Re: [ruby-trunk - Feature #5512][Open] Integer#/ の改訂"
on Tue, 1 Nov 2011 22:12:54 +0900, Yusuke Endoh mame@tsg.ne.jp writes:

|本気で変える予定があるのなら、特大の非互換になりますので、今のうちに
|切り捨てたい場合の推奨代替策を決めて ( (x/y).round ですかね?) 、
|2.0 から啓蒙しておいたほうがいいと思います。(つまり推奨形式になって
|いない場合に warning を出す)

方針としては賛成ですが、「推奨形式になっていない」ことをどう
やって検出しますか? Integer#/ が呼ばれる度に警告を出す?

|個人的には、Integer#// とか別の演算子を導入して、Integer#/ は変えない
|方が嬉しいです。切り捨てを期待したコードをすごく書いてきた。。。

別の演算子という意味では quo があるので、「変えない」という
のはこの提案の意味がなくなるのではないでしょうか。また、整数
が要求されるところではほとんどの場合切り捨てが行われているは
ずなので、実際にはあまり問題にならないことが多いかもしれませ
ん。つまり、

p 1/2

みたいのは影響を受けるけど

ary[1/2]

みたいのは影響を受けないってこと。

                             まつもと ゆきひろ /:|)

#6 Updated by Yusuke Endoh over 2 years ago

ふなばさん、まつもとさん、
お返事ありがとうございます。

2011年11月1日22:46 Tadayoshi Funaba tadf@dotrb.org:

本気で変える予定があるのなら、特大の非互換になりますので、今のうちに
切り捨てたい場合の推奨代替策を決めて ( (x/y).round ですかね?) 、
2.0 から啓蒙しておいたほうがいいと思います。(つまり推奨形式になって
いない場合に warning を出す)

それは賛成です。これまでの事を考えるとあまり期待できないですが。
python2 でやったような事ですが、ruby だと div をつかえってくらいでしょ
う。

なるほど。
「代わりに Integer#div 使え」ということなので、Integer#/ が
呼ばれるたび、もしくは初めて呼ばれた時だけに警告する感じですかね。

個人的には、Integer#// とか別の演算子を導入して、Integer#/ は変えない
方が嬉しいです。切り捨てを期待したコードをすごく書いてきた。。。

smalltalk では、// が切捨て \ がそれの対になる余りなっていますが、
ruby では // は正規表現に被るのでダメだと言われました。どっちにしても
Integer#/ を変える事に意味があるので、それだったら、div と quo をつかい
ましょうで終りですね。後はつかいやすいように div メソッドではなく、div
演算子を用意するくらいか。

見やすい中置演算子がないことが不満なのかなと思ったのですが、
変えること自体が目的なんですかね。

2011年11月1日23:00 Yukihiro Matsumoto matz@ruby-lang.org:

また、整数
が要求されるところではほとんどの場合切り捨てが行われているは
ずなので、実際にはあまり問題にならないことが多いかもしれませ
ん。

x を n の倍数にアラインさせるために

x / n * n

というイディオムをかなり書いてきてるんですよね。

このイディオムが具体的にどういうときに必要かというと、簡単には
説明しにくいんですが、ええと、タイルを対称的に並べるため個数を
偶数に限定する (x / 2 * 2) とか、1014 .. 1014 + 1000000 の
範囲の素数を列挙する (2 段階エラトステネス) とか。
妙な例ですみません。

あと、現状の quo だと、4.quo(2) が Rational になるみたいですが、
整数で済む時は整数になるようにしませんか?

--
Yusuke Endoh mame@tsg.ne.jp

#7 Updated by Yukihiro Matsumoto over 2 years ago

まつもと ゆきひろです

In message "Re: Re: [ruby-trunk - Feature #5512][Open] Integer#/ の改訂"
on Tue, 1 Nov 2011 23:40:20 +0900, Yusuke Endoh mame@tsg.ne.jp writes:

|x を n の倍数にアラインさせるために
|
| x / n * n
|
|というイディオムをかなり書いてきてるんですよね。

なるほど。互換性問題の解決にはなりませんが、整数をアラインさ
せるメソッドが欲しいこともあるかもしれませんね。

#8 Updated by Kenta Murata over 2 years ago

むらたです。

(2011.11.01 23:40 ), Yusuke Endoh wrote:

あと、現状の quo だと、4.quo(2) が Rational になるみたいですが、
整数で済む時は整数になるようにしませんか?

どうせなら、分母が 1 の Rational はすべて整数に正準化させるように
変更しませんか?

--
Kenta Murata muraken@gmail.com
1D69 ADDE 081C 9CC2 2E54 98C1 CEFE 8AFB 6081 B062

#9 Updated by Masaya Tarui over 2 years ago

たるいです。

2011年11月1日22:12 Yusuke Endoh mame@tsg.ne.jp:

本気で変える予定があるのなら、特大の非互換になりますので、今のうちに
切り捨てたい場合の推奨代替策を決めて ( (x/y).round ですかね?) 、
2.0 から啓蒙しておいたほうがいいと思います。(つまり推奨形式になって
いない場合に warning を出す)

推奨代替案ってx.div(y)ですよね?

個人的には、Integer#// とか別の演算子を導入して、Integer#/ は変えない
方が嬉しいです。切り捨てを期待したコードをすごく書いてきた。。。

私も x / a * b みたいなコードはずいぶん沢山書いてきたので、
非互換は嬉しくないです。

普段は演算子で整数に閉じた演算をしたいのですが、
Numericの総称性の確保と上手く混ぜた解はないでしょうか?

--
樽家昌也(Masaya TARUI)
No Tool,No Life.

#10 Updated by Koichi Sasada about 1 year ago

  • Category set to core
  • Assignee set to Yukihiro Matsumoto

宙ぶらりんになっているようなので、まつもとさんにアサインしておきます。
ご検討下さい。

#11 Updated by Shugo Maeda about 1 year ago

  • Status changed from Open to Assigned

ko1 (Koichi Sasada) wrote:

宙ぶらりんになっているようなので、まつもとさんにアサインしておきます。
ご検討下さい。

そういえば、mrubyでは1 / 2が0.5 (Float)になる(ので規格に準拠していない)ようなのですが、
将来CRubyで仕様変更するための布石でしょうか。

後方互換性については、

using OldIntegerDivision

としたらInteger#/が現在の挙動に戻るといった対応は考えられるかなと思いますが、その前に
Refinementsを何とかしないといけないですね…。

Also available in: Atom PDF