t-hom’s diary

主にVBAネタを扱っているブログ…とも言えなくなってきたこの頃。

プログラムコード中に値(あたい)は登場しない

VBAに限らず全てのプログラミング言語で言えることだが、コード中に値(あたい)が直接登場することは無い。
最近、「値とは何か」ということを掘り下げて考えることがあり、ようやくこの結論に行きついた。

たとえば、数字の「1」。これは一般的に値だと理解されるが、表面的には単なる文字にすぎない。
「ひとつ」という概念を表した文字だ。

「1」という値が現れるのは、その文字を見た人の頭の中である。
値は確かに存在するが、書かれた文字は単なる記号でしかない。人が理解することで、初めて値が現れる。

プログラミングにおいても同じことが言える。
コンピューターは物事の概念を理解しないが、しいていえばコンピューターにとっての値とは、CPUが直接処理可能な「電気信号」である。

ただしブログ上に電気信号を書き表すというわけにもいかないので、便宜上スイッチのON・OFFを1と0で表した二進数で説明する。

たとえば次のコードを考えてみる。

Debug.Print 2 + 3

仮にCPUが32ビットだとすると、
「2」は「00000000000000000000000000000010」に変換され、
「3」は「00000000000000000000000000000011」に変換され、
CPUで加算されて「00000000000000000000000000000101」になり、
「5」という文字に変換されて出力される。

プログラム中に現れる「2」や「3」は値ではなく式である。
式と聞くと数式を思い浮かべる方が多いと思うが、本来の意味は「何かの事物や構造を記号で書き表したもの」を指す。
たとえば「2」は2という概念を表した式だ。

このように特定の値を直接的に指す式のことを、リテラルと呼ぶ。
リテラルの和訳は「即値」といい、これまで私はリテラルを式でもあり、値でもあると考えていた。

しかし、リテラルは単に式であり、値ではない。
つまりコード中に現れるこれまで「値」と呼ばれてきたものは、すべて「式」だ。

この視点でFizzBuzzを見てみよう。

Sub FizzBuzz()
    Dim i As Integer
    For i = 1 To 100
        If i Mod 15 = 0 Then
            Debug.Print "FizzBuzz"
        ElseIf i Mod 3 = 0 Then
            Debug.Print "Fizz"
        ElseIf i Mod 5 = 0 Then
            Debug.Print "Buzz"
        Else
            Debug.Print i
        End If
    Next
End Sub

文法的には、こういうことになる。

Sub 識別子()
    Dim 変数 As 型名
    For 変数 =ToIfThen
            Debug.PrintElseIfThen
            Debug.PrintElseIfThen
            Debug.PrintElse
            Debug.PrintEnd If
    Next
End Sub

「式」という表記が、すべての例外を吸収してくれる。

ザッツ、シンプル!ビューティフォー!

裏付け

以下はVBAの言語仕様書
VBA Language Specification(英語)

この76~77ページにFor文の定義がある。

For文の定義

for-statement = simple-for-statement / explicit-for-statement
simple-for-statement = for-clause EOS statement-block "Next"
explicit-for-statement = for-clause EOS statement-block ("Next" / (nested-for-statement ",")) bound-variable-expression
nested-for-statement = explicit-for-statement / explicit-for-each-statement
for-clause = "For" bound-variable-expression "=" start-value "To" end-value [stepclause]
start-value = expression
end-value = expression
step-clause = Step" step-increment
step-increment = expression

For文の定義の訳

for-statement = simple-for-statement / explicit-for-statement
for文 とは シンプルなfor文 または 明示的なfor文 である。

simple-for-statement = for-clause EOS statement-block "Next"
シンプルなfor文 は for節 ステートメントの終わり ステートメントブロック Next で構成される。

explicit-for-statement = for-clause EOS statement-block ("Next" / (nested-for-statement ",")) bound-variable-expression
明示的なfor文 は for節 ステートメントの終わり ステートメントブロック (Next または (ネストされたfor文とカンマ)) 束縛変数式 で構成される。

nested-for-statement = explicit-for-statement / explicit-for-each-statement
ネストされたfor文 とは 明示的なfor文 または 明示的なfor-each文である。

for-clause = "For" bound-variable-expression "=" start-value "To" end-value [stepclause]
for節 は For 束縛変数式 = 開始値 To 終了値 [step節] で構成される。

start-value = expression
始値 は 式である。

end-value = expression
終了値 は 式である。

step-clause = Step" step-increment
step節は Step step増分 で構成される。

step-increment = expression
step増分 は 式である。

参考

VBAの言語仕様書の定義はABNFというメタ言語で記述されている。基本情報技術者試験で出題されるBNFを拡張したものだ。
ABNFの定義はRFC4234 http://www.rfc-editor.org/rfc/rfc4234.txt を参照(英語)

以上。

当ブログは、amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイト宣伝プログラムである、 Amazonアソシエイト・プログラムの参加者です。