凪瀬 Blog
Programming SHOT BAR

目次

Blog 利用状況
  • 投稿数 - 260
  • 記事 - 0
  • コメント - 46952
  • トラックバック - 192
ニュース
広告
  • Java開発者募集中
  • 経歴不問
  • 腕に自信のある方
  • 富山市内
  • (株)凪瀬アーキテクツ
アクセサリ
  • あわせて読みたい
凪瀬悠輝(なぎせ ゆうき)
  • Java技術者
  • お茶好き。カクテル好き。
  • 所属は(株)凪瀬アーキテクツ
  • Twitter:@nagise

書庫

日記カテゴリ

 

R・田中一郎さんのエントリに端を発した型推論の是非。 議論が盛り上がってきましたね。個人的には型推論なんて不要と考えています。

そもそも型推論なんてなんらメリットがないじゃないかと思っていたのですが、 菊池さんの仕様は変わっても真理は変わらない を読んでなるほどと思ったわけです。

しかし、それでもやっぱり型推論は不要だと思うわけです。Javaだと(Javaに限らないけど)

List<String> list = new ArrayList<String>();

といったコードをよく記述します。変数型は具象型ではなく、抽象型のjava.util.Listとして宣言する。 そして、newするのは具象型となるわけです。具象型特有のメソッドでも使うのでない限り、より抽象的な型として 宣言し扱うのがセオリーというものです。

おや、型推論の話と似ていますね。菊池さんのエントリには

「汎用的で可搬性の高いコードを書くためには型の決定はできうる限り遅らせるべき」なのです。

という記述がありました。この話には同意します。これは抽象型であるListで変数を宣言する感性を持っている人なら 基本的にみな同意できる事項だと思います。

しかし、私は抽象型で宣言する方がvarを用いて型推論するよりもメリットがあると考えます。 このあたり抽象と具象の線引きをどこでするのかという話題でしょうが、varは抽象が過ぎると思うのです。

