R.Tanaka.Ichiro's Blog

主にC# な話題です

目次

Blog 利用状況

ニュース

暗黙的型付け(その4)

http://blogs.wankuma.com/rti/archive/2007/12/27/114850.aspx
暗黙的型付け(その3)

http://blogs.wankuma.com/rti/archive/2007/12/26/114624.aspx
暗黙的型付け(その2)

http://blogs.wankuma.com/rti/archive/2007/12/25/114456.aspx
暗黙的型付け

今回は、マメにコメントに返信をしたので、終息に向かっているように感じます。

しかし、もう1回だけネタにします^^;
今回は、var を

使えるところは使う理由

についてに論点を絞ってみたいと思います。



int i = 0;
Int32 i = 0;
Dim i As Integer = 0
var i = 0;


int 型であることを表現する方法は、いろいろあります。
var i = 0 も int 型であることを表現する方法の一つだと考えることはできないでしょうか?

僕は英語のできない人ですが、Book と言われて本と日本語に訳した後に本のイメージが頭に浮かびます。
英語のできる人は、Book と言われるだけで本のイメージが頭に浮かびます。
var も似たようなもので、慣れてしまうと、そこに紛れもなく型が存在していることを意識できるようになります。


float f = 1f;
var f = 1f;


例えば、上記のコードの前者は、float と書くことと 1f と書くことの2箇所で、f が float 型であることを表してます。
後者は、1f と書くことだけで float 型であることを表しています。
これは、以下のコードの HogeHoge 型を var にすることと何ら変わりはありません。


HogeHoge hoge = new HogeHoge();


