観察日記 2012-08-24

Flonumと不変オブジェクト

r36798 で flonum が入ったわけですが。Feature #6763

あー、flonum導入で32bit環境と64bit環境でFloatのインスタンス変数やtaintの挙動が異なるようになったのか
なんか不味いことになりそうですか
その辺考えたつもりなんだけど
taint は考えてなかったな
Float って taint な可能性ってあるんかな
インスタンスメソッドメソッド上書きしてたりすると思いっきりtaintですね
それは32/64で共に禁止したから良いが (注: 元から禁止されている)
> 09:59 nurse > インスタンスメソッドメソッド上書きしてたりすると思いっきりtaintですね
taint の定義ってそれだっけ
s/taintですね/汚れてますね/g
汚れるの定義は難しそうな
そうですね

flonumってFloatは別クラスなの? ←いまさら
どちらもFloatですよ
じゃあ差異は0じゃないといけないのか
FixnumとBignumみたいにクラス別なら多少は挙動が違っててもいいのかなとか思って
Floatの挙動かえてもどうせ非互換なんだから、Flonumクラスつくって、スクリプト中の浮動小数即値はFlonumになるというルールにしてtaint欲しい人は明示的にFloatオブジェクトつくってねとしたらだめなのだろうか
うつくしくない
C#のボクシングみたいに内部的にオブジェクトができてほしい?
あーまあそれでもいいですよ > へんなことしたやつはboxing
boxingは object space で object id が見えてしまっているので、そこらへんを考えないと穴がありそうだ
Rubyは常にオブジェクトがあるのでboxingもなにも
taintが欲しいかじゃなくて、taintが保持されるべき状態になることがあるかと申しましょうか
C#にも常にオブジェクトはある。
C#だとvar a=1.0; var b=1.0; とあるときに、b固有の何かってありませんよね
JavaScriptだとオブジェクトにすればなんかあった気がするが
a=new Number(1.0)とかか
Java でいう primitive 型と Object 型,だろうか
Javaも7からauto boxingはいるんだっけか。わすれたけど
7 からだっけ?
(知らない)
C#はなんでもオブジェクトだがオブジェクトがスタックに乗ったりヒープに確保されたりする
var a = 1.0;ってやるとスタックに乗る
Object a = 1.0;ってやるとヒープに逃げる
それはオブジェクトモデルとは関係無さそうな
どうかな。オブジェクトモデルそのものではないと思うが関係ないかというと
そもそもboxing/unboxingとスタックに乗るか乗らないかは根が深い関係があると思われるので。
そこはそうだけど、オブジェクト固有のデータを持てるかとはジャンプがあるな
auto unboxingがある時点で持てない気がする
ジャンプがあるのは認める。いまのケースだと auto unboxing はありえないものね
unboxしたいシーンもないし
特異クラスと同じく、一回特異クラスになってしまったら、もう普通の世界にはもどれない
というか、オブジェクトじゃないとRubyの世界に存在できないので、unboxできるはずがない
それはオブジェクトとは何かという根源的な問題に触れているように思う
ここでオブジェクトと値という対比がboxingだと立場になっているのでそういう反論が出てくるのだとおもう。一般的にはこっそりproxy objectが生成されるしかけのことなので私的には矛盾しない
Fixnuは常にこっそりproxy objectが存在するんだろうか
どうなんだろう
unboxingされた値さんがその言語に存在しなければそれunboxingじゃねーだろ感がある
で、RubyにオブジェクトでないC#的な「値」はない
Rubyにおける「値」ってのはインスタンス変数が共有されちゃうやつかなぁ
unboxingにこだわるなあ
unboxingというか、値とは何か、オブジェクトとは何かってのはとても重要なことですから
オブジェクトとはなにかだけで1年は議論できる、もちろん結論は出ない
まず、わたしの主張となるせさんの反論はかみあってないと思っている
わたしはunboxingさせろとはいってなくて、さっきと違う言葉でいいなおすと、ある操作をしたときに proxy object が自動的に生成されて taint を持つことを許すのはありやなしや
それはなんというかtaintさせることが目的になっているので本末転倒である
特異メソッドもできるよ
普通のオブジェクトじゃないというのが制限の由来でしょ
非即値化ですね
うん

