特集
|
|
|
Visual Basicを再び動的プログラミング言語にする試み
本レポートの最後に触れておきたいのが、動的型付言語としてのVB9固有の拡張機能である。
VBにはC#にはない大きな特徴がある。遅延バインディング(Late Binding)支援機能だ。C#ではリフレクション構文を使って書かなければならないコードを、VBではあたかも型の内容を知っているかのように書くことができる。これはCOM Interop(COM相互運用)でExcelのセルを操作するようなコードを書くときなどに重宝する。
だが一方で、Option Strict Onを無条件に推奨するような風潮の中では、VBのこの機能はVBが「本物のプログラミング言語」になるためには捨て去るべき過去の遺物のように扱われているのも事実だ。
結局のところ、.NET Frameworkにおける当初のメッセージは「どの言語でも同じ」だったのだから、C#とVBに違いがあってはならず、VBはC#の後を追いかけているような印象を常に与えていた。
しかし今回のPDC05では、VBチームはいよいよこの風潮と決別しようとしていることが明らかになった。「My」の導入やフォームをインスタンス化する構文など、OOP(オブジェクト指向プログラミング)至上主義からは反対される機能をVisual Basic 2005で導入したことは前触れにすぎなかった。
PDC05で発表されたVB9は、もともと動的型付言語だった時代のVBからの、いまはやりの動的型付言語に対する回答だ。
■遅延バインディングによるXMLアクセス
VBで遅延バインディングを有効にしていると、次のようなコードがコンパイルできる(この場合は実行時例外となる)。
Option Strict Off
Imports System
Class Person
Friend Name As String
End Class
Module Module1
Sub Main()
Dim p As New Person()
p.Name = "Yoshimatsu"
ProcessPerson(p)
End Sub
Sub ProcessPerson(p As Object)
Console.WriteLine("{0} {1}", p.FirstName, p.LastName)
End Sub
End Module
静的型付言語の発想からするとこのようなコードは許されるものではない。
しかし、XML文書にアクセスするときには次のコードのように文字列でタグ名を記述しなければならず、結果として遅延バインディングを行っていることになる。
' VB9
For Each link As XElement In Select links From links In (Select item.Descendants("link") From item In rss.Descendants("item"))
Console.WriteLine(link.Value)
Next
どうせ文字列で識別子を指定して暗黙に遅延バインディングをしなければならないのだとしたら、このような不自然な記述をプログラマに強いる必要がどこにあるだろうか。VB9ではこのコードは次のように書いてコンパイルできる。
' VB9
For Each link In rss...item...link
Console.WriteLine(link.Value)
Next
属性には「rss...item...enclosure.@type」のような書き方でアクセスできる。コンパイル時点では、読み込まれたXML文書にitem要素が含まれるかどうかはいずれにしても分からないのだから、遅延バインディングをせざるを得ない。それならせめてコードは簡単に書けた方がいい。
■Extreme Late Binding
JavaScriptでは、次のようなコードを記述できる。
class1 = function() {
var _name = "Yoshimatsu";
var _age = 22;
this.get_Name = function() { return _name; }
this.get_Age = function() { return _age; }
}
function callMethod(obj, methodName) {
return obj[methodName]();
}
function main() {
var obj = new class1();
WScript.Echo(callMethod(obj, "get_Name"));
WScript.Echo(callMethod(obj, "get_Age"));
}
main();
このコードを実行すると、「Yoshimatsu」と「22」が表示される。つまり、オブジェクトに対してメソッドを呼び出すのだが、呼び出すメソッドの名前は実行してみないと分からないのである。これも遅延バインディングの例だ。従来のVBでも、リフレクションのコードを記述すればこのような動作は可能だったが、リフレクションのコードを書くのはとにかく面倒だ。
VB9では次のコードを実行できる。「p.(propName)」のようにメソッド呼び出しにカッコを付けていることに注意してほしい。
Option Strict Off
Imports System
Class Person
Private _Name As String = "Yoshimatsu"
Private _Age As Integer = 22
Public ReadOnly Property Name As String
Get
Return _Name
End Get
End Property
Public Readonly Property Age As String
Get
Return _Age
End Get
End Property
End Class
Module Module1
Sub Main(Args As String())
Dim p As New Person()
ProcessPerson(p, Args(0))
End Sub
Sub ProcessPerson(p As Object, propName As String)
Console.WriteLine(p.(propName))
End Sub
End Module
■“Strong Duck Typing” ? − Dynamic Interface
「アヒルのように歩き、アヒルのように鳴くものは、アヒルに違いない」
静的型付言語では次のコードはコンパイルできない。
Option Strict On
Imports System
Class Person
Public Name As String
End Class
Class PetAnimal
Public Name As String
End Class
Module Module1
Sub Main()
Dim p As New Person()
p.Name = "John"
Dim q As New PetAnimal()
q.Name = "Pochi"
ProcessFamily(p)
ProcessFamily(q)
End Sub
Sub ProcessFamily(p As Object)
Console.WriteLine(p.Name)
End Sub
End Module
PersonクラスにもPetAnimalクラスにもNameフィールドがあるにもかかわらず、このコードはコンパイルできない。このコードをコンパイルするには、Option Strict Offにして、コンパイラの助けを一切あきらめ、その後あらゆるコードについて正しくタイピングしたことを自分で保証する以外にない。
VB9では、「Dynamic Interface」の機能により次のようなコードがコンパイルできるようになる予定だ。残念ながらPDC05後に配布されたプレビュー版コンパイラにもこの実装は含まれていない。
Option Strict On
Imports System
<Dynamic> _
Interface IHasName
ReadOnly Property Name As String
End Interface
Class Person
Private _Name As String
Public ReadOnly Property Name As String
Get
Return _Name
End Get
End Property
End Class
Class PetAnimal
Private _Name As String
Public ReadOnly Property Name As String
Get
Return _Name
End Get
End Property
End Class
Module Module1
Sub Main(Args As String())
Dim p As New Person()
Dim q As New PetAnimal()
ProcessFamily(p)
ProcessFamily(q)
End Sub
Sub ProcessFamily(p As IHasName)
Console.WriteLine(p.Name)
End Sub
End Module
IHasNameインターフェイスは通常のInterface型ではなく、<Dynamic>属性によりVB9コンパイラに対するヒントとして機能する。コンパイル後はProcessFamilyメソッドが取るパラメータはObject型になる。だが、「As Object」とすると失われてしまうIntelliSense機能やコンパイル時の型チェックはDynamic Interfaceによって維持される。
これらの機能はいずれも最近の動的型付言語に何らかの形で含まれている。VBはそのルーツであるBASICの動的型付言語としての側面を排除し続けてこれまで進化してきた。しかしVB9は再度遅延バインディングを主要機能として前面に押し出し、特徴ある言語としての生き方を模索しようとしているようだ。
なお、ここまでの解説で「オブジェクト指向」という言葉をほとんど使わなかったことに気付いてほしい。動的な型付きとオブジェクト指向は両立する。Interface型によるポリモーフィズムだけがOOPではない。動的なプログラミングへの流れは、必ずしもオブジェクト指向と矛盾するものではない。
まとめ
PDC05で紹介されたMicrosoftの取り組みは、必ずしも技術として目新しいものではない。実際、本レポートで紹介したRSS、Ajax、動的プログラミングはいずれもすでに実践されているもので、Microsoftが発明したものではない。その意味では、今回のPDCはそれほどエキサイティングな場ではなかったのかもしれず、前編の冒頭で触れたPDCの法則は当たってしまったのかもしれない。
しかし、Microsoftはいつも追いかける立場にあってこそ技術を進歩させてきた。Javaを追いかけてCLRを作り、Netscapeを追いかけてInternet Explorerを作った。PDC05が先行者を追いかけ始める“のろし”だったのかどうか、答えはそう遠くない将来に出ることだろう。
INDEX | ||
[特集] PDC05レポート | ||
巻き返しが始まるMicrosoftのRSS/Ajax戦略 | ||
1.PDC05の3つのテーマ | ||
2.RSSへの取り組み | ||
3.Ajaxと新世代Webアプリケーション | ||
動的プログラミング言語へと発展するC# 3.0とVB 9.0 | ||
1.動的型付言語への憧憬 | ||
2.型推論とラムダ式/Extension Methodsの導入 | ||
3.クエリ構文の統合「LINQ」/DLinqとXLinq | ||
4.Visual Basicを再び動的プログラミング言語にする試み | ||
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|