次に、僕が for (var i = 0; と書く理由を、もう少し詳しく説明します。


var i = 0;
for (var i = 0; ・・・


どちらも i という変数を定義して 0 という定数を代入しているだけの式です。
一方が for のカウンタとして使われることを除いては、という前提が付きますが。

では、以下のコードはどうでしょうか?


var i = 0;
while (i < count) {
  ++i;
}


カウンタだから、var を使うべきではありませんか?
仮に、使っても良いなら、何故 for だけ特別に駄目なのでしょうか?

・・・についてご意見を伺いたいですね。

もう一つ、前回の記事に書いた部分を再度アップします。


private int unitPrice;
private int quantity;
:
private int GetAmount1() {
  return unitPrice * quantity;
}
private int GetAmount2() {
  var u = unitPrice;
  var q = quantity;
  return u * q;
}


GetAmount1 のような記述は許せて、GetAmount2 のような記述はすべきではないという明確な理由が僕には未だにわかりません。

ちなみに、皆さんが懸念されている「型を意識しない新人が増える危険性」についてですが、これは僕も同意見です。
でも、少なくとも僕にとっては、それが var を使ってはいけない理由にはなりません。

他の理由としては、考え方の順番通り記述できる点も好きですね。

1.金額を格納する変数を作ろう→(var)
2.名前は何にしよう→(var amount)
3.型はどうしよう→(var amount = 0m;)

また、変数の定義が綺麗にまとまるというのも好きですね。


HogeHoge hoge = new HogeHoge();
int i = 5;
float f = 1f;

var hoge = new HoegHoge();
var i = 5;
var f = 1f;


まあ、使う理由としては弱いですか・・・


#満員御礼!w

投稿日時 : 2007年12月28日 13:33

Feedback

# re: 暗黙的型付け(その4) 2007/12/28 13:42 NyaRuRu

まあR.Tanaka.Ichiro氏にはそろそろ Haskell とか F# とかおすすめですよと.
手軽さという意味では Nemerle (http://nemerle.org/) も.

もっとも,C# に帰ってこなくなるかもしれませんけど.

# re: 暗黙的型付け(その4) 2007/12/28 13:54 774RR

放置してたけど俺ちゃんなら
・コンパイラの推測する型は俺の使いたい型ではないかもしれない
という理由で var 却下。

C++ 屋さんなのでサンプルは C++ で書くが
base* p=new derived; // 基底クラスがつかいたいんぢゃ
カウンタとして int と size_t のどっちが使われるか見た目で判断しづらい
size_t n; があるとき while (n>=0) は無限ループなので

GetAmount2 はオブジェクトのコピーが生じるので却下

# re: 暗黙的型付け(その4) 2007/12/28 14:06 シャノン

もう一度、主張を整理して欲しいと思います。
その際、消極的な主張はやめて欲しいです。

どういうことかというと、「デメリットがあるから使うべきでない」という意見に対して「デメリットがないから使っても良い」では、反論として弱いと思うのです。
そうではなく「メリットがあるから使うべきである」を強調して欲しいです。

> C++ 屋さんなのでサンプルは C++ で書くが
C++0xでは型推論が入りますね。

# re: 暗黙的型付け(その4) 2007/12/28 14:11 επιστημη

> コンパイラの推測する型は俺の使いたい型ではないかもしれない

ナカーマ 【http://blogs.wankuma.com/episteme/archive/2007/12/27/114856.aspx

# re: 暗黙的型付け(その4) 2007/12/28 14:42 NyaRuRu

動的な型つけ言語とローカル変数の「暗黙的に型指定されたローカル変数」は,シンタックスが幾ら似ているからといって,セマンティクスは全く異なるものだ,という点はまあおくとしても,議論でこの辺の溝が埋まりにくいという点についてはこの文章がおすすめ.

http://capsctrl.que.jp/kdmsnr/wiki/bliki/?DynamicTyping

# re: 暗黙的型付け(その4) 2007/12/28 14:43 NyaRuRu

文面修正.

>動的な型つけ言語とローカル変数の「暗黙的に型指定されたローカル変数」は

動的な型つけ言語でのローカル変数と,C#での「暗黙的に型指定されたローカル変数」は

# re: 暗黙的型付け(その4) 2007/12/28 14:59 囚人

> コンパイラの推測する型は俺の使いたい型ではないかもしれない

var を使う文脈でそんな曖昧さはないので、その理屈はおかしいと思うんですけど。

# re: 暗黙的型付け(その4) 2007/12/28 15:05 Streetw☆

今思ったんですが、次のみたいなバグをうっかり書いちゃいそう(><)
var amount = 105; // 本当は105m
amount = amount / 2;

それと、しばらくVisualBasicで遊んでからC#に戻ってきたときに
var amount = 105d;
と書いて、どこかで誤差が出ちゃうとか(((;゜Д゜))
#decimalのサフィックスは、C#ではmですけどVisualBasicではdです。

# re: 暗黙的型付け(その4) 2007/12/28 15:06 NyaRuRu

>var を使う文脈でそんな曖昧さはないので、その理屈はおかしいと思うんですけど。

これで 774RR さんが関数テンプレートでも常に型を明示していたりすれば首尾一貫しているのですが,C++ 屋さんは関数テンプレートは「良い型推論」と特別扱いしていたりするふしがあるので,そのルートからは議論が成り立たないような気がします.
というかまあどのルートを通っても議論に見える疑似議論で終わりそうですが.

# re: 暗黙的型付け(その4) 2007/12/28 15:20 囚人

>これで 774RR さんが関数テンプレートでも常に型を明示していたりすれば首尾一貫しているのですが,C++ 屋さんは関数テンプレートは「良い型推論」と特別扱いしていたりするふしがあるので,そのルートからは議論が成り立たないような気がします.

ん~確かに。

ちょっと思い直し。
> コンパイラの推測する型は俺の使いたい型ではないかもしれない
てのが、「コンパイルエラーで教えてくれるからバグが少なくなるぅっ」って意味ならすごく納得。勝手に推論されたらコンパイルエラーになりませんらね。
base* p=new derived // derived は base を継承してないぜ!byコンパイラ

でも、
>C++ 屋さんなのでサンプルは C++ で書くが
>base* p=new derived; // 基底クラスがつかいたいんぢゃ
って理屈がまだ理解できないです。基底クラスで受けても、インスタンスの型は derived で変わりないでしょうって思うんですが。

# var を使う条件 2007/12/28 15:25 えムナウ Blog

var を使う条件

# re: 暗黙的型付け(その4) 2007/12/28 15:31 Gushwell

var i = 0;
とかは、intであることは、C#プログラマならば明白だから、使ってもなんら不都合はないと思うし、これを排除する積極的な理由は思いつきません。
じゃあ、僕が積極的に使うか、と問われると、もう体に染み付いている書き方をそのまま書き続けると思うけど...

ちょっと違った視点で僕の考えをまとめて、ブログに掲載しておきました。


# re: 暗黙的型付け(その4) 2007/12/28 15:35 Gushwell

リンク間違えてた m(_ _)m

# re: 暗黙的型付け(その4) 2007/12/28 15:48 シャノン

>> base* p=new derived; // 基底クラスがつかいたいんぢゃ
> って理屈がまだ理解できないです。基底クラスで受けても、インスタンスの型は derived で変わりないでしょうって思うんですが。

気分の問題ですよ。
敢えて言うなら、この後の処理には base で十分で、deribed に特有のメンバが必要ないときに、必要ないものは使えないようにしたい、とか。

# re: 暗黙的型付け(その4) 2007/12/28 15:57 囚人

>気分の問題ですよ。

だったら理屈を並べないで、「それが気分いいから」で良いと思うんですけどね。「気分いいから」は結構重要だと思いますし。


>敢えて言うなら、この後の処理には base で十分で、deribed に特有のメンバが必要ないときに、必要ないものは使えないようにしたい、とか。

new derived()
つー文脈がコードに出た以上それって若干弱いと思うんですよね。

じゃあ
base *p = GetHoge();
ならどうよ、って話も同じで
var p = GetHoge();
ってしたら、p は base になるわけで。

「変数の型をしっかり書きたい。見た目でソレが分かる方が気分良い」って理屈は非常に納得いきますが「推論される型が自分の意図と違うかも」って心配は杞憂でしょって言いたいだけ。

# re: 暗黙的型付け(その4) 2007/12/28 15:59 NyaRuRu

>敢えて言うなら、この後の処理には base で十分で、deribed に特有のメンバが必要ないときに、必要ないものは使えないようにしたい、とか。

それは C# 2.0 以降なら Generic Method と制約つかって書けばいいような,って気もします.気分の問題ですが.
C# をベター C++ としてのみ使いたいというのであれば止めはしませんけど.

# re: 暗黙的型付け(その4) 2007/12/28 16:01 NyaRuRu

>だったら理屈を並べないで、「それが気分いいから」で良いと思うんですけどね。「気分いいから」は結構重要だと思いますし。

ああ囚人さんも私と同じ結論にたどり着いたっぽ.
結局そこしか同じ視点で語れるところが無いんですよね.

# re: 暗黙的型付け(その4) 2007/12/28 16:05 NyaRuRu

そしてガウディ本の冒頭に戻る,と.
C# における var ですが,個人的には「歴史的偶然」に分類してよい事柄じゃないかなぁと思います.

http://d.hatena.ne.jp/asin/4798113468
「選ばれた言語に含まれる歴史的偶然が基礎概念とあまりにも密接にないまぜになっていて分離することが出来ない。ツールと概念がごちゃごちゃになっている。それに輪をかけて、オブジェクト指向、論理型、関数型等の「パラダイム(paradigm)」と呼ばれる、プログラミングの異なる見方に基づく、考え方の異なる流派がはびこっている。流派それぞれが独自の科学を持つ。1つの学問としてのプログラミングの統一性は失われた。」

# re: 暗黙的型付け(その4) 2007/12/28 16:20 Gushwell

僕も囚人さんの考えに近いかも。

var hoge = new HoegHoge();

が問題になる理由が思いつきません。わざわざインターフェースを萎めてしまうのは、どうなのかな。

じゃあ

var hoge = Factory.CreateHoge();

はどうよ? 
ということですが、もし、

Ihoge hoge = Factory.CreateHoge();

って書きたいってことなら、CreateHoge() の戻り値をIHoge()にすれば良いだけなので、

var hoge = Factory.CreateHoge();

も、結果的には同じになります。

# re: 暗黙的型付け(その4) 2007/12/28 16:38 シャノン

> だったら理屈を並べないで、「それが気分いいから」で良いと思うんですけどね。「気分いいから」は結構重要だと思いますし。

根拠としては最強ですね。
「理屈の問題じゃねぇんだよ」って、反論を許しませんから。

> 敢えて言うなら、この後の処理には base で十分で、deribed に特有のメンバが必要ないときに、必要ないものは使えないようにしたい、とか。

C++屋って、縛れるところはガチガチに縛りたいドMなんじゃないですかね?

> CreateHoge() の戻り値をIHoge()にすれば良いだけなので

えー?
ファクトリですから、もともと戻り値の宣言は IHoge だと思いますけど、そうでないなら、var を使いたいがためにメソッドシグネチャを変更するのはダメでしょう。

# re: 暗黙的型付け(その4) 2007/12/28 16:52 囚人

>ああ囚人さんも私と同じ結論にたどり着いたっぽ.
>結局そこしか同じ視点で語れるところが無いんですよね.

同じ事をやるのに複数のやり方で書けるプログラミング言語議論については「気分論」がむしろ正義って気がしてきました。

そして、

>根拠としては最強ですね。
>「理屈の問題じゃねぇんだよ」って、反論を許しませんから。

が伝家の宝刀ですね。

# re: ぱいなっぷるはちゅうかにはいっててもいいかろんそう。 2007/12/28 17:25 拝啓、サカモトと申します。

re: ぱいなっぷるはちゅうかにはいっててもいいかろんそう。

# re: 暗黙的型付け(その4) 2007/12/28 19:45 Gushwell

>ファクトリですから、もともと戻り値の宣言は IHoge だと思いますけど、そうでないなら、var を使いたいがためにメソッドシグネチャを変更するのはダメでしょう。

はい、もちろんです。varとは無関係に IHogeを返すことになりますね。

# varって.NET Framework 2.0でも使えるんだ~ 2007/12/29 6:52 XAMLab(ザムラボ)

varって.NET Framework 2.0でも使えるんだ~

# re: 暗黙的型付け(その4) 2007/12/29 11:33 R・田中一郎

NyaRuRu さん

>まあR.Tanaka.Ichiro氏にはそろそろ Haskell とか F# とかおすすめですよと.
>手軽さという意味では Nemerle (http://nemerle.org/) も.

魅力的ではありますね。
でも、僕としては、本来こうあるべきだという考え方はあまりないんです。
例えば、perl のスカラ変数が嫌いだから、perl なんかで書かないよ、なんて思ったことは一度もないです。

foreach(GetCollection()) {
SetValue($_);
}
(久しぶりなので、間違っているかも・・・)

とか何の拘りもなく使います。
だから、C# で var があるなら使えばいいし、使っちゃいけない理由も無いでしょうという考え方です。

>もっとも,C# に帰ってこなくなるかもしれませんけど.

逆にそういう身分になりたいですね^^;
VB6 に帰りたくなかったのですが、今の仕事で VB6 使ってます。

--------------------------------------------------------
774RR さん

>・コンパイラの推測する型は俺の使いたい型ではないかもしれない

推論という言葉だから誤解を生むんだろうなー、と改めて思いました^^;
僕としては var x と書いた時に、x が何の型なのか自分でわからないなら var を使うべきじゃないと思ってます。

--------------------------------------------------------
シャノン さん

>そうではなく「メリットがあるから使うべきである」を強調して欲しいです。

基本的にコメントへの返信をまとめているので、主張が分散してしまいましたが、前回までにメリットは書いてきたように思います。

・・・いや書いてないかな^^;

型を2重定義しなくて良い。
型が重要でない場面で、型を意識しない振る舞いを書ける。
代入元の型に常に順ずる型という定義ができる。
楽。
統一性。

みたいなものかな。
使う理由として弱いというなら、デメリットがないことを主張したことで、使わない理由が・・・となるので、この辺りは堂々巡りになってしまうかもしれません。

--------------------------------------------------------
επιστημη さん

>ナカーマ

というか、結局、好みの問題なんですよね。

--------------------------------------------------------
囚人 さん

>var を使う文脈でそんな曖昧さはないので、その理屈はおかしいと思うんですけど。

最近何かと囚人さんを「なかーまっ( ^^)人(^^ )」と感じる・・・

--------------------------------------------------------
Streetw☆ さん

>今思ったんですが、次のみたいなバグをうっかり書いちゃいそう(><)

確かにそれは否めませんね。

--------------------------------------------------------
Gushwell さん

>とかは、intであることは、C#プログラマならば明白だから、使ってもなんら不都合はないと思うし、これを排除する積極的な理由は思いつきません。

ですね。

new { id = 0, name = "aa" }

と言う書き方が現実に「ある」のですからね。

>じゃあ、僕が積極的に使うか、と問われると、もう体に染み付いている書き方をそのまま書き続けると思うけど...

良いこと言うなぁ。
これが真理ですね。
こっちの書き方だけはOK、こっちが悪い理由なんて、気分とか今までそうしていたからという理由でしかないですね。

と言うことで、結局、気分という結論に僕も同意です。
論じたところでキリが無いや^^;

# re: 暗黙的型付け(その4) 2007/12/29 15:22 Craf

はじめまして。
C++屋でC#はまだほとんど使ったことがないのですが、一連の議論を読ませてもらって俄然興味が沸いてきてます。C++0xでもautoの導入で同じような議論が起きるんだろうな。
議論を見てると、なんかハンガリアン規約で
int iCount = 0; //←intじゃなくなったら名前を変えなきゃいけない
なんて話との類似を感じるところがありますね。

私の立場としては、自分でR・田中一郎さんほど積極的には使うかはわからないけど、使える人にはどんどん使ってサンプルコードを出して欲しいと思ってます。
最初はJavaのクローンみたいに感じられたC#ですけど全然違う方向へ進歩して行ってますし、まだまだ全く予想のつかない発展をしていくのかも知れない。varもその第一歩かも。
明確なメリットがないなら使うべきではないという立場の型も多いようですが、なんか将来性というか、若い力とか未来への希望(おおげさ)を感じるのですよね。

まぁ業務で使ってないので気楽な外野の感想ですがヽ(´ー`)ノ

# re: 暗黙的型付け(その4) 2007/12/30 9:40 R・田中一郎

>議論を見てると、なんかハンガリアン規約で

僕も、同じことを思いました^^;

型推論は確かに素晴らしい技術ですし、使うべきところを考えるのはとても有意義ではあります。

一方で、後半の議論は、コーディングスタイルという点での議論になってしまいました。

ですから、~とするのは間違っているという反論に対しては、コードの例を提示して、一般的に許容できる記法との類似点と、その違いの説明を求めた訳です。

しかし、コーディングスタイルという論点は、とかく「気に入る」「気に入らない」という結論にしかならないので、最終的には人それぞれということなのでしょうね。

タイトル
名前
Url
コメント