式(Expression)と文(Statement)

式と文の違いは知っておくといろいろ役立ちますので、ご紹介したいと思います。

プログラミング言語の構文の要素は、式(Expression)と文(Statement)に分類されます。プログラマであれば、用語としては把握していなくても、プログラミングの実践の中で、式と文を明確に区別して認識されていると思います。以降では、式と文とは何か、その違いがプログラミング言語の構文に与える影響、プログラムの書き方に与える影響を説明します。

VBで例を挙げると、文には代入文、If文、For文、While文、呼び出し文などがあり、式には条件式(比較式)、呼び出し式、加減算式、定数式などがあります。

1: Dim a As Integer
2: a = 10            ' ←代入文
3: If a = 10 Then    ' ← ここのa = 10は条件式
4:     Console.WriteLine("aは10です。")
5: End If

※左端の1:〜5:は行番号を示すために便宜上付加しているもので、コードの一部ではありません。

上記のコード例では、1行目のDim 〜の部分は宣言文、2行目は代入文、3〜5行目はIf文で、3行目の「a = 10」の部分は条件式で、4行目のConsole.〜の部分は、呼び出し文(戻り値を持たないメソッド呼び出しのため)です。さらに細かく言えば、2行目や3行目のaは、単純名前式で、10は定数式です。

この例から、式、文の違いがぼんやりと見えてきたでしょうか。文はそれ単独で完結する言語要素です。式はそれ単独では基本的に完結せず、文または式の一部として使用される言語要素です。また、式の最大の特徴として、値を返すという点が挙げられます(文は値を返しません)。例えば、定数式はその値そのものを返します。条件式は真偽値(True/False)を返す式です。条件式の一つとして比較式がありますが、条件式そのものはTrue/Falseを返せばなんでもよいため、単なるBooleanのTrue(定数式)もまた条件式になります。比較式は比較演算子を挟んで左辺と右辺の式を比較し、その結果をTrue/Falseで返すため、条件式になることができます。

VBC#を式と文の観点で比較するときに代入は興味深い違いがあります。VBでは代入は文ですが、C#では代入は式です。C#の代入が式なのは、C言語の系譜を継ぐ言語だからでしょう。以下のコード例で、代入文と代入式の違いを示します。

' VBのコード
Dim a As Boolean
Dim b As Integer
a = b = 0
// C#のコード
int a;
int b;
a = b = 0;

上がVB、下がC#のコード例です。3行目は「a = b = 0」という形になっているのは共通しています。しかし、この行の意味はVBC#でまったく異なります。先にC#の意味を説明すると、b = 0は代入式のため、変数bに定数0を代入します。それと同時にこの代入式は代入した値自身を返します。つまり、0を返します。その結果、

b = 0;
a = 0;

と書いた場合と同じ意味になります。それに対してVBの場合、「a = ?」という形式は、代入文の形ですが、?に当たる「b = 0」の部分には、文は来ることができないルールが言語仕様で定められているため、「b = 0」は式であるとみなされ、その結果、比較式であると解釈されます。bはIntegerで宣言だけをしてあるので、暗黙的に値は0です。そのため、「b = 0」の比較式はTrueを返します。よって、a = Trueと記述した場合と同じ結果になります。

では、C#VBの場合と同じ意味のコードを書くとどうなるかというと以下のようになります。

bool a;
int b;
a = b == 0;

VBでは代入演算子も比較演算子の等号もどちらも「=」ですが、C#では代入演算子は「=」、比較演算子の等号は「==」として区別されているため、このようなコードになります。
逆に言えば、C#で「a = b = 0」と記述して、aにもbにも0を代入と記述できるのは、代入演算子と比較演算子の等号とをそれ単独で区別可能な記号体系にしているからと言えます。VBでこのC#の機能を実現しようと思ったら、代入と等号を別の記号にするか、あるいは、連続的に代入するための記号を追加するといった何らかの大きな言語仕様の変更が必要です。

ちなみに、VB9.0ではIf式が追加されましたが、当記事の解説を読むとIf文とIf式の区別の意味がわかります。式と文の違いを理解していると様々な言語とその言語仕様を理解する上で役立ちます。プログラミングをする際にその違いを意識してみてはどうでしょうか。