Re: IS演算子の必要性 (No.1) [スレッド一覧へ] |
- 日時: 2007/06/20 10:40
- 名前: 魔界の仮面弁士
- > ・オブジェクト変数へのオブジェクト代入は、VB6ではSet文で行った。VB2005ではSetは不要(すなわちLet)
どちらかというと、(Letではなく)Set の動作ですね、VB2005では。 値型に付いては、ボックス化(boxing)とその解除(unboxing)が行われます。
ただし COM 相互運用時においては、やはり Let と Set とを別に扱う必要があります。 # だからこそ CallByName では、両者を区別して呼び出せるようになっています。
また Let / Set の使い分けは、呼び出し側ではなく、それを受け取る側の実装に依存しています。 COM クラス側の実装如何では、「オブジェクトを Let で渡す」こともできますし、 実際、そのような仕様になっている COM クラスも少なからず存在しています。
例をあげてみると、ADODB.Command オブジェクトの "Output Stream" 動的プロパティが、 Stream オブジェクトを Let で渡す仕様になっていましたし、より身近なところでは、 VB6 PictureBox オブジェクトの Picture プロパティは、Picture オブジェクトを Let でも Set でも渡せる仕様になっています。
> ・それなのに変数比較だけはVB6同様、ISと=を使い分けている。 すべてがオブジェクトである、とは言っても、だからといって 「参照」と「値」の概念まで無くなったわけではないですよね。 VB6 でいうところの IsObject(x) 、.NET でいうところの IsReference(x) の違いです。
そもそも Is 演算子の意味は、VB6 の頃から変化していないと思います。 すなわち、「オブジェクト参照の一致性を見るための演算子」です。 .NET では参照型にしか使えず、VB6 においてはオブジェクトにしか使えません。
= 演算子についても、(VBS / VB6 / .NET でそれぞれ微妙に意味が異なるとはいえ) 基本的には「値の一致性を見るための物」である点は変化していないと思います。 (ちなみに、VB.NET の = 比較演算子と、C# の == 比較演算子は別物です)
両者に求められる機能が異なっている以上、一方を廃止する事も出来ないのではないでしょうか。
> いやちゃんとIS演算子と=比較演算子は分ける必然性があるというなら、宜しくお聞かせ下さい。 逆に質問しますが、Is 演算子があると困る場合というのはありますでしょうか? あるいは、「Is 比較では False だが、= 比較では True となる場合」において、 ダンボさんであれば、どのような言語実装がなされれば、違和感を感じなくなりますか?
|
Re: IS演算子の必要性 (No.2) [スレッド一覧へ] |
- 日時: 2007/06/20 12:43
- 名前: ダンボ
- 魔界の仮面弁士さん、いつもお世話になっています。
お答えいただいて恐縮なんですが「言葉の上での理解」は「そんなものかも」程度です。 回答文章に「具体的にはこれこれ」という事例も提示していただいていますが、 私の経験不足・知識不足でまだピンと来ていません。 (あ、だからと言って他の具体例を説明してくれというのではないです。多分追いつけません)
もう少しVB2005のプログラミングに習熟しながら考え続けて行きます。
>ダンボさんであれば、どのような言語実装がなされれば、違和感を感じなくなりますか? 違和感なので強い根拠がないのです。「Is 比較では False だが、= 比較では True となる場合」 も思いつきませぬ。「違和感」と呼んだのは下記と同列(統一性の欠如)で、
[BASIC] =に算術演算子と論理演算子の2つの意味を持たせたのはかなりひどい言語設計誤り。 [BASIC] 演算子に「記号」と「予約語」が混在している。+、=、&、AND、NOT、MOD [VB6.0] 上記2思想を踏襲するなら、参照の代入の場合も Set A = Nothing ではなく Let A Is Nothing にすべきだったのでは? [VB.Net] 代入のときは=で統一できたのに、比較の時には=とISを使い分けるの?何で統一できないの?
|
Re: IS演算子の必要性 (No.3) [スレッド一覧へ] |
- 日時: 2007/06/20 14:25
- 名前: 魔界の仮面弁士
- > [BASIC] =に算術演算子と論理演算子の2つの意味を持たせたのはかなりひどい言語設計誤り。
そのあとに続く論拠を見る限り、問題点を感じているのは、「算術演算子」「論理演算子」という 点ではなく、「代入演算子としても使われている」という点なのでは……?
> 他の具体例を説明してくれというのではないです。多分追いつけません まぁ、ネタとして書いているだけなので、適当に読み飛ばしてくださいませ。
>「Is 比較では False だが、= 比較では True となる場合」も思いつきませぬ
たとえば、『分数クラス』を作った場合を想像してみてください。
「1/2個のリンゴ」と「1/2個のミカン」があったととき、『値』は「1/2」で一致しますが、 『物(Object)』は、「リンゴ」と「ミカン」という別物を示していますよね。 そのような状況であれば、Is は False、= は True となります。
VB2005 で書くなら、こんな感じですね。 http://www.vb-user.net/junk/replySamples/2007.06.20.12.57/ObjectReference.txt
あるいは、VB6の『テキストボックス』でも良いです。
フォームに、「Text1」と「Text2」を貼って、いずれの Text にも「あいうえお」と入れます。 この場合、Text1 と Text2 は異なるオブジェクトなので、Is は False ですが、 テキストの内容は一致しているので、= は True になりますね。 If Text1 Is Text2 Then '… False となる。 If Text1 = Text2 Then '… True となる。
|
Re: IS演算子の必要性 (No.4) [スレッド一覧へ] |
- 日時: 2007/06/20 14:16
- 名前: よねKEN
- #魔界の仮面弁士さんのレスとかぶりまくりですが、せっかく書いたので投稿しときます(^^;
Isと(比較演算子としての)=は同じ比較演算子ですので、同じ文脈で使われます。 そのためIsを単純に=で代用するという言語仕様にはできません。
Class Aの変数aと変数Xを比較する場合、以下のような2種類の比較ができます。 (1) If a Is X Then (2) If a = X Then
それぞれの意味は、
(1)は変数aとXが指すインスタンスの参照が同一かどうかを判定します。 (2)は変数aの指すインスタンスの値と変数Xの指すインスタンスの値が同一かを判定します。
というように異なるものですので、2パターンを区別することができる必要があります。 今は、Isと=というキーワードの違いから判別できます。 これを単にIsを使わない(=を使う)とした文法ではその区別ができないため、 Is→=と変えた場合には、別のキーワードの導入など何らかの文法上の変更が必要になります。
代入の「=」とは同じ文脈で使われることはないので、 比較の「=」と確実に区別ができます。(できるように言語が設計されています)
>>ダンボさんであれば、どのような言語実装がなされれば、違和感を感じなくなりますか? >違和感なので強い根拠がないのです。「Is 比較では False だが、= 比較では True となる場合」 >も思いつきませぬ。「違和感」と呼んだのは下記と同列(統一性の欠如)で、
先の例で言うと「a Is X はFalseだが、a = X はTrue」な例ですが、 Class Aを人間クラスとして以下のように定義したとします。 Public Class A Public 身長 As Integer Public 体重 As Integer End Class
変数aは鈴木さん(身長170、体重60)、変数Xは田中さん(身長170、体重60)だとすると 同一人物ではないので、a Is X はFalse、 身長、体重という観点からは同一なので、a = X はTrueになります。
実際にはクラス同士はデフォルトでは「=」で比較できませんので、 演算子のオーバーロード機能により比較演算子「=」をオーバーロードしてやる必要がありますが。
>[BASIC] =に算術演算子と論理演算子の2つの意味を持たせたのはかなりひどい言語設計誤り。
代入演算子と比較演算子ですよね? 他の言語ではまた違った方法を採用していることの多い部分でもありますので、 言語設計者の影響の受けた言語や考え次第なところはありますね。 でも、誤りとは言えないと思います。
>[BASIC] 演算子に「記号」と「予約語」が混在している。+、=、&、AND、NOT、MOD
逆に記号ばかりを突き詰めた言語やなるべく 英語で表現できるようにした言語などいろいろありますね。 何が正解というのはありません。
個人的にはVBでのその辺のバランスはMod以外はよいかなと思っています。 全部、英語だと長すぎるし、全部記号はわかりにくいですから。 (記号の数は限られているので)
>[VB6.0] 上記2思想を踏襲するなら、参照の代入の場合も Set A = Nothing ではなく Let A Is Nothing にすべきだったのでは?
この辺はLetそのもののセンスがよくわからないのと(大昔のBASICでもLetを書いたことは一度もない)、 そもそもSetを用意した理由もよくわからない(たぶんVariant型が存在するためだろうと思うのですが)ので、 何とも言えないですね。
代入の=と比較の=は、言語設計上は区別する必要性は高くないのですが、 Pascalのように「:=」と「=」で区別している言語もありますね。 その点では元々のBASICの「Let」は「:=」の「:」の役割を意図したものだったのかもしれません。
>[VB.Net] 代入のときは=で統一できたのに、比較の時には=とISを使い分けるの?何で統一できないの?
VB6以前でも言語設計の観点からは「Set」は絶対に必要というものではなかったように思います。 ただ、Setがあった方がコンパイラの開発はずいぶん簡単になるので必須としたのでしょう。
VB.NETになって、すべてはオブジェクトとなった時点で、統一できたというより、 すべてが「Set a = X」の形になったから結果として「Set」が不要になったのだと思います。
代入と比較の=を統一できる理由、Isと=を統一できない理由は先頭に書いた通りです。
|
Re: IS演算子の必要性 (No.5) [スレッド一覧へ] |
- 日時: 2007/06/20 19:43
- 名前: 魔界の仮面弁士
- # 雑談として、よねKENさんの記事に繋げてみる。
> 個人的にはVBでのその辺のバランスはMod以外はよいかなと思っています。 微妙なのが、/ 演算子と \ 演算子。
英語圏では「/と\」なので、対の演算子に見えるのだろうけど、 日本語圏では「/と¥」のように見えてしまうのが気持ち悪いと感じています……。
> 比較の「=」と確実に区別ができます。(できるように言語が設計されています) でも、個人的には分けてほしかったです。(^^:
Pascal や Oracle みたいに、「a := 値」なんてのも良いかもしれない。 残念ながら、VBではすでに「:=」が別の意味を持っているのだけれども。
> VB6以前でも言語設計の観点からは「Set」は絶対に必要というものではなかったように思います。 無いと困る場面もあります。たとえば、 Dim rs As DAO.Recordset Dim v1 As Variant, v2 As Variant '(中略) Let v1 = rs!ID Set v2 = rs!ID だと、明らかに別の意味になりますしね。
# 上記に関しては、「v1 = rs.Fields("ID").Value」にすれば曖昧さ回避になりますが、 # オブジェクトによっては、そういった回避方法ができないものもあったりするわけで。
で。Set/Let については、VB の歴史をたどっていくと微妙なところもあって…。
VB2 では、「Object 型」は存在していませんでした。 クラスモジュールの作成機能さえありません。
しかし当時から、オブジェクトという概念は存在していました。
この時代のオブジェクト型として存在したのは、ジェネリック(総称)な オブジェクトである Form 型と Control 型、スペシフィック(固有)な オブジェクトである MDIForm、ユーザー定義フォーム型(Form1, Form2等)、 カスタムコントロール型(今でいう ActiveX コントロール)、そして 標準コントロール型(TextBox, PictureBox等)です。
この中に、Picture というオブジェクトは存在していません。 LoadPicture で返される画像は、まだオブジェクトでは無かったのです。
それゆえに、VB2 当時では Let Picture1.Picture = LoadPicture(…) Picture1.Picture = LoadPicture(…) などは動作しましたが、 Set Picture1.Picture = LoadPicture(…) はコンパイルエラーとなりました。
しかし VB4 になると、オブジェクト指向の取り入れが強くなります。 (OLE も、1.0 から 2.0 へと進化しました) DLL を作成できるようになり、画像も Picture オブジェクトとなったため、 Set Picture1.Picture = LoadPicture(…) が推奨されるようになりました。しかし、過去との互換性から、Let も残されました。
今現在、「Let Picture1.Picture = LoadPicture(…)」が行えるのにもかかわらず、 「Let MSHFlexGrid1.CellPicture = LoadPicture(…)」が使えないのは、このような理由によります。
|
Re: IS演算子の必要性 (No.6) [スレッド一覧へ] |
- 日時: 2007/06/21 10:48
- 名前: ダンボ
- 魔界の仮面弁士さん、よねKENさん、そして読んでくださっている皆さんありがとうございます。
(カウンターが付いたのでどれだけ多くの人が読んでいることかと面白いやら怖いやら)
おかげさまで一次的な疑問は解決しました。
以下は雑談なので、フレーミングにならない程度にお読み下さい(機種依存文字有り)
・Isと=を統一できない理由 参照と値が区別できないからですか。 そこのところはVB.Netで「デフォルトプロパティを廃止した」というから安心していたのですが 魔界の仮面弁士さんご紹介の http://www.vb-user.net/junk/replySamples/2007.06.20.12.57/ObjectReference.txt を見るとユーザ定義のクラスでは実現できてしまうのかな。 そういうサンプルがあるところを見ると私の疑念も一般的かも。
・代入演算子と比較演算子の2つの意味を1つの記号に持たせたこと 「誤り」の定義に依ってしまうのであまり議論はやめましょう。しかし=に2つの意味を 持たせることによる「メリットは何も無くてデメリット(可読性・誤誘原因)はある」。 更に自由奔放に言えば、代入演算子には←を、ポインタには→を提案したいなぁ。 入門書に必ず繰り返される「=と*」の説明も、もっと直感的な記号を言語に採用していたら 不要だったかも。
|
Re: IS演算子の必要性 (No.7) [スレッド一覧へ] |
- 日時: 2007/06/21 13:40
- 名前: 魔界の仮面弁士
- >>6
> メリットは何も無くて これについてはノーコメントで。(^^;
> デメリット(可読性・誤誘原因)はある これはありますね。
= 記号以外だと、 ・引数の丸括弧 ・配列の丸括弧 ・数式の丸括弧 の違いもあるかも。 配列を返すメソッドだと、どっちの丸括弧だかわからなくなったりとか。
でもって、2002 / 2003 / 2005 のときには、この点の揺れを何とかしようと もがいた結果、IntelliSense の丸括弧処理の仕様が、微妙に異なっていたり。
> 代入演算子には←を、ポインタには→を提案したいなぁ マルチバイト文字は、英語圏の人達に嫌がられるんじゃないかな? やるならば、「<- 演算子」あたりが無難かも。
ちなみに C# の言語仕様では、「=>」「>=」「<=」「->」が既に定義済みだったりする。
>>4 > 代入の=と比較の=は、言語設計上は区別する必要性は高くないのですが、 「a = 1」などの代入操作については、C# では『式』で、 VB では『ステートメント(文)』であるという違いがありますね。
なので、「a = b = true」というコードは、VB と C# では意味が異なる、と。
> (記号の数は限られているので) VB 言語で未定義の記号って、ASCII の範囲だと「`」「|」「~」「@」ぐらいでしたっけ。 まぁ、「 _」や「<<=」みたいに複合記号で数は増やせますが……それもややこしいなぁ。
|