特異メソッドは前から定義されないのでいいのだが、
インスタンス変数は持てるのがひっかかる
特異メソッド持てるようにしたとして、
a=1.0; b=a; c=1.0; def a.foo;end; a.foo; b.foo; c.foo
むりじゃないかこりは
やだやだできなきゃやだ
しかしどう考えても現実的じゃなかった。
taintに自然に拡張したいならb とcにfooはできてはだめなんだよな
つまり、この世には無数の1.0があるという宗派に改宗しないといけなくなる。
それもやだ。
taintが目的じゃなくて
両方却下されたのでこの件はおひらき
taintされなければならいないような例が存在するかってのが求めている答え
non flonumだと特定のfloatが独自のインスタンス変数を持てるので、そこが懸念ポイント
ああ、即値のtaintってなんじゃらほいってこと?
Webフォームから入力された数値をDBに登録したいお^^
数値に変換できてる時点でサニタイズ終わっているはずだもんな
で、即値は常にサニタイズ済みだろうと考えられている
bignumやnon flonum floatはあやしい
rational/complexあたりはアウトだと思っている
rationalはサニタイズ済みと仮定できないということ? > なるせさん
インスタンス変数のほうの話かな
いや、実は仮定できるのかな
とりあえず特異メソッドは持てなかった
72.to_s #=> "千早" とかしたいよ?
途中から見たのでよくわからんけど、即値オブジェクトが云々というより、不変オブジェクトが云々という観点で考えるべきなのではないか。
その指摘は正しいような、実装と理念を混ぜてるような
rubyのオブジェクトモデルにimmutableって概念はあるのだろうか
たまたまない。
あんまり明には書かれてない気がする
ので、混同が生じているのではないだろうか。
ない、ってあれだな、あるんだけど、影が薄い。
Timeはimmutableだな
オブジェクトモデルにはないんだけど、特定のクラスの設計においてimmutableにしていることはある
BignumとかFloat(not flonum)とかRationalとかComplexとかは
いまその混乱の狭間に置かれているという感がある。
しかし Stringがimmutableだけど taint ありな言語はいくらでもあるわけで、symbol みたいに immutable でかつオブジェクト共有してるから即値としてつかえるよん的なクラスでないと議論がすれちがうな
変更不能、と、不変、はちょっと違う。
無窮オブジェクト
普遍オブジェクトという観点では、a=1<<128; def a.foo;9;end (1<<128).foo #=> 9 とかなってほしい
なってほしいかなあ。あんまりそんな気がしないんだけど
実用じゃなくて理念の話なので> 1<<128

