Visual Basic(VB)の次期版9.0の言語仕様が明らかになってきた。2月2~3日に横浜で開催されたMicrosoft Developers Conference 2006の講演,およびマイクロソフトのWebサイトに掲載されているドキュメントによれば,VB 9.0は動的言語を意識したものになるようだ。1月17日に公開されたVB 9.0 LINQ Technology Previewをインストールすれば,実際にコードの動作を確認することもできる。以下では,VB 9.0の新機能のうち,動的言語と関係の深い「暗黙の型のローカル変数」「動的インタフェース」「動的識別子」の3つに注目し,その概要を紹介する。

●暗黙の型のローカル変数

 VB 9.0では,ローカル変数を宣言する際に,型を明示的に指定しなくてもコンパイラが初期化に使用する値を基に推測してくれる。例えば,


Dim Age = 39
Dim Name = "John"
Dim Emp = New Employee{ Id := 1001,…}

と宣言するのは,それぞれ


Dim Age As Integer = 39
Dim Name As String = "John"
Dim Emp As Employee = New Employee{ Id := 1001,…}

と宣言するのと同等になる。ちなみに,「New Employee{ Id := 1001,…}」のように「プロパティ名:=初期値」の形式でオブジェクトの生成と初期化を簡潔に記述できるのもVB 9.0の新機能の一つである。

 ここで,「同等」と述べたことから分かるように,As以下を省略したからといってVBが動的な型付けの言語になるわけではないことに注意していただきたい。VBのコンパイラは,「=」の右辺の「39」がInteger型なので左辺のAgeもInteger型であると推測し,以後AgeをInteger型とみなして静的な型チェックを行うのである。変数を初期化式と異なる型にするためには,以下のように明示的に型を指定しなければならない。


Dim Emp As Object = New Employee{ Id := 1001,…}

 こうした点から推測できるように,この機能を使えば動的言語とよく似た記述ができるのは間違いないものの,それを最大の目的としているわけではないようだ。C#の次期版であるC# 3.0が同様の機能を搭載する予定であることからも,それがうかがえる。C# 3.0では,


Employee emp = new Employee(…);
と記述する代わりに

var emp = new Employee(…);

と書けるようになる。

 実は,C++の次期ISO標準(C++0xと呼ぶ)でも,autoと宣言した変数の型をコンパイラが初期化式から推測する機能を追加することが検討されている。C++の設計者であるBjarne Stroustrupは,C/C++ Users Journal2005年5月号の記事でC++の初心者をサポートするための機能の一つとしてこの機能を紹介している。テンプレートを利用した型やイテレータなどの宣言は長くなりがちなので,


vector<vector<Employee> >::const_iterator p = find(v.begin( )…);

などと書く代わりに,単に


auto p = find(v.begin( )…);

と記述できるのは,上級者にとっても入力ミスを防止するメリットがあると言える。

●動的インタフェース

 動的言語の特徴の一つにDuck Typingが可能な点が挙げられる。Duck Typingは,「アヒルのように歩き,アヒルのように鳴くなら,それはアヒルである」,つまり「オブジェクトが期待する振る舞いをするなら,そのオブジェクトの実際の型が何であるかは問わない」という考え方を指す。例えば以下のコードは,引数duckが実際に参照するオブジェクトが文字列を返すQuackメソッドを持つ限り,そのオブジェクトの型が何であっても動作する。duckが特定のインタフェースを持つかどうかなどは関係ない。


Option Strict Off
…
Sub DuckTalk(duck) 
  Console.WriteLine(duck.Quack())
End Sub

 VBでは遅延バインディング(実行時バインディング)を行うことで以前からDuck Typingが可能であった。VB .NET以降でDuck Typingを行うには,「Option Strict Off」としたうえで,型を省略してオブジェクトを宣言すればよい。とはいえ,遅延バインディングであっても結局のところ「特定の名前のメンバーを持つ」など何らかの仮定の基にコードを記述せざるを得ない。

 そこで,こうした仮定をコード中で明確にし,Duck Typingの安全性と利便性を高めるために用意されたのが「動的インタフェース」である。動的インタフェースは,通常のインタフェースと同様に公開するメソッドの仕様を定めるものの,それが参照するオブジェクトのバインディングは遅延バインディングになる。例えば以下のようなコードを記述すると,引数duckを遅延バインディングで扱う一方で,duckに対して型チェックやIntelliSenseなどが有効になる。明示的なキャストなどが不要になるのも利点の一つだ。


…
Dynamic Interface IDuck
  Function Quack() As String
End Interface

Sub DuckTalk(duck As IDuck) 
…

●動的識別子

 動的識別子は,メソッド名などの識別子を実行時に動的に指定して呼び出せるようにする機能である。VB 6.0,VB .NETは,それぞれOLEオートメーション,.NETのリフレクションを使ってメソッドやプロパティなどをアドレスやインデックスではなく「名前」を指定してアクセスする方法を用意していたが,実際に利用するのはかなり面倒だった。VB 9.0ではこうした仕組みを明示的に使わなくても,実行時に指定した名前でアクセスできるようになる。使い方については以下のコードを参照してほしい。


Class Dog
  Public Bark As String
End Class

Class Cat
  Public Mew As String
End Class

Dim Props = New Dictionary(Of String, String) _
    { {"Dog", "Bark"}, {"Cat", "Mew"} }

Dim Animal As Object = New Dog { Bark := "Wow" }
  …
Console.WriteLine(Animal.(Props(Animal.GetType().Name)))