『リーダブルコード』第3章のテーマは、良い名前の第一条件は曖昧さがないことだ、という話。読み手の立場に立ち、どんな誤解が起こりうるかを先に想像してから名前を決める。
これまでの読書感想はこちら:
第3章は8つの節に分かれていて、それぞれ実際のコーディング場面を扱っている。
8つの節
3.1節は filter() が題材。 filter は、条件に合うデータを残すとも、条件に合うデータを取り除くとも読めてしまう。書籍では、この曖昧な名前を捨てて、実際の意味に合わせて select() (残す)か exclude() (取り除く)に変えるよう勧めている。
3.2節は Clip(text, length) の問題。 Clip には、末尾から N 文字を削除する、最大 N 文字になるように切り詰める、という2通りの読み方がある。引数の length も、バイト数なのか文字数なのか単語数なのか分からない。書籍では Truncate(text, max_chars) に変えている。名前で切り詰めという動作を表し、引数に単位を付けることで、曖昧さをなくす。
3.3節は境界を表す定数の名前。 XXX_LIMIT のような名前では、その境界値を含むのか含まないのかが読み手に分からない。上限と下限を表す定数には max_ と min_ を前置する、という決まりにすれば、境界の意味がひと目で分かり、オフバイワン(off-by-one)系のバグも避けやすくなる。
3.4節は、始点も終点も範囲に含める閉区間。 start と stop では曖昧になるので、 first と last を優先して使う。意味が合う場面なら min と max でもいい。
3.5節は、始点を含み終点を含まない半開区間。この場面では begin と end を使うのが業界の慣習だ。 end は字面だけだと曖昧だが、C++ の標準ライブラリなどで広く使われている書き方なので、現時点ではこれが最善の選択になる。
3.6節は、真偽値の変数と、真偽値を返す関数の名前。意味のはっきりしない単語は避けて、 is 、 has 、 can 、 should を前置する習慣をつける。否定形の名前もなるべく避け、たとえば disable_ssl ではなく、肯定形の use_ssl にする。
3.7節は、プログラマーがすでに持っている期待を裏切らないこと。 get*() と書いてあれば軽い値の取得、 size() と書いてあれば O(1) の高速な呼び出し、と誰もが思い込む。実際にはコストの大きいメソッドなら、こうした名前は使わない。使ってしまうと、呼び出す側が先入観のまま非効率なコードを書いてしまう。
3.8節は、A/B テストの実験設定という実際の業務の例で、名前を決める思考の流れを通して見せている。開発者はまず template 、 reuse 、 copy 、 inherit といった候補を挙げ、業務を知らない利用者の立場から、それぞれがどんな誤解を生むかを順に考える。そのうえで、曖昧さがもっとも小さい copy_experiment と inherit_from_experiment_id を選ぶ。
感想
読み終えて考えたのは、この章が AI 駆動開発でどう効いてくるか、ということだ。AI は処理の中身を読んで、各関数が何をしているかを判断できる。だから名前はそこまで重要ではない、と思いがちだ。ただ、理解のミスを減らし、理解のずれを減らし、トークンの消費を減らすという点で、誤解されない関数名を書くことは今も重要だと思う。特に、名前が曖昧だと、AI は意味を確かめるために関数の本体や呼び出し元など、より多くの文脈を読みにいくことになる。そこにコストがかかる。
人間は曖昧な名前に出会うと、迷って確認する。AI は、もっともありそうな解釈でそのまま書き進める傾向がある。一度誤解が起きると、その後に生成されるコードは誤解の上に積み重なっていく。これが理解のずれだ。
もう一つの問題はレビューにある。人間が AI の書いたコードをレビューするとき、事前にある程度の制約を置いていないと、AI は誤解を招きやすい名前をつけることがある。危ないのは、明らかにおかしい名前ではない。そういう名前は一目で分かる。危ないのは、一見もっともらしいのに意味が少しずれている名前のほうだ。たとえば get_user_data が実際にはネットワークリクエストを送っているなら、3.7節の原則にまさに反している。こういう名前はざっと見ただけでは見逃しやすく、レビューする人の心の負担も重くなる。
では、AI 自身に「読み手の立場で推論させる」ことで解決できるか。効果は限定的だと思う。AI は全部の文脈を持っているので、本当に「業務を知らない」状態にはなりにくいからだ。もっと現実的なのは、ルールをプロジェクトの規約に書いておき、AI の判断力に頼らず、ルールを実行させるやり方だ。たとえば、真偽値の変数には is 、 has 、 can 、 should を必ず付ける。区間は begin / end で統一する。単位のある引数は、単位を名前に入れる。