@__DaLong D言語偉い。int[int] 連想配列は = 0 せずに += するだけでカウントアップできる。つまり暗黙の初期値0が入ってる。#D_lang
2012-06-16 23:26:23これはint.initが0なため。double,floatの場合はnanになるので注意 RT @__DaLong: @__DaLong D言語偉い。int[int] 連想配列は = 0 せずに += するだけでカウントアップできる。つまり暗黙の初期値0が入ってる。#D_lang
2012-06-17 02:50:49@9rnsr おお、そのうち (連想配列でないところで) double 初期化しないでひどい目に遭いそうです。
2012-06-17 02:56:24@9rnsr @__DaLong これってdefined behaviorなんでしょうか。dmd だと int[int] x; int n=x[0]+1; が例外なのに x[0]=x[0]+1; が通るのですがバグのような気がしていて、x[0]+=1も同様にたまたまと疑ってました
2012-06-17 02:55:41正しいかどうかはともかく、Python で dict を継承して default 値をもつ dect を作ってたこともあるし、便利ではある。その点では他所へ値を出すのはバグの元だからよくなくてカウントアップだけに使えるのはよいが、定義されてるかっていうと怪しいなあ。
2012-06-17 03:01:36少なくとも昔はC++のstd::mapと同じ、なかったら.initを埋める仕様だったのを、読み取りのときは例外飛ばすことにある時点で変えた議論は記憶にあって、http://t.co/kN5Jihow でも例外のこと書いてない…。
2012-06-17 03:02:09@kinaba @__DaLong あー、そうか意味的にはx[0]を初期化する前に操作する挙動になるのか。すいません、Dではx[0]に値を代入する前に読み出すのはRangeErrorが投げられます。
2012-06-17 03:03:13@kinaba @9rnsr @__DaLong バグのような。まだ登録されていないキーを使っているので、RangeErrorが正しいような気がしますね。
2012-06-17 03:05:11ただここで現在の実装では動いてしまう場合があって、x[0]=yyy、x[0]op=yyyの場合は左辺の評価で「値を代入するための領域を確保」してしまうため、右辺の評価時には例外が飛ばない、ということが起きます。
2012-06-17 03:06:39@kinaba 値がまだないときは指定されたデフォルト値を返す、getという組み込みプロパティは一応すでにありますが… http://t.co/zb1RGOwG このデフォルト値が省略時にValue.initになったらいいのかな?
2012-06-17 03:11:28@9rnsr 仕様書に、「x[0]=yyy、x[0]op=yyy で値を代入するための領域がない場合は、新しく領域をT.initの初期値の値で確保します。」って追加するのがいいのかなぁ。
2012-06-17 03:14:18@mono_shoo 要素を格納する領域確保のタイミングが「代入の直前」ではなく「左辺値の評価時点(=右辺値の評価前)」なのが問題ですから、ある意味ここだけ非直感的な評価順序になってしまっているのを仕様にするのはちょっとためらわれますね。
2012-06-17 03:19:44@9rnsr getはrefでもなくデフォルト値をついでにセットしたりもしないので、x.get(i, int.init)+=1; ができないので、それではあまり嬉しくなさそうです。x[i]=x.get(i(,0))+1 と書かないといけないなら ,0 がなくても大差ないかも
2012-06-17 03:25:46@9rnsr そうですね。代入式は = の右の式が最初に評価される…って実は仕様ではないのですが、a[0] = a[0] + 1;がエラーにならないのはとても非直感的。
2012-06-17 03:26:26@kinaba あー、getは左辺値を返さないのか。ただ現状getはobjectモジュールのAssociativeArrayテンプレートで定義されるので、これがrefで値を返すように変更することは出来ると思います。既存コードも壊れませんし。
2012-06-17 03:29:10@9rnsr え、それって aa.get(key) のkeyがaaに存在しない場合、aa[key]が存在しないままValue.initが返されますが、その場合は何をrefで返すのです?
2012-06-17 03:31:57