投稿

クロージャ、java7での導入厳しいのかしら?

クロージャはjava7での導入の見込み薄い という書き込みを見かけた。 ソースを手繰るとjava7のメーリングリストっぽい。 ガーン。 BGGAのクロージャ実装、色々調べたのにー。 言語仕様の変化が大きすぎるのかー!? ……ん、ただのシンタックスシュガーだし関係ないか…。 (ここのClosure日記は、jdk1.6.0_10-bataでコンパイル/実行してる) だから逆に「そんなシンタックスシュガーごときいらん」 ということなのかな。ラムダ式楽しいぜ? Effective Java Second Edition に"Item21: Use function objects to represent strategies"という項目が増えてたりして、 Third EditionでのClosure項目追加の布石かしら? とか期待していたんだけどなあ。 でも一方でどこか安心している自分もいたり…。言語仕様の拡張を 好まないところはjavaらしいかなと。私がjavaを好む理由のひとつは 言語仕様拡張よりライブラリ提供での機能拡張を好むところだし。 まだ決まったわけじゃないし、来年のJavaOneの内容を楽しみに 待ちますかー。    

Javaのクロージャをいじってみた。(1)

イメージ
BGGAのクロージャサイト(http://javac.info/) の プロトタイプ実装をいじってみた。 マイコミジャーナルに概要を書いた記事があるようです。 今回いじってみたのは2008-07-07版と2008-07-13版のプロトタイプ実装。 JSRもドキュメントもちゃんと読まずにいじっているけど まあいいや。 1.単純実装の逆コンパイルして中身見る ・クロージャを用いたjavaコード public class SimpleClosure {   public static void main(String[] args) {     int sum = { int x, int y => x + y }.invoke(3, 4); // return 7     System.out.println(sum);   } } ・下のコードは上記コードをコンパイルし、jadで逆コンパイルしたコード import java.io.PrintStream; import javax.lang.function.III; public class SimpleClosure {   public SimpleClosure() {}   public static void main(String args[]) {     static class _cls1 implements III {       public final int _2B_invoke(int j, int k) {         return j + k;       }              public final int invoke(int j, int k) {         return _2B_invoke(j, k);       }     }     int i = _2B_INSTANCE0.invoke(3, 4);     System.out.println(i);   }   // ↓クロージャの実体(staticのメンバとして記述される)   public static final _cls1 _2B_INSTANCE0 = new _cls1(); } 逆コンパイルで気づいた点  ・クロージャの場合実際はstaticメンバとして宣言されるため...

丸め誤差で散々悩む

Rhinoを使ってスクリプティングをちょっと試してたところ、妙な計算結果に遭遇。 (100.5-30.4)*15.2=1065.5199999999998 掛け算しかしていないんですけど…。 全く原因がわかららず、   windowsの電卓 誤差無し   Ruby(1.8.5)   誤差無し   ActivePerl    誤差無し で試してみる。でも正しく計算されてしまいました。 これってRhinoのバグかしら。Bugzillaの使い方覚えなくちゃかしら。 とか考えるほど混乱。 頭を冷やすため、それからしばらくこの件は放置していました。 先日Firefox3のβをいじっていたところ、不意にこの件を思い出し、 javascriptの処理系が違ったら…ということで調べてみることに。 Firefox3とIE7で同じ計算をさせたところ、同じ誤差が発生し バグでないことが判明しました。 これ何なのさ…と調べ、"2進数表現による丸め誤差" という結論に たどり着きました。 長かった…。 ついでに手元にある他の処理系で試してみた。 【誤差有り】   java(6)   jruby(1.1 java6) (javaの影響)   Firefox(3 bate5)   IE(7) 【誤差無し】   C#(C#3.0)   C++(VC++9.0) C++で丸め誤差が発生しないのはびっくり。古めの言語だから逆に仕様として Javaのように丸め誤差が残っているものと思っていたのに。 Microsoftが気を利かせたのか、ISOの標準C++とかだとOKなのか。 面倒臭がって調べていない。 JavaはBigDecimalとかのクラスによって解決法を提供しているため、 言語仕様では(わざと?)誤差が残っているみたい。    

Blogger Syntax Highlighterテスト

前からやりたかったコードの表示、「クリボウの Blogger Tips」さんの記事に すごいのがあったので早速導入。& テスト。 public class HelloWorld {   public static void main(String[] args) {     System.out.println("Hello World!");   } } 今まで作成した日記も書き直そうか、どうしよう。    

Effective Java Second Editionが届きました。

イメージ
予約してから1ヶ月待たされてました。それが今日amazonからやっと届きました。 明日はJavaOne報告会に行ってきます。 ITProの記事で櫻庭祐一氏が書かれているJava 7情報。 同氏のJavaSE最新情報が聞けるので、期待して行ってきます。    

Java Genericsが難しい(4)

3.ジェネリクスと可変長引数と継承 以下のコードをコンパイル,実行すると、実行時エラー(ClassCastException)になる。 class Plus {   R apply(T... t) {     return t[0] + t[1];   } } class Client {   public void main(String[] args) {     Plus <Integer,Integer> p = new Plus< Integer,Integer > ();     Integer result = p.apply(1,2);        :        :   } } 私はjad使ってイレイジャの処理を見ていたのですぐにわかったが、 ソースコードだけ見て原因を特定できる人はすごいと思う。 jadで逆コンパイルすると以下のコードになる。 class Plus {   Object apply(Ojbect[] t) {     return apply((Integer[]) t); //   }   Integer apply(Integer[] t) {     return t[0] + t[1];   } } class Client {   public void main(String[] args) {     Plus p = new Plus ();     Integer result =       p.apply(new Object[] {1,2}); //        :   } } イレイジャ処理で生成されたブリッジメソッドに対し、可変長引数の処理が 行われるためブリッジメソッド内部で無理やりキャストする処理でエラーになる。 ブリッジメソッド、可変長引数など自動生成されるコード内でのエラーのため これははまると解決が大変なエラーだと思う。 ということで可変長引数とジェネリクスの組み合わせは良くない組み合わせ だと思う。    

Java Genericsが難しい(3)

2.ジェネリクスとオーバーロード 既存の方法で、何とか演算処理をさせたく少し試してみた。 Genericsメソッド内から、型だけ異なるオーバーロードメソッドの 呼び出してみた。 class Plus T,R > implements Function T,R > {   R apply(T arg1, T arg2) {     return apply(arg1,arg2);   }   Integer apply(Integer arg1, Integer arg2) {     return arg1 + arg2;   }   Double apply(Double arg1, Double arg2) {     return arg1 + arg2;   } } 結果はコンパイルエラー。 イレイジャ処理でObject型になってしまうので、IntegerともDoubleとも 合わない適当なメソッドが無い、とコンパイラが文句言う。 そもそもこのコードがうまくいったとしても、折角Genericsを利用しているのに オーバーロードメソッド定義していたらGenerics使っている意味無いし。 (Genericsなんか使わずオーバーロードメソッドで十分と)