From: Shin-ichiro HARA Date: 2008-04-30T18:50:06+09:00 Subject: [ruby-dev:34541] Re: ComplexFloat 原です。 だいぶ間が空いてしまいました。 Tanaka Akira さんは書きました: > Complex と ComplexFloat とクラスをふたつに分ける理由がどうに > もわかりません。 その理由こそちゃんと述べないといけないのですが、なかなか伝わ らないですね。うまく表現ができてないみたいです。一応答えるこ とができるところだけ答えます。 > In article <480AE086.9070107@blade.nagaokaut.ac.jp>, > Shin-ichiro HARA writes: > >> それは、ComplexFloat の方が扱いやすく、利用する人も多いだろうと思われる >> からです。 > > たとえば、Complex(r,i) が中身が Float の Complex を生成し、 > 中身が Float でない Complex を生成するには Complex.new を使 > うというのはどうでしょうか。 > > 仮にそうしたとすれば、Complex() を使って生成する限り、一貫し > て Float な Complex を使うことが出来ます。ComplexFloat とい > う長い名前を使う必要もありませんし、そっちのほうが使いやすい > んじゃないでしょうか。 Complex() と Complex.new() では、その違いが(マニュアルを読ま ないと)わかり難い、また、Complex() という形の数値の生成は、 実は生成ではなくて「実は数値は計算機内に予め存在していて、そ れを連れてくる」というイメージを持っているので、このような使 い分けに用いるのは、適切ではないかもしれません。 Complex に new があってもいいかな、と思っています。 生成時に成分が Float であることを指定するというのは、一つの方 法だと思います。 > ここで、ComplexFloat と、中身が Float の Complex の挙動が等 > しいと想定しています。もし挙動が異なるんでしたらそう指摘して > ください。 この2つの挙動は等しいとして考えています。 >> むらたさんの提案と私の提案にはずれがあり、私自身の提案も変遷しているの >> で、分かりにくいかもしれません。私の提案は、実装の事も気にしていますが、 >> 基本的には仕様を問題にしています。ふなばさんは、Complex がコンテナであ >> るということに起因する問題([ruby-dev:34439])に対してどう考えていますか? >> >> もう一度少し違う例を挙げると、Complex を導入すると >> >> x.class == y.class かつ x == y だが、x - z != y - z >> >> となる例があります。x = Complex(0, 1.6), y = Complex(0, Rational(16, 10)), >> z = Complex(0, 1) です。 >> >> 数値 x の振舞いは x の属するクラスで決まって欲しい、そのようなものが組 >> み込みではより望ましい、のではないでしょうか? > > なんでクラスで決まってほしいんでしょう? 単純に、挙動がクラスで決まる、というのはいいことではないです かね。特に数値クラスという単純であるべきものでは。少なくとも 現行の組み込みの数値クラスはすべてクラスで決まっている。 > 上の例は、不正確数のいやらしさが Complex に表れたものであり、 > [ruby-dev:34439] は / の挙動のいやらしさが Complex に表れた > ものです。たしかに、Complex は中身の性質が表に出てきます。 > > その性質が簡単に判断できないというのはたしかに問題かもしれま > せん。でも、その性質って、クラスで判断することが適切なんでしょ > うか? > > たしかに、ComplexFloat を導入すれば、ComplexFloat が不正確数 > であることをクラスで判断できます。 > > でも、[ruby-dev:34439] の / の問題は解決できません。これをク > ラスで判断できるようにするには、ComplexInteger を導入する必 > 要があるでしょう。 Complex を利用した場合、クラスで判断できるようにする必要はな い、というのが私の考えです。 一方でクラスで判断できるべき、と言い、一方で判断できる必要は ない、と言ってます。ここだけ取り上げるとおかしく聞こえるかも。 多くの人は ComplexFloat を使うのでクラスで判断できる。特殊な ケースでは Complex を使うが、特殊なのでクラスで判断できなくて いい、ということです。 > また、不正確数は Float だけではありません。BigDecimal や > Decimal を (その表現できる桁を越えた値の近似として) 使えば、 > 不正確数になります。これをクラスで判断できるようにするには > ComplexBigDecimal や ComplexDecimal を導入するんでしょうか。 > これは際限がない気がします。 ComplexFloat のみ導入し、他の Complex* は(組み込みとしては)導 入しない、という提案をしています。ComplexBigDecimal 等は拡張 ライブラリでしてもらう。 ComplexFloat は組み込みなのに、ComplexBigDecimal はそうではな い。その線引はなぜかというと、使用頻度によるものです。 > あと、Complex() に Float や Integer が与えられたらどうするの > か、という問題もあります。原さんの案だと、ComplexFloat は組 > み込みですから、Float が与えられた時に ComplexFloat を生成す > るのは可能かもしれません。でも、今はまだない ComplexInteger > を誰かが定義した時、Complex() に Integer を与えて Complex オ > ブジェクトが生成されるとすれば、中身が Integer では「ない」 > ことはクラスでは判断できません。 Complex() に Float を与えると、ComplexFloat と同じ挙動をする オブジェクトが得られます。同じような振舞いをするオブジェクト が2通りあることになりますね。あまり良くないが仕方がない、とい う考えです。最大の欠点? 誰かが ComplexInteger を作ったとすれば、やはり Complex() に Integer を与えたものと2重になってしまうでしょう。 > 中身の性質を判断したいという要求は充分にあり得ると思うんです > が、それにクラスを用いるという点が納得できません。 > > 正確数か不正確数か判断したいというなら、 > Scheme の exact?, inexact? あたりを取り入れて、 > Numeric#exact?, Numeric#inexact? を提案するほうがいいと思う > んですが、なんでクラスを使いたいんでしょう? exact? と inexact? の導入は検討されてもいいと思います。しかし 数の挙動を表現する情報としては不十分なわけで(例えば Rational と Integer は exact だけど挙動はかなり違う)、そのものズバリ 「クラスが体を表す」のはいいことではないかと思うのですが… 数値なのにクラスで性質が判断できない、という気持ち悪さを感じ 過ぎなのかなあ。