From: keiju@... (Keiju ISHITSUKA) Date: 1999-02-10T23:12:50+09:00 Subject: [ruby-dev:4982] Re: coerce the next generation けいじゅ@日本ラショナルソフトウェアです. In [ruby-dev :4953 ] the message: "[ruby-dev:4953] coerce the next generation ", on Feb/10 06:07(JST) GOTO Kentaro writes: >ごとけんです >>>なんか僕が先走ってるような気もするので些細な疑問でも >>>おっしゃってください. >しかも意志の疎通がヘタですみません m(_ _)m いえ. 私もあまり人のことはいえませんし(^^;;; >長くて恐縮なんですが,次のような感じで使うと >いいと思ってました.が,確かに下の coerce で出て来る >super は Precision#super ではないので良くないですね. そうなっていると思うんですが?? でも, Smalltalkのgeneralityの概念を用いると, Rationalの用に既存クラス の間に入るクラスはここでのRational#coerceの様な実装になります. で, Precision#coerceがそのまま適応できるのは, 新しいクラスが全ての既存クラ スよりもgeneralityが高い場合だけです. とはいえ, Matrixが既にあるのでそ ういう風になることはもうないと思います. # 残りはTensorぐらいですか(^^;;; つまり, 今後作る全ての数値クラスでは Precision#coerceをそのまま使うこ とはできません. >名残惜しいですが,やっぱり Precision#coerce は追加しません. 同名でなくて, 別名で2つ用意するのはありかも知れません. Precision#general方向の_coerce Precision#逆方向の_coerce 必要に応じてaliasしても良いし, coerceの中で使っても良いし. ># ちなみに 上の Rational.induced_from(float) は趣味なので ># 無視されても構いませんが,Float には基数2で仮数と ># 指数の値を返すメソッドがあってもがいいとは思っています. 既に近いのはあります. Math.frexp(f) です. たぶん, floatの正規系の 仮数部と 指数部をそのまま返しています. おもうんですが, Rational.induced_from(float) は何故 分子が10**bなんで しょう? Floatのフォーマットからいって 2**bの方がよいと思うんですが? >> Fixnum.coerce_type(Bignum) -> [Bignum, Bignum] >> (Fixnum/Bignum).coerce_type(Float) -> [Float, Float] >> (Fixnum/Bignum).coerce_type(Rational) -> [Rational, Rational] >> Float.coerce_type(Rational) -> [Float, Float] >> (Fixnum/Float/Rational).coerce_type(Complex) -> [Complex, Complex] >> (Fixnum/Float/Rational/Complex).coerce_type(Matrix) >> -> [Matrix::Scalar, Matrix] >>def op(other) >>1. 演算できる時は計算する >>2. 演算できない時は, other.coerce_type(self)で変換すべきクラス(N, M)を得る >>3. self.prec(N) op other.prec(M) >>end >>どうせ変えるんだったら, 昔の豊福さんの案もマージして >> >> [N', M', op'] = M.coerce_type(N, op) >> >>も良いかも. > >同意します. (^^;;; まだ, ちょっと早いような... >同時に行き違いの原因がなんとなく分かったような気が. >僕は上の self.prec(N) op other.prec(M) という表現が >嫌いです.僕が prec に対して偏執すぎるのかも知れませんが, >prec はあくまで精度を決めて欲しいと思います. この辺の認識のずれがあるんですね... 私は, 精度云々よりも型変換のイメージが強いんですね. でも, 数値演算で使っ ているcoerceは型変換というよりも演算ができるように型を調整するのが目的 なのでこれを precで実現するのは無理があるなと感じてきました. coerceは必要とあればどんな変換でも行ないます. 例えば, num * aMatrix とかは, Matrix::Scalar(num) なんて極悪な変換を行なう必要があるし, これ をprecに入れろとかいっちゃうと, ムシズが走っちゃいますよね? (^^;;; >だから,うえの self.prec(N) は N.induced_from(self) なら >名前的に構わないけどメソッド形式でないのは確かに不便です. えーと. self.prec(N)とN.induced_from(self)って同じ機能とは限らないので, これは無理です. Integerを実装した時にFloatはまだ存在していないと仮定します. そうすると, float.prec(Integer) は多分値を返すでしょうが, Integer.indeced_from(float) は値を返すように実装されていませんよね. >そこで,各クラスは project という各要素を置き換えた結果を >返すブロックメソッドを用意し,この project を使って次を >行うメソッド over をモジュールで提供するのはどうでしょう. > >def be_over(klass) > project{|i| klass.induced_from(i)} >end > >これで,self.be_over(N) なら全然気になりません. >ちなみに project のようなモノがあると collect! に相当する >ものも作れるので,だいぶ前から何故ないんだと思ってました. 上記のような理由のわけで, これではまずいです. さらに, int.be_over(Complex) -> Complex(int, 0) のようになって欲しいので, それも満たされていません. でも, project(射影)という考えはもしかしたら良いかもです. projectの定義: Precisionなクラス(空間)のproject == proc そうでないクラス(空間)project その空間(クラス)への自然な射影 例: int.project(Complex) -> Complex(int, 0) でも, int.project(Matrix)が... 後定義も... >>def op(other) >> 計算できる時は計算してretuen >> super >>end >このようなことができるのは理想的ですね. ># いったい誰が実装するのでしょう(^^;; うーん. >ただ,この問題は Precision とは分けて考えたいというのが >僕の気持ちで,Algebra というモジュールにした方がよいような >気がしています. むかし, Arithmeticって案はあったような... >あんまりモジュールを増やしてはいけないのかも知れませんが. なんか, 複雑になって来てえることが少ないような気がしてきました(^^;;; __ ................................石塚 圭樹@日本ラショナルソフトェア... ----------------------------------->> e-mail: keiju@rational.com <<---