文書構造を読み解く習慣がコードの質を高める、と思う

Corredor 200記事目なので、持論を展開してみる。

「英語ができない人はプログラミングもできない」と云われると思う。プログラミング言語やシステム開発に英語が多く登場し、それらの英単語としての語源や意味を詳しく知らないから、表面的な知識に終始してしまうから、というのも勿論要因だと思う。

でも、プログラミングができる日本人は、必ずしも英語がよく読めて英会話も難なくできる…というわけではないと思う。

では何が違うかというと、英語にしても日本語にしても、文章を読むときにその構造を分解して理解しているかどうかではないかと思う。

多分スラッシュリーディングが重要

例えば、ぼくは大学の受験勉強の時に英語の文法を押さえるために以下のようなマーキングを行っていた (平成28年度のセンター英語より)。

Although Tokyo has a relatively small land area,
           S    V           M             O

it has a huge population.
 S   V     M      O

もともとは英文法の講師に教わって始めたことで、文型に合わせて下線を引き、その下に SVOCM を書き入れる。俗にいうスラッシュリーディングというヤツで、これによって文章をチャンク (意味ごとのかたまり) で区切って読み取る習慣がついた。そして自分が英文を書くときも、このチャンクを意識して文型と単語を合わせていくことで、拙いながらも大きくは間違えていない、ギリギリ点数の入る英文が書けた。

スラッシュリーディングの精度が高いに越したことはないが、大事なのは日本語を読むにしても英語を読むにしても、この「スラッシュリーディング」に近い考え方を常にしているかどうかがカギだと思う。

現代文の読解も、ある文章の塊が別の文章にかかっているとか、前段を受けて最終段の締めが書かれているとか、そういった文章全体の構造を読み取れるかどうかで、点数が取れる、つまり正確に文章を理解できているかが変わってくる。

SQL もソースコードもスラッシュリーディングできる

たいていのプログラミング言語は、英語と同じ構成で書けるようになっている。これはつまり、スラッシュリーディングができるということだ。

例えば SQL の場合は、こんな感じでチャンクに区切って読むことができる。

Select name
  V    O

From member_table
    M

Where age > 20;
  M       (Greater Than)

これはあくまでイメージで、これらの単語がそれぞれ SVOCM のどれに属するか判断したりする必要はないと思う。また、プログラミング言語は大抵が「命令文」なので、S が登場しないことが多いが、大事なのは「何となくでもチャンク (意味ごとのかたまり)」を分けられるか、だ。

スラッシュリーディングをしようとして、チャンクを分けようとすると、

SELECT NAME FROM MEMBER_TABLE WHERE AGE > 20

と書いていた改行も色もついていない文章に対して、自然と改行を入れ、色付けをして、意味が分かりづらいところには解説コメントを入れるようになる。これがコードの可読性を上げるポイントに繋がると思う。これができると、

SELECT
    name
FROM
    member_table
WHERE
    age > 20
;

というインデントの意味が読み取れるようになり、自分が書くときもこうした改行・インデントが付けられるようになるはずだ。

もう一例

次は Java のコードで英語の文型を感じてみる。

/** ユーザを示すクラス */
public class User {
  /** 名前 */
  private String name;
  /** 年齢 */
  private int age;
  
  /** 名前を返す */
  public String getFullName() {
    return name;
  }
  
  /** 成人かどうか */
  public isAdult() {
    return age >= 20;
  }
}

このクラスを使う時はこうなる。

User currentUser = new User();  // ユーザの生成処理は省略。
String currentUsersName = currentUser.getName();
                               S       V   O
                          (get は say などに読み替えると分かりやすいかも)

if(currentUser.isAdult()) { /* 成人の場合の処理 */ }
[?]     S      V   C

オブジェクトが S で、メソッドが V。オブジェクト指向に組み立てていけば、基本的にこの構造は変わらない。メソッドの引数は、動作を変更・限定させるための目的語だったり修飾語だったりする、と考えることもできる。

・ネイティブ話者でない人と意思疎通するにはSVを先に明示するのが合理的
・意思疎通において SV は必須だが OやCは省略可能
ということを強調したかったからです。この事をオブジェクト指向言語的に記述してみると「S.V(O,C,M)」もうちょっとプログラムっぽく書くと
subject.verb(Object o,Complement c,Modifier m) の様な感じでしょうか?
ここでのカッコ() 表記は、メソッド(関数)の呼び出しを意味するカッコ表記ですが、このカッコの意味を「省略可能である」「補足情報である」という意味でとらえ直すとなかなか興味深い表記に見えてきませんか?

オブジェクト指向は可読性が高い、という。なぜか。
オブジェクト指向はS Vの順番になるから。主語、述語。

これを全て逆に考えていくと、「ココでユーザ名を答えさせたい。名前を返答するのは誰だ?ユーザクラスだ」と考えられ、User (S) が name (O) を say (V) する。say (言う) の単語は言語的な考え方で、get (取得する) で書き換える、と。そうすれば、User クラスに getName() メソッドを構築するに至るはずだ。

英単語を沢山知っているとか、英文法を完璧に押さえているとか、そんな必要はないし、英語がよくできるようになったとしても、すぐプログラミングができるとは限らない。大事なのは文章の意味ごとに区切り、構造を分解できるようになること。そしてコーディングに際しては、分解した構造を改行やインデントで表現することだ。