理念から入ってますが、
(1) 初めからあって永遠にあって決して変わらないという種類のオブジェクトがあるはずである。これをとりあえず不変オブジェクトと呼ぶ。
それは不変じゃなくて普遍ではないか
かもしれない。
呼称は適当なのでとりあえず受け入れてくれ。
不変だとはじめからあるは条件になくても使っていいイメージ
see also http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/33832
(2) 具体的な例としては true false nil なんかは間違いなくそれである。
(3) 「数値」というのもそれに該当されるのではないか。つまり、1はどこにいっても1であり、どこに現れる1も全て同じオブジェクトのはずである、ということ。
(4) 「不変オブジェクト」が特異メソッドなりtaintされたりしちゃいけないという道理はあるかもしれないしないかもしれない。ただし、どこかで1がtaintされうるとしたら、他の1も(同じオブジェクトなので)taintされることになることに留意。
その立場だと特異メソッドもtaintも、そんなんあるはずないだろ。はい解散。でおわりな気がする
どこかのアホが即値の1をtaintしたら全スクリプトが汚れるとかありえんし
4.taint; 13.taint
別にあって悪くはない。
(5) 「不変オブジェクト」の実装には、たまたま、VALUE埋め込みというテクが使える^^
(6) 一方、VALUE埋め込み以外で「不変オブジェクト」を実装するのは相当困難である。
とりあえずこんなあたりは前提として共有されたい。
floatが普遍オブジェクトであるべきかってのには若干の議論の余地はある気はしないでもなかりけり
6なんだけど不変なんだから別にふつうにオブジェクトつくってヒープにおいてもいいはずである。変更されそうな操作をことごとく蹴るという話に帰着するだけなので
うん。
で、Bignumとか一通り禁止されているのだが、インスタンス変数が漏れてる
というわけで、今はそういう方向なわけです。
2.0から禁止で(^^
で、ある1をtaintしたいけど他の1がtaintされるのおかしくね? っていうのはオラも十分理解できるんだけど、
それはつまり「ある1」は値としての1ではなくて何か特別な意味・意図を付与された1なのであり、
なのでそれはNumericの1ではなくて、1という値を持つ別のオブジェクトなんでないの、
ゆえにラッピングして扱って、そのラッピングの方にtaintをつけるべきじゃないの
と思うわけです。
なるほど。
var a=1; a.taint じゃなくて
var a=new Number(1); a.taint しろと
思うんですが、それってつまりboxing/unboxingを自前でやれフハーハッハッハっていうことなので
なんだか悲しい気もする。
特別なぼくだけの72を作りたいって話なんだから、自前でやるのは当たり前な気もする
やー、ぼくは自前でやれに傾いてますよ
taint必要な状況がほぼないんじゃね。という意見に説得された
というわけで、理念は理念としておいといて、利便性という観点から適当に妥協するという考え方はなくもないかもしれにゃい。
まぁ、fixnuやflonum floatはおいておいて、non flonum floatが目下の問題。
FixnumとBignumは明らかにクラスが違うことが見た目でわかっちまうので、ちょっと挙動が違ってもしゃーないかもしれない。
flonum/non flonumはそうでないので、許しにくい。
モヒカンに全部禁止していくと非互換になる。というのが課題だとおもっていい?
Integerに統合したい
非互換になるのはどうでもよくて(マテ
どうでもいいのか
どうあるべきかの方が問題
まあ、できる/できないの観点から考えても、全部禁止に倒すしかなかろ、とは思う。
うん。他に選択肢ってあるのかな?
その「全部」の洗い出しが十分じゃないかも、という感じはある。インスタンス変数が漏れてるとか、Rational/Complexあたりがどうなのかいまいちわからんとかいうのはそういうことかと。
なるほろり
Rationalは特異メソッド禁止してた
Complexもだな
Numericで禁止されてるので、その子孫はみんな禁止されてると思う。
で、えーと、全部禁止してもたらされる非互換についてはですね、
「理念から言ってできるはずないのにそんなことしてたおめーが全部悪い」
でいいんじゃないかと。
そうですね。

Rational(1,2).extend Module.new できるのっていいのかな
module Foo;def +(b);9;end;end;(r=Rational(1,2)).extend Foo;r+1 #=> 9
おい
特異メソッドナシナシにするのが正しい方向な気がしてきたので、extend 禁止がいいのかなあ
しかし特異クラスができた時点でもうRationalじゃないんだから、ゆるされるはずという立場もあるのか
r=Rational(1,2); s=r; r.extend Foo; s+1 とか
破壊的にクラスが変わるってのはちょっと聞いたことがない
禁止候補:特異メソッド、特異クラス、インスタンス変数、オブジェクトフラグ(taintなど)
他なんかあったら、あるいは反論あったらどうぞ。
そうね
obj.extendした時って、obj側は何も呼ばないのか
Numeric#extend定義して禁止すればいいか
てっとりばやいね。
デザイナmatzの見解は聞きたいところではあるな。
そもそも class < 特異クラス作成禁止APIが必要
普遍オブジェクトのクラスとして登録、とかか。
FrozenCore.register_universal_class :Rational
ObjectSpaceのメソッドであろう。
Classクラスのメソッドかもしれないが。
不変=immutable 普遍=universal か
ObjectSpaceかも
universal_classはクラスがuniversalな気がしてしまうのでやや微妙
Classに登録というよりは、世界に対しての登録なので
ふむ、まあそうね。
深淵というニュアンスでFrozenCoreだったんだけど、ObjectSpaceの方が適切かも
Classのメソッドなら、Class#declare_univeral みたいに「俺がガンダムだ」的に叫ばせる感じ。
叫んで登録されるような安っぽいメソッドではないのです
まあ、ObjectSpaceでいいと思います。
そもそも、declare_universalがあるクラスしか登録できないのはおかしい。