投稿日時 : 2007年12月26日 21:29
コメント
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    かずくん
    Posted @ 2007/12/26 22:14
    > 抽象と具象の線引きをどこでするのかという話題でしょうが
    ビジネスロジックや永続層は、そうそう仕様が変わるものでもないでしょうから、型抽象で実装。

    UI層はどちらかといえば、使い勝手が求められるため、容易な変更が行える型推論で実装。

    という線引きははどんなもんでしょう?

    まあ、あれですわ。どこで見かけたかは忘れましたが、UIはPHPなどのスクリプト言語でさっくりと、内部の深層はJavaでしっかりと、てゆうやつですわ。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    かつのり
    Posted @ 2007/12/26 22:20
    自分はどちらかというと、型推論が欲しい方。
    Map<String,Map<String, Integer>> map = new HashMap<String,Map<String, Integer>>();
    みたいなコードはもう書きたくない・・・。

    型推論は代入によって型が静的に確定できるだけで、抽象化とはまたちょっと違う概念ですね。
    -------------------------------------------
    var foo;

    //fooはこの文脈からHoge型と推論される。
    foo = new Hoge();
    foo.hoge();

    //fooはこの文脈からPiyo型と推論される。
    foo = new Piyo();
    foo.piyo();
    foo.hoge();//コンパイルエラー
    -------------------------------------------
    こんな感じで1つの変数名に対して、文脈で静的に型が決まるのが型推論かな。
    導入されると結構便利ですよ。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    凪瀬
    Posted @ 2007/12/26 22:49
    自分の型推論の理解ってjavascriptからきているんですよね。いまのところ自分の理解は間違ってはいなさそう。

    そのうえで、自分は明示的に
    Map<String,Map<String, Integer>> map = new HashMap<String,Map<String, Integer>>();
    って書きたい人。
    型推論だと、何の型なのかコード的には明示されないので、
    人間である自分が脳内VMで型推論のアルゴリズム同等の推論を働かせて型を推定しないといけないのが非常につらい。

    便利というのはわかるんだけど、曖昧さのあるコードにしてまで欲しい利便性とは思えないなぁ…。
    型推論って変更が安易すぎて怖い。

    今だとEclipseのリファクタリングが強力なんで、静的型付けでもなんら困らないんですよね。
    テキストエディタでコーディングしろと言われたら動的言語を使いたくなるかもしれない。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    かつのり
    Posted @ 2007/12/26 23:39
    >型推論だと、何の型なのかコード的には明示されないので、
    >人間である自分が脳内VMで型推論のアルゴリズム同等の推論を働かせて型を推定しないといけないのが非常につらい。

    いやいや、文脈上の代入文で型が決まるので、EclipseのようなIDEでも静的に型解決できますよ。
    ある時点での代入から次の代入までが、その変数の型が有効な期間になります。

    パッと見は確かに分かりにくいかもしれませんが、VBのVariantみたいな型の変数への代入ではないので、代入によって人間が見ても型は明確ですよ。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    かずき
    Posted @ 2007/12/27 0:06
    私は、メソッドの戻り値や引数みたいな部分には抽象的なjava.util.List(もしくはjava.util.Collection)を使うべきだと思います。
    これは、内部実装が変わっても外部に与える影響を下げるためです。

    でも、varみたいにローカル変数のみにしぼって考えると
    Collection c = new ArrayList();
    って書くのと
    ArrayList c = new ArrayList();
    って書くのはあんまり変わらないと思います。

    もし、メソッドの後の方でCollectionには無くてArrayListにはあるメソッドを呼んでたら、そのメソッドではArrayListをつかわないといけないものなんでしょう。

    って感じます。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    じゃんぬねっと
    Posted @ 2007/12/27 9:12
    私も nagise さんとだいたい同じですね。
    精神衛生上の問題が多いです。

    用意されたら濫用もありえるわけで、先を考えると怖いです。
    実際継承なんて概念を VB が持った時、VB の方々は継承を濫用しました。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    じゃんぬねっと
    Posted @ 2007/12/27 9:33
    各所の同フィードバック Blog で暴れて参りました...
    仕事しま~す。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    シャノン
    Posted @ 2007/12/27 10:06
    > Map<String,Map<String, Integer>> map = new HashMap<String,Map<String, Integer>>();

    だからC++屋はtypedefが好きなんです。
    これは必ずしも型推論が必須ではない問題。

    > 人間である自分が脳内VMで型推論のアルゴリズム同等の推論を働かせて型を推定しないといけないのが非常につらい。

    御意。
    これを軽視しているやつはいっぺんLISPのコードを読んでみろ、と言いたくなります。

    > ある時点での代入から次の代入までが、その変数の型が有効な期間になります。

    いえ、C#の型推論は、違う型の再代入(型の変更)を許しません。

    > パッと見は確かに分かりにくいかもしれませんが、VBのVariantみたいな型の変数への代入ではないので、代入によって人間が見ても型は明確ですよ。

    どちらかと言うと Java の var は VB の Variant に近いですよ。

    > 仕事しま~す。

    うぃ~す。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    アキラ
    Posted @ 2007/12/27 11:04
    > Map<String,Map<String, Integer>> map = new HashMap<String,Map<String, Integer>>();

    だからC++では型推論がほしいです

    typedefがあるから型の中に型を持てるので(標準ライブラリのクラスも)
    そういうのを使うと変数宣言がハンパじゃなく長くなるんですよねー

    こんなのはもうお決まりなんだし(C++流の日常使うfor文)
    for (std::vector<int>::const_iterator it = v.begin(); it != v.end(); ++it)

    こう書けてもいいじゃないか(使いどころはもちろん考えますけど)
    for (auto it = v.begin(); it != v.end(); ++it)


    C#はただでさえシンタックスシュガー多いんだし、型推論いらないんじゃね?と
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    アキラ
    Posted @ 2007/12/27 11:07
    > Map<String,Map<String, Integer>> map = new HashMap<String,Map<String, Integer>>();

    この場合はtypedef使うでしょうけど
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    かつのり
    Posted @ 2007/12/27 11:30
    Javaで検討されている型推論についてはまだ検討中みたいですね。ちょっと勘違いしていました。

    案ではfinal foo = new HashMap<String, String>();
    みたいな感じになっているので、再代入は無理っぽいですね。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    凪瀬
    Posted @ 2007/12/27 12:08
    自分は宣言が半端ない長さになることを厭わないからなぁ。
    だって、結局そういう型であることをどこかで意識するわけでしょう?
    明示してもいいじゃん。

    プログラムがおぼつか無い頃は静的な型付けの強い言語って鬱陶しいんですよね。
    どうすればコンパイルエラーなくせるんじゃー!ってなもんで。
    慣れてくると動的言語の方が難しい。型推論のルールを把握するよりも、静的な型付けの方がルールが簡単。

    C#やJavaの型推論(Javaは検討中レベルだけど)ってのはシンタックスシュガーだろうけども
    それ、本当にシュガーか?麻薬かなんかじゃないの?という感想。
  • # re: 仕様は変わっても真理は変わらない
    菊池 Blog
    Posted @ 2007/12/27 12:10
    re: 仕様は変わっても真理は変わらない
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    シャノン
    Posted @ 2007/12/27 12:16
    間違えてた。

    > Java の var は VB の Variant に近いですよ。

    JavaScript の var です。大違いだこりゃ。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    菊池
    Posted @ 2007/12/27 13:37
    var 使わないとどうにもならん例

    -- Entities.cs
    class Product<TCurrency>
    {
    string name;
    TCurrency unitPrice;
    }

    class Sales<TAmount,TCurrency>
    {
    Product<TCurrency> item;
    TAmount amount;
    abstract void WritePrice( TextWriter write )
    }

    -- Sales.impl.cs
    partial class SpecifiedSales
    {
    override void WritePrice(TextWriter wr)
    {
    var price = item.UnitPrice * amount;
    wr.Write(price);
    }
    }
    --

    でSalesを日本のコンビ二に特化させる

    --Spec.cs
    // 何個何円だから両方int
    partial class SpecifiedSales: Sales<int,int> {}
    --


    これをアメリカのガソリンスタンドにする

    --Spec.cs をこれに入れ替える
    // 何ガロン何ドル.セントだから両方double
    partial class SpecifiedSales: Sales<double,double> {}
    --

    簡単に言うとジェネリック対象メソッド内では計算できないのでWritePriceはabstractにならざるを得ないのです。

    抽象度は確かに高すぎるんだけど代替する表現手段がないのよね。
  • # re: 型推論とは、人間には明らかに分かる型に対して、いちいち型名を明示しない事
    囚人のジレンマな日々
    Posted @ 2007/12/27 14:40
    re: 型推論とは、人間には明らかに分かる型に対して、いちいち型名を明示しない事
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    シャノン
    Posted @ 2007/12/27 15:07
    うへ。
    「partialクラスなんてコードの自動生成ツールのためのものでしかない」な俺には想像できないサンプルケースですな。
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    凪瀬
    Posted @ 2007/12/27 16:19
    プリミティブ型のintとかdoubleだからvarを使わないといけないように思えるだけでは?
    適切な抽象型を定義してやれば片付く問題に思えるんですが。
    C#のコードはいまひとつ馴染みがないのですぐには代替えコードの提示ができませんが…
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    菊池
    Posted @ 2007/12/27 20:35
    >プリミティブ型のintとかdoubleだからvarを使わないといけないように思えるだけでは?

    「演算できないから」と言っている以上はプリミティブ型しかもともと自分は考えてませんよ。
    CLR/ILではプリミティブしか根本的には演算できんのだし。

    >適切な抽象型を定義してやれば片付く問題に思えるんですが。

    根本的に演算できない以上はここに IMullable(積算可能) や IAlythmeticOperationalbe(四則演算可能)のint特化やdouble特化を挟む以外は解決策がないのよ。そして interface 経由の呼び出しはメソッドのインライン化がされないというパフォーマンスペナルティを背負うトレードオフを背負う覚悟でなければできないのよね。

    そういう意味では非プリミティブは.NET Framework2.0のvar無しジェネリックで十分と思ってます。
    記述が長ったらしくなってvarで逃げたいと思うことはよくあるし、それに簡単に負ける自分だけど。(これは単なる記述性での問題であって根本的な機能問題ではないと自分は思ってる)

    var以外でこれをイージーに(NyaRuRuさんの得意な分野の、ExpressionTreeをコネコネしてCompileは決してイージーな手段としては認めません)コンパイルが通る方法を探し出してくれればvarが絶対に必要なケースは自分でも方法がないと結論出し切れない一つだけになる。(これはなんか回避策がありそうな気がしてるので表にはまだ出せない)

  • # partial class + generic = template ?
    囚人のジレンマな日々
    Posted @ 2007/12/27 21:42
    partial class + generic = template ?
  • # re: 型推論を使う理由は抽象型を使うようなもの?
    凪瀬
    Posted @ 2007/12/27 21:43
    なるほど、確かにプリミティブ型では他に手だてはないですね。
    Pythonなどの言語ではプリミティブ型での型宣言がないようなのですが、言語で適切な扱いするから気にすんなって方向性のようなのですよね。
    そういう意図で型推論というのは、確かに利があると思えますね。
  • # partial class + generic = template ?
    囚人のジレンマな日々
    Posted @ 2007/12/27 21:49
    partial class + generic = template ?
  • # varは、2007年のクリスマスプレゼント?
    石野光仁 Blog
    Posted @ 2007/12/28 9:39
    varは、2007年のクリスマスプレゼント?
タイトル
名前
Url
コメント